公众号:
JavaScript与编程艺术
1. 设置 CSP 有几种渠道?
答:服务端设置和客户端设置。即 HTTP Header 和 HTTP meta 标签。
HTTP Header:
Content-Security-Policy: img-src 'self' data: blob:;
HTTP meta 标签:
<meta http-equiv="Content-Security-Policy" content="img-src 'self' data: blob:" />
2. 二者有何区别?如何选择?哪个优先级更高?
区别
| 设置方式 | 安全性 | 范围 | 兼容性 |
|---|---|---|---|
| HTTP Header | 更安全 | 所有域名 | 所有指令都可配置 |
| HTML meta | 篡改风险 | 单个文档,meta 标签之后 | 某些会被忽略 |
会被忽略的指令:
Content-Security-Policy-Report-Only,report-uri,frame-ancestors,sandbox
如何选择
出于安全性考虑应该优先选择 HTTP Header。
优先级
从先后顺序来看:HTTP Header > HTTP meta 标签。
- 不同规则合并。
- 相同规则以更严格为准,即『可以更严格但是不能更宽松』。
举例来说,一旦 HTTP Header 指定了 img-src https: data:,在 HTTP meta 中改成 img-src https: (更严格因为仅允许加载来自 https 的图片)可以生效,但是若改成更宽松 img-src https: data: blob: 则不会生效。
改成
img-src https:新插入的data:image/png;base64,xyz...图片将报错(已展示的图片不受影响):Refused to load the image 'data:image/png;base64,xyz...' because it violates the following Content Security Policy directive: "img-src https:".
3. 'self' 是什么意思?包含 data: 或 blob: 吗?
首先 self 必须加 单 引号。img-src self 或 img-src "self" 都是错误的。
self 是指允许加载来自同源(same origin)的资源。不包含 data: 或 blob:。
同源:协议 & domain 或 subdomain & 端口号。
4. * 通配符用法
* 可以用于任何部位,scheme、domain 和 port。
http://*等同于http:。- 而
http:等同于http:+https。协议升级自动包含,再比如ws:到wss: http://*.example.com匹配所有子 domain 和对应的httpshttp://foo.example.comhttp://foo.bar.example.comhttps://foo.example.comhttps://foo.bar.example.com- ...
有误理解:
*.example.com错误应该是http://*.example.com。http://*.example.com匹配端口号80443,但不匹配其他端口。
其他知识
- 一旦指令被 parse 则后续的修改都不会生效。具体来说解析后对 meta 元素的内容属性进行的任何修改都将被忽略。这意味着一旦 meta http-equiv 标签被处理,对其内容的进一步修改将不会产生效果。
参考
Difference Between HTTP Headers and Meta http-equiv for Content Security Policy (CSP)