什么是CSP违规报告
CSP,即内容安全策略(Content Security Policy),是浏览器提供的一种安全机制,用来防止XSS、数据注入等攻击。当页面上的资源加载违反了预设的CSP规则时,浏览器可以将违规详情以报告的形式发送到指定地址,这就是CSP违规报告。
比如你在公司开发一个后台管理系统,某天用户反馈页面部分图片加载不出来,查看控制台才发现是因为CSP阻止了外链图片。如果你配置了报告接收,就能第一时间收到这类问题,而不是等用户上报。
开启报告功能
要接收CSP违规报告,先得在HTTP响应头中启用 report-uri 或 report-to 指令。虽然report-uri已被标记为废弃,但目前仍广泛支持。
Content-Security-Policy: default-src 'self'; img-src *; script-src 'self'; report-uri /csp-report-endpoint加上这行头后,一旦有资源违反策略,浏览器就会往 /csp-report-endpoint 发一个POST请求,携带详细的违规信息。
实际收到的报告长什么样
请求体通常是一个JSON对象,包含blocked-uri、violated-directive、document-uri等字段。比如:
{
"csp-report": {
"document-uri": "https://example.com/page.html",
"referrer": "",
"blocked-uri": "https://evil.com/evil.js",
"violated-directive": "script-src 'self'",
"effective-directive": "script-src",
"original-policy": "default-src 'self'; report-uri /csp-report-endpoint",
"disposition": "enforce",
"source-file": "https://example.com/page.html",
"line-number": 15,
"column-number": 5,
"status-code": 200,
"script-sample": ""
}
}通过这些数据,你能快速定位是哪个脚本被拦了,发生在哪一行,甚至是从哪个第三方域名试图加载的。
搭建接收端
接收报告的接口其实就是一个普通的HTTP POST端点。可以用Node.js、Python Flask、PHP等任意后端技术实现。重点是要能解析application/csp-report格式的请求体。
以Express为例:
const express = require('express');
const app = express();
app.use(express.raw({ type: 'application/csp-report', limit: '1mb' }));
app.post('/csp-report-endpoint', (req, res) => {
const report = JSON.parse(req.body.toString());
console.log('收到CSP违规报告:', report);
// 这里可以写入日志、发告警、存数据库
res.status(204).end();
});
app.listen(3000);部署之后,只要前端触发违规,你就能在服务端看到输出。
常见问题与优化
刚上线时可能会收到大量报告,尤其是来自用户浏览器插件的脚本被拦截。这时候别慌,先按blocked-uri分类,过滤掉常见的广告或跟踪脚本。
也可以结合User-Agent分析,看看是不是某些旧版本浏览器兼容性问题导致误报。如果发现某个内部资源频繁被拦,可能是开发环境和生产环境策略不一致,及时调整策略更省心。
还可以把报告接入监控系统,比如用Grafana展示每日违规趋势,设置阈值告警。这样不用天天盯着日志,也能掌握站点安全状况。