Subject: [websec] Question regarding RFC 6797

From: "Ben Andrews (beandrew)" <[email-masked]>
Date: Tue, 13 Nov 2018 23:47:42 +0000

To whom it may concern,

I'm not sure if this is the best way to get this answer, but I'm looking for some clarification as to what is the correct behavior for HSTS when you have a web service on ServerA that is then proxied by ServerB, and both hosts have HSTS enabled. This question was spurred by a customer who open up a case stating that SSLLabs was reporting that their site was reporting our HSTS implementation was invalid because it had more than one HSTS header.

- The customer (and SSLLabs) reasoning comes from Section 7.1 where it states that "If an STS header field is included, the HSTS Host MUST include only one such header field."
https://tools.ietf.org/html/rfc6797#section-7.1
* It's definitely clear that an individual HSTS Host should never add two HSTS headers to the packet.
* What isn't clear to me is what happens when you have two HSTS hosts involved in the connection especially since that same section specifies the following which implies that any HSTS should add an HSTS header if it is responding to a secure HTTP request.
"When replying to an HTTP request that was conveyed over a secure transport, an HSTS Host SHOULD include in its response message an STS header field that MUST satisfy the grammar specified above in Section 6.1".

- However, when you look at both Section 8.1 and Appendix A it's defining specific behaviors for when there are more than one HSTS host/header which insinuates that having more than one header is not actually invalid.
https://tools.ietf.org/html/rfc6797#section-8.1
"If a UA receives more than one STS header field in an HTTP response message over secure transport, then the UA MUST process only the first such header field."
* This statement especially specifically defines the UA's behavior when it receives more than one HSTS header is received. Was this intended simply to avoid errors, or was the behavior described specifically to support situations when you might have more than one HSTS header?
https://tools.ietf.org/html/rfc6797#appendix-A
"An HSTS Host may update UA notions of HSTS Policy via new HSTS header field parameter values.  We chose to have UAs honor the "freshest" information received from a server because there is the chance of a web site sending out an erroneous HSTS Policy, such as a multi-year max-age value, and/or an incorrect includeSubDomains directive."

For example, if you have 2x HSTS Hosts involved in a connection, once source HTTP server (ServerA) on the corporate network and one proxy server (ServerB) for external users to reach the HTTP server.
What would be the correct behavior when ServerB receives an HTTPS packet from ServerA with an existing HSTS header that it is supposed to proxy to the UA:
A) ServerB should include its own HSTS header as the second header since it was the second host to add the HSTS header to the HTTP packet.
B) ServerB should include its own HSTS header as the first header since it's the "freshest" information.
C) ServerB should update the existing HSTS header field with any updated HSTS header parameters/directives.
D) ServerB should include its own HSTS header overwriting ServerA's HSTS header completely
E) ServerB should forward ServerA's HSTS header without modifying the HSTS header in any way.

This question regarding the behavior of HSTS in non-transparent proxy situations also brings up the question of what happens when that proxy server's purpose is to transform an external routable domain to an internal only domain. Assuming an error-free secure transport, would the UA add the domain it used to reach the proxy or if it's aware of the internal domain should it add the internal domain instead since that was the original source of the content? This specifically would be an extremely fringe situation that wouldn't apply to most use cases. Not to mention it likely would fall outside of the scope of this RFC especially after reading the rationale within Section 14.3 and Appendix A, but it definitely would be a situation where more guidance on the expected behavior with HSTS in proxy situations could be useful.

Please let me know if you have any further comments, questions, issues, or concerns.

Kind regards,

Ben Andrews
Cisco TAC
Business Hours: 09:30-17:30 EST M - F
Tel: (919)574-6712
Email: [email-masked]<mailto:[email-masked]>

Direct Manager: Chris Myers
Phone: (919) 574-5319
Email: [email-masked]<mailto:[email-masked]>

CIN contact numbers are:
North America +1 800 553 2447
Asia-Pacific +61 2 8448 7107
Australia +1 800 805 227
Europe +32 2 704 5555
UK +44 800 960 547
Case uploader: https://cway.cisco.com/csc/

---

From: "Mehner, Carl" <[email-masked]>
Date: Mon, 26 Nov 2018 15:51:59 +0000

Hi Ben,

