前言
CSP策略全称为Content Security Policy,是以白名单的机制对网站加载或者执行的资源起作用。CSP通常以HTTP头信息或者meta元素定义,可以较好的防御dom xss。
实现
1.使用meta标签,直接在页面中定义csp
1 | <meta http-equiv="content-security-policy" content="策略"> |
这种方式较为简单,但需要每个页面都添加,较为繁琐。
2.使用HTTP头定义CSP
Apache :
Add the following to your httpd.conf in your VirtualHost or in an .htaccess file:
Header set Content-Security-Policy “default-src ‘self’;”
Nginx :
In your server {} block add:
add_header Content-Security-Policy “default-src ‘self’;”
也可使用PHP设置http头:
1 |
|
CSP的书写规则
举个例子
1 | //限制所有外部资源,所有资源只能从当前域名加载 |
default-src是CSP指令,多个指令用分号分隔,指令值用空格分隔,如:
1 | Content-Security-Policy: default-src http://xxx.com; script-src http://aaa.com http://bbb.com |
1 | //通过report-uri指令发送拦截报告到指定地址 |
常用的CSP指令
指令 | 指令和指令值示例 | 指令说明 |
---|---|---|
default-src | ‘self’ cdn.example.com | 默认加载策略 |
script-src | ‘self’ js.example.com | 对 JavaScript 的加载策略。 |
style-src | ‘self’ css.example.com | 对样式的加载策略。 |
img-src | ‘self’ img.example.com | 对图片的加载策略。 |
connect-src | ‘self’ | 对 Ajax、WebSocket 等请求的加载策略。不允许的情况下,浏览器会模拟一个状态为 400 的响应。 |
font-src | font.cdn.example.com | 针对 WebFont 的加载策略。 |
object-src | ‘self’ | 针对 、 或 等标签引入的 flash 等插件的加载策略。 |
media-src | media.cdn.example.com | 针对媒体引入的 HTML 多媒体的加载策略。 |
frame-src | ‘self’ | 针对 frame 的加载策略。 |
report-uri | /report-uri | 告诉浏览器如果请求的资源不被策略允许时,往哪个地址提交日志信息。 特别的:如果想让浏览器只汇报日志,不阻止任何内容,可以改用 Content-Security-Policy-Report-Only 头。 |
sandbox | 设置沙盒环境 | |
child-src | 主要防御 <frame> ,<iframe> | |
form-action | 主要防御 <form> | |
frame-ancestors | 主要防御 <frame> ,<iframe> ,<object> ,<embed> ,<applet> | |
plugin-types | 主要防御 <object> ,<embed> ,<applet> |
CSP指令值
指令值 | 指令和指令值示例 | 指令值说明 |
---|---|---|
* | img-src * | 允许任何内容。 |
‘none’ | img-src ‘none’ | 不允许任何内容。 |
‘self’ | img-src ‘self’ | 允许来自相同来源的内容(相同的协议、域名和端口)。 |
data: | img-src data: | 允许 data: 协议(如 base64 编码的图片)。 |
example.com | img-src img.example.com | 允许加载指定域名的资源。 |
*.example.com | img-src *.example.com | 允许加载 example.com 任何子域的资源。 |
‘unsafe-inline’ | script-src ‘unsafe-inline’ | 允许加载 inline 资源(例如常见的 style 属性,onclick,inline js 和 inline css 等等)。 |
‘unsafe-eval’ | script-src ‘unsafe-eval’ | 允许加载动态 js 代码,例如 eval()。 |
演示
定义CSP,图片资源只能从当前域名加载
1 |
|
输入<img src=1.jpeg >
图片成功加载
输入<img src="https://zer0blog.oss-cn-hangzhou.aliyuncs.com/blog_image/csp/01.png" >
图片加载被浏览器阻止,stasus显示为blocked:csp
总结
CSP策略虽然通过白名单限制了资源的加载,减少了XSS攻击,但也造成了:Eval及相关函数被禁用、内嵌的JavaScript代码将不会执行、只能通过白名单来加载远程脚本,并且需要浏览器支持CSP策略。如果使用CSP策略,开发者不得不使内嵌脚本和文档分离,但好在CSP使开发者减少了对XSS攻击的负担。
现在大多数浏览器都已支持CSP策略,大大减少了用户被广告骚扰和盗取cookie的风险。