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.
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:
TLS1.0and its set of desired ciphersuites.
AlertDescriptionseems not to matter, but
handshake_failureseems most obvious) or merely closes the connection at a TCP level with a
FIN. It doesn’t matter which.
SSL3and (in all most cases) a poorer set of SSL3 ciphersuites.
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:
TLS_RSA_WITH_RC4_128_SHA: 50 sites
TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA: 8 sites
TLS_RSA_WITH_RC4_128_SHA: 6 sites
TLS_RSA_WITH_RC4_128_SHA: 3 sites
TLS_DHE_RSA_WITH_AES_256_CBC_SHA: 2 sites
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.
(As of March 2013)
The following products correctly treat fatal alerts and unexpected connection closures as errors, and are not affected.
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.
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.
Today TLS1.2 support reached Chrome mainline. Unfortunately there doesn’t seem to be any mitigation implemented for downgrade:
So unfortunately this implementation of TLS1.2 doesn’t offer any advantage over SSL3.0 in the face of even a trivial active attacker :(