# 内容安全策略
# 作用
- 限制资源获取
- 报告资源获取越权
# 限制方式
- default-src 限制全局:限制所有跟链接请求有关的作用范围;
- 指定资源类型
# node 实践
# 限制资源的加载只能通过 http/https 的方式
const http = require('http')
const fs = require('fs')
http.createServer(function(req, res) {
if (req.url === '/') {
const html = fs.readFileSync('test.html', 'utf-8')
res.writeHead(200, {
'Content-Type': 'text/html',
// 限制 html 中只能通过 http 或者 https 的方式请求资源,内联的方式不行; 会报错:Refused to execute inline script
'Content-Security-Policy': 'default-src http: https:'
})
res.end(html)
}
}).listen(8888)
# 限制只能加载本域名下的资源
const http = require('http')
const fs = require('fs')
http.createServer(function(req, res) {
if (req.url === '/') {
const html = fs.readFileSync('test.html', 'utf-8')
res.writeHead(200, {
'Content-Type': 'text/html',
'Content-Security-Policy': 'default-src \'self\''
})
res.end(html)
}
}).listen(8888)
# 限制可以在指定域名下加载资源
允许 https://cdn.bootcss.com/ 域名下的资源可以加载
const http = require('http')
const fs = require('fs')
http.createServer(function(req, res) {
if (req.url === '/') {
const html = fs.readFileSync('test.html', 'utf-8')
res.writeHead(200, {
'Content-Type': 'text/html',
'Content-Security-Policy': 'default-src \'self\' https://cdn.bootcss.com/'
})
res.end(html)
}
}).listen(8888)
# 限制表单提交到本域名地址
form-action 'self' 限制提交的范围
const http = require('http')
const fs = require('fs')
http.createServer(function(req, res) {
if (req.url === '/') {
const html = fs.readFileSync('test.html', 'utf-8')
res.writeHead(200, {
'Content-Type': 'text/html',
'Content-Security-Policy': 'default-src \'self\'; form-action \'self\''
})
res.end(html)
}
}).listen(8888)
# 不对全局资源请求限制,只限制 script 资源请求
const http = require('http')
const fs = require('fs')
http.createServer(function(req, res) {
if (req.url === '/') {
const html = fs.readFileSync('test.html', 'utf-8')
res.writeHead(200, {
'Content-Type': 'text/html',
'Content-Security-Policy': 'script-src \'self\''
})
res.end(html)
}
}).listen(8888)
# 发送发生违规的文档 URI
如果我们对页面资源请求做了限制,但发生了违规,可以将违规信息发送到服务器: report-uri /report 后面的 /report 是发送违规文档的 url 地址。
const http = require('http')
const fs = require('fs')
http.createServer(function(req, res) {
if (req.url === '/') {
const html = fs.readFileSync('test.html', 'utf-8')
res.writeHead(200, {
'Content-Type': 'text/html',
'Content-Security-Policy': 'script-src \'self\'; form-action \'self\'; report-uri /report'
})
res.end(html)
}
}).listen(8888)
# 不限制文件违规不加载,只限制发送违规的文档
修改 Content-Security-Policy-Report-Only 为头信息。
const http = require('http')
const fs = require('fs')
http.createServer(function(req, res) {
if (req.url === '/') {
const html = fs.readFileSync('test.html', 'utf-8')
res.writeHead(200, {
'Content-Type': 'text/html',
'Content-Security-Policy-Report-Only': 'script-src \'self\'; form-action \'self\'; report-uri /report'
})
res.end(html)
}
}).listen(8888)
# html 中使用 meta 标签进行内容安全策略限制
report-uri 是不能在 meta 中设置
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- report-uri 是不能在 meta 中设置 -->
<meta http-equiv="Content-Security-Policy" content="script-src 'self'; form-action 'self'">
<!-- connect-src 是限制发送 ajax 请求 -->
<!-- <meta http-equiv="Content-Security-Policy" content="connect-src 'self'; form-action 'self'"> -->
</head>
阅读量: