使用浏览器的CSP机制从根本上解决XSS问题
关于 xss 的介绍,和危害。这里不多赘述。自行百度。
什么是CSP机制
网页安全政策(Content Security Policy),实质上就是通过一个HttpHeader来提供一个白名单,让浏览器仅仅可以加载指定的js文件。以及约束内联js的执行。来彻底的杜绝XSS攻击。
Content-Security-Policy
一个简单的案例开始
Content-Security-Policy: script-src 'none';img-src 'self' https://baidu.com;
-
script-src
表示一个选项,该选项的主要作用就是指定 js代码的加载白名单。它的值目前是none
表示不从任何URL加载 js 脚本。如果html
有执行加载的话,浏览器会抛出异常
-
img-src
选项表示限制html
页面中的图片加载地址。它有两个值。self
表示允许从当前的域中加载,还允许从https://baidu.com
下加载。如果加载的图片地址不在白名单内,那么浏览器就会阻止加载,并且给出异常
常用的限制选项
选项 | 限制内容 |
---|---|
script-src |
外部脚本 |
style-src |
样式表 |
img-src |
图像 |
media-src |
媒体文件(音频和视频) |
font-src |
字体文件 |
object-src |
插件,比如 Flash ) |
child-src |
框架 |
frame-ancestors |
嵌入的外部资源,比如frame iframe embed 和 applet |
connect-src |
HTTP 连接(通过 XHR 、WebSockets 、EventSource 等) |
worker-src |
worker脚本 |
manifest-src |
manifest 文件 |
default-src |
上述所有选项的默认选项(可以被覆盖) |
可以有多个选项,每个选项之间使用分号
;
分割。如果同一个选项多次声明,只有第一个会生效。
选项值的表达式
限制主机
http://springboot.io
https://statis.springboot.io
限制路径
http://springboot.io/assert/js/
使用通配符限制
*.example.org //任意协议,指定域名,指定端口(80)
*://*.example.com:* // 任意协议,指定域名,任意子域名,任意端口
限制使用的协议
https: // 允许以https:协议加载
data: // 允许以data:协议加载
关键字 self 和 none
关键字必须添加单引号
script-src 'none' //none 表示禁止加载
img-src 'self' // self 表示允许从当前域加载
script-src 选项的特殊值
下列值,都是关键字,在设置的时候,必须使用单引号
unsafe-inline
如果设置了该值,表示允许内嵌的<script>
代码块,和标签上的事件监听函数执行。
unsafe-eval
如果设置了该值,允许将字符串当作代码执行,比如使用 eval
setTimeout
setInterval
和 Function
等函数。
nonce
该值表示一个授权值,只有通过该值授权的内联代码块才能执行
Content-Security-Policy: script-src 'nonce-123456'
<script type="text/javascript" nonce="123456">
console.log('内联代码执行');
</script>
在
<script>
标签上添加一个nonce
属性,该属性的值。与 header 中 nonce 的值一样。该内联代码块才能执行。该值的表达式:once-字符串
hash
该值表示内联代码块中js代码的hash值。只有在内联代码块的hash值匹配的时候才能执行
content-Security-Policy: script-src 'sha256-qznLcsROx4GACP2dm0UCKCzCG-HiZ1guq6ZZDob_Tng='
<script>alert('Hello, world.');</script>
该值的表达式:hash算法名-hash值
report-uri 报告
report-uri
用来设置一个回调,在浏览器发生注入异常的时候,浏览器会把详细的信息提交给该回调地址。
content-Security-Policy: report-uri /xss/report; // 把注入异常提交到 /xss/report
提交的是一个JSON体
{
"csp-report": {
"document-uri": "http://example.org/page.html", //发生违规的文档的URI。
"referrer": "http://evil.example.com/", //referrer
"blocked-uri": "http://evil.example.com/evil.js", //被CSP阻止的资源URI。如果被阻止的URI来自不同的源而非文档URI,那么被阻止的资源URI会被删减,仅保留协议,主机和端口号。
"violated-directive": "script-src 'self' https://apis.google.com", //违反的策略名称。
"original-policy": "script-src 'self' https://apis.google.com; report-uri http://example.org/my_amazing_csp_report_parser" // 在 Content-Security-Policy HTTP 头部中指明的原始策略。
}
}
其他一些可以限制的选项
block-all-mixed-content
HTTPS 网页不得加载 HTTP 资源(浏览器已经默认开启)
upgrade-insecure-requests
自动将网页上所有加载外部资源的 HTTP 链接换成 HTTPS 协议
plugin-types
限制可以使用的插件格式
sandbox
浏览器行为的限制,比如不能有弹出窗口等