This is based on joint research involving
Two ways to establish TLS connection:
In the web we only use implicit TLS
(HTTPS, separate port 443)
Most common use of STARTTLS is with E-Mail protocols
This talk mostly focuses on client to server communication, but we will discuss server to server later
All E-Mail protocols (SMTP, POP3, IMAP) support STARTTLS.
For client to server communication all three protocols also support implicit TLS.
How does STARTTLS work?
S: 220 example.org ESMTP C: EHLO myhost S: 250-example.org Hello [126.96.36.199] 250-8BITMIME 250 STARTTLS C: STARTTLS S: 220 OK [TLS Handshake] C: EHLO myhost S: 250-example.org Hello [188.8.131.52] 250-8BITMIME 250 AUTH PLAIN C: AUTH PLAIN AGFsaWNlQGV4YW1wbGUuaW52YWxpZFM0NQ== S: 235 Authentication succeeded C: MAIL FROM:<firstname.lastname@example.org> [...]
Let's first state the obvious:
Opportunistic STARTTLS is insecure
Some clients implement STARTTLS in a mode where they will use it if the server offers it, but stay in plain text when the server does not ("Opportunistic")
This is uncommon in modern clients, and it obviously provides no protection against active attackers, as they can just pretend the server does not support STARTTLS
But this is not the only security problem with STARTTLS
We have a special state transition, there is a part of the protocol interaction before and after the TLS handshake
This raises some questions:
Can be sent at any time
Alert sent in plain text, but it looks like a legitimate message from the server
Is it part of the TLS session or not?
Plaintext command injection in multiple implementations of STARTTLS
C: STARTTLS S: 220 OK [TLS Handshake] C: EHLO myhost S: 250-example.org Hello [184.108.40.206]
C: STARTTLS EHLO myhost S: 220 OK [TLS Handshake] S: 250-example.org Hello [220.127.116.11]
We can send something in plaintext together with the STARTTLS command, a buggy server will think it it is part of the TLS connection
This bug was originally found in Postfix, but affected multiple mail servers, including Cyrus, Courier, Qmail, and various proprietary mail stacks
How can we attack this?
A similar attack works with IMAP
This bug was discovered in 2011, but our research showed that it is still prevalent
1,5% of SMTP servers
2,6% of POP3 servers
2,4% of IMAP servers
Can we do the same the other way round?
C: STARTTLS S: 220 OK 250-example.org Hello [18.104.22.168] [TLS Handshake]
Clients can be vulnerable to the same type of bug, we call this a response injection
This can be used by an attacker to spoof mailbox content
More than half of the mail clients we tested were vulnerable to this bug
STARTTLS Command Injection was discovered in 2011 and affected multiple implementations, vulnerable implementations are still widely used
The same bug class exists on the client and affects the majority of implementations
If you try to implement STARTTLS and are not aware of this flaw it is very likely that you will have this bug, too
These are clear signs that we should consider this to be a systemic problem in the standard
An IMAP server can start a session in PREAUTH mode, meaning the user is already in an authenticated state without logging in
STARTTLS must not be performed in an authenticated state
What do you do if you want to use STARTTLS, but the server answers with PREAUTH?
This is a logical inconsistency in the standard
The only reasonable way for a client to react to PREAUTH on a supposedly STARTTLS connection is to terminate the connection with an error
Some clients will allow PREAUTH connections and just skip STARTTLS
This obviously leads to mailbox content spoofing, it also may lead to stealing mail content that are synced from the client
This is an IMAP feature where a server tells a client to use another server
Combining PREAUTH and MAILBOX-REFERRALS we can establish a plain text connection and then forward the user to a server we control and steal credentials
MAILBOX-REFERRALS and the similar feature LOGIN-REFERRALS are not widely supported, we only found one mail client where we could perform this attack (Alpine)
Do not use STARTTLS in mail client connections!
Configure your mail client to use implicit TLS ports, not STARTTLS
If you run a mail server make sure to support implicit TLS.
If you can: Disable STARTTLS.
This is a different situation
There is currently no specified way to use implicit TLS on MTA-to-MTA connections
Traditionally STARTTLS for server to server connections is purely opportunistic, does not validate certificates and does not protect against active attackers
This is slowly changing:
DANE and MTA-STS
Establishing an implicit TLS mode in MTA-to-MTA connections is challenging
If we want to secure MTA-to-MTA connections we need to make sure they don't suffer from STARTTLS bugs, particularly Command and Response Injection
XMPP, FTP, Managedsieve, LDAP, MySQL, NNTP, ...
Similar bugs to the ones we found can be present in all protocols supporting STARTTLS, there is lots of potential for future research here
Our general recommendation to avoid STARTTLS and prefer implicit TLS is true for all protocols that support both
Have you ever tried to send an e-mail with your phone and a bad Internet connection?
A lot of effort has been put into reducing TLS round trips, it's noteworthy that no such effort has been put into optimizing E-Mails protocols
All information exchanged before the STARTTLS transition should be ignored and needs to be retransmitted after the TLS handshake
In other words: Everything happening before the TLS handshake is wasted
STARTTLS needs more round trips (usually 2-3) than implicit TLS
Avoiding STARTTLS is faster
There are more easy ways to improve E-Mail protocol round trips
E-Mail authentication (in all three protocols) uses an authentication framework called SASL
C: A0 AUTHENTICATE PLAIN AGFsaWNlQGV4YW1wbGUub3JnAHBhc3N3b3Jk (base64 encoding of \0[username]\0password)
A0 AUTHENTICATE LOGIN + VXNlcm5hbWU6 ("Username:") YWxpY2VAZXhhbXBsZS5vcmcK + UGFzc3dvcmQ6 ("Password:") cGFzc3dvcmQ=
IMAP has a feature "SASL-IR", which means you can initiate an authentication and send authentication data right away
SASL has two basic (username/password) authentication modes: PLAIN and LOGIN
To make matters more complicated, POP3 and IMAP also have a built-in (non-SASL) authentication method
In IMAP this works with one round trip, in POP3 it takes two
Not standardized and declared OBSOLETE by the IANA
Sends username and password base64 encoded in two round trips
Standardized (RFC 4616)
Sends username and password base64 encoded in one round trip
PLAIN is standardized and faster than LOGIN
Almost everyone supports both, yet there is no good reason for LOGIN
Thanks for listening, any questions?