People still talk about “SSL encryption”, which is so last century. SSL – Secure Sockets Layer – was superseded by TLS – Transport Layer Security – in 1999 (which is when the TLS 1.0 specification was published). TLS 1.1 came out in 2006. That’s 12 years ago, which is, like, well, ages and ages in Internet time. The problem with standards, however, is that people standardise on them. It turns out that TLS v1.0 and v1.1 have some security holes in them, which mean that you shouldn’t use them, but people not only did, but they wrote their specifications and implementations to do so – and to continue doing so. In fact, as reported by The Register, the IETF is leading a call for TLS v1.0 and v1.1 to be fully deprecated: in other words, to tell people that they definitely, really, absolutely shouldn’t be using them.
Given that TLS v1.2 came out in August 2008, nearly ten years ago, and that TLS v1.3 is edging towards publication now, surely nobody is still using TLS v1.0 or v1.1 anyway, right?
Answer – it doesn’t matter whether they are or not
This sounds a bit odd as an answer, but bear with me. Let’s say that you have implemented a new website, a new browser, or a client for some TLS-supporting server. You’re a good and knowledgeable developer, or you’re following the designs from your good and knowledgeable architect or the tests from your good and knowledgeable test designer. You are, of course, therefore using the latest version of TLS, which is v1.2. You’ll be upgrading to v1.3 just as soon as it’s available. You’re safe, right? None of those nasty vulnerabilities associated with v1.0 or v1.1 can come and bite you, because all of the other clients or servers to which you’ll be connecting will be using v1.2 as well.
But what if they aren’t? What about legacy clients or old server versions? Wouldn’t it just be better to allow them to say “You know what? I don’t speak v1.2, so let’s speak a version that I do support, say v1.0 instead?”
This is fallback, and although it seems like the sensible, helpful thing to do, once you support it – and it’s easy, as many TLS implementations allow it – then you’ve got problems. You’ve just made a decision to sacrifice security for usability – and worse, what you’re actually doing is opening the door for attackers not just to do bad things if they come across legitimate connections, but actually to pretend to be legitimate, force you to downgrade the protocol version to one they can break, and then do bad things. Of course, those bad things will depend on a variety of factors, including the protocol version, the data being passed, cipher suites in use, etc., but this is a classic example of extending your attack surface when you don’t need to.
The two problems are:
- it feels like the right thing to do;
- it’s really easy to implement.
The right thing to do?
Ask yourself the question: do I really need to accept connections from old clients or make connections to new servers? If I do, should I not at least throw an error? You should consider whether this is really required, or just feels like the right thing to do, and it’s a question that should be considered by the security folks on your project team. Would it not be safer to upgrade the old clients and servers? In lots of cases, the answer is yes – or at least ensure that you deprecate in one release, and then remove support in the next.
The easy implementation?
According to a survey performed by Qualys SSL Labs in May 2018 this was a breakdown of 150,000 popular websites in the world, here are versions of TLS that are supported:
- TLS v1.2 – 92.3%
- TLS v1.1 – 83.5%
- TLS v1.0 – 83.4%
- SSL v3.0 – 10.7%
- SSL v2.0 – 2.8%
Yes, you’re reading that correctly: over ten percent of the most popular 150,000 websites in the world support SSL v3.0. You don’t even want to think about that, believe me. Now, there may be legitimate reasons for some of those websites to support legacy browsers, but you can bet your hat that a good number of them have just left support in for some of these versions just because it’s more effort to turn off than it is to leave on. This is lazy programming, and it’s insecure practice. Don’t do it.
TLS isn’t the only protocol that supports fallback, and there can be good reasons for allowing it. But when the protocol you’re using is a security protocol, and the new version fixes security problems in the old version(s), then you should really avoid it unless you absolutely have to allow it.
1 – the only type of developer to read this blog.
2 – I think you get the idea.
3 – of course you will.
4 – note – throwing security-based errors that users understand and will act on is notoriously difficult.
5 – if you don’t have any security folks on your design team, find some.
6 – or at least one, for pity’s sake.
7 – or nominate yourself and do some serious reading…
8 – I remember having to hand-code SOCKS v2.0 to SOCKS v1.0 auto-fallback into a client implementation way back in 1996 or so, because the SOCKS v2.0 protocol didn’t support it.