Search code examples
httpsslheaderhttp-headerstls1.2

On HSTS HTTP Header Syntax


From the specification [here][1]:

The ABNF (Augmented Backus-Naur Form) syntax for the STS header field is given below. It is based on the Generic Grammar defined in Section 2 of [RFC2616] (which includes a notion of "implied linear whitespace", also known as "implied *LWS").

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

And [here][2],

implied *LWS The grammar described by this specification is word-based. Except where noted otherwise, linear white space (LWS) can be included between any two adjacent words (token or quoted-string), and between adjacent words and separators, without changing the interpretation of a field. At least one delimiter (LWS and/or

  separators) MUST exist between any two tokens (for the definition
  of "token" below), since they would otherwise be interpreted as a
  single token.

Given the specs. example:

Strict-Transport-Security: max-age="31536000"

Q1: Does this mean, it is allowed to add only one space between each two words? i.e. this header is correct (note the space before and after the equal sign)?

 Strict-Transport-Security : max-age = "31536000"

Q2: Are quotations on the number "31536000" required or optional?

Q3: Does the specs. explanation include multiple spaces or strictly only single space is allowed? e.g. what about:

 Strict-Transport-Security : max-age        = "31536000"

Q4: Is adding single or double quotes around the key or values acceptable? For example, is this acceptable:

 "Strict-Transport-Security" : "max-age"="31536000"

Please clarify. Interpreting specs can be tricky. But with your help I hope I can get accurate understanding. [1]: https://www.rfc-editor.org/rfc/rfc6797#section-6.1 [2]: https://www.rfc-editor.org/rfc/rfc2616#section-2


Solution

  • Strict-Transport-Security : max-age = "31536000"
    

    This header is in my opinion not correct since it has a space between the field-name and the :. Section 4.2 of RFC 2616 says "Each header field consists of a name followed by a colon (":") and the field value.", i.e. nothing about LWS after the name. But it is actually not fully clear if this is just does not mention LWS since it is implied or if it explicitly does not mention LWS since it is not allowed here. In fact, implementations vary and this can be used to cause different interpretation in different systems.

    As for the LWS between parameter name and parameter value I think this fits the definition of implied LWS, i.e. it is valid. But implied LWS does not mean that you can add only a single space, it says in 2.1 "... At least one delimiter (LWS and/or separators) MUST exist between any two tokens..." which means that there can actually be multiple spaces or none (just a separator).

    Q2: Are quotations on the number "31536000" required or optional?

    RFC 6797 has explicit examples in section 6.2 which should make this clear:

    Strict-Transport-Security: max-age=15768000 ; includeSubDomains
    

    ... The max-age directive value can optionally be quoted:

    Strict-Transport-Security: max-age="31536000"
    

     

    Q3: Does the specs. explanation include multiple spaces or strictly only single space is allowed? e.g. what about:

    Again, it does not limit the amount of spaces for implied LWS.

     "Strict-Transport-Security" : "max-age"="31536000"
    

    The field name and the parameter name are defined as token. Tokens should not be quoted.

    Please clarify. Interpreting specs can be tricky. But with your help I hope I can get accurate understanding.

    You are damn right. It is not only tricky but often confusing, not clear enough and sometimes specs even contradict each other. Treating critical data as loose text with optional LWS on various spaces, optional or required quoting, ... gives a variety of ways for implementation and parsing and often unexpected ones.

    I've used such vague and ambiguous definitions successfully to bypass various security systems since these handle the fields slightly different than browsers and thus interpret the content differently. In my opinion these kind of text-based, complex, extensible and (unnecessary) flexible standards are simply broken by design from the standpoint of security and also make implementations and testing unnecessary complex.