Subject: [websec] wrt "breaking pins" aka "un-pinning" (breakv, breakc directives; draft-evans-palmer-hsts-pinning-00)

From: =JeffH <[email-masked]>
Date: Fri, 14 Oct 2011 15:05:09 -0700

below is the text on "un-pinning" and the breakv & breakc directives from 
https://tools.ietf.org/html/draft-evans-palmer-hsts-pinning-00

discussion below this excerpt...

 > 2.  Server and Client Behavior
                 .
                 .
 >    The breakv directive communicates to UAs a pin break verifier, and
 >    the breakc directive communicates the pin break code.  Hosts SHOULD
 >    generate pin break codes and verifiers.  When present, UAs MUST note
 >    pin break verifiers and honor pin break codes.  See Section 2.3 for a
 >    discussion of verifiers and codes.
                 .
                 .
2.1.  Noting and Validating Pins
                 .
                 .
 >    UAs MUST cache pins and pin break verifiers for Known Pinned HSTS
 >    Hosts, and MIGHT AS WELL do so in the same manner as other HSTS
 >    metadata.
                 .
                 .
 > 2.3.  Un-pinning
 >
 >    Hosts can enable pin revocation for their previously-pinned key
 >    fingerprints by setting pin break verifiers using the breakv
 >    directive.  Then, when hosts want to break pins, they set the pin
 >    break code in their HSTS headers using the breakc directive.  (This
 >    idea is due to Perrin in [pin-break-codes].)
 >
 >    Pin break codes are short random strings, kept secret until the host
 >    operator wants to break the pins.  Pin break verifiers are simply
 >    hashes of the codes.
                 .
                 .
 >    Hosts can request that UAs forget pinned fingerprints by issuing a
 >    valid HSTS header containing the pin break code.  UAs MUST forget all
 >    pinned fingerprints associated with the matching pin break verifier,
 >    and MUST NOT forget any pinned fingerprints not associated with that
 >    verifier.
 >
 >    In the event that a host sends an HSTS header containing a breakc
 >    that does not match a breakv the UA has previously noted, the UA MUST
 >    ignore that breakc and MUST process any pins or breakv directives as
 >    normal.  This is so that hosts can break old pins but still
 >    successfully set new pins and verifiers in UAs that have not
 >    previously (or recently) noted the host.
 >
 >    Host operators SHOULD keep the pin break code secret, and SHOULD
 >    generate codes that are computationally infeasible to guess (such as
 >    by using their system's cryptographic random number generator; note
 >    that a 128-bit security level suffices).

In order for this "un-pinning" pin-break-verifier-and-code mechanism to 
generally work, the UA still connects and and makes an HTTP request and reads 
response headers. See this paragraph from S 2.1...

    Note that to validate pins, UAs must necessarily read the headers of
    a response.  In case of mismatch, UAs SHOULD NOT read the response
    body as part of failing hard.

This appears to be necessary in order to receive a break code (breakc) 
invalidating the pin(s) of a Known Pinned Host that doesn't already have its 
present cert/key, i.e. that it's showing in the TLS handshake (for whatever 
reason), cached in UAs. This situation would render the Host unavailable to 
those UAs.

So if a purported Known Pinned Host presents a cert chain in the TLS handshake 
lacking any keys on the UA's pinned key list, then it could be a bogus host (eg 
attacker), and if the UA does a HTTP GET and sends cookies (as well as receives 
a response and examines headers (e.g. the UA could be redirected further 
afield)) in any case, then this is a (non-trivial) vulnerability.

In such a situation, the way the UA can tell it is connected to the intended 
host is if the host presents a break code that properly matches a previously 
noted verifier for that host. This property holds because the break code is a 
secret held by the host until needed. This prevents any host from being able to 
unpin other hosts, which is necessary when the pin check is located up in the 
HTTP layer.

So we have a fundamental question here:

   Must the pinning mechanism provide the capability for a pinned host to
   dynamically recover from situations that otherwise render it unavailable
   (to those UAs that have noted the host as a Known Pinned Host)?

In examining the various such situations (aka "disasters") outlined in Sec 3, 
it appears that essentially all of them are mitigated if the host operators 
allocated a backup server key/cert as advised, and have properly issued a pin 
to it, along with their pin to their present operational key/cert. In this 
situation, it appears that having the pin-break-verifier-and-code mechanism 
isn't strictly necessary.

