Cleartext Transmission of Sensitive Information in the smtplib
Module
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
).
- Using rule ID
- Using category name
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()
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: cleartext_transmission
server = smtplib.SMTP('localhost')
# suppress: cleartext_transmission
server.login("user", "password")
server.set_debuglevel(1)
server.sendmail(fromaddr, toaddrs, msg)
server.quit()