Skip to main content

Cleartext Transmission of Sensitive Information in the smtplib Module

PY016
cleartext_transmission
CWE-319
⛔️ Error

The Python module smtplib provides a number of functions for accessing SMTP servers. However, the default behavior of the module does not provide utilize secure connections. This means that data transmitted over the network, including passwords, is sent in cleartext. This makes it possible for attackers to intercept and read this data.

The Python module smtplib should only in a secure mannner to protect sensitive data when accessing SMTP servers.

Example

import smtplib


def prompt(prompt):
return input(prompt).strip()

fromaddr = prompt("From: ")
toaddrs = prompt("To: ").split()
print("Enter message, end with ^D (Unix) or ^Z (Windows):")

# Add the From: and To: headers at the start!
msg = ("From: %s\r\nTo: %s\r\n\r\n" % (fromaddr, ", ".join(toaddrs)))
while True:
try:
line = input()
except EOFError:
break
if not line:
break
msg = msg + line

print("Message length is", len(msg))

server = smtplib.SMTP('localhost')
server.login("user", "password")
server.set_debuglevel(1)
server.sendmail(fromaddr, toaddrs, msg)
server.quit()

Remediation

If the SMTP protocol must be used and sensitive data will be transferred, it is recommended to secure the connection using SMTP_SSL class. Alternatively, the starttls function can be used to enter a secure session.

import smtplib


def prompt(prompt):
return input(prompt).strip()

fromaddr = prompt("From: ")
toaddrs = prompt("To: ").split()
print("Enter message, end with ^D (Unix) or ^Z (Windows):")

# Add the From: and To: headers at the start!
msg = ("From: %s\r\nTo: %s\r\n\r\n" % (fromaddr, ", ".join(toaddrs)))
while True:
try:
line = input()
except EOFError:
break
if not line:
break
msg = msg + line

print("Message length is", len(msg))

server = smtplib.SMTP_SSL('localhost')
server.login("user", "password")
server.set_debuglevel(1)
server.sendmail(fromaddr, toaddrs, msg)
server.quit()

False Positives

In the case of a false positive the rule can be suppressed. Simply add a trailing or preceding comment line with either the rule ID (PY016) or rule category name (cleartext_transmission).

Fix Iconfix
import smtplib


def prompt(prompt):
return input(prompt).strip()

fromaddr = prompt("From: ")
toaddrs = prompt("To: ").split()
print("Enter message, end with ^D (Unix) or ^Z (Windows):")

# Add the From: and To: headers at the start!
msg = ("From: %s\r\nTo: %s\r\n\r\n" % (fromaddr, ", ".join(toaddrs)))
while True:
try:
line = input()
except EOFError:
break
if not line:
break
msg = msg + line

print("Message length is", len(msg))

# suppress: PY016
server = smtplib.SMTP('localhost')
# suppress: PY016
server.login("user", "password")
server.set_debuglevel(1)
server.sendmail(fromaddr, toaddrs, msg)
server.quit()

See also