CSP 全称是 Content Security Policy,控制浏览器在加载网络资源时,告知浏览器哪些资源是可信的、安全的。可以有效地降低和杜绝 XSS 攻击。
如何产生 XSS 攻击,可以参考 http://blog.zhengxianjun.com/2015/web-security-xss/。
有时候即便整个网站增加了 XSS 防注入,也可能在迭代过程中存在遗漏。
浏览器不能区分哪些资源是安全的,一旦下载之后就会执行。(有些浏览器可以识别简单的 XSS 注入)。
CSP 就是为了告诉浏览器哪些资源是可信任的、安全的,通过白名单去加载网络资源和执行。这样即使网页存在 XSS 注入,出现损失的可能性也会大大地降低。
比如:
Content-Security-Policy: script-src https://s.fiaox.com
那么浏览器只会信任来自 s.zhengxianjun.com 的脚本,这样即使网站被注入了第三方站点脚本或者内联,也不会执行,那 XSS 攻击也就失效了。
代码示例:
<?php header('Content-Security-Policy: script-src https://s.fiaox.com');?> <script type="text/javascript" src="https://code.jquery.com/jquery.js"></script> // 支持 CSP 则不会加载来自 jquery.com 的脚本
以上代码分别在 IE、Chrome、Firefox 中的效果。
在 IE10 中,似乎没有支持 CSP,jquery.js 被正常加载和执行。这是因为早期 CSP 没有规范,IE 识别 X-Content-Security-Policy,但并不是完整支持。
Chrome 正确识别了 CSP,并且说明了原因。
Firefox 正确识别了 CSP,并且说明了原因。
CSP 是帮助浏览器创建了一个网络资源白名单。
CSP 规则列表
Content-Security-Policy: script-src 'self' s.zhengxianjun.com;style-src 'self';img-src 'self'
- 多个指令之间用英文分号隔开;
- 指令的值不是域名时需要引号引起来;
- 指令重复以第一个为准。
指令 | 说明 |
default-src | 定义资源默认加载策略 |
connect-src | 定义 Ajax、WebSocket 等加载策略 |
font-src | 定义 Font 加载策略 |
frame-src | 定义 Frame 加载策略 |
img-src | 定义图片加载策略 |
media-src | 定义 <audio>、<video> 等引用资源加载策略 |
object-src | 定义 <applet>、<embed>、<object> 等引用资源加载策略 |
script-src | 定义 JS 加载策略 |
style-src | 定义 CSS 加载策略 |
sandbox | 值为 allow-forms,对资源启用 sandbox |
report-uri | 值为 /report-uri,提交日志 |
以上指令除了 sandbox、report-uri 是比较特殊的值,其余指令可以接收 ‘self’、data、域名 等值。
指令示例
示例 | 说明 |
script-src | 允许任何资源 |
script-src ‘none’ | 不允许任何资源 |
script-src ‘self’ | 允许同源资源(协议、域名、端口均相同) |
script-src ‘unsafe-eval’ | 允许动态脚本,如 eval、setTimeout、new Function |
script-src ‘unsafe-inline’ | 允许内联资源 |
script-src s.zhengxianjun.com | 允许某个域名下的资源 |
script-src *.zhengxianjun.com | 允许子域名下的资源 |
script-src https | 允许 https 资源 |
script-src https://zhengxianjun.com | 允许某个域名下的 https 资源 |
img-src data | 允许 data: 协议资源 |
report-uri 会接收到一个 post 请求,包含 CSP 阻止的详细信息。
虽然 CSP 能够有效降低 XSS 攻击,但是不要指望它可以完全杜绝 XSS 攻击。
为了让产品能够顺利过渡到 CSP,可以通过 Content-Security-Policy-Report-Only 先收集 CSP 报告,根据报告修正被阻止的正确资源,再启用 CSP。使用了 Content-Security-Policy-Report-Only 则一定要配置 report-uri。
示例:
Content-Security-Policy-Report-Only: script-src 'self'; report-uri https://www.zhengxianjun.com/csp/report