内容安全策略 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.comhttps://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,内容如下:

  1. If the first character of expression’s host-part is an U+002A ASTERISK character (*):

  2. Let remaining be the result of removing the leading "*" from expression.

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

请注意,“匹配主机或其任何子域上的任何资源” 现在只读为“匹配主机上的任何资源”子域名”.