不能直接上线strict CSP策略,因会立即拦截大量未纳管合法脚本(如第三方SDK、CDN组件、内联代码),导致白屏、功能异常;且缺乏前置风险识别,仅靠report-uri/report-to上报的无上下文JSON难以归因真实攻击。
为什么不能直接上线 strict CSP 策略
生产环境一旦配置
且含
这类严格指令,大量合法但未纳管的脚本会立即被浏览器拦截——比如第三方统计 SDK、A/B 测试工具、CDN 上未加 nonce 的旧版组件、甚至内联初始化代码。用户白屏、功能异常、客服电话暴增是常见后果。
更关键的是:你根本不知道哪些脚本会被拦,因为前端资源加载路径分散在 HTML 模板、构建产物、运行时动态插入、甚至 CMS 后台富文本中。
浏览器只在拦截时上报违规,不提前告诉你“这里有个潜在风险”
或
接收到的是一条条原始 JSON,没有上下文归因(哪个页面?哪个用户?哪个版本 JS?)
默认策略下,
和
图片等宽松项可能掩盖真实攻击流量
用 Report-Only 模式收全非法脚本行为
必须先启用
响应头,让浏览器照常加载所有资源,但把所有违反策略的行为(包括 script、eval、inline event、base-uri 覆盖等)全部上报到指定端点。
典型配置示例(Nginx):
注意点:
是现代标准(需配合
header),比已废弃的
更可靠,支持批量上报与重试
不要在 Report-Only 模式下写
—— 它会让内联脚本“合法化”,从而漏掉真实 XSS 注入行为
必须覆盖
、
、
三类,XSS 常通过 fetch/XHR 外泄数据,而不仅仅是执行脚本
从原始 report 数据里识别真实攻击特征
浏览器发来的
请求体是 JSON,但字段含义容易误读:
真正要盯住的不是
,而是:
为
且
是非白名单域名(尤其含
、短域名、可疑 TLD)
为空或指向用户可控输入(如
、
、
)—— 这极大概率是 DOM XSS
字段里出现
或
,说明有 eval() 或内联事件(
)正在运行,属于高危信号
别依赖简单关键词匹配(如 “evil.com”),攻击者会用 CDN 中转、IP 直连、或 base64 编码绕过;重点看行为模式是否偏离正常业务流量分布。
告警链路必须带上下文与抑制机制
原始 CSP report 本身不含用户身份、设备指纹、请求 Referer、UA 等信息,直接告警等于盲报。必须在接收端做增强:
用 Nginx 的
、
、
等变量,和 report JSON 一起存入日志或数据库
对同一
+
组合做 5 分钟内频次统计,单次触发不告警,10+ 次/分钟才触发(过滤扫描器试探)
自动关联前端 sourcemap 或构建产物哈希,定位到具体 JS 文件与代码行 —— 否则开发无法快速判断是漏洞还是误配
设置静默规则:比如只对
路径下的 report 告警,或排除已知灰度环境 IP 段
最易被忽略的一点:CSP report 本身可被伪造。攻击者能手动发一个
来刷爆你的告警系统。接收端必须校验
或
是否来自你自己的域名,否则整套体系不可信。
Content-Security-Policyscript-src 'self'report-urireport-to'unsafe-inline'data:Content-Security-Policy-Report-Onlyadd_header Content-Security-Policy-Report-Only "default-src 'self'; script-src 'self' https://cdn.example.com; report-to /csp-report;";report-toReporting-Endpointsreport-uriscript-src 'unsafe-inline'script-srcstyle-srcconnect-src/csp-report{
"csp-report": {
"document-url": "https://example.com/dashboard",
"blocked-uri": "https://evil.com/xss.js",
"violated-directive": "script-src",
"source-file": "https://example.com/app.js",
"line-number": 42,
"column-number": 15
}
}blocked-uriviolated-directivescript-srcblocked-urihttp://source-filedata:text/html,javascript:blob:original-policyunsafe-evalunsafe-inlineonclick=...$http_referer$http_user_agent$remote_addrblocked-uridocument-url/admin/POST /csp-reportOriginReferer