This is the third post in my series on HPKP. In my first post I declared HPKP dead, and in my second post I explored the possibility of fixing it by introducing pin revocation. Today I will consider an entirely different approach to make HPKP much safer, by changing how it’s activated.
In my previous blog post I argued that the biggest flaw of HPKP is that it doesn’t tolerate failures. That’s why I offered pin revocation as a solution. In my approach, the CAs’ existing OCSP infrastructure is used for the revocation, keeping things simple. The main disadvantage of the proposal is that there is deep distrust of both CAs and also no faith that they will maintain rock-solid revocation infrastructure.
Rethinking the problems with HPKP, I decided that I could attempt to solve them from another angle. To summarise, there are two big problems with HPKP: 1) it’s too easy to activate by anyone who can set HTTP response headers on your site and 2) there is no way to recover from failure. This incredibly low activation bar allows deployments that haven’t been thought through, activation by mistake, and even malicious pinning. The lack of failure recovery makes it very dangerous.
It recently occurred to me that we could fix things largely by allowing HPKP activation only on the certificates that allow it. Technically, this could be achieved by placing a special OID in the certificates when appropriate. If the OID is there, browsers pin, otherwise they don’t.
With this feature in place, CAs could designate certain intermediates as suitable for pinning, guarantee public key longevity, and place the appropriate OIDs in them. Because this is a special type of certificate, it’s not something that you’d get by default. And, even if you did, recovering from failure is as easy as getting a new certificate.
If we really wanted to—for the brave—we could use a different OID to allow pinning to the leaf, in which case HPKP would be more difficult to activate, as secure as it is today in preventing MITM attacks, but there wouldn’t be a way to recover from failure. In this case the CAs wouldn’t need to promise key longevity, but they would still operate as gatekeepers to make malicious pinning less likely. Honestly, I don’t think this OID is a good idea. Those rare companies that wish to pin can still fallback to static pinning (embedded in the browser code). Even though static pinning is inefficient, there’s so few of those who might be interested that it doesn’t really matter.
The most efficient and most secure way way to pin today is to get a pair of intermediate certificates from different CAs and pin to them. Obviously, only wealthy organisations can do that. With certificate constraints, nothing would change, as their intermediates would just need to have the correct OIDs in place.
Are there any drawbacks to HPKP with certificate constraints? You could argue that it makes pinning more expensive because it reduces the pool of CAs from which you can get your certificates. However, the certificate expense is only a fraction of the overall cost of pinning, so I think that the difference doesn’t really matter.
The best thing about this approach is that the browser vendors would only need to add a tiny amount of code to make it happen. Most of the work would be in standardising the OIDs.