Content-Security-Policy 内容安全策略
让网站变得更加安全
mdn csp
限制资源获取
报告资源获取越权
default-src限制全局
制定资源类型
connect-src
img-src
font-src
media-src
frame-src
script-src
manifest-src
style-src
在 web 领域,xss 可以通过注入脚本的方式进行攻击
const http = require('http')
const fs = require('fs')
http.createServer(function (request, response) {
console.log('request come', request.url)
if (request.url === '/') {
const html = fs.readFileSync('test.html', 'utf8')
response.writeHead(200, {
'Content-Type': 'text/html',
'Content-Security-Policy': 'default-src http: https:' // 只能通过http或https的方式加载
})
response.end(html)
} else {
response.writeHead(200, {
'Content-Type': 'application/javascript'
})
response.end('console.log("loaded script")')
}
}).listen(8888)
console.log('server listening on 8888')
<body>
<div>This is content</div>
<!-- 内联脚本 -->
<script>
console.log('inline js')
</script>
</body>
</html>
控制台报错
Refused to execute inline script because it violates the following Content Security Policy directive: "default-src http: https:". Either the 'unsafe-inline' keyword, a hash ('sha256-KU4m2rqHAFwi569te1RE5P3qW1O/qJ+m+gVo66Frm4k='), or a nonce ('nonce-...') is required to enable inline execution. Note also that 'script-src' was not explicitly set, so 'default-src' is used as a fallback.
限制外链接在 的 script 通过哪些域名进行加载
如,限制只能通过本域名进行加载 外链 script
// server.js
'Content-Security-Policy': 'script-src \'self\'' // 限制外链 script 只能是本域名下的
// test.html
<script src="test.js">script> 本域名下的可以使用
<script src="https://cdn.bootcss.com/jquery/3.3.1/core.js">script>
8888端口访问,可以看到报错信息
Refused to load the script 'https://cdn.bootcss.com/jquery/3.3.1/core.js' because it violates the following Content Security Policy directive: "script-src 'self'".
查看 network,发现在浏览器端就被 block掉了,没有发送请求。
'Content-Security-Policy': 'script-src \'self\' https://cdn.bootcss.com' // 限制外链 script 只能是本域名下的,允许指定域名script加载
这样就没有报错信息了,network 看到 core.js加载成功
form 不接受 default-src 的限制,可以通过 form-action来限制。
下例中 form 会调转到 baidu.com,通过 form-action限制浏览器会报错。
// server.js
'Content-Security-Policy': 'script-src \'self\'; form-action \'self\'' // 限制表单提交只能在本域下
// test.html
<form action="http://baidu.com">
<button type="submit">click mebutton>
form>
报错信息
Refused to send form data to 'http://baidu.com/' because it violates the following Content Security Policy directive: "form-action 'self'".
通过全局限制 default-src 就可以实现
'Content-Security-Policy': 'default-src \'self\'; form-action \'self\''
通过 connect-src
'Content-Security-Policy': 'connect-src \'self\'; form-action \'self\'; report-uri / report'
})
<script>
fetch('http://baidu.com')
script>
报错信息
Refused to connect to 'http://baidu.com/' because it violates the following Content Security Policy directive: "connect-src 'self'".
// server.js
'Content-Security-Policy': 'default-src \'self\'; form-action \'self\'; report-uri / report'
network查看,发送的内容,是 标准的 csp report 的内容。
使用 ‘Content-Security-Policy-Report-Only’
// server.js
'Content-Security-Policy-Report-Only': 'default-src \'self\'; form-action \'self\'; report-uri / report'
资源会正常加载,但是汇报 Report-Only相关的错误提醒
和在服务端使用效果相同,最好在服务端做。
<meta http-equiv="Content-Security-Policy" content="script-src 'self'; form-action 'self';">
report-uri 不允许在 html 的 meta 中使用,只能在服务端通过 head 进行设置。