在设置网站内容安全策略(Content Security Policy,简称 CSP)时,很多人会用到星号(*)来匹配多个子域名。这种方式看似方便,但如果不理解其规则,反而可能带来安全隐患或资源加载失败。
什么是星号域名匹配
CSP 允许通过域名白名单控制哪些外部资源可以被加载,比如脚本、样式、图片等。星号作为通配符,可以用来代表一部分或全部子域名。例如:
script-src https://*.example.com;
这条规则表示允许从 example.com 的任意一级子域名加载脚本,比如 cdn.example.com、api.example.com 都可以,但不会匹配二级以上的子域名,如 user.api.example.com。
星号只能匹配一级子域名
一个常见的误解是认为 * 能匹配任意层级的子域名,但实际上它只匹配一级。比如:
img-src https://*.cdn.example.com;
这个规则只允许像 static.cdn.example.com 这样的域名,而无法匹配 deep.static.cdn.example.com。如果想让后者也能加载图片,必须显式添加或换用更宽松的策略,但后者通常不推荐。
根域名不会被 * 匹配
很多人以为 *.example.com 可以包含 example.com 本身,其实不行。下面这条策略:
script-src *.example.com;
会阻止从 https://example.com 直接加载脚本,因为星号只代表前缀部分,不包括空子域名的情况。如果需要包含主域名,得单独写上:
script-src example.com *.example.com;
避免滥用通配符
有些开发者为了省事,直接写成:
default-src *;
这相当于完全关闭了 CSP 的保护作用,任何域名的资源都能加载,失去了安全意义。就像为了方便开门,把家门钥匙挂在门口一样,风险极高。
实际应用场景
假设你在维护一个电商平台,静态资源分布在多个 CDN 子域名下,比如 img1.store.com、static.store.com、video.store.com。你可以这样写:
img-src *.store.com;
script-src https://static.store.com;
这样既保证了灵活性,又控制了范围,避免不必要的权限开放。
注意协议限制
星号只管域名部分,不管协议。如果你写了 *.example.com,那么 http 和 https 都会被允许,除非你明确限定:
script-src https://*.example.com;
加上 https:// 后,就只会允许 HTTPS 资源加载,更安全。
开发调试小技巧
在浏览器开发者工具的控制台中,如果看到类似“Refused to load script from...”的提示,很可能是 CSP 拦截了请求。检查当前页面的响应头是否有正确的 CSP 规则,尤其是星号是否误用了。
可以用 Chrome 的 Network 标签页查看 response headers 中的 Content-Security-Policy 字段,确认配置是否生效。