Subject: Re: [websec] draft-ietf-websec-key-pinning

From: Ryan Sleevi <[email-masked]>
Date: Sun, 24 Aug 2014 23:03:50 -0700

On Fri, Aug 8, 2014 at 1:50 PM, Eric Lawrence <[email-masked]>
wrote:

>   Comments on http://tools.ietf.org/html/draft-ietf-websec-key-pinning-20
> -------
> In several places, the text seems to suggest that PKP-RO rules are not
> intended to be cached within the UA. Is that the case? If so, this isn't
> explicit; max-age should be forbidden.
>
> In contrast, if PKP-RO rules are allowed to be cached within the UA, then
> the following should be removed:
>
>    Note: There is no purpose to using the PKP-RO header without the
>    report-uri directive.  User Agents MAY discard such headers without
>    interpreting them further.
>
> ... because the site may wish to disable a previously-cached PKP-RO entry.
>

No, PKP-RO is not meant to be cached. In this respect, it behaves similar
to Content-Security-Policy's reporting mechanism.

I'm not sure if you're suggesting forbidden - such as treating the header
as ill-formed, ergo not sending a report - or merely ignored. I feel like
#6 of Section 2.1 already reflects this, but would be happy to add specific
text directly stating that max-age is IGNORED for PKP-RO.

>
> -------
> 2.3.1.
>
> RO header fieled
> -
> typo, fieled->field
>
> -------
> 2.5
>    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.
> -
> If the failing criteria was "cert chain didn't contain at least one of the
> SPKI signatures", should this trigger a report to the report URI to aid
> developers and/or enable some amount of protection for sloppy attacks (or
> captive/corporate MITM interception, etc) against 1st-time visitors?
>

