Subject: Re: [websec] #60: Well Known URIs vs Response Headers

From: Gervase Markham <[email-masked]>
Date: Thu, 01 Aug 2013 09:28:37 +0100

On 31/07/13 21:33, Yoav Nir wrote:
> This issue turned out to be more contentious that I had expected.
> We've had two people in support of the change, in addition to one
> response that seems to indicate support for such a change, and Mark's
> remarks at the meeting, which were also kind-of, sort-of in support
> of such a change.
> 
> This does not look to me like consensus to keep the status quo. Do
> others feel differently?  If so, please speak up soon.

The Mozilla team working on CSP went back and forth on a related
question - that of whether the header should contain the policy, or a
URI to a file containing the policy, or have the option of doing both.

We eventually decided that having it only in the header was OK, although
I cannot now find a document which lays out the reasoning. However, I
would be happy to ask someone.

Obviously, a well-known URI has the advantage of not having to be sent
for every request. But it has the disadvantage that (unless you make the
file format syntax complex) there's only one policy per domain, the
browser has to cache the information, and it's an extra HTTP request on
every connection to a new site (because you can't know the file is there
until you look for it). I suspect that has performance implications.

Gerv

---

From: Trevor Perrin <[email-masked]>
Date: Thu, 1 Aug 2013 01:50:05 -0700

> would be happy to ask someone.

Hi Gerv,

CSP is quite different from HPKP, isn't it?

CSP needs to be delivered with the page it's being applied to.  It
can't be fetched asynchronously, but that's fine for HPKP.  Also, CSP
applies to particular resources, whereas TLS-layer checks are applied
to the hostname.

So I don't think CSP's reasoning for header vs URI is going to
translate that well.  Also, to Yoav and Tobias's point - I don't think
it would ever make sense to combine CSP and HPKP in a single
.well-known URI.

However, I'm not sure about naming the file so specifically as
"PublicKeyPinning", as Yoav proposes.  That implies that it can't be
extended to contain related data, they would need their own URIs.

Joe Bonneau has used the term "transport security policy" to refer to
policies like pinning assertions for HSTS, HPKP, TACK, opt-in to CT or
DNSSEC/DANE, etc.

It seems reasonable that we might want more "transport security
policies" for these things in the future.  If that happens, I don't
see why we'd want the browser to make separate requests for each one.

So I'd prefer a more generic name like
"transport_security_policy.json", and explicitly allowing such
extensibility.

Trevor

---

From: Yoav Nir <[email-masked]>
Date: Thu, 1 Aug 2013 08:59:23 +0000

> would be happy to ask someone.

Thanks for the information. It is interesting that this was considered, but maybe some of the disadvantages you cite below apply to CSP more than to HPKP.

> until you look for it). I suspect that has performance implications.

One policy per domain is find for HPKP (also for HSTS), but CSP has some directive that may be page-specific (font-src ?)

Thanks again.

Yoav

---

From: Tobias Gondrom <[email-masked]>
Date: Thu, 01 Aug 2013 11:13:17 +0200

> One policy per domain is find for HPKP (also for HSTS), but CSP has some directive that may be page-specific (font-src ?)
<no hats>
Actually CSP is per se page specific - which is reflected in many parts
of the policy.
So one policy URL for every resource on a server would not work IMHO.

Best regards, Tobias

>
> Thanks again.
>
> Yoav
>
> _______________________________________________
> websec mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/websec

---

From: Gervase Markham <[email-masked]>
Date: Thu, 01 Aug 2013 15:21:24 +0100

>> others feel differently?  If so, please speak up soon.

Further input from one of our network library engineers:

"From a networking performance point of view we would much rather have
smallish redundant header data (anything smaller than the order of
magnitude of uris and cookies is effectively smallish) than to be
initiating additional out of band transactions. I also think there are
timing issues here - the argument is that the oob fetch is non-blocking
because it only applies to the next connection - but "next connection"
and "async oob" are not necessarily strictly ordered - especially when
we're really busy or the network is performing poorly.

