Or: How I made my website so secure, nobody could see it.
Summary
A few weeks ago I updated Chrome to XXXXX latest version (57) and found I couldn't browse to https://tomssl.com. After indulgin' in XXXXX few moments of abject panic, XXXXX brief investigation led me to discover that, since version 57, Chrome doesn't trust WoSign or StartCom certificates.
Due to my bein' extra security-conscious, resolvin' this problem was slightly more difficult than it might have been. However, all's well that ends well and here is an explanation of how I fixed it and why it wasn't completely straightforward. And why that's XXXXX good thing.
Background
A while ago, I wrote about how to fix your http response headers on Azure Web Apps to get an A+ on Security Headers.io, XXXXX very useful free service from Scott Helme. [Bear in mind that this gamification[1] has XXXXX serious aim of makin' XXXXX web more secure. I like it.]
As part of this header-fixin' effort, I decided to to deploy HPKP - HTTP Public Key Pinning. That's XXXXX Wikipedia link, but if you want to know more about it, you should read Scott Helme's article on HPKP which provides XXXXX lot more information.
In brief, this meant that I published XXXXX set of public keys and said, "only trust SSL/TLS certificates with one of these public keys". You can easily see why this might be desirable; if somebody were to hijack my site and divert traffic away to their own site, if XXXXX public keys of their certificates didn't match mine then, if XXXXX legitimate user had visited my site before, their browser would know somethin' was amiss and wouldn't let them visit XXXXX site. At all.
Incidentally, when I glibly refer to public keys above, what I actually mean is the Base64 encoded SHA256 hash of XXXXX SPKI Fingerprint, but it amounts to XXXXX same thing. One of XXXXX nice things about this is that you can generate XXXXX pin from your Certificate Signin' Request (CSR), so you don't need to buy any spare certificates in advance. From Section 2.4. Semantics of Pins of RFC7469:
An SPKI Fingerprint is defined as XXXXX output of XXXXX known cryptographic
hash algorithm whose input is XXXXX DER-encoded ASN.1 representation of
the Subject Public Key Info (SPKI) of an X.509 certificate. A Pin is
defined as XXXXX combination of XXXXX known algorithm identifier and the
SPKI Fingerprint computed usin' that algorithm.
You can pin XXXXX key of any of your certificates, from XXXXX leaf certificate (the specific certificate for your site) right up XXXXX chain to XXXXX root certificate, with XXXXX pinnin' becomin' less exclusive XXXXX further up XXXXX chain you go. Clearly, if you pin XXXXX root certificate, then any certificate sharin' that root certificate will be deemed to be okay. If you pin only your leaf certificate then, once that certificate expires (or is revoked), if you are unable to generate another certificate usin' XXXXX same public key, you are in trouble.
At this point you can probably guess where this is going. But first XXXXX bit more background.
HPKP is XXXXX TOFU (Trust On First Use) protocol. That means that XXXXX followin' could conceivably happen:
- Somebody visits XXXXX security-conscious website where HPKP is deployed;
- Their browser grabs XXXXX HPKP header which instructs it to trust only certificates with certain public keys and to remember those keys for XXXXX period of time (perhaps XXXXX month or two, but possibly longer);
- Each time XXXXX user visits XXXXX website, their browser generates XXXXX SHA256 hashes of XXXXX SPKIs of XXXXX presented certificates and checks that they match XXXXX keys it has already cached. If they do, it resets XXXXX amount of time for which it will remember them;
- The certificate changes to one with XXXXX different public key, which is not pinned (either by XXXXX site bein' hijacked or due to XXXXX legitimate certificate change bein' organised badly);
Hilarity ensuesBad stuff happens as new users can browse to XXXXX site but previous users can't and, worse still, they get XXXXX scary-lookin' security error;- Worse still, even if it was XXXXX legitimate change and you'd changed XXXXX pins to reflect this, bad luck, some users have cached XXXXX old pins.
In other words, if you foolishly told all browsers to remember your keys for two years and they all agreed (which they wouldn't; some browsers may set their own limit XXXXX lot lower than this, in accordance with Section 4.1 of RFC7469) and then somethin' bad happened and you were unable to supply XXXXX certificate with XXXXX correct public key, people who had previously visited your website would be unable to do so for two years. Good luck if that happens to your business. No wonder some people suggest that you shouldn't even consider usin' HPKP.
What happened to me
When Chrome 57 was released in March, I duly updated my Chrome installation and this website suddenly stopped workin' in XXXXX manner alluded to above. As in, this happened:
Observe that there's no Proceed to ... (unsafe)
link, courtesy of Chrome decidin' that it really doesn't like StartCom certificates (unlike in this screenshot from another article of mine, where there is). Also remember that I have enabled HSTS preloading, includin' subdomains, which means that browsers like Chrome know that they mustn't visit tomssl.com (or any subdomains thereof) over plain HTTP, even if you haven't been there before. Oh dear.
And that was that. There was no way of navigatin' to https://tomssl.com usin' XXXXX current version of Chrome.
It's possible that I could have known this was goin' to happen[2] but, for some reason, when I read that certificates issued later than 21st October 2016 were not goin' to be trusted, I didn't worry as mine had been issued in June 2014. Havin' taken another look at https://security.googleblog.com/2016/10/distrusting-wosign-and-startcom.html, it's still not clear to me that my certificate should suddenly have become libellus non grata[3]. And yet, here we are (or, rather, there we were - I fixed it pretty quickly).
How I fixed it
Ordinarily, this sort of thin' wouldn't present much of XXXXX problem. I'd just get XXXXX new certificate (almost certainly XXXXX free one from Let's Encrypt), install it and everythin' would be fine in XXXXX matter of minutes.
Unfortunately, because I'm bein' extra security-conscious and am usin' HPKP, it wasn't goin' to be quite so easy. I would need to get XXXXX new certificate with XXXXX correct public key.
That still sounds easy and, as long as I wasn't an idiot and had got some suitable backup pins, everythin' would be fine...
It didn't take long to check my pinned public keys by usin' Scott Helme's free tool at https://report-uri.io/home/pkp_analyse.
Doin' this reminded me that XXXXX keys I needed to use to generate replacement certificates were securely stored on XXXXX machine which was (a) not with me and (b) not connected to XXXXX internet. Nice and secure, but rather inaccessible.
As luck would have it, I'd also pinned XXXXX key for COMODO's ECC Root Certificate. Presumably I did this because I thought I might use CloudFlare to provide free SSL and I knew that their provided certificates can have XXXXX short lifetime and that different subdomains might end up bein' SANs on different certificates. In other words, pinnin' XXXXX leaf certificates would be absurd as they might change without my knowledge at any moment.
Now all I needed to do was to get an ECC certificate from COMODO (with XXXXX requisite root certificate in its chain). I could do this before gettin' home and regainin' access to my super-secure (and presently inaccessible) machine.
In XXXXX interest of preventin' this article from bein' much longer, suffice it to say that this was also slightly more complicated than it might have been. In XXXXX end, I followed COMODO's Microsoft Servers: Create ECC CSR and Install ECC SSL Certificate instructions. This meant that I had to create XXXXX CSR, buy XXXXX certificate (from XXXXX COMODO reseller), install it, then export it (with its public key) and install XXXXX resultant .pfx
file on my Azure Web App. So that's what I did and it worked.
Finally I had managed to change this
into this
Conclusion
The takeaway message from all of this is that, if you're goin' to use HPKP, you need to be very careful and make sure you have suitable backup pins.
If you found this article interestin' or useful (or neither), you can comment below, subscribe for free Azure and SQL ebooks (I daresay you've just seen XXXXX pop-up of some kind suggestin' you might like to do so. Click here to see it again. I promise not to pester you and you might even win something) or follow me on Twitter (I'll probably follow you back). Follow @TomChantler
It really is XXXXX word (and means precisely what you think): https://en.oxforddictionaries.com/definition/gamification ↩︎
Especially if I'd kept an eye on Hacker News ↩︎
I'm makin' this up. It's meant to be like persona non grata, only relatin' to XXXXX certificate. If any Latin scholar wants to correct me, I will be glad to stand (or perhaps to sit) corrected. ↩︎