Doesn't
http://tools.ietf.org/html/draft-ietf-websec-key-pinning-20#section-2.1.3
already accomplish this?

   When used in the PKP or PKP-RO headers, the presence of a report-uri
   directive indicates to the UA that in the event of Pin Validation
   failure it SHOULD POST a report to the report-uri.  If the header is
   Public-Key-Pins, the UA should do this in addition to terminating the
   connection (as described in Section 2.6
<http://tools.ietf.org/html/draft-ietf-websec-key-pinning-20#section-2.6>).

>
> -------
> 2.6.  Validating Pinned Connections
>    When a UA connects to a Pinned Host, if the TLS connection has
>    errors"
> -
> This probably should be "connects to a Pinned host using TLS connection"
> since PKP does not require that the user connect via a secure connection.
>

Thanks, yes.

>
> -------
> "If the connection has no errors, then the UA will determine whether
>    to apply a new, additional correctness check: Pin Validation"
> -
> Should this wait until the TLS validation has fully completed, or should
> it happen before the client potentially responds to a
> clientCertificateRequest from the server?
>

The implementations are already consistently-inconsistent in this respect.
That is, both Chrome and Firefox do this during certificate validation, but
for timing reasons, certificate validation occurs at different times.

Both are currently allowed.

>
> -------
> 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.
> -
> Might it be useful to explain the motivation here, however briefly? I'm
> super-happy to see this here (Fiddler!), but most UAs don't have trust
> anchors built-in, they rely on the operating system to provide them.
>
>

Well, this was merely meant as one representative example, not necessarily
a normative recommendation. That is, one could equally add "For example, a
UA without built-in trust anchors may also decide to ..." and still be
consistent with the normative SHOULD - that is, the examples are
non-exhaustive.

Still, happy to expand this text further, as I suspect this is just an
unintentional use of restrictive terminology (i.e. a UA can do this even
when it defers to the OS trust store)

> -------
> The UA MUST ignore superfluous certificates in the chain that do not form
> part of the validating chain.
> -
> As far as I understand things, there can be multiple valid chains to
> multiple roots. Should the validation procedure be required to check each
> possible candidate chain?
>

Neither RFC 5280 nor RFC 5246 require UAs to evaluate all candidate chains.
Indeed, there's enough controversy from parties in TLS that I suspect there
is not clean resolution in either event.

In the UA sphere, not all UAs consider candidate chains. Mozilla Firefox,
before version 31 (implementing mozilla::pkix) did not consider all
candidate chains. 31+, it does, and it does the pinning check during the
evaluation of potentially valid candidate chains.

Google Chrome defers to the OS for the chain building, which OS X does not
consider candidate chains, but Windows does. However, Windows lacks a
suitable means for calling back on evaluating candidate chains. As a
result, Chrome performs validation after the candidate chain has been
declared "successful".

So the answer is "No, it should be required"

>
> -------
> locally-installed anchor
> -
> This should probably be "user-defined trust anchor" to match the earlier
> prose.
>
> -------
> "served-certificate-chain": [
>        pem1, ... pemN
>      ],
> -
> Privacy: This could leak organizationally-private information; say the
> user's company is using BlueCoat or another intercepting proxy with
> interception certificates that contain data that should not leave the
> organization.
>

Funny that this spec would consider the privacy of the attacker (as such
situations are indistinguishable from an attack on the pins).

Still, happy to call it out specifically.

>
> -------
> "include-subdomains": include-subdomains,
> -
> This field could be misleading, as the JSON report contains the hostname
> that the user visited, which may differ than the host that originally set
> the rule if include-Subdomains was set on that rule.
>

Good point. This suggests that the JSON may need to indicate both the
target hostname and the source (of the PKP data) hostname.

>
> -------
> indeed could pin to issuers not in the chain
> -
> Per the spec, they indeed MUST include a pin to an issuer not in the chain
>
> -------
> 4.4.  Interactions With Cookie Scoping
> -
> I'll mention that IE sends cookies to subdomains even when a domain
> attribute isn't present. Q3:
> http://blogs.msdn.com/b/ieinternals/archive/2009/08/20/wininet-ie-cookie-internals-faq.aspx
>
> This section suffers from the same incompleteness that Section 14 of the
> HSTS spec suffers: Because a rule specified on a subdomain
> (effective-third-level-domain) does not apply to the
> effective-second-level-domain, if a user visits the 3rd-level domain first
> or exclusively, a MITM attacker can perform a cookie-injection by
> generating a phony insecure request to the effective-second-level-domain
> and returning a Set-Cookie header in his poisoned response.
>

I'm not sure I understand your remark with respect to "incompleteness".
This is more of an operational guidance for server operators, correct?

>
> -------
> 5.  Privacy Considerations
> "UAs MAY, therefore, refuse to send reports outside of the origin that set
> the PKP or PKP-RO header."
> -
> 1. It seems odd to put a mitigation inside a description of the attack.
>

Per Stephen's DISCUSS, I think we'll be bringing this mitigation 'out' a
level in the spec.

> 2. Doesn't the proposed mitigation inherently failure-prone, since the
> report would inevitably fail, because the origin's PKP rule would block the
> report?
>

It prevents the collusion, so that seems to effectively mitigate that
particular attack, does it not?

>
> -------
> 5.  Privacy Considerations
> "Conforming implementations..."
> -
> 1. This 3rd privacy attack should be bulleted as a separate point.
>

Agreed

> 2. Earlier, it's stated that PKPs should be stored in "non-volatile
> storage". In practice, I would expect UAs would ignore attempts to update
> PKP/PKP-RO rules while in their respective "Private Mode"s. Is that the
> expectation of the authors?
>

Update the non-volatile storage? Yes, that's what a UA would likely do.
Prevent updates to volatile storage? No, just as UAs in such modes
traditionally allow a degree of volatile storage (since the modes are
primarily meant to prevent disk persistence, rather than tracking). This
allows, for example, session cookies to work.

> Thanks!
> -Eric Lawrence

---

From: "Eric Lawrence" <[email-masked]>
Date: Mon, 25 Aug 2014 13:07:36 -0500

Thanks, Ryan! A few remarks inline...
> No, PKP-RO is not meant to be cached. In this respect, it behaves similar to Content-Security-Policy's reporting mechanism.
Ah, interesting. I’m curious why not? Is there no use-case for allowing “report-only” pins to be persisted?
If PKP-RO is not meant to persist, then I’d suggest that this sentence should be significantly altered: “If a host sets the PKP-RO header, the UA SHOULD note the Pins and directives given in the PKP-RO header as specified by the max-age directive.” The pins aren’t being “noted” (recorded) anywhere, and “specified by the max-age directive” has no meaning.
Furthermore, saying that “max-age is OPTIONAL within a "Public-Key-Pins- Report-Only" header field.”  implies to me that the intent is that supplying a max-age would have some function.
     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. 
  -
  If the failing criteria was "cert chain didn't contain at least one of the SPKI signatures", should this trigger a report to the report URI to aid developers and/or enable some amount of protection for sloppy attacks (or captive/corporate MITM interception, etc) against 1st-time visitors?

> Doesn't http://tools.ietf.org/html/draft-ietf-websec-key-pinning-20#section-2.1.3 already accomplish this?

Perhaps?  To me, the “UA MUST NOT note the host as a Pinned Host” suggests that the pin is deemed entirely invalid and no further processing is warranted. That assumption is based on the text that follows:

“the UA MUST NOT note the host as a Pinned Host. A PKP response header field that meets all these critera is known as a Valid Pinning Header.”

It seems odd to take action based on anything that is not a “Valid Pinning Header.”

Perhaps one of my confusions around the prose is the use of the term “note” as a verb. “Note” could mean “preserve a rule for the future” or it could mean “apply the rule for now and into the future.”

Incidentally, typo: “critera”->”criteria” in section 2.5.

  "If the connection has no errors, then the UA will determine whether
     to apply a new, additional correctness check: Pin Validation"
  -
  Should this wait until the TLS validation has fully completed, or should it happen before the client potentially responds to a clientCertificateRequest from the server?
> Both are currently allowed.

Interesting. It seems worthwhile to at least note that there’s a benefit of performing the check before the TLS handshake responds to a clientCertificateRequest message.

>>As far as I understand things, there can be multiple valid chains to multiple roots. Should the validation procedure be required to check each possible candidate chain?

Based on context, I /think/ this was a typo, missing the word “not”? 

  4.4.  Interactions With Cookie Scoping
  This section suffers from the same incompleteness that Section 14 of the HSTS spec suffers: Because a rule specified on a subdomain (effective-third-level-domain) does not apply to the effective-second-level-domain, if a user visits the 3rd-level domain first or exclusively, a MITM attacker can perform a cookie-injection by generating a phony insecure request to the effective-second-level-domain and returning a Set-Cookie header in his poisoned response.

> I'm not sure I understand your remark with respect to "incompleteness". This is more of an operational guidance for server operators, correct?

Section 4.4 describes how PKP interacts with “Cookie Scoping” but it only describes interaction with SUBDOMAINS of the target host, omitting entirely mention of the scoping of cookies to the target host’s PARENT. It’s unclear why the spec should mention one but not the other.

> It prevents the collusion, so that seems to effectively mitigate that particular attack, does it not?

As far as I can tell, yes, this approach prevents collusion, but only by completely disabling the reportURI feature. There are two possible scenarios:

  Case 1: ReportURI is cross-origin to target. Outcome: UA blocks for privacy reasons.
  Case 2: ReportURI is same-origin to target. Outcome: UA blocks reports to the ReportURI because the ReportURI refers to a host with a failing PKP rule.

Have I overlooked something?

thx,
Eric

---

From: Tom Ritter <[email-masked]>
Date: Mon, 25 Aug 2014 21:05:53 -0500

On 25 August 2014 13:07, Eric Lawrence <[email-masked]> wrote:
> Ah, interesting. I'm curious why not? Is there no use-case for allowing
> "report-only" pins to be persisted?

I think there definitely are, and I and most organizations I advise
would like that option.

-tom

---

From: Chris Palmer <[email-masked]>
Date: Tue, 26 Aug 2014 12:36:06 -0700

> I think there definitely are, and I and most organizations I advise

What would they get from it that they would not get from just
consistently serving the PKP-RO header?

---

From: Tom Ritter <[email-masked]>
Date: Tue, 26 Aug 2014 15:33:50 -0500

> consistently serving the PKP-RO header?

Well the whole threat model of HPKP (without preloading) is an
attacker that can MITM some TLS connections, but not all of them,
right?  Requiring PKP-RO to be on every load would allow an attacker
to strip the header on the connections they MITM. Letting it be cached
allows an organization to put a max-age of 45 days on it, without the
risk of bricking their site if they aren't administratively competent.

Obviously an attacker can also block the reports from being sent, but
I'm hoping that the clause "In any case of report failure, the UA MAY
attempt to re-send the report later" will be considered in this case,
and that UAs will make an attempt at getting potentially blocked
reports out at a later date.

-tom

---

From: Chris Palmer <[email-masked]>
Date: Tue, 26 Aug 2014 13:51:23 -0700

On Tue, Aug 26, 2014 at 1:33 PM, Tom Ritter <[email-masked]> wrote:

> right?

"""By effectively reducing the number of authorities who can
authenticate the domain during the lifetime of the pin, pinning may
reduce the incidence of man-in-the-middle attacks due to compromised
Certification Authorities."""

The threat model is that The Alice Foundation wants to trust only
Trents 1, 4, and 9, and no other Trents, to vouch for her identity.
That way, if Trent 6 mis-issues for The Alice Foundation, Mallory
cannot make use of the mis-issued certificate in an attack.

But, yes, Mallory can still attack CarolCorp, if CarolCorp does not
use pinning or pins to Trent 6.

> Requiring PKP-RO to be on every load would allow an attacker
> to strip the header on the connections they MITM.

Only if The Alice Foundation did not also use a regular PKP header.

> Letting it be cached

Yeah, sort of. But don't think of PKP-RO as a defense against attacks,
even if it might sometimes have that secondary benefit. It is
primarily a debugging aid for The Alice Foundation and BobCorp to get
PKP working. ("What all Trents do we need to trust, anyway?")

---

From: Chris Palmer <[email-masked]>
Date: Tue, 26 Aug 2014 14:04:32 -0700

On Tue, Aug 26, 2014 at 1:58 PM, Eric Lawrence <[email-masked]> wrote:

> As a site operator, I'd think of PKP-RO as a debugging aid more along the
> lines of: "If I turn this thing on, will anything break for anyone?"
>
> If PKP-RO doesn't have the same semantics as PKP, its utility for answering
> that question declines.

PKP-RO has the same semantics as PKP, at the time of Pin Validation,
which is what matters.

---

From: Tom Ritter <[email-masked]>
Date: Tue, 26 Aug 2014 16:06:54 -0500

> Only if The Alice Foundation did not also use a regular PKP header.

Correct.

> PKP working. ("What all Trents do we need to trust, anyway?")

I'm not going to put words in your mouth, because different authors
have different opinions about things, but I will quote from another:

> Ryan Sleevi wrote (http://lists.w3.org/Archives/Public/public-webcrypto-comments/2013Feb/0001.html)
>> I wrote:
>> 1. A large site that is commonly proxies by corporate and malicious
>> actors wishes to monitor how common this is done.  They place
>> javascript bindings in their code to view the user's certificate and
>> report the observed value.
>> Note this use case has already been performed by Facebook, who had to
>> resort to Flash to do so, because javascript did not provide the
>> functionality.
>
>Use report-uri with HPKP, in report-only mode

I don't consider PKP-RO as a defense, but as an attempt at detection
of attacks, with no risk of breaking your site.  It is extraordinarily
useful to be notified of attacks against your users, even if they are
not prevented. They help you understand where you should invest time
and money.

The foot-gun potential is very high with HPKP, we all know that.  It's
high enough to the point that many organizations, who have someone
maintaining a website part time (or outsource it) may forgoe PKP
entirely because it makes them nervous - but they would be happy to
deploy a no-risk PKP-RO.  But the benefit of doing so if it is not
being cached is extraordinarily low, to the point it's probably not
worth doing.

-tom

---

From: "Eric Lawrence" <[email-masked]>
Date: Tue, 26 Aug 2014 15:58:54 -0500

-Eric

-----Original Message----- 
From: Chris Palmer
Sent: Tuesday, August 26, 2014 3:51 PM
To: Tom Ritter
Cc: Eric Lawrence ; [email-masked] ; IETF 
WebSec WG ; Ryan Sleevi
Subject: Re: [websec] draft-ietf-websec-key-pinning

---

From: Ryan Sleevi <[email-masked]>
Date: Tue, 26 Aug 2014 14:12:36 -0700

On Tue, Aug 26, 2014 at 2:06 PM, Tom Ritter <[email-masked]> wrote:

> > Ryan Sleevi wrote (
> http://lists.w3.org/Archives/Public/public-webcrypto-comments/2013Feb/0001.html
> )
> >> I wrote:

To be clear, I absolutely agree with Chris. You cannot and should not be
seeing PKP-RO as a security mechanism.

Contextually, this also lacks the significant discussion of enterprise
policy and the like. As noted in the spec, UAs MAY disable Pin Validation
according to policy - such as locally trusted authorities, such as
corporate proxies or malicious actors.

---

From: Chris Palmer <[email-masked]>
Date: Tue, 26 Aug 2014 14:20:38 -0700

> being cached is extraordinarily low, to the point it's probably not

3 full years ago, HPKP was conceived as a single new directive to
piggyback on HSTS. Now it's a design-by-committee extravaganza with
knobs and bells and whistles all over the place. It also has a jaunty
cap. The cap is not a protective helmet, but hey — it *is* jaunty as
all get-out. :)

I just want to get something published, even if it's imperfect, so we
can move on. This process is taking my time away from other important
tasks, and I can't let that happen much longer.

---

From: Trevor Perrin <[email-masked]>
Date: Tue, 26 Aug 2014 14:38:09 -0700

> PKP-RO has the same semantics as PKP, at the time of Pin Validation,

That's not completely true, because PKP affects Pin Validation of
other connections, and PKP-RO doesn't.

So turning on PKP-RO tests "do browsers construct the certificate path
I expect".  It doesn't test "does my site return the correct
certificate for all connections".

So Eric's point is valid: PKP-RO doesn't provide an administrator much
confidence that their site is ready for PKP, and might even mislead
them.

Trevor

---

From: Tom Ritter <[email-masked]>
Date: Tue, 26 Aug 2014 16:42:29 -0500

On 26 August 2014 16:38, Trevor Perrin <[email-masked]> wrote:
> ...

This is especially true if includeSubdomains is enabled. It'd be
common for that directive to apply to hosts that the -RO header would
not be included on. In PKP-RO, it would not be applied to them; in PKP
it would.

-tom

---

From: Chris Palmer <[email-masked]>
Date: Tue, 26 Aug 2014 15:10:25 -0700

> not be included on. In PKP-RO, it would not be applied to them; in PKP

OK, so, what do you want?

Is it even possible for me to write text you would accept?

---

From: Joseph Bonneau <[email-masked]>
Date: Tue, 26 Aug 2014 18:44:46 -0400

> Is it even possible for me to write text you would accept?

The answer may be "no" here which would suggest dropping PKP-RO completely
as an alternative way forward. Taking a step back, this thread features two
sides arguing that this feature is (largely) useless for what the other
side wants it for (testing vs. security).

As pointed out, the current version is not nearly sufficient for testing a
site's PKP-readiness due to subdomains and (potentially) load-balancing a
domain onto servers with different keys (some of which may not be in the
pin set and not set PKP-RO and be missed by setting the header on other
servers). Testing with -RO is surely better than no testing at all, but it
seems most domains would need to do more extensive testing manually by
crawling/viewing network traffic/etc. at which point they'd gain the
benefit of -RO testing anyways.

Maybe there is some benefit for quick tests to see what certs UAs are
actually receiving, which it was pointed out Facebook used Flash to achieve
(I know of at least two other academic research efforts that have used the
same approach). But if this is the goal, PKP-RO is pretty limited compared
to adding something to JS or WebCrypto which would just ping back with the
exact cert chain received. This use case seems best addressed elsewhere
rather than bolted onto this spec.

Hence, given the concern that this spec is already bloated, I would
advocate we seriously consider dropping -RO mode completely.

---

From: Tom Ritter <[email-masked]>
Date: Tue, 26 Aug 2014 18:07:56 -0500

> Is it even possible for me to write text you would accept?

Just because I have a concern or preference doesn't mean I don't
really appreciate the work you've done. I do.

I'd like PKP-RO to be cached like PKP and applied the same way, absent
the connection termination (preference). After I realized the
includeSubdomains issue (concern), I want it even more for testing a
deployment than I want it for my prior attack detection arguments
(preference).

I've tried to find all the references someone (e.g. a reviewer) might
want changed to do this.  My suggestions:

----------

The "max-age" directive is REQUIRED to be present within a "Public-
   Key-Pins" header field, and is OPTIONAL within a "Public-Key-Pins-
   Report-Only" header field.

Become

The "max-age" directive is REQUIRED to be present within the "Public-
   Key-Pins" and "Public-Key-Pins-Report-Only" header fields.

----------

Become

Note: The only purpose to using the PKP-RO header without the
   report-uri directive is to include a max-age=0 to clear any previously
   saved PKP-RO directives.  After doing so, User Agents MAY discard
   such headers without interpreting them further.

----------

If a host sets both the PKP header and the PKP-RO header, the UA MUST
   note and enforce Pin Validation as specified by the PKP header, and
   SHOULD process the Pins and directives given in the PKP-RO header.
   If the UA does process the Pins and directives in the PKP-RO header
   it SHOULD evaluate the specified policy and SHOULD report any would-
   be Pin Validation failures that would occur if the report-only policy
   were enforced.

Become

If a host sets both the PKP header and the PKP-RO header, the UA MUST
   note and enforce Pin Validation as specified by the PKP header, and
   SHOULD note and process the Pins and directives given in the PKP-RO header.
   If the UA does process the Pins and directives in the PKP-RO header
   it SHOULD evaluate the specified policy and SHOULD report any would-
   be Pin Validation failures that would occur if the report-only policy
   were enforced.

----------

Upon receipt of the PKP response header field, the UA notes the host
   as a Known Pinned Host, storing the Pins and their associated
   directives in non-volatile storage (for example, along with the HSTS
   metadata).  The Pins and their associated directives are collectively
   known as Pinning Metadata.

Become

Upon receipt of a PKP or PKP-RO response header field, the UA notes the host
   as a Known Pinned Host, storing the Pins and their associated
   directives in non-volatile storage (for example, along with the HSTS
   metadata).  The Pins and their associated directives are collectively
   known as Pinning Metadata.

----------

It received the PKP response header field over an error-free TLS
      connection.

Become

It received the PKP or PKP-RO response header field over an error-free TLS
      connection.

----------

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 critera is known as a
   Valid Pinning Header.

Become

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

----------

The UA need not note any Pins or other policy expressed in the PKP-RO
   response header field, except for the purpose of determining that it
   has already sent a report for a given policy.  UAs SHOULD make a best
   effort not to inundate report-uris with redundant reports.

be removed entirely. The final sentence is included previously as a
SHOULD at the end of 2.1.3

----------
In Section 2.6:

Otherwise, the UA MUST
   treat this Pin Validation Failure as a non-recoverable error.

Become

Otherwise, if the Pinning Metadata indicates the policy was not set by
   the PKP-RO header, the UA MUST treat this Pin Validation Failure
   as a non-recoverable error.

----------

I believe that Section 2.3.2, paragraph "If a host sets the PKP-RO
header..." is clear enough as is.

-tom

---

From: Joseph Bonneau <[email-masked]>
Date: Tue, 26 Aug 2014 20:15:53 -0400

> really appreciate the work you've done. I do.

Well said.

> deployment than I want it for my prior attack detection arguments

My email wasn't very clear but I would also prefer this policy; I was
simply trying to say that if this isn't possible or acceptable dropping it
completely might be preferable to the current version.

---

From: Trevor Perrin <[email-masked]>
Date: Tue, 26 Aug 2014 17:46:30 -0700

On Tue, Aug 26, 2014 at 5:15 PM, Joseph Bonneau <[email-masked]> wrote:
> My email wasn't very clear but I would also prefer this policy

I'd prefer this as well.  To be even clearer, I think the browser
should treat PKP and PKP-RO headers independently.  I.e., the browser
should maintain separate stores for PKP and PKP-RO data.  PKP headers
only affect the PKP store, and PKP-RO headers only affect the PKP-RO
store.

(For example, PKP max-age=0 doesn't clear PKP-RO, and vice versa).

A browser implementing this probably already has separate stores for
HSTS and HPKP, so this is just adding a third for HPKP-RO, which seems
reasonable to implement.

Trevor

---

From: Ryan Sleevi <[email-masked]>
Date: Tue, 26 Aug 2014 17:53:27 -0700

This seems like it would meaningfully necessitate changes to the security
and privacy considerations. In these cases, in specs and in code, my
feeling is that less is more desirable, and I agree with Joe's remarks
about whether or not PKP-RO meets the goals.

Chairs, can you provide feedback on how to progress  with such significant
changes based on post-WGLC feedback: either the removal of or the changing
definition of PKP-RO.

---

From: Yoav Nir <[email-masked]>
Date: Wed, 27 Aug 2014 13:46:56 +0300

On Aug 27, 2014, at 3:53 AM, Ryan Sleevi <[email-masked]> wrote:

> This seems like it would meaningfully necessitate changes to the security and privacy considerations. In these cases, in specs and in code, my feeling is that less is more desirable, and I agree with Joe's remarks about whether or not PKP-RO meets the goals.
> 
> Chairs, can you provide feedback on how to progress  with such significant changes based on post-WGLC feedback: either the removal of or the changing definition of PKP-RO.
> 
I thought I did, but to re-iterate: We are past WGLC. More importantly, we are past IETF LC, and in the middle of IESG evaluation.

At this stage, we can make editorial changes, but we cannot make significant changes on our own. We can withdraw the request to publish, and take it back to the working group, but I think that would be inadvisable.

I think we should proceed, making only editorial changes, and changes resulting from discussion with IESG members.

Yoav
(with chair hat on)

---

From: Tom Ritter <[email-masked]>
Date: Wed, 27 Aug 2014 07:26:15 -0500

On 27 August 2014 05:46, Yoav Nir <[email-masked]> wrote:
> At this stage, we can make editorial changes, but we cannot make significant
> changes on our own. We can withdraw the request to publish, and take it back
> to the working group, but I think that would be inadvisable.
>
> I think we should proceed, making only editorial changes, and changes
> resulting from discussion with IESG members.

If adding a note in 4.2 about includeSubdomains and PKP-RO (for
testing) counts as editorial, I think that is worthwhile.
Otherwise/regardless I also don't want to withdraw.

-tom

---

From: "Eric Lawrence" <[email-masked]>
Date: Thu, 28 Aug 2014 09:26:35 -0500

I’ll take one last tilt at this, because I think this spec is quite important and folks aren’t actually very far apart on this. 

To start, I want to reiterate that Draft #20 was the first time I got involved in PKP, so my perspective comes from that draft and not any other conversations, tribal knowledge, meetings, etc, that others in the group may have been a part of. 

Here’s how I *thought* Draft #20 specified things to work:

  1> PKP and PKP-RO are equivalent in every way except that PKP mismatch triggers a Report *and* fails the connection, while PKP-RO mismatch only triggers a Report. That’s why PKP-RO is named “Public Key Pins Report Only” and not “Sorta Like Public Key Pins But Does Not Break Connections And Does Not Persist (SLPKPBDNBCADNP)”

  2> Site administrators should use PKP-RO to prototype a policy to be later deployed PKP. They use PKP-RO first to generate confidence that they will not be self-inflicting any broad denial-of-service when enabling PKP.

  3> When PKP and PKP-RO headers are initially encountered (pins not previously stored), a failure to match the specified policy triggers a Report. The mismatched policy is NOT stored, which blocks the DOS bomb attack Ryan mentions below.

  4> PKP and PKP-RO only exist as different headers because it allows a site to have one policy in force and also prototype proposed policy changes.

This design made perfect sense to me, and my feedback on the draft was primarily intended to clarify the language around this design.

Instead, it appears that PKP-RO works dramatically differently than PKP, in ways that I believe are entirely non-obvious to implementers who only read the draft. While I believe it would be possible to editorially change the language to make PKP-RO’s different behavior, to me, that approach only seems to be codifying a more confusing, less useful design, and would require more work on the part of the authors.

I don’t believe there are any privacy or security implications in allowing PKP-RO to behave like PKP except that it’s “Report Only.” Any privacy or security implications in PKP-RO are shared by PKP. 

-Eric Lawrence 

From: Ryan Sleevi 
Sent: Wednesday, August 27, 2014 8:14 PM
To: Tom Ritter 
Cc: Yoav Nir ; draft-ietf-websec-key-pinning ; Eric Lawrence ; mailto:[email-masked] 
Subject: Re: [websec] draft-ietf-websec-key-pinning

Right, so, I do agree with Joe that I do think we've reached conclusions on the suitability for security and the suitability for testing, and I do want to see what can be done to editorially resolve this. 

Without having fully drafted the text, it seems like one possible solution is to describe HOW a site operator might use this to test deployment of pins, knowing that it may not be a perfect solution for all use cases, it would at least help to clarify both the strengths and limitations.

The example I'm thinking of is as follows:

-- Begin
Site operator deploys PKP-RO on their domain
- In order for this to be useful, the assumption here (and which I think had always been implicit, but it may help to call this out, in several places if necessary) is that PKP-RO does not require that the current connection MATCH the pins in order to send a report (otherwise, you'd never get a negative report, because you'd never evaluate PKP-RO in the negative case)
- They gather data from their users, which may include information about possible certificate chain paths that they were not aware of (assuming a publicly trusted CA with UAs with different trust stores, etc)

After gathering data, they deploy PKP, which makes the RO now a hard fail.
They may still use report-uri with their PKP header, along with shorter timeframes, to ensure no critical errors were missed

Now it comes time to gather in the sub-domains, the site operator works through their (known) subdomains with PKP-RO, doing the same steps as they did for the parent domain, setting PKP on these subdomains.

Believing they have gathered all their subdomains into a unified policy, they then work to set PKP on the 'main' domain with includeSubDomains + reportURI set.
They likely do this in small bursts, temporarily decreasing the max-age of the 'main' domain when setting the includeSubDomains (e.g. perhaps 1 day or even 4-12h), examining reportURI for failures, and then turning on their sans-includeSubDomains policy with the longer max-age

Finally, believing to have gathered sufficient data, they turn on includeSubDomains (with report-URI), and have the whole system protected

-- Fin

As Eric noted in HSTS, this may include having the subdomains either set their own policies (for redundancy/safety, but at the tradeoff of potentially conflicting pin policies, as already noted), or having the subdomains source a resource from the parent domain (which causes them to fetch/detect the includeSubDomains from the parent domain)

The assumption here, and I realize is perhaps unfair for some use cases, is that you know the sub-domains you wish to protect. Hopefully a competant domain administrator was responsible and this information can be discovered. The short-lived PKP+includeSubDomains+reportUri provides an added means of testing, but is admittedly 'more' heavy-handed than simply PKP-RO with persistence.

PKP-RO with persistence is, I think, dangerous. In the naieve form, it allows a MITM to setup a DOS bomb against a legitimate server, by setting a PKP-RO to report errors. Unlike a PKP policy (which is detectable by the user, by virtue of fail-closed), whose fail-closed nature may indicate to the user that somebody set them up a bomb, a PKP-RO is conceptually and practically silent to the user, which may cause the user to flood the legitimate server with reports once they're away from the MITM. Now, we could tweak how persistence works for that case, but I think as we do, we get further and further into a complexity that may require significant edits/reviews. We can do that, but I gather the spirit, both of the editors and, from the responses, those involved in this discussion, that it's not necessarily something felt too strongly about.

The question is, does the above scenario sound reasonable enough to include, perhaps in an "operational advice" or some form of appendix, that provides guidance on how the existing primitives can be used, but also highlights the limitations of the current primitives so as not to cause confusion?

On Wed, Aug 27, 2014 at 5:26 AM, Tom Ritter <[email-masked]> wrote:

  -tom

---

From: Ryan Sleevi <[email-masked]>
Date: Wed, 27 Aug 2014 18:14:11 -0700

Right, so, I do agree with Joe that I do think we've reached conclusions on
the suitability for security and the suitability for testing, and I do want
to see what can be done to editorially resolve this.

Without having fully drafted the text, it seems like one possible solution
is to describe HOW a site operator might use this to test deployment of
pins, knowing that it may not be a perfect solution for all use cases, it
would at least help to clarify both the strengths and limitations.

-- Begin
Site operator deploys PKP-RO on their domain
- In order for this to be useful, the assumption here (and which I think
had always been implicit, but it may help to call this out, in several
places if necessary) is that PKP-RO does not require that the current
connection MATCH the pins in order to send a report (otherwise, you'd never
get a negative report, because you'd never evaluate PKP-RO in the negative
case)
- They gather data from their users, which may include information about
possible certificate chain paths that they were not aware of (assuming a
publicly trusted CA with UAs with different trust stores, etc)

After gathering data, they deploy PKP, which makes the RO now a hard fail.
They may still use report-uri with their PKP header, along with shorter
timeframes, to ensure no critical errors were missed

Now it comes time to gather in the sub-domains, the site operator works
through their (known) subdomains with PKP-RO, doing the same steps as they
did for the parent domain, setting PKP on these subdomains.

Believing they have gathered all their subdomains into a unified policy,
they then work to set PKP on the 'main' domain with includeSubDomains +
reportURI set.
They likely do this in small bursts, temporarily decreasing the max-age of
the 'main' domain when setting the includeSubDomains (e.g. perhaps 1 day or
even 4-12h), examining reportURI for failures, and then turning on their
sans-includeSubDomains policy with the longer max-age

Finally, believing to have gathered sufficient data, they turn on
includeSubDomains (with report-URI), and have the whole system protected

-- Fin

As Eric noted in HSTS, this may include having the subdomains either set
their own policies (for redundancy/safety, but at the tradeoff of
potentially conflicting pin policies, as already noted), or having the
subdomains source a resource from the parent domain (which causes them to
fetch/detect the includeSubDomains from the parent domain)

The assumption here, and I realize is perhaps unfair for some use cases, is
that you know the sub-domains you wish to protect. Hopefully a competant
domain administrator was responsible and this information can be
discovered. The short-lived PKP+includeSubDomains+reportUri provides an
added means of testing, but is admittedly 'more' heavy-handed than simply
PKP-RO with persistence.

PKP-RO with persistence is, I think, dangerous. In the naieve form, it
allows a MITM to setup a DOS bomb against a legitimate server, by setting a
PKP-RO to report errors. Unlike a PKP policy (which is detectable by the
user, by virtue of fail-closed), whose fail-closed nature may indicate to
the user that somebody set them up a bomb, a PKP-RO is conceptually and
practically silent to the user, which may cause the user to flood the
legitimate server with reports once they're away from the MITM. Now, we
could tweak how persistence works for that case, but I think as we do, we
get further and further into a complexity that may require significant
edits/reviews. We can do that, but I gather the spirit, both of the editors
and, from the responses, those involved in this discussion, that it's not
necessarily something felt too strongly about.

The question is, does the above scenario sound reasonable enough to
include, perhaps in an "operational advice" or some form of appendix, that
provides guidance on how the existing primitives can be used, but also
highlights the limitations of the current primitives so as not to cause
confusion?

---

From: Yoav Nir <[email-masked]>
Date: Thu, 28 Aug 2014 17:59:07 +0300

Hi Eric

Part of the issue is that PKP (and PKP-RO) follow the lead of other headers such as CSP that also have report-only alternatives, but PKP is inherently different.

CSP has directives that relate to the content delivered, so if CSP has a directive that says the resource cannot be displayed behind a transparent floating frame, the content will not be displayed. If it’s CSP-RO instead of CSP, the content is displayed, but a report is also sent. That makes sense, and if you see that the CSP-RO header causes reports, you can adjust it. Once you move to CSP, you’re fine as long as the content does not change, and even if it does change, you can test it first with a test server.

For PKP it’s different. The thing that changes is the certificate presented to the client. You can’t test the new certificate on a side server, at least not in a way that will fill you with confidence. And because of the way certificates are used, there is no such thing as a static structure to the site. You have to change the certificate (and usually the key) every year, so testing with PKP-RO may be fine before first deploying PKP, but it doesn’t help you where it’s dangerous - when it’s time to change certificates.

This leads some people around here to conclude that PKP-RO is not useful.

Yoav

---

From: Joseph Bonneau <[email-masked]>
Date: Thu, 28 Aug 2014 12:02:36 -0400

On Wed, Aug 27, 2014 at 9:14 PM, Ryan Sleevi <[email-masked]> wrote:

> Right, so, I do agree with Joe that I do think we've reached conclusions
> on the suitability for security and the suitability for testing, and I do
> want to see what can be done to editorially resolve this.
>

With Ryan's proposed testing plan I fear many site operators can't easily
enumerate all subdomains and even if they try this is a particularly
difficult test mode because there's no feedback if you forget a subdomain.
This allows you to make sure it works on all subdomains you know about-but
what about the ones you don't?

Beyond that though, we're probably kidding ourselves if we think most site
operators will actually sit down and read an RFC front-to-back. They won't.
Some evidence from a project a student of mine is working on, finding a
large number of sites (~30%) are not properly setting HSTS headers per the
spec (which is comparably simple to achieve):
http://jbonneau.com/doc/KB14-hsts_pinning_survey_working_draft.pdf. Clearly
a lot of people didn't read the RFC and that's not even counting minor
errors like incorrect capitalization.

I think we should be realistic that this RFC will primarily be read by
developers building support into user agents and not site operators. Site
operators will, at best, read somebody's 500-word how-to blog post. Many
will probably just copy what some other site is doing and modify it until
it appears to work.

In a perfect world, we'd do "developer testing" on an draft like this where
we give a random site-operator-off-the-street the RFC and ask if they can
comprehend it and add support to their site. This is similar to how any new
software tool should have user testing. Short of that, the evidence we have
is that multiple people (including myself) who are security enthusiasts and
have been following this draft for years had a broken mental model of how
PKP-RO works. I think this design is violating the Principal of Least
Astonishment and we're asking for trouble no matter how much explanatory
text gets added to the RFC.

---

From: "Eric Lawrence" <[email-masked]>
Date: Thu, 28 Aug 2014 11:13:23 -0500

> testing with PKP-RO may 
> be fine before first deploying PKP, but it doesn’t help you where it’s dangerous - 
> when it’s time to change certificates.

In addition to raising confidence before you first deploy, PKP-RO helps when you wish to retire a pinned SPKI. 

For instance:

  0. Acme Corp has a secure website; they’re using PKP with includeSubdomains.
  1. Acme Corp currently buys its certs from Verisign and uses PKP to pin the Verisign intermediate SPKI. 
  2. Next year, Acme Corp decides that they want to buy GoDaddy certs instead. They update their PKP header to add the GoDaddy intermediate’s SPKI to the list.
  3. Because Acme Corp is a huge enterprise, they don’t know if some business unit (e.g. SpecialProjects.Acme.com) didn’t get the memo about the move to GoDaddy and may still be using a Verisign cert. So, in addition to the updated PKP header, they ALSO send a PKP-RO header that specifies *only* the GoDaddy SPKI and watch for any reporting failures.
  4. After an appropriate period, Acme concludes that they are safe in replacing the PKP set of SPKIs with the set they prototyped in PKP-RO. They do so and remove the PKP-RO header.

-Eric

*An aside vis-à-vis the plausibility of #3, a site not knowing about its own subdomains: I recently spoke to a site (“example.com”) that wasn’t using includeSubdomains on their HSTS header. I asked why not, since all of the company’s public websites were HTTPS. It turns out that they can’t use includeSubdomains because their private Intranet uses internally-mapped domains subordinate to their public domain name suffix. So, while “hr.example.com” isn’t publicly reachable, browsers don’t know or care, and HSTS+includeSubdomains will fail any insecure connection for the employees inside the company. 

A similar challenge will face any such companies when they try to use PKP with includeSubdomains.

From: Yoav Nir 
Sent: Thursday, August 28, 2014 9:59 AM
To: Eric Lawrence 
Cc: Ryan Sleevi ; Tom Ritter ; draft-ietf-websec-key-pinning ; [email-masked] 
Subject: Re: [websec] draft-ietf-websec-key-pinning

Hi Eric 

Yoav

  -Eric Lawrence