> From: websec [mailto:[email-masked]] On Behalf Of Ben Andrews
> Sent: Tuesday, November 13, 2018 5:48 PM
> 
> - The customer (and SSLLabs) reasoning comes from Section 7.1 where it
> states that “If an STS header field is included, the HSTS Host MUST include
> only one such header field.”
> * It’s definitely clear that an individual HSTS Host should never add two HSTS
> headers to the packet.
> * What isn’t clear to me is what happens when you have two HSTS hosts
> involved in the connection especially since that same section specifies the
> following which implies that any HSTS should add an HSTS header if it is
> responding to a secure HTTP request.

Well the rfc does say "include" not add. So, even if you treat a proxy as a host, the proxy MUST only send one header.

> “When replying to an HTTP request that was conveyed over a secure
> transport, an HSTS Host SHOULD include in its response message an STS
> header field that MUST satisfy the grammar specified above in Section 6.1”.
> 
> - However, when you look at both Section 8.1 and Appendix A it’s defining
> specific behaviors for when there are more than one HSTS host/header
> which insinuates that having more than one header is not actually invalid.

Discussing how to dealing with multiple headers does not mean that sending multiple headers is valid. 

> “If a UA receives more than one STS header field in an HTTP response
> message over secure transport, then the UA MUST process only the first
> such header field.”
> * This statement especially specifically defines the UA’s behavior when it
> receives more than one HSTS header is received.. Was this intended simply
> to avoid errors, or was the behavior described specifically to support
> situations when you might have more than one HSTS header?

To avoid errors and to have consistency across UAs on dealing with misconfigured HSTS Hosts.

> “An HSTS Host may update UA notions of HSTS Policy via new HSTS header
> field parameter values.  We chose to have UAs honor the "freshest"
> information received from a server because there is the chance of a web site
> sending out an erroneous HSTS Policy, such as a multi-year max-age value,
> and/or an incorrect includeSubDomains directive.”

This is across multiple requests, not within the same response (so it doesn't apply to your example below).

> For example, if you have 2x HSTS Hosts involved in a connection, once source
> HTTP server (ServerA) on the corporate network and one proxy server
> (ServerB) for external users to reach the HTTP server.
> What would be the correct behavior when ServerB receives an HTTPS packet
> from ServerA with an existing HSTS header that it is supposed to proxy to the
> UA:
> A) ServerB should include its own HSTS header as the second header since it
> was the second host to add the HSTS header to the HTTP packet.
> B) ServerB should include its own HSTS header as the first header since it’s
> the “freshest” information.
> D) ServerB should include its own HSTS header overwriting ServerA’s HSTS
> header completely
> E) ServerB should forward ServerA’s HSTS header without modifying the
> HSTS header in any way.

Logically, the UA would see both servers as the same "HSTS Host", so I would say, "E". Although, you could do 'C' or 'D' if you chose to or had a need to (e.g internal UAs hitting Server A should get one header, but external UAs hitting proxy Server B should get another).
A) would be wrong, because the HSTS Host would be sending multiple headers
B) doesn't make a lot of sense, because the discussion about 'freshness' is more around fixing an old HSTS directive (e.g. replacing one sent weeks ago for 2 years max-age with one sent now with 2-months max-age.) not events that are happening milliseconds apart.

> This question regarding the behavior of HSTS in non-transparent proxy
> situations also brings up the question of what happens when that proxy
> server’s purpose is to transform an external routable domain to an internal
> only domain. Assuming an error-free secure transport, would the UA add the
> domain it used to reach the proxy or if it’s aware of the internal domain
> should it add the internal domain instead since that was the original source of
> the content? This specifically would be an extremely fringe situation that
> wouldn’t apply to most use cases. Not to mention it likely would fall outside
> of the scope of this RFC especially after reading the rationale within Section
> 14.3 and Appendix A, but it definitely would be a situation where more
> guidance on the expected behavior with HSTS in proxy situations could be
> useful.

The UA would only add the domain it used to reach the HSTS Host. If that domain is the proxy then it would note that one, if the domain is the internal-only one, then it would note the internal domain.

> Email: mailto:[email-masked]<mailto:[email-masked]>
> 
> Email: mailto:[email-masked]<mailto:[email-masked]>
> 
> CIN contact numbers are: