HPKP Public Key Pinning backup pin

I’m having an easy time of adding the primary pin, since I can hash the existing certificate. But I need a valid backup pin.

I read something about using an upstream pin, such as the CA certificate, and so on, but those don’t look to be valid pins. It seems that in real world, the certificate process is handled locally and you’d have a CSR generated and ready to use when it comes to generating a new certificate. This isn’t the case for Cloudflare users.

What should the backup pin be? For now, I generated my own CSR, etc, but I doubt it will work as a backup pin.

As it stands using HPKP with Cloudflare is like playing with fire… you probably will get an outage whilst you fudge around after a cert renewal if you go down your current path.

What you could do is start generating your own keys on your backend via Let’s Encrypt, say, and include their hash as your backup. If Cloudflare were to change your key (they do not notify you of this, your site would simply stop working) then you could disable their proxying (go grey cloud) so clients were served your Let’s Encrypt key and continue to work, you could then update your HPKP record with the hash of the new Cloudflare key. However you wouldn’t be able to return to Cloudflare proxying (orange cloud) until you were sure your old cached HPKP has expired on all your clients (which would depend on the expiration time you set). Also, you’d need to monitor your site for when the SSL key had rotated and you needed to step in.

As you can see, this is quite the overhead so it may be better for you to use the hash of the upstream keys such as the ‘COMODO ECC Certification Authority’ etc. I know for CAA Cloudflare have said we’d need comodoca, digicert and globalsign defined - maybe a staff member could give us the keys that’d be used for each of these as that should cover all bases.

Here’s the blurb about the upstream keys:

  • Public keys corresponding to certificate authorities and their intermediate certificates

But when I use this tool to get my keys:
https://report-uri.io/home/pkp_hash

It gives me hashes for the upstream certificates, but then I run this tool:
https://report-uri.io/home/pkp_analyse

It recognizes the keys of the upstream providers, but warns that they don’t count as backup pins. I’m attaching a screenshot of the pins I’ve tried using.

Yeah, don’t think they consider it a backup if it is just further back up the same chain.

Disclaimer:

  1. We really don’t recommend you do this.
  2. You probably can do it anyway, but it’s not a feature we support.
  3. Cloudflare will be sympathetic when things break (and they will break) but we will refer you to items 1 & 2.

The Backup Pin would be something you manage with a certificate external to Cloudflare. My (very limited) understanding is that this pin exists in the event you move away form Cloudflare or gray cloud a record.

2 Likes

After all this, it doesn’t seem like HPKP is as robust as it should be. The primary key is fine, but implementing a backup key seems to work in a very limited real world situation. That backup key is supposed to kick in when your primary pin expires…or, yes, if you move away from Cloudflare, or some other situation where your primary key changes.

At least with CAA (which I have implemented, thanks to Cloudflare) helps protect against the same attack vector as HPKP.

My big question at this point is: Why doesn’t a key further up the chain count as a backup? Those keys are less likely to change than my primary key.

I found the answer to my own question: Keys in the current chain can’t be used as a backup. I found this near the end of:

Does a browser really ignore HPKP if the backup is in the same chain? There’s only one place that red-flags my HPKP: the HPHP Policy Analyzer I posted earlier, but securityheaders.io (same guy) doesn’t flag it.

HPKP RFC 7469 states that:

The UA MUST note the Pins for a Host if and only if all three of the following conditions hold:

  • It received the PKP response header field over an error-free TLS connection. If the host is a Pinned Host, this includes the validation added in Section 2.6.
  • The TLS connection was authenticated with a certificate chain containing at least one of the SPKI structures indicated by at least one of the given SPKI Fingerprints (see Section 2.6).
  • The given set of Pins contains at least one Pin that does NOT refer to an SPKI in the certificate chain. (That is, the host must set a Backup Pin; see Section 4.3.)

If the PKP response header field does not meet all three of these criteria, the UA MUST NOT note the host as a Pinned Host. A PKP response header field that meets all these criteria is known as a Valid Pinning Header.

So, yes backup key must not be in the same chain.

If you still wanted to set up HPKP, here’s the certificates you should pin:

Universal SSL

Dedicated SSL

Let’s Encrypt (Since Let’s Encrypt is planning to provide Wildcards certs, there’s a chance that Cloudflare will use Let’s Encrypt in the future)

If you are a Business or Enterprise customer, you can pin your desired root certificate since you can upload your own certificate.

Disclaimer
Neither Cloudflare nor I am responsible if you lose access to your website due to setting up HPKP. The information provided here is accurate to the best of my knowledge at the time of writing. As a suggestion, please keep a low max-age.

1 Like

Thanks, tanto259. Good solid information. Glad to say it hasn’t upset anything I’ve learned so far. I set the Comodo ECC certificate as my primary pin. That should be pretty solid for a while.

So that still leaves me the issue of a backup pin. I’m using a self-generated CSR for this one. It’s at least a valid format, but one that will never suffice as a true backup.

Is there no reliable way to create a backup pin that will work for someone using Cloudflare Universal SSL?

Plan B:
I’ve used Let’s Encrypt in the past and can generate LE certs on my server. Should I just make my own CSR (I’ve done this already) that I manually feed to Let’s Encrypt in an emergency where I lose my primary key?

The main problem is that Cloudflare can change their CA at any time. This has happened in the past. Before Comodo, they use GlobalSign, and based on this tweet by Patrick, Cloudflare’s SSL/TLS Product Manager, they might change to Let’s Encrypt in the future.

In my opinion, the most reliable solution is to use Business or Enterprise plan, so you can always use your own certificate and control the CA used. But, it is quite expensive.

Another option is to :grey: your domain and set up SSL and HPKP on your origin server, abandoning Cloudflare’s CDN altogether, using only the DNS. But, you’ll lose Cloudflare’s security and caching benefits.

Or, you can pin the current Comodo root certificates with Let’s Encrypt as backup and set a low max-age so that you can recover quickly with minimum downtime in the case of an accident.

Thanks for all the help. I think I’ve just about explored this one out. What I’ve learned:

  1. You will have an outage if your certificate goes away due to revocation or expiration/renewal/replacement. This outage will last until you replace your cert with your backup one that matches your backup pin.
  2. This is worse when someone, such as Cloudflare, controls your cert, as you don’t have a backup one that will work with Cloudflare.
  3. The only solution at the free/cheap plans is to jump off of Cloudflare when your primary certificate breaks and use your non-Cloudflare backup certificate.

At this point, I think I will use Comodo ECC Intermediary Certificate as my Primary Pin, and Let’s Encrypt Intermediary Certificate as my Backup Pin. This should let me function at Cloudflare, and a backup if Cloudflare switches to LE, or I Grey Cloud and LE myself.

review.aimrom.org is on Cloudflare and uses hpkp

I don’t use the proxy though, only DNS

As a followup, I’ve turned off HPKP. Good riddance.

I can confirm that if I click the CDN toggle hpkp still kicks in and blocks all access
Chrome also has an hpkp section in settings where you can add static pins for a website