Skip to main content

Synchronous Access of SMTP without Timeout

PY040
no_timeout
CWE-1088
⚠️ Warning

The smtplib.SMTP, smtplib.SMTP_SSL, and smtplib.LMTP classes are used to send emails via the Simple Mail Transfer Protocol (SMTP). These classes can establish network connections to mail servers and by default do not specify a timeout for network operations. If a timeout is not specified, the connection may block indefinitely, leading to potential resource exhaustion or application hang-ups, particularly in production environments or network failure scenarios.

This rule enforces that a timeout parameter must be provided when instantiating smtplib.SMTP, smtplib.SMTP_SSL, or smtplib.LMTP to prevent the possibility of indefinite blocking.

Failing to specify a timeout in these functions may cause the application to block indefinitely while waiting for a response from the mail server. This can lead to Denial of Service (DoS) vulnerabilities or cause the application to become unresponsive.

Example

import smtplib
import ssl


server = smtplib.SMTP("smtp.example.com", 587)
server.starttls(context=ssl.create_default_context())

Remediation

Always provide a timeout parameter when using smtplib.SMTP, smtplib.SMTP_SSL, or smtplib.LMTP. This ensures that if the mail server is unreachable or unresponsive, the connection attempt will fail after a set period, preventing indefinite blocking and resource exhaustion.

Alternatively, the global default timeout can be set via socket.setdefaulttimeout(). This is a good option to enforce a consistent timeout for any network library that uses sockets, including smtplib.

import smtplib
import ssl


server = smtplib.SMTP("smtp.example.com", 587, timeout=10)
server.starttls(context=ssl.create_default_context())

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 (PY040) or rule category name (no_timeout).

Fix Iconfix
import smtplib
import ssl


# suppress: PY040
server = smtplib.SMTP("smtp.example.com", 587)
server.starttls(context=ssl.create_default_context())

See also