CSP 用白名单约束页面资源
Content-Security-Policy 通过一组指令限制页面能加载和执行哪些来源的资源,是抵御跨站脚本的核心纵深防御手段。它不仅约束脚本,还包括样式、图片、字体、连接目标与嵌入框架。除了来源白名单,还支持用 nonce 或 hash 精确放行个别内联脚本,让严格策略与既有代码可以共存。部署时先用报告模式观察,再逐步收紧。
基本信息
| 响应头名 | Content-Security-Policy |
|---|---|
| 作用 | 限制脚本、样式、图片、连接与嵌入等资源来源 |
| 规范 | W3C Content Security Policy Level 3 |
| 报告模式 | Content-Security-Policy-Report-Only 只上报不拦截 |
| 精确放行 | 用 nonce 或 hash 允许特定内联脚本,避免整站放开 |
| 配套头 | frame-ancestors 用于防点击劫持,report-uri 或 report-to 用于收集违规 |
常用基线与报告模式
常用基线与报告模式
# 先观察:只上报不拦截,确认不会打断现有功能
# add_header Content-Security-Policy-Report-Only "default-src 'self'; report-uri /csp-report" always;
# 再收紧为强制模式,并用 nonce 精准放行内联脚本
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'nonce-随机值'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'" always;
curl -sI https://www.example.com/ | grep -i content-security-policy # 核对线上策略是否真的下发常用指令
| 指令 | 约束范围 | 典型写法 |
|---|---|---|
| default-src | 未单独指定时的兜底来源 | 'self' |
| script-src | 脚本来源与内联放行 | 'self' 'nonce-随机值' |
| style-src | 样式表来源 | 'self' 'unsafe-inline'(尽量避免) |
| img-src | 图片来源 | 'self' data: https://cdn.example.com |
| connect-src | 脚本发起网络请求的目标 | 'self' https://api.example.com |
| object-src | 插件类内容 | 'none' |
| base-uri | 页面 base 标签允许的地址 | 'self' |
| frame-ancestors | 允许把本站嵌为框架的站点 | 'self' 或 none |
落地步骤
- 第一步发布报告模式,收集一段时间内的违规来源,摸清页面真实依赖
- 第二步按高频违规逐项放行,优先用 nonce 或 hash 而不是放开整类来源
- 第三步切到强制模式并保留上报,观察是否有功能静默失败
- 第四步定期复查上报数据,逐步移除不再需要的放行项
- 跨团队协作时先把策略写成文档,避免各页各自加例外导致整体松散
CSP 配置错误会整站脚本失效,用户看到的是空白页或按钮全部无响应。上线前必须用报告模式收集违规,改完先在预发环境用真实浏览器回归一遍。
开启 'unsafe-inline' 后 CSP 对脚本注入的防护作用基本失效,它应当作为迁移期的过渡手段,并配合 nonce 逐步移除。