Controversial HTTP Public Key Pinning bypass?

in

HTTP Public Key Pinning is now a pretty well established standard, as defined by RFC 7469, with a visible presence among production websites (e.g. python.org). There's one controversial topic that has been recently raised on a number of forums, including IETF and OWASP, but is little known outside.

Essentially, HPKP allows website owners to publicly announce the identifiers of legitimate X.509 certificates used to authenticate their website over TLS. If the identifier doesn't match, the browser should generate an alert that can be reported to the website's owner. But this generally true policy has one interesting exception: in reality, not all the violations will be reported even when the actual key doesn't match the pinned one.

This is what Chromium project has to say on that topic:

Chrome does not perform pin validation when the certificate chain chains up to a private trust anchor. A key result of this policy is that private trust anchors can be used to proxy (or MITM) connections, even to pinned sites. “Data loss prevention” appliances, firewalls, content filters, and malware can use this feature to defeat the protections of key pinning.

We deem this acceptable because the proxy or MITM can only be effective if the client machine has already been configured to trust the proxy’s issuing certificate — that is, the client is already under the control of the person who controls the proxy (e.g. the enterprise’s IT administrator). If the client does not trust the private trust anchor, the proxy’s attempt to mediate the connection will fail as it should.

The same is restated in the RFC 7469 Section 2.6:

It is acceptable to allow Pin Validation to be disabled for some Hosts according to local policy. For example, a UA may disable Pin Validation for Pinned Hosts whose validated certificate chain terminates at a user-defined trust anchor, rather than a trust anchor built-in to the UA (or underlying platform).

The same RFC section also mutes reports in such cases:

UAs send validation failure reports only when Pin Validation is actually in effect. Pin Validation might not be in effect, e.g., because the user has elected to disable it, or because a presented certificate chain chains up to a user-defined trust anchor. In such cases, UAs SHOULD NOT send reports.

This policy has caused some heated discussions on IETF, Wikipedia and OWASP forums, which I can understand: the overall atmosphere around HPKP was that it gives the website owners control over their authenticity and now it comes out that there's a loophole in that control. Your website can be accessed through a MITM proxy, it's explicitly enabled for a certain class of these proxies and violation reports are explicitly disabled for that by the standard.

At the same time I can also understand the logic behind the "local certificate store exception" and it makes a lot of sense. Content inspection of TLS traffic at corporate networks has full business and legal justification in most cases, as companies are responsible for whatever their employees post or download. Also, if the corporate network is the only place where you're using a particular computer, then the whole HPKP model falls apart anyway — the proxy can strip the HPKP header from the response before the browser will ever see it and have a chance to remember the authentic pins.

The threat modelling assumption behind the current HPKP logic is that if your operating system's certificate store has been equipped with an additional intermediate CA certificate, it has been done for legitimate purpose. If you're accessing Internet from a clean computer in a globally content-inspecting country the HPKP assumption should hold and you will be warned of interception as well as will be the website owner. If your computer has been tampered with, either by law enforcement agency or by a malware, then bypassing HPKP is perhaps the least of your worries...