使用具有相同值的重复响应 header 可以吗?
Is it fine to use duplicate response header with same value?
我发现一个响应,其中重复的 header 被具有相同值的应用程序使用。谁能告诉我,这是一个好的编程实践,还是用于安全角度或其他任何方面?
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
此应用程序正在使用具有相同值的重复 X-Content-Type-Options header、Strict-Transport-Security、X-Frame-Options header。
这是一个 programming/configuration 错误。 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).
所以像这样使用多个 header:
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
Strict-Transport-Security: max-age=31536000; includeSubDomains
是未定义的行为。同一节说:
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.
所以上述 header 的一种可能解释是:
Strict-Transport-Security: max-age=31536000 ; includeSubDomains, max-age=31536000; includeSubDomains
根据 https://www.rfc-editor.org/rfc/rfc6797#section-6.1,这不是有效语法,可能会被拒绝(因此,HSTS 政策不适用)。
请注意,并非所有实施都可能遵循此指定行为。例如,Python http 库只是 returns 一个 header 的列表,在上面的例子中它可能看起来像:
[
# ...
('Strict-Transport-Security', 'max-age=31536000 ; includeSubDomains'),
('Strict-Transport-Security', 'max-age=31536000; includeSubDomains')
# ...
]
根据实现的不同,至少可以实现以下三种行为:
- 合并 headers,用逗号分隔(由 RFC 7230 指定)。
- 使用第一个 header 匹配项。
- 使用最后一个 header 匹配项。
验证和使用之间的解释不匹配可能会导致攻击,尽管这对于 HSTS 可能不是很严重 header。
我发现一个响应,其中重复的 header 被具有相同值的应用程序使用。谁能告诉我,这是一个好的编程实践,还是用于安全角度或其他任何方面?
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
此应用程序正在使用具有相同值的重复 X-Content-Type-Options header、Strict-Transport-Security、X-Frame-Options header。
这是一个 programming/configuration 错误。 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).
所以像这样使用多个 header:
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
Strict-Transport-Security: max-age=31536000; includeSubDomains
是未定义的行为。同一节说:
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.
所以上述 header 的一种可能解释是:
Strict-Transport-Security: max-age=31536000 ; includeSubDomains, max-age=31536000; includeSubDomains
根据 https://www.rfc-editor.org/rfc/rfc6797#section-6.1,这不是有效语法,可能会被拒绝(因此,HSTS 政策不适用)。
请注意,并非所有实施都可能遵循此指定行为。例如,Python http 库只是 returns 一个 header 的列表,在上面的例子中它可能看起来像:
[
# ...
('Strict-Transport-Security', 'max-age=31536000 ; includeSubDomains'),
('Strict-Transport-Security', 'max-age=31536000; includeSubDomains')
# ...
]
根据实现的不同,至少可以实现以下三种行为:
- 合并 headers,用逗号分隔(由 RFC 7230 指定)。
- 使用第一个 header 匹配项。
- 使用最后一个 header 匹配项。
验证和使用之间的解释不匹配可能会导致攻击,尽管这对于 HSTS 可能不是很严重 header。