STARTTLS (opportunistic TLS upgrade)
Definition
STARTTLS is a command that upgrades an existing plaintext connection in protocols such as SMTP, IMAP and POP3 to TLS on the same port.
STARTTLS (called STLS in POP3) lets a client connect in plaintext, check that the server advertises TLS support, and then issue a command that switches the same TCP connection to TLS. For SMTP it is defined in RFC 3207; IMAP and POP3 use RFC 2595, and XMPP and LDAP have their own equivalents. The alternative is implicit TLS, where TLS starts immediately on a dedicated port such as 465 for SMTP submission, 993 for IMAP or 995 for POP3.
Why it matters
The upgrade step itself is unprotected. An active attacker can remove the STARTTLS capability from the server's response or make the command fail, and many clients then continue in plaintext. Between mail servers on port 25, TLS is usually opportunistic and certificates are often not verified at all. Defenses: configure user clients to require TLS, and for server-to-server mail publish DANE TLSA records (RFC 7672) or an MTA-STS policy (RFC 8461), so that sending servers insist on authenticated TLS. RFC 8314 recommends implicit TLS for users submitting and reading mail.
Example
openssl s_client -connect mail.example.com:25 -starttls smtp -servername mail.example.com </dev/null
openssl s_client -connect mail.example.com:587 -starttls smtp -servername mail.example.com </dev/null
openssl s_client -connect mail.example.com:143 -starttls imap -servername mail.example.com </dev/null
The STARTTLS checker runs the same test from outside your network.
Common misconceptions
- STARTTLS is a different protocol from TLS. It is only a command; once issued, the connection runs ordinary TLS with ordinary certificates.
- If both mail servers support STARTTLS, mail is encrypted end to end. It protects each hop only, and without DANE or MTA-STS a downgrade on a hop can go unnoticed. End-to-end protection needs S/MIME or similar.
- Ports 465 and 587 are interchangeable. Port 465 expects TLS from the first byte; port 587 expects plaintext followed by STARTTLS. Mixing them up causes handshake failures or timeouts.