Scoring an A+ for SSL/TLS

It's not hard

A+

(Side note: in this post I’m going to use TLS and SSL interchangably. To all intents and purposes you can think of TLS as the successor to SSL; most libraries do both).

You can think of security as a stack. Each layer of the stack needs to be secure in order for the whole thing to be secure. Or, alternatively, you can think of it as a chain; the whole thing is only as strong as the weakest link.

No matter how you look at it, you need to ensure that every part of the environment is good.

In previous posts I’ve talked about static code analysis, and system scanning. This can help make sure your program hasn’t any obvious gaps, and that you’re not running a bad alternate path.

Now let’s look at protecting the data between you and your users. Typically we do this with SSL. So you get your certificate and click the “turn on SSL” option and you’re done; right?

Unfortunately not. SSL has a long and not so clean history. There have been both implementation bugs and logic issues. “Heartbleed”, “BEAST”, “POODLE”… at one point it seemed that an issue was found in SSL every other week.

Further, something that was considered strong 10 years ago isn’t strong today (RC4 codes). And new and better methods of protecting data now exist (elliptical curve, forward secrecy).

So we may need to tune your SSL setup as well. Turn off weak settings, add new configurations.

The problem is in how to know if you’ve done a good job?

Testing

Fortunately there’s a very useful web site run by Qualys: https://www.ssllabs.com/ssltest/

This will run through your site, testing for common failure modes. It’ll try common bugs, weak settings and even provide a good summary of how well your site will work with common browsers. It takes somewhere around 90-120 seconds to run.

My site (PDF) scores an A+ on these tests and it flags some compatibility issues.

e.g. “This site works only in browsers with SNI support.” That’s because I present a different SSL certificate for each virtual host, and for this to work we need the SSL “Server Name Indication” extention. Pretty much every common browser supports this these days.

If we go down further into the report it tells me the Android 2.3.7, IE6, IE8, Java 6 don’t support SNI. I can live with that!

Further it tells me that IE6 and IE8 just won’t work with my site because of other settings. Do I care? According to a browser market share report IE8 is under 4% of usage. I can live with that.

Browser breakdown

My settings

I use Apache with OpenSSL, which allows you to specify the protocols and cipher suites. The first is to ensure SSLv2 and SSLv3 are turned off. Then we can pick the ciphers we want:

SSLProtocol all -SSLv2 -SSLv3
SSLHonorCipherOrder on

SSLCipherSuite ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:HIGH:!EDH-RSA-DES-CBC3-SHA:!DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4

Conclusion

These settings aren’t necessarily the best. I could tighten it up if I don’t care about compatibility with older tools (java6 and java7 might be easy to discard).

These settings are also not always going to be fixed; a few months back I did not have !EDH-RSA-DES-CBC3-SHA:!DES-CBC3-SHA in the Cipher suite because these used to be considered good. It’s worth reviewing the results of the SSLlabs test on a regular basis. And definitely after a new vulnerability has been exposed.

Getting an A or an A+ is easy, and is an essential part of the complete security solution for your web site. There are many good reasons to do it!