pshtt icon indicating copy to clipboard operation
pshtt copied to clipboard

Update HSTS check

Open mcdonnnj opened this issue 4 years ago • 0 comments

This PR would update the hsts_check() function's method of processing the HSTS header. Currently we do not closely conform to RFCs 7230 and 6797 with regard to valid header formats. This is specifically related to domains returning multiple Strict-Transport-Security headers. This has allowed some domains to pass checks they might not otherwise because they are responding with an invalid HSTS header format.

This change would result in domains that previously passed some checks now failing them. However, if it is a result of them failing to conform to the RFC specification then I believe that is appropriate. This is still a lenient change because we use the first header instead of immediately failing if multiple headers are seen.

This is in part a result of the requests library assuming that a response with multiple header fields with the same field name conform to 7230-3.2.2. It concatenates them with a comma so in a server incorrectly outputting multiple Strict-Transport-Security headers it combines them following the guidelines of 7230-3.2.2.

Example HTTP response (just Strict-Transport-Security fields from curl output):

< Strict-Transport-Security: max-age=31536000
< Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
< Strict-Transport-Security:  max-age=31536000

becomes "max-age=31536000, max-age=31536000; includeSubDomains; preload, max-age=31536000"

The same domain run against the Qualys SSL Labs SSL Server Test:

Server sent invalid HSTS policy. See below for further information. Strict Transport Security (HSTS) | Invalid Server provided more than one HSTS header

Per RFC 7230 section 3.2.2:

A sender MUST NOT generate multiple header fields with the same field name in a message unless either the entire field value for that header field is defined as a comma-separated list [i.e., #(values)] or the header field is a well-known exception (as noted below).

Per RFC 6797 section 6.1:

Strict-Transport-Security = "Strict-Transport-Security" ":"
                            [ directive ]  *( ";" [ directive ] )

directive                 = directive-name [ "=" directive-value ]
directive-name            = token
directive-value           = token | quoted-string

where:
     token          = <token, defined in [RFC2616], Section 2.2>
     quoted-string  = <quoted-string, defined in [RFC2616], Section 2.2>

mcdonnnj avatar Aug 13 '19 08:08 mcdonnnj