jbp.io Archive
07 July 2013

TLS downgrade behaviour or: why you shouldn't put all your eggs into the TLS forward secrecy basket

Recently there has been a sequence of recommendations promoting the use of TLS ciphersuites which provide forward secrecy, particular in the context of PRISM and Tempora.

Unfortunately most browsers have implemented unsafe downgrade behaviour when a TLS connection fails. Since an attacker can usually invoke such a failure, he can often remove forward secrecy from a TLS connection which would have otherwise had it. This happens transparently to the user.

This is bad, and surprising.

Browser behaviour

A browser starts a new TLS connection with the highest (most recent) TLS protocol version it can speak. If the connection fails early on, it moves down to an older version and retries from the beginning.

Importantly, this downgrade is outside the protocol version negotiation facilities that TLS provides: there is no binding between the first and subsequent connections, and so the way TLS detects version downgrade is not in play.

In concrete terms:

  1. User opens a TCP connection to google.com and sends a ClientHello with version TLS1.0 and its set of desired ciphersuites.
  2. The adversary intercepts this message, and sends back a TLS fatal alert (the AlertDescription seems not to matter, but handshake_failure seems most obvious) or merely closes the connection at a TCP level with a FIN. It doesn’t matter which.
  3. Upon receipt of the alert, the client closes the connection.
  4. The client opens a new TCP connection, and sends a ClientHello with version SSL3 and (in all most cases) a poorer set of SSL3 ciphersuites.
  5. The adversary passes remaining traffic between the Server and Client without alteration or omission.

Here we made two TCP connections: one for the first TLS1.0 handshake, and one for the SSL3 handshake.


(As of July 2013)

Pretending to be Chrome’s TLS stack, I simulated the attack against the top 300 websites. 209 sites supported any kind of TLS. Of those, 69 (33%) chose different security parameters under downgrade conditions:

So, if you’re counting, 53 (25%) lost forward secrecy under attacker control. Notably, this includes all Google properties.

Also, consider an attacker who has a preference for attacking RC4 statistical biases. The 6 sites which switched to RC4 under downgrade (including all Microsoft properties) just became more appealing,


This is not a new discovery. Browser vendors implemented this downgrade deliberately to continue working in the presence of ‘middle-boxes’ (such as those made by Bluecoat, amongst others) which barf on use of modern TLS protocol versions.

Aside: read the ‘Resolution’ part of that article and try and work out if Bluecoat is evil or merely incompetent.

Affected browsers

(As of March 2013)

Unaffected browsers

The following products correctly treat fatal alerts and unexpected connection closures as errors, and are not affected.

The future

Encouragingly, there is already a formalisation of Opera’s sensible behaviour in the form of Managing and removing automatic version rollback in TLS Clients. Less encouragingly, there hasn’t been any clear push behind this proposal, or indications that Google, Microsoft or Mozilla will actually implement it.

Worse still, work on TLS1.2 support in NSS (Network Security Services – used by Chrome and Firefox, amongst others) continues apace. This is somewhat pointless in any normal attack scenario: the attacker will merely downgrade the client back from TLS1.2.

The code

During this investigation I wrote a pure python toy TLS stack. Please observe the emphasis on toy. Of particular note is src/socks_proxy.py – a dodgy SOCKS proxy which implements this attack.

Update: 2013-08-21

Today TLS1.2 support reached Chrome mainline. Unfortunately there doesn’t seem to be any mitigation implemented for downgrade:

screenshot showing Chrome 29 with TLS1.2 being downgraded to SSL3.0

So unfortunately this implementation of TLS1.2 doesn’t offer any advantage over SSL3.0 in the face of even a trivial active attacker :(