Rather, the pin-break-verifier-and-code mechanism is arguably useful only in 
the case where one doesn't have properly pinned backup server key/cert that 
chains to a different trust root than one's other key/cert(s). But it has the 
security issues noted above given its present design.

It appears that we need to decide whether this pin-break-verifier-and-code 
mechanism is worth the complexity and its vulnerability. One argument is that 
if some web app provider is willing to take the risk of pinning itself without 
proper, carefully considered recovery means and plans, then that's their 
decision. Additionally, if UAs provide users the means to clear(and set) pins, 
then worst-case, they can contact their users with instructions for how to do 
so, and perhaps along with a new pin to enter.

Providers wishing to avoid such situation will need to craft and implement 
proper, carefully considered recovery means and plans.

If we took this approach, then we could eliminate the breakc and breakv 
directives and manage pins in the a fashion similar to how HSTS works -- the UA 
notes the freshest info from a Known HSTS Host if it is different than what is 
presently cached for that host, and a "max-age = 0" will clear the cached 
metadata for that host.

( this dovetails with a discussion of using a separate header for pinning, 
"separate pinning header" )

=JeffH

ps: of course this discussion begs the question of conveying pinning 
information in the TLS channel, perhaps as data in an X.509 cert extension, as 
Adam L is doing for "DNSSEC authenticated HTTPS", or in some other fashion.

---

From: Trevor Perrin <[email-masked]>
Date: Sun, 16 Oct 2011 20:09:21 -0700

Hi Jeff,

In defense of pin-break codes! -

On Fri, Oct 14, 2011 at 3:05 PM, =JeffH <[email-masked]> wrote:
> So if a purported Known Pinned Host presents a cert chain in the TLS
> handshake lacking any keys on the UA's pinned key list, then it could be a
> bogus host (eg attacker), and if the UA does a HTTP GET and sends cookies
> (as well as receives a response and examines headers (e.g. the UA could be
> redirected further afield)) in any case, then this is a (non-trivial)
> vulnerability.

A better alternative might be to deliver pin-break codes as part of
the TLS handshake (e.g. a TLS Extension).  Then:
 * Pin-break codes would work regardless of how the pin-break
verifiers are set, so pin-break codes could be used with pins set via
HSTS header, browser hardcodes, Convergence, DNS, etc.
 * Pin-break codes would work with non-HTTP protocols like SMTP or POP.
 * Pin-break codes would be retrieved without an HTTP Request,
removing the risk noted above.

What do you think?

> In examining the various such situations (aka "disasters") outlined in Sec
> 3, it appears that essentially all of them are mitigated if the host
> operators allocated a backup server key/cert as advised, and have properly
> issued a pin to it, along with their pin to their present operational
> key/cert. In this situation, it appears that having the
> pin-break-verifier-and-code mechanism isn't strictly necessary.

Both backup pins and pin-break codes let a site switch from its
current cert chain to a different one, so they have similar "disaster
mitigation" properties, and a site could choose one or the other.

Pin-break codes might be preferred by site operators nervous about
boxing themselves in with pinning, since pin-break codes let the site
change its cert chain arbitrarily without being limited by backup pins
or waiting for expiration.

Trevor

---

From: Chris Palmer <[email-masked]>
Date: Mon, 17 Oct 2011 13:31:49 -0700

On Fri, Oct 14, 2011 at 3:05 PM, =JeffH <[email-masked]> wrote:

> generally work, the UA still connects and and makes an HTTP request and
> reads response headers.

Note that the TLS layer could still abort the connection if the
connection doesn't pass the pinning test (i.e. if the connection was
made with a server certificate that does not contain any previously
pinned public keys).

Thus, in order to successfully use a breakc, you would still have to
serve it with a cert containing a public key you had pinned.
(Including, perhaps, your backup pin.)

> pin-break-verifier-and-code mechanism isn't strictly necessary.

Chris E. and I now agree with this, and are probably going to remove
breakc and breakv from the draft specification. Even if they stay,
they probably won't appear in the first rev of the Chrome
implementation. The thinking is now, "Get the simplest thing
implemented, see how people like it, and implement breakc/v if there
is demand."

This would probably/almost certainly imply that pins expire when the
server stops mentioning them in the pins directive (or when max-age
expires, whichever is soonest).