Subject: [websec] Why are multiple PKP header fields allowed?

From: Ivan Ristić <[email-masked]>
Date: Wed, 23 Apr 2014 08:15:32 +0100

According to the HPKP spec:

"If a UA receives more than one PKP header field in an HTTP
 response message over secure transport, then the UA MUST process
 only the first such header field."

What's the rationale for this decision? (The same logic is applied in
HSTS, so perhaps the behaviour is copied from there?)

HPKP and HSTS are both vulnerable to response header injection attacks.
Assuming an application that correctly sets the security headers, a
successful attack produces a response with multiple security headers and
the attacker has a good chance to place his headers first.

Have you considered instructing UAs to ignore all headers when there are
two or more?

-- 
Ivan

---

From: Yoav Nir <[email-masked]>
Date: Wed, 23 Apr 2014 10:42:54 +0300

Hi, Ivan

Both HPKP and HSTS are only considered when they are received over a TLS-protected connection. TLS should protect against response header injection, no?

Yoav

On Apr 23, 2014, at 10:15 AM, Ivan Ristić <[email-masked]> wrote:

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

---

From: Ivan Ristić <[email-masked]>
Date: Wed, 23 Apr 2014 09:20:43 +0100

On 23/04/2014 08:42, Yoav Nir wrote:
> Hi, Ivan
> 
> Both HPKP and HSTS are only considered when they are received over a
> TLS-protected connection. TLS should protect against response header
> injection, no?

No, the attack vector here is not transport, but a vulnerable web
application. The vulnerability exists whenever an attacker is able to
freely inject CRLF sequences into a HTTP response.

For example:

https://www.example.com/redirect.jsp?target=https://www.example.com/%0d%0aPublic-Key-Pins:%20max-age=0

If the target parameter is used without checking when constructing the
Location header in the redirection, the result could be something like:

HTTP/1.1 302 Moved Temporarily
Some-Header: ...
Location: https://www.example.com/
Public-Key-Pins: max-age=0
Other-Headers: ...
Public-Key-Pins: max-age=3000;
       pin-sha256="d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=";
       pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=";

To be fair, an attacker who can do this can also inject a double-CRLF
and terminate the HTTP response early, leaving only his PKP response. In
other words, this attack vector cannot be fully avoided. Still, being
less tolerant to malformed HTTP headers is generally a good thing. I was
wondering if there was a reason for doing otherwise.

In any case, I think it's worth mentioning this attack in the RFC, so
that the risk is understood. Another attack vector that could be
described is against the user clock.

>> What's the rationale for this decision? (The same logic is applied
>> in HSTS, so perhaps the behaviour is copied from there?)
>> 
>> HPKP and HSTS are both vulnerable to response header injection
>> attacks. Assuming an application that correctly sets the security
>> headers, a successful attack produces a response with multiple
>> security headers and the attacker has a good chance to place his
>> headers first.
>> 
>> Have you considered instructing UAs to ignore all headers when
>> there are two or more?
>> 
>> -- Ivan
>> 
>> _______________________________________________ websec mailing
>> list [email-masked] https://www.ietf.org/mailman/listinfo/websec
> 

-- 
Ivan

---

From: "Ryan Sleevi" <[email-masked]>
Date: Wed, 23 Apr 2014 11:28:03 -0700

>  HSTS, so perhaps the behaviour is copied from there?)

Correct.

>  Have you considered instructing UAs to ignore all headers when there are

The choice here was made explicitly *because* of header injection.

The disagreement here is whether or not an attacker has a greater chance
of getting their headers to appear first or last. The belief - of both
HPKP and HSTS - is that it is harder, in most web servers (and, for that
matter, scripting languages), for an attacker to get their headers to
appear first. Instead, a webserver is more likely to send any
system-wide/host-wide headers first, and then append any (scripting,
user-specific) headers.

---

From: Ivan Ristic <[email-masked]>
Date: Thu, 24 Apr 2014 19:43:51 +0100

> system-wide/host-wide headers first, and then append any (scripting,

I don't think that's the disagreement. My first point is that this
attack vector should be discussed in the RFC, and the decision to use
the first PKP header explained.

The second (and less important) point is that rejecting HTTP responses
with multiple PKP headers might be marginally better than the current
behaviour. No matter where the header is injected (first or second),
it's never wrong reject both. It certainly feels safer to me; after all
we know that that response is contaminated.

Further, there'll be a class of attackers who can inject at the first
position, but can't inject a double CRLF to perform full HTTP response
splitting. For example, the length of the parameter might be limited.

-- 
Ivan