The HTTP Public Key Pinning header, or HPKP, can prevent fraudsters using mis-issued TLS certificates. While it offers a robust defence against website impersonation, hardly any HTTPS websites are actually making use of this powerful security feature, even though it has been supported by some browsers for more than a year.
Less than 0.1%of certificates found in Netcraft’s March 2016 SSL Survey were served with the HPKP header. Where it has been deployed, a third of webmasters have mistakenly set a broken HPKP policy. With so many mistakes being made, the barrier to entry is evidently high.
Even for those webmasters who have set a valid policy, a lot of ongoing care and attention is required: both routine and emergency maintenance poses a significant risk of blocking legitimate visitors, potentially for long periods of time. However, when correctly deployed and carefully maintained, HPKP is a powerful security feature.
What does HPKP defend against?
A website can defend against most man-in-the-middle attacks by deploying HTTPS , HSTS and HSTS preloading . Together, these ensure all communication to and from the website is authenticated and encrypted.
While these provide a fairly robust defence against attacks like pharming and sslstrip , there is still a line of attack open. A knowledgeable and dedicated attacker can still attack an otherwise well-defended HTTPS website if he can convince a certificate authority to fraudulently issue him a certificate for it.
HPKP can prevent a customer from accessing a spoof website when it uses a fraudulently-issued (but otherwise valid) certificate. Both sites use certificates issued by trusted CAs, but only the legitimate site’s certificate chain contains a certificate that is expected by the client browser. Hashes that correspond to each pinned certificate will have been noted by the browser during a previous visit to the legitimate site.
Although it is extremely difficult for a fraudster to obtain a certificate for a domain he does not control, it is not impossible. In fact, there is ample precedent . Several certificate authorities have been breached , lax issuance policies have been discovered , and technical flaws have been exploited by attackers.
The HPKP header is motivated by the history of mis-issuance within this ecosystem. To use HPKP, website owners must select a set of public keys that must be used in future connections. After visiting the site, its HPKP policy is then stored by the client to reject future connections to servers that use different, non-whitelisted keys.
However, creating an HPKP policy is not entirely sufficient to defend against impersonation attacks. In particular, HPKP cannot defend against rogue root certificates installed locally on users’ computers.
Both Dell and Lenovo have recently been caught deploying local root certificates to their customers, along with accompanying private keys. With this knowledge, an attacker can generate a certificate for any website and use it to impersonate that site. The victim’s browser will regard the certificate as valid, regardless of the genuine site’s HPKP policy.
How is HPKP used?
There are three types of key that can be pinned using HPKP:
- The current public key of the certificate issued to a site.
- Public keys corresponding to certificate authorities and their intermediate certificates.
- Backup keys.
In order for browsers to accept and store a website’s HPKP policy, there must be at least two pins specified. At least one pin must be in the chain of trust formed by the browser when verifying the site’s certificate, and there must be at least one pin that is not in the chain (a backup pin).
Here is an example of a valid HPKP header, which sets pins for three distinct public keys (marked in bold). This policy is valid for one year over all subdomains of the current origin:
Public-Key-Pins: pin-sha256="Q0ig6URMeMsmXgWNXolEtNhPlmK9Jtslf4k0pEPHAWE="; pin-sha256="F5OSegYUVJeJrc4vjzT38LZtDzrjo7hNIewV27pPrcc="; pin-sha256="p1Uk2ryJ7QmI5/zIzFmdzme0X+2nvXG5bHwR88A5ZjA="; max-age=31536000; includeSubDomains
Webmasters must be cautious when pinning certificate authority keys. CAs may change their issuance practices without notice, and new certificates may not use the same chain of trust as the old ones. If the new certificate chain no longer includes the pinned keys, the website will not be accessible until the HPKP policy expires.
To avoid the problems posed by using certificate authority keys, webmasters can elect to pin their own keys. This is also a risky practice if the backup key cannot be used: it may have been lost, or may no longer qualify for inclusion in certificates (for example, if a backup key is known to be a Debian weak key , CAs will not accept it for use in new certificates).
"Who dares pins"
HPKP is perfectly safe to implement when pins and certificates are well-managed, but it can also be considered rather risky when you think about what could go wrong: A small mistake could effectively wipe out an online business by preventing its own customers from accessing its website for months. Here are some of the most popular sites that are brave enough to be using HPKP today:
GitHub is the busiest site to have deployed HPKP. Well-known for taking security seriously, it sets a plethora of well-configured best-practice security headers.
One of the headers that is set when visiting https://www.github.com is the following HPKP header:
Public-Key-Pins: max-age=300; pin-sha256="WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18="; pin-sha256="JbQbUG5JMJUoI6brnx0x3vZF6jilxsapbXGVfjhN8Fg="; includeSubDomains
This HPKP policy specifies two pins, and the directive applies to all subdomains.
The first pinned key (identified by the
WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18= SHA-256 hash) corresponds to the DigiCert High Assurance EV Root CA . This is the root of the chain of trust currently used by github.com.
The second hash (
JbQbUG5JMJUoI6brnx0x3vZF6jilxsapbXGVfjhN8Fg= ) is GitHub’s backup pin. This corresponds to the VeriSign Class 3 Public Primary Certification Authority – G5 root. As this key does not appear in GitHub’s served certificate chain, it is treated as a backup pin.
When GitHub wants to replace its TLS certificate, the new certificate must be signed by either DigiCert or Symantec – otherwise, none of the key hashes in the new certificate chain would match the existing HPKP policy, and its users would be blocked from accessing the site.
Pinning a pair of root certificate keys is arguably less risky than pinning one of GitHub’s own backup keys, but there is a rather large trade-off. With GitHub’s current HPKP policy, an attacker can still impersonate the site if he can obtain a fraudulent certificate issued by either DigiCert or Symantec. Conversely, if GitHub were to rely on backup keys that only it controlled, then the only way an attacker could impersonate the site is by compromising GitHub’s private keys.
Even so, GitHub evidently remains wary — its HPKP header sets a max-age value of 300. This instructs browsers to remember the policy for no longer than 300 seconds, so in the event of a mistake, users will only be denied access for at most five minutes. However, this makes the policy practically toothless.
In the event of an attack, anybody who has not visited the real www.github.com within the past five minutes is a potential victim. Even if a user has visited GitHub within the past five minutes, being denied access might just be put down to a temporary glitch. A savvy attacker may decide to wait until five minutes after the users last access to GitHub to ensure he will not be caught.
Mozilla is using HPKP much more effectively on its support site, as this site sets a much longer max-age attribute:
Public-Key-Pins: max-age=1296000; pin-sha256="r/mIkG3eEpVdm+u/ko/cwxzOMo1bk4TyHIlByibiA5E=" pin-sha256="WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18=";
This equates to 15 days, which means it will provide effective protection to anyone who visits the site at least once a fortnight.
Rather than using public key hashes that correspond to more than one certificate authority, Mozilla has chosen to pin to a single CA: both keys are controlled by DigiCert. In some respects, this is a safer policy by ensuring that only a single CA is able to issue new certificates; however, it leaves Mozilla beholden to DigiCert. If DigiCert were ever forced to stop issuance and Mozilla’s certificate required replacement, visitors could be locked out of Mozilla’s site for up to 15 days.
A much bolder implementation has been deployed by the Pixabay image library on pixabay.com . Its
Public-Key-Pins header specifies a
max-age of one year.
Public-Key-Pins: pin-sha256="Kx1dtEVeqnPn0gfhzqIJfChEYFr5zMe+FjvcJ0AhVgE="; pin-sha256="zN9pxsvWtHm05/fKZ6zA1NJOq4j2NJJA3oIecCNc1eU="; max-age=31536000;
Rather than pinning CA-controlled keys, Pixabay has pinned its own certificate’s key, as well as a backup key held by Pixabay. This option trades complete defence against CA compromise with a significant risk if the backup pin cannot be used.
If Pixabay were to lose the private keys for both of these certificates, it would likely be catastrophic – visitors would be denied access to its site for an entire year. Pixabay has evidently decided that robust prevention of impersonation attacks is worth the risk.
Why are so few sites daring to use HPKP?
Only 0.09% of all certificates in Netcraft’s March 2016 SSL Survey are using HPKP – that’s fewer than 4,100 certificates in the whole world that are being delivered with the Public-Key-Pins header.
If that amount did not already seem astonishingly low, more than a quarter of these sites are using the HPKP header incorrectly, which effectively disables HPKP. Consequently, the total number of certificates that are really using HPKP is actually less than 3,000.
Still in its infancy
One of the reasons why HPKP is so rarely deployed could be that it is a relatively new standard, and is still not supported by all mainstream browsers. However, this only partly explains its poor uptake on servers. Although the Public Key Pinning Extension for HTTP was not formalised until the publication of RFC 7469 in April 2015, a significant proportion of internet users have already been able to benefit from this feature since October 2014, when HPKP support was introduced to Chrome 38.
By the time HPKP support was also added to Firefox 35 in January 2015, around a quarter of all internet users were in a position to benefit from sites using HPKP. But today, HPKP remains unsupported in Internet Explorer, Edge, Safari and Opera Mini. Nonetheless, there are millions of people using browsers that do support HPKP, and the only reason they are not benefiting from this technology is because so few websites are deploying it.
Lack of awareness
Possibly the largest reason for the lack of HPKP deployment is that many website owners are simply unaware that this security feature exists, or do not realise the benefits it can bring. However, this is not the most significant problem for lots of websites, as most also lack simpler features that are widely supported,such as HSTS and "Secure" cookies. Implementing HPKP is largely redundant if a site does not also implement HSTS, as this would still allow a man-in-the-middle attacker to hijack unencrypted HTTP traffic and prevent the victim’s browser being redirected to the HTTPS site.
Lack of understanding
Netcraft’s SSL Survey shows that lots of trivial mistakes are being made when website administrators try to deploy HPKP headers, which indicates a widespread lack of understanding. The net result of these mistakes is that HPKP is not enabled on many sites.
Fear of the "HPKP Footgun"
HPKP is the best way of protecting a site from being impersonated by mis-issued certificates, but as we have already discussed, it is very easy for this protection to backfire with severe consequences. A small misconfiguration could result in a website becoming inaccessible to its own customers.
HPKP offers a very strong defence against man-in-the-middle attacks, providing it is used in conjunction with HTTPS, HSTS and HSTS Preloading – but despite the obvious security benefits, hardly anyone is using it. Currently, only 0.09% of all secure websites are making use of HPKP headers.
The risk of something going wrong when deploying HPKP is hard to overlook, as a small mistake could ultimately destroy a company’s business by making its website inaccessible for months. Only a few thousand secure websites have accepted this risk so far, although you could argue that it only makes sense to deploy HPKP on the largest and most visible websites. For smaller websites, the high risk of something going wrong is outweighed by the incredibly low risk of being attacked: Fraudulently issued certificates are a very rare occurrence, and are more likely to be used to impersonate the biggest websites.
An even newer technology known as Expect CT could potentially provide a safer and easier approach to tackling fraudulently issued certificates. Opted-in websites will be able to tell browsers to expect to see their legitimate certificates in a Certificate Transparency log. These logs are open to public scrutiny, allowing mis-issued certificates to be identified by domain owners, CAs and domain users; and fraudulently issued certificates that do not appear in logs would not be trusted under Expect CT. CAs would be responsible for entering correct details into these logs, thus removing the burden from website operators.
Sites that have properly configured HPKP would be extremely hard to attack in practice, although it is still not impossible. Browsers that have never visited a site before could still be vulnerable to man-in-the-middle attacks if an attacker obtains a valid certificate, because unlike with HSTS, there is no common preload list available for HPKP (it is, however, possible to request special treatment in Google Chrome).
Netcraft offers a range of services that can be used to detect and defeat large-scale pharming attacks, and security testing services that identify man-in-the-middle vulnerabilities in web application and mobile apps. Contact firstname.lastname@example.org for more information.