A couple of weeks ago those of us interested in Internet security formally received a new tool in our toolbox to improve the overall security of the TLS infrastructure that we use for pretty much all secure communication across the Internet. RFC 7469, “Public Key Pinning Extension for HTTP” was published and is available at:
I say “formally” because in practice what is more commonly known as “HPKP” or “PKP” has been implemented for some time now by Google Chrome and Mozilla Firefox (see ticket) as the Internet-Draft worked its way through the WEBSEC Working Group within the IETF on its way to becoming a formal RFC.
At a basic level, “certificate pinning” is a fairly simple concept: once you connect to a site and receive its TLS certificate (i.e. you switch to using HTTPS and have the “lock” icon in your browser), “pin” that certificate inside your application for a specified period of time and ONLY accept connections that use that exact TLS certificate. This removes the possibility of an attacker succeeding with a Man-In-The-Middle (MITM) attack where the attacker can fool your browser into thinking you are connecting to the correct secure site. (If you want a deeper dive, OWASP has a long description of certificate pinning.)
Certificate pinning is a concept that has been around for a while but this new HPKP header makes it easier for sites to implement.
RFC 7469’s abstract doesn’t put it quite so simply as I did above, but you get the idea:
This document defines a new HTTP header that allows web host operators to instruct user agents to remember (“pin”) the hosts’ cryptographic identities over a period of time. During that time, user agents (UAs) will require that the host presents a certificate chain including at least one Subject Public Key Info structure whose fingerprint matches one of the pinned fingerprints for that host. By effectively reducing the number of trusted authorities who can authenticate the domain during the lifetime of the pin, pinning may reduce the incidence of man-in-the-middle attacks due to compromised Certification Authorities.
Now in practice it turns out that pinning the exact TLS certificate can cause operational problems in some website configurations and so the specification allows for the pinning of the key of the entity that issues the TLS certificates for your site, such as a certificate authority (CA). This allows you, for instance, to specify that a browser should only accept TLS certificates from a specific CA. This reduces the risk of a MITM attack where an attacker uses a TLS cert from a different CA who they were able to get to issue the bogus cert.
This new RFC 7469 dives into all the details of HPKP, but if you want a higher level view, Joseph Bonneau gave a talk in March 2015 at IETF 92 in Dallas about HPKP and its companion, HTTP Strict Transport Security (HSTS – RFC 6797). The slides are available:
and you can listen to the presentation starting at about 24:30 in the recording of the SAAG session.
Certificate pinning is a great tool that we have now, although it does have a few challenges to be aware of:
- Trust-On-First-Use (TOFU) – Certificate pinning relies on you connecting to the correct server on the first connection in order to get the TLS cert that you are now going to pin in the browser. As noted in the RFC 7469 Introduction, the issue is that if you were to connect to an attacker’s site first you could in fact wind up pinning the false certificate and thereby being blocked out of connecting to the correct site until the time of the pin expires (what is called in the spec “max-age”).
- Blocking a site due to certificate changes – If you need to change a TLS cert, or if a TLS cert should be compromised or a private key is lost, you could potentially wind up in a situation where people using browsers that perform cert pinning would not be able to get to your site. This could happen if you pinned to an exact cert and had to change the cert, or if you pinned to a CA and then switched to a new CA, and in either case were unable to provide enough notice to manage the migration. The Security Considerations section of RFC 7469 discusses this issue.
On the TOFU issue, one way to deal with having to trust the site on first use is to “pre-load” the certificate to be pinned into the web browser or other application. This is being done by both Chrome and Firefox (see Mozilla’s list). The only concern here is that if you need to change the certificate in the pre-loaded list, you need to wait for an update to the browser to be available (and for users to install that update).
In various conversations I’ve suggested DNSSEC could help here because if the local system performed DNSSEC validation on a signed domain, the browser would then have a high level of assurance that it was connecting to the correct IP address where it could then receive a HPKP header with the correct TLS cert to be pinned. So DNSSEC could help bootstrap the pinning process and get around the TOFU concern.
Whenever I’ve raised this point, the response has typically been that if you have DNSSEC validation available you could simply use DANE to ensure you are using the correct TLS certificate. This is true, and I’d like to hope we’ll someday get there, but: 1) DANE requires the creation and usage of TLSA records, which is one more step people have to take; and 2) web browsers don’t have full support of DANE yet (although plugins are available). In the meantime, I still see DNSSEC as a powerful way to help with ensuring cert pinning works correctly.
Regardless, the key point is that RFC 7469 is now out there and certificate pinning via the HPKP header is now possible. It’s another tool we have and one that anyone interested in TLS security should definitely understand.
I’d love to hear your comments on this – please do feel free to leave them here. Tell me why cert pinning is great… tell me why it’s not. Tell me I’m wrong (or right!). Please do note that we do moderate comments because of spam but we approve basically very comment that isn’t abusive or spam.