SMTP TLS configuration and credential protection¶
A mail-submission client can expose credentials or message content when it authenticates before transport protection is established. This guide uses Python smtplib with an SMTP submission service on port 587. Use the transport mode documented by your provider; port numbers alone do not establish encryption.
Require STARTTLS before authentication¶
Assume smtp_host is a deployment-controlled hostname and username and password come from the application's secret mechanism. Neither example sends a message.
Unsafe: authenticate on the initial unencrypted connection.
import smtplib
with smtplib.SMTP(smtp_host, 587, timeout=10) as smtp:
smtp.login(username, password)
Safer: upgrade with certificate validation, then authenticate.
import smtplib
import ssl
context = ssl.create_default_context()
with smtplib.SMTP(smtp_host, 587, timeout=10) as smtp:
smtp.ehlo()
smtp.starttls(context=context)
smtp.ehlo()
smtp.login(username, password)
If STARTTLS is unavailable or certificate validation fails, let the operation fail. Do not catch that error and retry authentication over plaintext. The second EHLO refreshes server capabilities after the upgrade. Python's smtplib documentation explains this sequence.
A service requiring TLS from the beginning commonly uses SMTP_SSL instead; pass a validating SSL context there too. Keep hostname checking and trust validation enabled. The Python SSL documentation describes the default client context.
Check the failure path¶
Use a local test SMTP service and fictional credentials. Verify that authentication occurs only after a successful TLS upgrade. When the server omits STARTTLS or presents an untrusted certificate, assert that the client sends no authentication command. No email needs to be delivered and no real mailbox should be involved.
Also check the deployed endpoint, timeout and retry policy. Disable protocol debug output in production when it could expose authentication exchanges or message contents. Store credentials outside source and rotate them if an earlier plaintext connection exposed them.
Continue with cleartext protocols, certificate validation and hardcoded keys. TLS to the submission server protects that connection; it is not a claim of end-to-end encryption through every relay to the recipient.