内容安全策略 header 的 *.example.com 是否也匹配 example.com?
Does a *.example.com for a content security policy header also match example.com?
假设我在 mywebsite.com
上设置了这个 header:
Content-Security-Policy: script-src self https://*.example.com
我知道它会允许 https://foo.example.com
和 https://bar.example.com
,但它会单独允许 https://example.com
吗?
正在查看the spec...
Hosts such as example.com (which matches any resource on the host, regardless of scheme) or *.example.com (which matches any resource on the host or any of its subdomains (and any of its subdomains' subdomains, and so on))
...它似乎应该允许纯 https://example.com
。但是,我发现几个不同的网站 (site 1, site 2, site 3, site 4) all 都说 https://example.com
不包括在内。是哪个?
根据 Mozilla's docs,如果您想包含基本域,您应该在 CSP header 中包含 'self'
和 *.example.com
。
*.example.com
对于 CSP header 也不匹配 example.com
.
从(旧的)CSP 规范中引用的文本是错误的 (now fixed)。引用的其他来源是正确的。
但引用的 https://www.w3.org/TR/CSP/#source-expression 部分定义了 CSP 源表达式 是什么,实际上并没有说明相关的规范要求。
实际上规范定义相关要求的 CSP 规范部分是 Does url match expression in origin with redirect count algorithm, in a substep at https://www.w3.org/TR/CSP/#ref-for-grammardef-host-part-2,内容如下:
If the first character of expression’s host-part is an U+002A ASTERISK character (*
):
Let remaining be the result of removing the leading "*
" from expression.
If remaining (including the leading U+002E FULL STOP character (.
)) is not an ASCII case-insensitive match for the rightmost
characters of url
’s host, then return "Does Not Match".
要求的包括前导的U+002E句号(.
)部分表示剩余部分删除星号后包括前导句号,因此 url
的主机最右边的字符也必须以点开头才能匹配。
换句话说,如果您从 *.example.com
开始并完成算法的那部分,您首先会删除 *
以获得 .example.com
作为 remaining 部分,然后将 url
的主机最右边的字符与其匹配,包括前导句号。
所以https://foo.example.com
匹配,因为它的宿主部分最右边的字符匹配.example.com
,但是https://example.com
不匹配,因为它的宿主部分最右边的字符不匹配匹配 .example.com
(因为它缺少包含的句号)。
2017-10-13更新
不久前 I reported the problem with the CSP spec and it’s now been fixed.
relevant part of the CSP spec 现在是:
Hosts such as example.com
(which matches any resource on the host, regardless of scheme) or *.example.com
(which matches any resource on the host’s subdomains (and any of its subdomains' subdomains, and so on))
请注意,“匹配主机或其任何子域上的任何资源” 现在只读为“匹配主机上的任何资源”子域名”.
假设我在 mywebsite.com
上设置了这个 header:
Content-Security-Policy: script-src self https://*.example.com
我知道它会允许 https://foo.example.com
和 https://bar.example.com
,但它会单独允许 https://example.com
吗?
正在查看the spec...
Hosts such as example.com (which matches any resource on the host, regardless of scheme) or *.example.com (which matches any resource on the host or any of its subdomains (and any of its subdomains' subdomains, and so on))
...它似乎应该允许纯 https://example.com
。但是,我发现几个不同的网站 (site 1, site 2, site 3, site 4) all 都说 https://example.com
不包括在内。是哪个?
根据 Mozilla's docs,如果您想包含基本域,您应该在 CSP header 中包含 'self'
和 *.example.com
。
*.example.com
对于 CSP header 也不匹配 example.com
.
从(旧的)CSP 规范中引用的文本是错误的 (now fixed)。引用的其他来源是正确的。
但引用的 https://www.w3.org/TR/CSP/#source-expression 部分定义了 CSP 源表达式 是什么,实际上并没有说明相关的规范要求。
实际上规范定义相关要求的 CSP 规范部分是 Does url match expression in origin with redirect count algorithm, in a substep at https://www.w3.org/TR/CSP/#ref-for-grammardef-host-part-2,内容如下:
If the first character of expression’s host-part is an U+002A ASTERISK character (
*
):Let remaining be the result of removing the leading "
*
" from expression.If remaining (including the leading U+002E FULL STOP character (
.
)) is not an ASCII case-insensitive match for the rightmost characters ofurl
’s host, then return "Does Not Match".
要求的包括前导的U+002E句号(.
)部分表示剩余部分删除星号后包括前导句号,因此 url
的主机最右边的字符也必须以点开头才能匹配。
换句话说,如果您从 *.example.com
开始并完成算法的那部分,您首先会删除 *
以获得 .example.com
作为 remaining 部分,然后将 url
的主机最右边的字符与其匹配,包括前导句号。
所以https://foo.example.com
匹配,因为它的宿主部分最右边的字符匹配.example.com
,但是https://example.com
不匹配,因为它的宿主部分最右边的字符不匹配匹配 .example.com
(因为它缺少包含的句号)。
2017-10-13更新
不久前 I reported the problem with the CSP spec and it’s now been fixed.
relevant part of the CSP spec 现在是:
Hosts such as
example.com
(which matches any resource on the host, regardless of scheme) or*.example.com
(which matches any resource on the host’s subdomains (and any of its subdomains' subdomains, and so on))
请注意,“匹配主机或其任何子域上的任何资源” 现在只读为“匹配主机上的任何资源”子域名”.