There are all sorts of pieces of server information that would be
interesting in a well-known uri (including many non security oriented
ones) - lets not go building a fetch-and-persistently-cache model
separately for each one of them. An integrated effort would be much more
interesting."

Gerv

---

From: Chris Palmer <[email-masked]>
Date: Thu, 1 Aug 2013 09:24:35 -0700

I wish people had expressed their strong desire for a W-K URI earlier.
Previously, there was an apparently weak desire, but suddenly now that
we're in last call it's a big issue. Recall that pinning was intended
to be a quick and easy extension of HSTS before Certificate
Transparency landed...

Here is an attempt to summarize what's going on.

* """For example, if the administrators of https://example.net/ allow
the user foo to publish arbitrary content below
https://example.net/~foo/, and that user emits an HPKP header, they
could potentially override the backup pins offered by the site
administrator, ..."""

No, the same-origin policy is defined such that paths are not part of
the origin. Thus, code in https://example.net/~foo/ already has
complete control over the entire (https, example.net, 443) origin.

* Regarding generic security policy URI: If we can't achieve consensus
in this WG, why would adding dependencies on more WGs and W3C help?
Obviously, it would not. Thus, we should stick to defining only
pinning policy in this draft. I don't expect that we will ever have a
generic security policy W-K URI, so that cannot be a reason to support
moving HPKP to a W-K URI. It does make more sense to try to make it
generic to transport security, but even then, it's optional and Jeff
Hodges might be tired and might not want to specify JSON syntax for
HSTS... Jeff? And it doesn't make much sense to put TACK policy in the
resource, does it? TACK is all at the TLS layer.

* "possibly dozens of hashes": As we can see from Chrome's
net/http/transport_security_state_static.json, Twitter does indeed
trust a huge number of signers in its static key pins. I hope that
Twitter is an outlier in this, and that sites don't start needing to
trust so many signers. (Google uses fewer pins, for example.) But,
maybe not, and maybe header bloat will become a concern. (Even so,
wake me up when response body bloat is no longer a concern...) But we
can resolve that problem with trust anchor names in place of SPKIs
just as easily as with a W-K URI.

* We could also relax the requirement to send the PKP header on each
response. To be honest I can't recall now why we required it, but it
seems like it resolved some security concern? Maybe it's in the
archives...

* """caching: With a well-known URI, there are probably still caching
issues to stake out; how often should a browser update its security
policy for a given site in the absence of standard HTTP caching
headers from the server? Or is it a MUST that the well-known URI needs
to publish caching headers?"""

We could simply get rid of max-age, and have the policy apply for
however long the resource is defined to be valid (with cache control
headers). I would say that site operators SHOULD set good cache
control headers for *all* their resources.

---

From: Trevor Perrin <[email-masked]>
Date: Thu, 1 Aug 2013 17:51:08 -0700

On Thu, Aug 1, 2013 at 9:24 AM, Chris Palmer <[email-masked]> wrote:
> pinning policy in this draft.

Definitely.

> It does make more sense to try to make it
> HSTS... Jeff?

If we go the .well-known URI route, it might as well be extensible to
"similar things", though I agree we shouldn't spend effort on them
now.

> And it doesn't make much sense to put TACK policy in the

It might make sense, at some point.  TACK is mainly just a key that
can be pinned.

TACK has its own way of asserting pins (setting an "activation flag").
 But if you leave the flag cleared then a tack is just a signing key
and signature.  Other layers could assert pins to the signing key,
perhaps to add features like HPKP's "report-URI" or "strict" or
something.

Not saying that's a great idea, but it's not crazy...

> trust so many signers. (Google uses fewer pins, for example.)

They may be an outlier, but we don't really know.  Sites might want
very safe pins that list several CAs, so they have backup options.
And apparently some CAs have several keys (11 for Verisign?  7 for
GeoTrust?)

