The Importance of Validating SSL Certificates
One of the more common but still widely forgotten security issues I see is that of forgetting to validate SSL certificates. I’m not talking about accepting certificate mismatches while browsing a mailing list archive. I’m talking about developers programming https communication.
What all developers need to keep in mind are two things:
1) SSL does very little good unless you are talking to who you think you are talking to.
2) The communication library you are using may not be validating SSL certificates.
Regarding #1: Why does SSL do little good without certificate validation? It’s because having an encrypted conversation with a man-in-the-middle is not the idea. In that case, all you’re protecting against is someone snooping on the wire between you and the attacker you are having the SSL conversation with. In the day of BGP attacks and DNS cache poisoning, which I’m lumping together in the “MITM” category for these purposes, the MITM isn’t necessarily only a powerful entity like a government. These aren’t just theoretical risks.
Sometimes developers do this intentionally out of ignorance and convenience, like popular billing systems disabling certificate validation. (Side note: as far as I know, that company didn’t actually respond by making the default secure, instead they just buried a new option where you can enable proper SSL communication. Nice!) Other times, though, it’s not willful stupidity or intentionally putting users at risk, but rather just a lack of understanding of how SSL works and what the dangers are that SSL exists to protect against.
Related to understanding the purpose of SSL are the general arguments for better education about fundamental security topics (in schools, among employees, and by developers on their own), requiring an understanding of security fundamentals when hiring developers, and also recognizing that having security experts on your team is crucial because you can’t expect your developers to all be security experts.
Regarding #2: Often, though, developers are smart people who know the risks as well as the solution. They’re using SSL for the right reasons. It just, unfortunately, happens that they took for granted that other developers understood the same things and those other developers defaulted to correct security. When using a library that handles SSL, informed developers often assume that other informed developers wrote the SSL code. It makes sense. They assume that certificates are being validated by default. They assume that if the library can’t find the OS’s installed root certificates, that every request will fail and the developer using the library will then have to make sure that the code can find the root certificates available on the system. That’s the smart and expected behavior. However, the code we use was not always written this intelligently.
An example of this is python’s urllib. Many smart developers have written insecure code because they assumed if you use urllib to make an SSL connection, SSL will be used as it’s supposed to be. Instead, urllib as it was originally written and still currently exist ignores the fact that SSL is used for a handful of important reasons and just ignores security almost completely (and silently). It proceeds to retrieve any https-requested content with almost the same level of security as a plain http connection (because, really, when you are not validating SSL certificates, that’s basically what you have unless your adversary is someone passively listening with wireshark at the same cafĂ© as you).
Many important projects have been bitten by python’s urllib SSL negligence. These includes Red Hat Enterprise’s update system, YUM, and Tor’s in-development updater. Thankfully, urllib will get better but not perfect in python 2.6.
What should you do? First, understand why SSL exists. Second, test any code you write that uses or might use https urls to ensure that that it fails when the SSL certificate isn’t valid.