HTTP public key pinning (or just ‘public key pinning’ or HPKP) is a security mechanism designed to improve online privacy. But like other mechanisms, such as Certificate Transparency (CT) and Certification Authority Authorization (CAA) checking, it has its drawbacks.
In this article we’ll explain what public key pinning is, discuss its problems, and explain how you can implement it both securely and effectively.
First, let’s take a step back first and review the basics: client/server applications use the Transport Layer Security (TLS) protocol to communicate across a network. TLS aims to provide a level of privacy and security between client/server applications in a way that prevents eavesdropping, tampering or message forgery. It typically involves a client connecting to a server and proving that the server has a private key chained up to a root certificate in the client’s trust store.
When TLS/SSL was first envisaged, it was considered a foolproof way to connect clients and servers without the risk of man-in-the-middle (MITM) attacks. However, over time, people realized that another entity could sit in between client and server (creating two TLS connections in place of one) without revealing itself to either end. There are legitimate uses for this, but malicious parties can do this too. This is where HPKP comes in.
Public key pinning is a mechanism for detecting and blocking certain kinds of man-in-the-middle attacks.
So how does it work? A domain owner pins the hash of one or more public keys in the certificate chain for their website, creating what is called a HPKP policy. This policy specifies hashes for one or more of the certificates in the website’s public key certificate chain.
When someone visits the website, it returns the public key pins to the visitor’s browser via HTTP headers. The browser checks that at least one of the pins is valid for the certificate chain, and caches the pins for the next visit. In order to validate the chain, at least one of the certificate chain’s public keys needs to match a pinned public key.
The whole mechanism tells an application that the certificate chain from a server must contain at least one of the pinned certificates - and to sound the alarm if it finds none. In doing so, users can be more certain there is no-one interfering with (or eavesdropping on) communication over a network, which is especially important for websites that handle sensitive information like healthcare or financial records.
Above all, public key pinning gives domain operators the ability to reduce the risk of MITM attacks and other false-authentication problems. But it’s not a silver bullet, and it does have its drawbacks.
Although public key pinning can reduce the risk of a MITM attack, it’s not a perfect defense against attackers - especially those capable of passing certificate chain validation procedures.
In reality, public key pinning is a brittle mechanism and can be problematic by design. Here are some of the issues:
Public key pinning is powerful, but it can be dangerous too - especially given that the risk of misconfigured pinning policies is quite high.
Our advice is to avoid deploying HPKP unless you’ve studied the specifications, have a system in place for auditing your configuration (and to detect unwanted pinning) and have a strong understanding of the necessary steps. You should also be careful which certificate you pin to.
When a Certification Authority (CA) certifies your website’s domain, they’ll give you an end entity certificate signed by an intermediate certificate that is, in turn, signed by a root certificate embedded in browsers. We recommend pinning to the end entity certificate. Why? Because this means you can update your pin whenever your end entity certificate is updated. Pinning an intermediate or root certificate is more dangerous because the CA might change them without knowing that you are using them as HPKP pins.
Pinning your end entity certificate is a little more work than pinning to your intermediate certificate or root certificate, but you remain in control.