> But,

Agreed.

If we had to solve this one way or the other, I'd prefer to do pinning
CA names, because I think it solves a bigger useability problem for
sites.

> seems like it resolved some security concern? Maybe it's in the

I don't recall it being discussed.  I do think this requirement could
be relaxed.

Trevor

---

From: Joseph Bonneau <[email-masked]>
Date: Sat, 3 Aug 2013 17:33:31 -0400

> > pinning policy in this draft.

I agree it wouldn't make sense to bog-down the HPKP spec with HSTS (and
definitely not CSP). I think the question is, for the next HTTPS policy
that sites may want to declare, can we make it as easy to do so as
possible?

CT is the right test case here because IMO it will be very useful to set a
CT-required bit. If refactoring the HPKP spec to a well-known URI enables
CT to push this through in a few months instead of a year, that's a nice
benefit though still not the main motivation for switching to a well-known
URI.

> And apparently some CAs have several keys (11 for Verisign?  7 for

Another way of looking at this is, how can the spec be written to minimally
disincentivize sites from adopting it? If sites want to pin but feel they
can't deploy a pinning  policy with less than Twitter's 19 hashes, and they
have to add that to every response, some percentage may skip it that would
have pinned if they weren't adding almost 1 kB to every response. That's
the case I'm worried about.

> CA names, because I think it solves a bigger useability problem for

Maybe I've missed this, but where is the mapping of CA names to keys
defined?

> > seems like it resolved some security concern? Maybe it's in the

I'd strongly advocate for dropping this requirement, though I don't
remember the argument for it either. As I've said, in my experience
scanning HSTS headers it's rare to see them deployed 100% of the time.

Here's an alternative approach I was thinking about which could fix any
header-bloat concerns without naming CAs or switching to a well-known URI:
add either a "policy-serial-number" directive to the HPKP response header,
or have clients compute a hash of each policy they store (definitely
doesn't need collision resistance and might not even need to be a crypto
hash, not sure if there are attacks if it's just a CRC). If user agents
have a cached policy for a site, they send a request header
"known-hpkp-policy: " request header with the serial number or policy of
the currently known policy.

If the server sees this, it can respond with an abbreviated header of just
"Public-Key-Pins: extend" which tells the user agent to re-up the current
policy. That's it. They can always send a clear message or a new policy if
they want. But in the case where header bloat may be a concern because
you're doing hundreds of requests to a domain quickly, you can do it all in
just a few bits...

This adds moderate complexity to the spec and implementation, but probably
much less than switching to a well-known URI.

---

From: Yoav Nir <[email-masked]>
Date: Mon, 5 Aug 2013 10:37:55 +0000

Hi

Let me try to summarize where we are with this discussion.

There has been some suggestions that all policy headers such as CSP. However, a well-known URI is unique per domain, while CSP can be different for each resource. So only policy elements that are domain-specific rather than resource-specific can be in the proposed well-known URI. That list is rather short: HPKP and HSTS. For now, we can ignore HSTS. If we take the well-known-uri path and someone later wants to move HSTS to the same or a different WK URI, that will be a separate effort.

With that in mind, the advantages of well-known URIs are obvious:

  *   Less bandwidth than repeating the HTTP header on each response.
  *   No need to send this data to clients that don't support HPKP

So the opinions against this that we've heard so far, I will try to summarize. I apologize in advance if I over-simplify or misrepresent your position:

  *   This should not be done as a one-off for HPKP. If it should be done at all, it should be done as part of a unified framework for policies (Jeff Hodges)
  *   "Agree with Jeff" (Chris Palmer, me, a few others)
  *   Current HPKP header is inefficient and inelegant, because there is no limit on number of hashes, and client needs to validate and update pins on every resource. (Trevor Perrin)
  *   HSTS deployment does not have the header on every path and every subdomain. If HPKP is deployed like that, we will have random results. Should use WK URI (Joseph Bonneau)
  *   [changing to WK URI] is a good idea, and if we don't do it now, we'll never do it (Mark Nottingham, Larry Manister)
  *   [changing to WK URI] is a good idea, because HTTP headers are supposed to be about the resource, not the site. (Daniel Kahn Gillmor)
  *   Maybe we should finish HPKP as it is, and later start a generic draft on moving everything to a well-known URI? (Tobias)
  *   We considered this for CSP, and decided against well-known URIs. It's an extra HTTP request. May have performance implications, and it's no big deal to have this in every response, since the size is "smallish". In some network conditions, we might never get to fetch the WK URI, because the "next conneciton" might come first (Gervase Markham, Mozilla)

As chair, I see that there is a majority for making the change, but I did not see the concerns raised by Gervase addressed. It is also troubling that the people who work on a browser (Chris and Gervase) are both against the change, so I think it's too early to declare consensus, until this issue has been more thoroughly discussed.

Yoav

---

From: Trevor Perrin <[email-masked]>
Date: Tue, 6 Aug 2013 01:51:11 -0700

> Let me try to summarize where we are with this discussion.

Good summary.  Here's more complications...

 * It would be good if crawlers and "network notaries" could reliably
query the HPKP for a site.  Sending an HPKP header on every response
accomplishes this.  So does a .well-known URI.  But letting the server
return the header whenever/wherever it feels like does not.

(Joe suggested having servers send the HPKP header only in response to
a request header.  While that may help with header bloat, it doesn't
solve this problem, because (as Joe points out) many sites don't
return HSTS consistently across URIs.  This is probably due to
different backend webservers being configured differently.  These
servers wouldn't consistently respond to a request header either.)

 * I argued that .well-known URI lookup could be async to page-load,
thus wouldn't add page-load latency.  Gerv countered that there may be
"timing issues" - in particular, such an async lookup might not
complete before the "next connection".

I'm not sure what counts as the "next connection", and I'm not sure we
need such a strict ordering requirement.  But one timing issue, I
think, is that async lookup means a separate TLS connection.  And that
means that a network MITM, even without a certificate, could filter
out the .well-known lookups without affecting the rest of the page
load, thus preventing clients from forming pins.  Not sure if there's
a good way to deal with this.

--

I wonder if HPKP should go in both a Response header *and* a well-known URI?

By allowing it in the response header, we can prevent a MITM from
filtering out the HPKP data.  But we don't need to require it on all
responses, because there may be inconsistently configured servers.
And CA pins would still be a good idea to reduce header size (and
improve useability).

Putting HPKP data in a well-known URI gives clients a reliable way to
query for HPKP.

Anyone like this?

Trevor

---

From: Trevor Perrin <[email-masked]>
Date: Tue, 6 Aug 2013 13:02:29 -0700

> I wonder if HPKP should go in both a Response header *and* a well-known URI?

Another alternative is to return HPKP as a TLS ServerHello Extension,
sent when the client requests it (same as TACK or Certificate
Transparency).

Pros:

 * Webcrawlers etc. can reliably retrieve the pinning policy.

 * The data is only presented during TLS handshakes, so clients aren't
being asked to process HPKP and update their local store constantly.

 * Sites commonly terminate TLS at a pool of similar hosts, then
forward connections to various back-end webservers.  So the TLS
terminators are a choke-point where it's easier to publish security
policy consistently, as opposed to trying to keep all back-end
webservers in sync.

 * The pinning data can be used with other protocols (e.g. email).

Cons:

 * Pushing changes into OpenSSL, NSS, and other TLS stacks is
difficult.  However OpenSSL head now supports "serverinfo" extensions
that are PEM-encoded blobs contained in a config file, and returned in
response to client requests.  This is sufficient for CT and TACK, and
could work for HPKP.  NSS could be extended to allow clients to
register "custom extension" handlers.  Were all this to happen, it
would be possible to deploy simple new TLS extensions without OpenSSL,
NSS, or Apache changes.

 * The ServerHello is sent early in the TCP Connection, before the
initcwnd window has widened.  So space is at a premium, since
exceeding the typical 4KB size for ServerHello incurs a RT of latency.
 Thus it would be even more important to reduce HPKP size via named CA
pins.  But I think this is important anyways, for usability.

 * There are some TLS-intolerant firewalls which trigger some (but not
all) browsers to fallback to SSLv3 [1].  SSLv3 doesn't support TLS
extensions.  This causes a range of security problems.  I'm hopeful we
can get more browsers to take a hard line against this and drive these
boxes to be upgraded, so workarounds like "special ciphersuite values"
aren't necessary.  In any case, this problem affects a wide range of
TLS enhancements, so there's general interest in fixing it.

Trevor

[1] http://www.ietf.org/mail-archive/web/tls/current/msg09450.html

---

From: "Ryan Sleevi" <[email-masked]>
Date: Tue, 6 Aug 2013 14:51:41 -0700

>  sent when the client requests it (same as TACK or Certificate

While appealing from a 'spec purity' point, I think the idea of using it
as a ServerHello extension is a concept that's more or less DOA, in that
it still leaves an unfortunate gap of servers that will not be able to do
anything to allow clients to discover this policy.

I think the cons for it definitely outweigh the pros. Even though there is
general interest in fixing the negotiation problem, it'd be a real shame
to lose an extremely valuable security policy by forcing it to go down a
path we know doesn't universally work. Further, I think it vastly
underestimates the work required to get it practically adopted - even if
two widely-used SSL stacks are easily amenable to it, you completely miss
out for platforms such as iOS, Android, OS X, or Windows, short of
platform upgrades, which we know are less than frequent.

Having a well-known URI *without* a Response header is an idea I'd like to
suggest is also DOA, simply because it creates yet-another-throwaway
request for the vast majority of sites (which we can reasonably presume
*won't* be pinned).

IF a well-known URI was adopted, minimally there should also be a Response
header to signal the existence of a well-known URI, so that you aren't
forcing an additional request for a non-existent file on every request
(see the favicon.ico debacle).

As Gerv mentioned, the practicality of the well-known URI is suspect.
While it's "easy" to think of browsers as simply starting one connection,
making a fetch, and then opening additional connections as needed, "up to
2", the reality is far, far divorced from that in just about "Every Modern
Browser".

It's not uncommon for additional connections to be opened based on
previously observed data - whether it be things like "DNS preloading" or
speculative fetches for resources commonly observed as related. The
benefit of the current, header-based approach is that immediately upon
processing the headers of the first request, all other requests can be
evaluated against that policy - before even the remainder of the body
request is retrieved.

In a WK-URI world, the policy cannot be applied until a request for the
additional URL is made (which may require additional connections to be
made or interrupting/aborting these speculative connections).

In an HTTP/2.0 world, where 'everything' is multiplexed over a single
logical connection, I would heartily agree that this is less of a concern.
But in an HTTP/1.0 and HTTP/1.1 world - which will still be here for a
while - it's a very real concern.

For those not familiar with these concerns from the browser/user-agent
perspective, at the risk of promotion I'd suggest checking out my
colleague Ilya Grigorik's (presently available free) book "High
Performance Browser Networking" (
http://chimera.labs.oreilly.com/books/1230000000545 ), in particular the
lessons learned, user metrics gained, and graphs discussed in chapters
9-13.

That's not to say that Well-Known URIs are not extremely tempting, for
some of the reasons already expressed by Joe and Trevor, but I think it
may be missed some of the downsides that are not necessarily present in
the current header-based approach.

In our mind, one of the biggest factors has been "What are the hurdles to
practical deployment?". While there is admittedly complexity from the
header approach, it's our view that it's not greater than the inherent
complexity of effective pinning, as enumerated in the existing
considerations. The complexity of an efficient and reasonable
implementation of well-known URIs, or of a practical deployment of server
extensions, seems to greatly outweigh both, and the benefits are not as
seemingly significant.

Cheers,
Ryan

---

From: Joseph Bonneau <[email-masked]>
Date: Tue, 6 Aug 2013 18:15:06 -0400

> extensions, seems to greatly outweigh both, and the benefits are not as

I am in agreement that a TLS extension seems like far too much to ask of
deploying sites. I'm also appreciating more and more from this thread the
difficulty of a well-known URI and though I think it's a cleaner approach
in the long-term I can see the argument that it's too much to do right now.

I'm fully on-board with headers if we can address two issues that I think
are real impediments to servers deploying HPKP and doing so correctly: (a)
header bloat (600 bytes of for a site requiring 10 pins) (b) inadvertent
HPKP hole-punching when resources are accidentally served without headers
set. Other issues (e.g. discoverability by crawlers) seem secondary.

I think we can address (b) by not interpreting a missing HPKP header as a
max-age=0, and I was hoping we could deal with (a) by clients sending a
hash or policy serial number to avoid repeatedly sending the header. Does
this approach add too much complexity given the level of concern about
header bloat, which doesn't seem huge?

---

From: Yoav Nir <[email-masked]>
Date: Wed, 7 Aug 2013 06:28:22 +0000

[no hats]

> while - it's a very real concern.

Both ideas get better with HTTP/2.0. the WK URI can be always requested with lowest priority, so it doesn't interfere with loading the web page. And header bloat does not matter that much if the header is included only once per TCP connection.

> extensions, seems to greatly outweigh both, and the benefits are not as

+1

Yoav

---

From: Trevor Perrin <[email-masked]>
Date: Wed, 7 Aug 2013 22:25:39 -0700

> platform upgrades, which we know are less than frequent.

I think you're overstating the challenges with TLS Extensions.  In the
short term they're a hassle.  But once we patch the things that need
patching and kill or workaround buggy middleboxes, there are
advantages to having TLS policy in the TLS layer.

I'm fine with HPKP being skeptical and wanting to avoid this.  But the
problems that this idea (and others) were trying to fix still need
resolution.

Joe's email summarizes the main problems:
"""
...two issues that I think are real impediments to servers deploying
HPKP and doing so correctly: (a) header bloat (600 bytes of for a site
requiring 10 pins) (b) inadvertent HPKP hole-punching when resources
are accidentally served without headers set.
"""

I would add: "discoverability by crawlers", which Joe dismisses but is
actually important.  It could be as simple as saying a site SHOULD
always return an HPKP response for the index page (or robots.txt).

Anyways, if we're keeping the HPKP response header, I'd like to
understand how we can modify things and make recommendations to
address these.

Trevor

---

From: Tobias Gondrom <[email-masked]>
Date: Mon, 12 Aug 2013 11:47:57 +0100

On 06/08/13 23:15, Joseph Bonneau wrote:
> I am in agreement that a TLS extension seems like far too much to ask
> of deploying sites. I'm also appreciating more and more from this
> thread the difficulty of a well-known URI and though I think it's a
> cleaner approach in the long-term I can see the argument that it's too
> much to do right now.

<no hats>
agree.
+1 for going with http header and _not_ going with well-known URI at
this point.
Best regards, Tobias

>
> I'm fully on-board with headers if we can address two issues that I
> think are real impediments to servers deploying HPKP and doing so
> correctly: (a) header bloat (600 bytes of for a site requiring 10
> pins) (b) inadvertent HPKP hole-punching when resources are
> accidentally served without headers set. Other issues (e.g.
> discoverability by crawlers) seem secondary.
>
> I think we can address (b) by not interpreting a missing HPKP header
> as a max-age=0, and I was hoping we could deal with (a) by clients
> sending a hash or policy serial number to avoid repeatedly sending the
> header. Does this approach add too much complexity given the level of
> concern about header bloat, which doesn't seem huge?
>
>