3

I found a response where duplicate headers are used by the application with the same value. Could anyone tell me that, Is it a good programming practice or those are used for security perspective or anything else?

  
     HTTP/1.1 200 
     Accept-Ranges: bytes
     Cache-Control: no-cache, must-revalidate, private
     Content-Type: text/html
     Date: Mon, 20 Nov 2017 04:08:51 GMT
     Expires: 0
     Last-Modified: Thu, 16 Nov 2017 14:04:48 GMT
     Pragma: 
     Public-Key-Pins: pin-sha256="5w0XrTCAbsVO7vTngDViNHPutlvB43qYionPbpV2ky0=";  
     max-age=5184000; includeSubDomains;
     Server: Any
     Set-Cookie: ********************* httponly; secure; path=/
     Strict-Transport-Security: max-age=31536000 ; includeSubDomains
     Strict-Transport-Security: max-age=31536000; includeSubDomains
     X-Content-Type-Options: nosniff
     X-Content-Type-Options: nosniff
     X-Frame-Options: SAMEORIGIN
     X-Frame-Options: SAMEORIGIN
     X-XSS-Protection: 1; mode=block
     Content-Length: 559
     Connection: Close

This application is using duplicate X-Content-Type-Options header, Strict-Transport-Security, X-Frame-Options header with same values.

Pawan Dwivedee
  • 115
  • 3
  • 12
  • Cross-posted here: https://security.stackexchange.com/questions/175840/is-it-fine-to-use-duplicate-response-header-with-same-value – Lekensteyn Dec 20 '17 at 09:43

1 Answers1

4

This is a programming/configuration error. RFC 7230 (Section 3.2.2) says:

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).

So using multiple headers like this:

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

is undefined behavior. The same section says:

A recipient MAY combine multiple header fields with the same field name into one "field-name: field-value" pair, without changing the semantics of the message, by appending each subsequent field value to the combined field value in order, separated by a comma.

So one possible interpretation of the above headers is:

Strict-Transport-Security: max-age=31536000 ; includeSubDomains, max-age=31536000; includeSubDomains

which is not valid syntax according to https://www.rfc-editor.org/rfc/rfc6797#section-6.1 and might get rejected (and as a result, the HSTS policy is not applied).

Note that not all implementation might follow to this specified behavior. For example, the Python http library just returns a list of headers, in the above case it might look like:

[
    # ...
    ('Strict-Transport-Security', 'max-age=31536000 ; includeSubDomains'),
    ('Strict-Transport-Security', 'max-age=31536000; includeSubDomains')
    # ...
]

Depending on the implementation, at least these three behaviors are possible:

  • Merging headers, separated by a comma (as specified by RFC 7230).
  • Using the first header match.
  • Using the last header match.

A mismatch of interpretation between validation and use could lead to attacks, although this will probably not very severe for the HSTS header.

Community
  • 1
  • 1
Lekensteyn
  • 64,486
  • 22
  • 159
  • 192
  • 1
    While [RFC 6797](https://tools.ietf.org/html/rfc6797) does not say if the header can be used multiple times [RFC 2616](https://www.ietf.org/rfc/rfc2616.txt) clearly says in section 4.2 that *"Multiple message-header fields with the same field-name MAY be present in a message if and only if the entire field-value for that header field is __defined__ as a comma-separated list"*. The HSTS header is not defined as a comma-separated list and thus is not allowed to occur multiple times. And if it does then there is no rule on how to proceed which also means no rule for folding. – Steffen Ullrich Dec 20 '17 at 10:46
  • Thanks, @SteffenUllrich and Lekensteyn now it's crystal clear. – Pawan Dwivedee Dec 20 '17 at 11:03
  • 1
    @SteffenUllrich RFC 2616 is obsoleted, I referenced RFC 7230 before (which is its successor). Now I have also added the relevant sections to the answer, thanks for the suggestion. Note that your quote is about the sender, the receiver is still free to combine the headers (see the *A recipient MAY combine ...* part in the answer) – Lekensteyn Dec 20 '17 at 13:44
  • @Lekensteyn: you are right in that the standard essentially allows the client to do whatever it likes. Let's just agree that the standard (no matter if RFC2616 or RFC7230) is broken in that it makes it possible (even though it not allows) for the sender to construct a header which has no clearly defined interpretation (not even that the client should discard response) in the client. This way different implementation will treat it differently which is especially bad if one is a firewall which tries to protect the browser behind it and both interpret the data differently. – Steffen Ullrich Dec 20 '17 at 15:44