You are here

Public Key Pinning

Affects product: 
Airlock WAF

Update November 2017:
Google's Chrome security team has announced to remove support for HPKP by end of May 2018 in release 67 [9].
Internet Explorer, Edge and Safari never supported HPKP. So there are only Firefox and Opera left. For this reason we do not recommend to set up HPKP usage scenarios.

This article describes HTTP public key pinning (HPKP) and how to configure it on Airlock WAF.

Deploying public key pinning safely will require operational and organizational maturity due to the risk that hosts may make themselves unavailable by pinning to a public key that becomes invalid.

What is HTTP Public Key Pinning

HPKP is a security mechanism which allows HTTPS websites to resist impersonation by attackers using misissued or otherwise fraudulent certificates. The HTTPS web server passes a list of public key hashes a.k.a. pins to the client. The client caches the domain name to pin relation. We call this process pinning. On subsequent connections the clients verifies that the server uses one or more of those pinned public keys in its certificate chain [1].

Benefits

  • Clients are notified and can no longer access HPKP protected websites if a man in the middle attacker (MITM) with a forged certificate is present. Note that a single compromised root certificate authority in the browser is enough to forge a certificate and perform a MITM attack on any HTTPS website (weakest link problem).
  • HPKP can increase the security rating of your website calculated by common security scanners [6][7].

Drawbacks and Limitations

  • The certificate renewal process is more complex (see section Renewal of a Certificate). Misconfiguration can render a website unavailable for clients with invalid cached pins.
  • HPKP is a Trust on First Use (TOFU) technique [2]. The very first request to the website is not protected. This also applies to the first request when the website is not visited for a certain amount of time (see parameter max-age in section Configuration). However, after the first untampered response is received, MITM attacks are prevented for the next max-age seconds.
  • HPKP supports SSL/TLS intercepting proxies, since HPKP is ignored by all major browsers if the certificate chain is terminated at a user defined certificate in the browsers certificate store. Even if a client has pinned the real certificate of the server in advance.

Browser Support

HPKP support is documented in [8].

Prerequisites

HPKP requires at least two pins to be sent to the client. One of the pin must be based on a public key in the servers certificate chain while the other must not. The second key which is not sent to the client is used as a backup key in case of the primary key is compromised and can be used for a regular certificate renewal. The backup private key should be stored in a safe place and the size should be chosen so that it fulfills your security requirements for the next certificate renewal.

Before you configure HPKP you have to decide whether you want to pin the root, intermediate or the leaf certificate in your certificate chain. Pinning intermediate certificates makes the renewal of leaf certificates easier. On the other hand, pinning leaf certificates is more secure, because MITM is not possible even when if the intermediate certificate authority is compromised. Additionally CAs typically don't guarantee the usage of a specific root or intermediate certificate. For most of the CAs browser have included multiple certificates. For security and stability reasons we recommend to pin the leaf certificate.

Configuration

HPKP is enforced on client side by sending the HTTP response header Public-Key-Pins. All available header value properties are described in [2]. We recommend to add the header on the HTTPS virtual host using Apache expert settings (Configuration Center - Virtual Host - "Expert Settings") rather than on individual mappings to prevent inconsistent settings among them. 

Example of the Apache expert setting:

Header set public-key-pins "pin-sha256=\"vwJbVK5Mh1vaO4wOEUzX9jnxalBjDnIJgh3cX5FMl9A=\"; pin-sha256=\"LeSTjTfnibfKHJmDfIGoWrE7JwFWMUy/+3Ft55sBTGs=\"; max-age=5184000"

A low value of max-age (e.g. a few seconds) can be used for testing purposes, so if something goes wrong, you can remove the header and the policy will expire very quickly. A higher value provides more security because of the TOFU security model described in section Drawbacks and Limitations. A reasonable value may be 60 days (5184000 seconds).

The following shell command generates the Subject Public Key Information (SPKI) fingerprint of a server certificate with the name airlock-test.ch configured on Airlock WAF [5]. The resulting value can be used for the pin-sha256 parameter value of the HPKP header.

openssl x509 -pubkey -in /opt/airlock/ext-apache/conf/ssl.crt/server.crt.airlock-test.ch.* | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | base64

Renewal of a Certificate

We recommend to start a regular certificate renewal at least 1 month plus max-age (see Configuration) before the actual certificate expires.

This section describes how to renew a pinned certificate, e.g. because it is compromised or will expire soon. We assume that the leaf certificate is pinned as recommended in section Prerequisites.

There are 3 different ways to renew a certificate. 

1) Reusing the old key for the new certificate

By reusing the old public/private key for the new certificate (order a new certificate based on the existing CSR), the certificate can be replaced without updating the HPKP header. This is because HPKP is based on the public key rather than the certificate.

2) Create a new certificate based on the backup key

This approach is recommended if you don't want to reuse the key of the old certificate or when the actual certificates private key is compromized. Steps to proceed:

  • Create a new certificate based on the backup key or backup CSR, respectively.
  • Create a new backup key and generate the pin for the key (see Configuration).
  • Replace the old certificate with the new one.
  • Update the HPKP header and replace the pin of the old certificate with the new backup pin.

3) Create a new certificate based on a new key

This approach required updating the HPKP header at least max-age seconds before the current certificate expires. Otherwise some clients might be locked out. The approach should only be chosen when the backup key can not be used for the certificate renewal, e.g. because the size of the key is no longer suitable. Steps to proceed:

  • Create a certificate based on a new key. Generate the pin for the new key (see Configuration).
  • Update the HPKP header and add the new pin. Now at least 3 pins must be configured (new pin, old pin, backup pin)
  • Wait at least max-age seconds. This step is necessary to ensure that all clients have learned the new pin or forget the old one.
  • Replace the old certificate with the new one.
  • Remove the pin of the old certificate from the HPKP header.
  • Create a new backup key and generate the pin for the key.
  • Replace the old backup pin with the new one.

Testing and Debugging

To verify that HPKP is working see section "How to verify Public Key Pinning (HPKP) is working" in [3].

We recommend to check the console events in Firefox after activating HPKP. Some common misconfigurations are reported there. Example:

Public-Key-Pins: The site specified a header that did not include a backup pin.

Pinning is deactivated in all major browsers if the certificate chain terminates at a user-defined trust anchor (see Drawbacks and Limitations). In Firefox this can be deactivated with the setting security.cert_pinning.process_headers_from_non_builtin_roots in the Firefox Configuration Editor (about:config).

Common Misconfigurations

  • The HPKP header does not contain two distinct pins.
  • The backup pin corresponds to a public key used by a certificate in the current chain.

References

[1] https://en.wikipedia.org/wiki/HTTP_Public_Key_Pinning
[2] https://developer.mozilla.org/en/docs/Web/Security/Public_Key_Pinning
[3] https://calomel.org/http_public_key_pinning_hpkp.html
[4] https://timtaubert.de/blog/2014/10/http-public-key-pinning-explained/
[5] https://tools.ietf.org/html/rfc7469#appendix-A
[6] https://www.ssllabs.com/ssltest/
[7] https://securityheaders.io/
[8] http://caniuse.com/#search=hpkp
[9] https://groups.google.com/a/chromium.org/forum/#!msg/blink-dev/he9tr7p3rZ8/eNMwKPmUBAAJ

Knowledge Base Categories: