CSP 是什么
CSP(Content Security Policy,内容安全策略)是一组由响应头声明的资源加载白名单,浏览器按策略决定哪些脚本、样式、图片、框架可以加载与执行。它对 XSS 的作用是缩小可利用路径:即使注入点存在,内联脚本与外部恶意域名也可能被执行策略阻断。配置要点是避免 'unsafe-inline' 与过于宽松的域名白名单。
基本信息
| 下发方式 | HTTP 响应头 Content-Security-Policy |
|---|---|
| 观察模式 | Content-Security-Policy-Report-Only 只上报不阻断 |
| 核心指令 | script-src、default-src、frame-ancestors |
| 常用放行方式 | 'self'、'nonce-随机值'、'sha256-哈希' |
常用指令
| 指令 | 作用 |
|---|---|
| default-src | 默认资源白名单,未单独声明的类型都落到它 |
| script-src | 脚本来源限制(核心) |
| style-src | 样式来源限制 |
| img-src | 图片来源限制 |
| frame-ancestors | 允许被哪些页面嵌套(防点击劫持) |
| report-uri / report-to | 违规报告上报地址 |
Report-Only 观察模式
Report-Only 观察模式
add_header Content-Security-Policy-Report-Only "default-src 'self'; report-uri /csp-report" always; # 只上报不阻断,用于上线前摸底
# 先跑一到两周收集违规报告,看清站内真实依赖哪些外部域名
# 报告接口要有速率限制,否则被刷会打满日志磁盘强制模式与 nonce 示例
强制模式与 nonce 示例
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'nonce-$request_id'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'" always;
# nonce 必须每次响应随机生成,且在服务端与页面内保持一致
# 内联脚本改造为外链,或加 nonce="..." 属性才允许执行
# object-src 'none' 与 base-uri 'self' 用来堵住插件与 base 标签劫持典型使用场景
- 存量站点加固:先用 Report-Only 摸底,再逐条白名单收敛到强制模式
- 新项目立项:模板层统一下发策略,把内联脚本从源头禁掉
- 等保与安全检查整改:CSP 常作为 XSS 缓解措施被写入整改说明
- 应急止血:XSS 泛滥时先上报告模式定位,再切强制模式降低利用成功率
- 多站点治理:在网关或 CDN 层统一配置,避免各应用各写一套
迁移到严格模式前先处理内联脚本:抽取为外链,或给标签加 nonce('nonce-随机值')、给脚本内容算哈希('sha256-...')。CSP Level 3 中 report-uri 逐渐被 report-to 取代,实际部署时要按浏览器支持情况决定用哪个。
白名单里放通大型 CDN 或第三方统计域名要谨慎:这些域名上托管的其他脚本也能被放行执行,一旦供应商被入侵,白名单会变成攻击通道。