Client software that is susceptible to downgrade attacks is defective, in the sense that it purposely does things outside of the standard in order to support server software that is defective.
Normally, the client announces (in the ClientHello
) its highest supported protocol version number (e.g. "3.2" to mean "TLS 1.1") and then the server responds (in the ServerHello
) with the protocol version that will be used for that connection. Therefore, the theoretical behaviour when a recent client talks to an old server is the following:
- Client says: "I support up to 3.2".
- Server thinks: "Mmh, I have no idea what SSL 3.2 may be, but I know SSL 3.0 and 3.0 is less than 3.2".
- Server responds: "We will use 3.0".
However, in some rare cases in practice, old server software is not only old but broken; and things go that way:
- Client says: "I support up to 3.2".
- Server thinks: "OMG 3.2 I HAVE NO IDEA WHAT THAT IS I MUST COMMIT HONOURABLE SEPPUKU". Server closes the connection abruptly.
- Client thinks: "Mmh, the server broke. Probably an old piece of junk. I must use patience when I speak to the elderly".
- Client reconnects and says: "I support up to 3.0".
- Server responds: "We will use 3.0".
When things go that way, the hash that is computed over all handshake messages and included in the Finished
messages does not include the fact that the client could have used a newer protocol. By reconnecting and using an artificially lower announced version, the client prevents the downgrade detection system from working. We can say that the problem occurs because the clients don't act as they should, but they do so because there are deployed servers that are even more broken. It can be hard to unambiguously lay blame here.
Attackers who want to force a protocol downgrade abuse that system by killing the first connection with a well-placed RST packet, so as to simulate a senile server that cannot tolerate any of this newfangled talk about a protocol version other than 3.0.
The TLS Fallback Signaling Cipher Suite Value (SCSV) for Preventing Protocol Downgrade Attacks extension, currently in draft, is a method for sneaking in the handshake message the information that the client really supports better than SSL 3.0, in a way that won't make old servers scatter their electronic brains on the floor; it takes the form of a special cipher suite identifier (it is based on the idea that even old broken servers will not go berserk when the list of supported cipher suites includes one that they do not know). Of course, the mechanism brings any protection only if both the client and server are aware of it (the client must put the special identifier, and the server must recognize it and say to itself: "how come we are doing SSL 3.0 if the client knows a newer version? This is fishy...").
Another view on the subject is that if SSL 3.0 is weak and should not be used at all, then the only sane practice is to reject it altogether. You need a protection against downgrade attacks only if you are still ready to use SSL 3.0 in case the server truthfully supports nothing else. If you fear the consequences of using SSL 3.0, then you should never accept to use it. This is considered as potentially extreme; a smoother compromise may be, on the client (browser) side, to maintain an explicit list of servers for which SSL 3.0 will be tolerated. Such a list, configurable by the user himself, combines possible tolerance of a few legacy systems, and a healthy dose of finger-pointing at the systems whose misery should have been ended long ago.
Edit: see the comments there; this is a discussion between Firefox maintainers where they discuss exactly the consequences of dropping SSL 3.0 support altogether, and various alternatives.