Subscribe

There are two ways that otherwise plain text protocols can provide
encryption with TLS. The first way is to listen on two ports: one port
that is always plain text, and a second port that is always encrypted
with TLS. The other way is to use a single port on which communication starts
out unencrypted, but can be "upgraded" to a TLS encrypted connection using
an application-level command specific to the protocol. HTTP/HTTPS uses exclusively the first approach,
with ports 80 and 443. The second approach, called STARTTLS, is used by SMTP,
XMPP, IMAP, and POP3, though several of those protocols also support the first approach.

There's a clear bias for STARTTLS in the IETF's email standards.
The use of alternative TLS-only ports for IMAP, POP3, and SMTP was never formally standardized:
people just started doing it that way,
and although port numbers were registered for the purpose, the registration of the encrypted SMTP (SMTPS) port (465) was
later rescinded. When the IETF finally standardized the use of TLS with IMAP and POP3 in 1999,
they prescribed the use of STARTTLS and gave several reasons
why STARTTLS should be used instead of an alternative TLS-only port. Briefly, the reasons are:

Separate ports lead to a separate URL scheme, which means the user has to choose between them. The software
is often more capable of making this choice than the user.

Separate ports imply a model of either "secure" or "not secure," which can be misleading. For example, the "secure"
port might be insecure because it's using export-crippled ciphers, or the normal port might be using a SASL mechanism
which includes a security layer.

Separate ports has caused clients to implement only two security policies: use TLS or don't use TLS. The desirable
security policy "use TLS when available" would be cumbersome with the separate port model, but is simple with STARTTLS.

Port numbers are a limited resource.

Except for reason four, these reasons are pretty terrible. Reason
one is not very true: unless the software keeps a database of
hosts which should use TLS, the software is incapable of making the
choice between TLS and non-TLS on behalf of the user without being
susceptible to active attacks. (Interestingly, web browsers have
recently started keeping a database of HTTPS-only websites with HSTS preload lists, but this
doesn't scale.)

Reason three is similarly dubious because "use TLS when available" is also susceptible to active attacks.
(If the software detects that TLS is not available, it doesn't know if
that's because the server doesn't support it or if it's because an active attacker
is blocking it.)

Reason two may have made some sense in 1999, but it certainly doesn't today.
The export cipher concern was mooted when export controls
were lifted in 2000, leading to the demise of export-crippled ciphers.
I have no idea how viable SASL security layers were in 1999, but in the last
ten years TLS has clearly won.

So STARTTLS is really no better than using an alternative TLS-only port.
But that's not all. There are several
reasons why STARTTLS is actually worse for security.

The first reason is that STARTTLS makes it impossible to terminate TLS in a protocol-agnostic way.
It's trivial to terminate a separate-port protocol like HTTPS in a software proxy like
titus or in a hardware load balancer: you simply accept a TLS
connection and proxy the plain text stream to the backend's non-TLS port. Terminating a STARTTLS protocol,
on the other hand, requires the TLS terminator to understand the protocol being proxied, so it can watch for
the STARTTLS command and only upgrade to TLS once the command is sent. Supporting IMAP/POP3/SMTP isn't
too difficult since they are simple line-based text protocols. (Though you have to be careful - you don't
want the TLS terminator to misfire if it sees the string "STARTTLS" inside the body of an email!) XMPP, on the
other hand, is an XML-based protocol, and do you really want your TLS terminator to contain an XML parser?

I care about this because I'd like to terminate TLS for my SMTP, IMAP, and XMPP servers in the highly-sandboxed
environment provided by titus, so that a vulnerability in the
TLS implementation can't compromise the state of my SMTP, IMAP, and XMPP servers. STARTTLS makes
it needlessly difficult to do this.

Another way that STARTTLS harms security is by adding complexity. Complexity is a fertile source
of security vulnerabilities. Consider CVE-2011-0411,
a vulnerability caused by SMTP implementations
failing to discard SMTP commands pipelined with the STARTTLS command. This vulnerability allowed attackers to inject
SMTP commands that would be executed by the server during the phase of the connection that was supposed to be protected with TLS. Such a vulnerability is impossible
when the connection uses TLS from the beginning.

STARTTLS also adds another potential avenue for a protocol downgrade attack. An active attacker can strip out the server's
advertisement of STARTTLS support, and a poorly-programmed client would fall back to using the protocol without TLS. Although it's trivial for a properly-programmed client to protect against this downgrade attack,
there are already enough ways
for programmers to mess up TLS client code and it's a bad idea to add yet another way.
It's better to avoid this pitfall entirely by connecting to a port that talks only TLS.

Fortunately, despite the IETF's recommendation to use STARTTLS and the rescinding of the SMTPS port assignment,
IMAP, POP3, and SMTP on dedicated TLS ports are still widely supported by both server and client email implementations,
so you can easily avoid STARTTLS with these protocols.
Unfortunately, the SMTPS port is only used for the submission of authenticated mail by mail clients.
Opportunistic encryption between SMTP servers, which is extremely important for preventing passive eavesdropping
of email, requires STARTTLS on port 25. And modern XMPP implementations support only STARTTLS.

Moving forward, this shouldn't even be a question for new protocols.
To mitigate pervasive monitoring,
new protocols should have only secure versions. They can be all TLS all the time.
No need to choose between using STARTTLS and burning an extra port number.
I just wish something could be done about the existing STARTTLS-only protocols.