Nginx全局配置CSP防御脚本注入,需顶层统一管理、禁用后端重复输出,并分阶段落地:先Report-Only收集日志,再收紧策略;内联脚本用nonce或hash替代unsafe-inline;API路径可设script-src 'none'强化防护。

在 Nginx 层用 Content-Security-Policy(CSP)全局防御脚本注入,核心是让浏览器只执行你明确允许的脚本,从源头阻断恶意代码运行。这不是加一行 header 就完事的事,得避开常见陷阱、分阶段落地、兼顾动态场景。
必须顶层统一管理,禁用后端重复输出
CSP 头只能由 Nginx 一家说了算。如果应用后端(如 PHP、Node.js)也输出 Content-Security-Policy,两个头并存时浏览器通常只认后端的,Nginx 的配置就白写了。所以:
- 在 Nginx 的
http或server块最外层设置add_header,确保作用范围覆盖全部响应 - 检查所有后端服务,移除所有手动设置 CSP 头的代码(包括框架默认行为)
- 确认错误页(404/500)、重定向响应(301/302)、静态资源(.js/.css/.svg)都继承该策略——
add_header默认不覆盖这些,需在对应 location 块中显式补上
从 Report-Only 模式起步,收集真实行为
直接上线严格策略容易导致页面功能崩溃。先用 Content-Security-Policy-Report-Only 观察真实流量中的脚本加载行为:
- 配置示例(放在 server 块内):
add_header Content-Security-Policy-Report-Only "default-src 'self'; script-src 'self' 'unsafe-inline' https:; report-uri /csp-report;"; - 搭建简单的
/csp-report接口接收浏览器上报的违规日志 - 持续收集 3–7 天,重点关注哪些内联脚本、外部 CDN、
eval()调用是业务必需的 - 根据报告结果逐步收紧:先去掉
'unsafe-eval',再处理'unsafe-inline'(改用 nonce 或 hash)
严格限制 script-src,配合 nonce 实现可控内联
生产环境应禁用 'unsafe-inline' 和 'unsafe-eval'。但很多前端框架或统计代码依赖内联脚本,这时要用 nonce:
- Nginx 本身无法生成随机 nonce,需前后端协同:后端渲染 HTML 时动态插入一个一次性值(如
<script nonce="abc123">...</script>) - Nginx 中配置为:
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'nonce-abc123' https://cdn.example.com;"; - 每次请求的 nonce 必须唯一且不可预测,不能硬编码,否则失去防护意义
- 若无法改造后端,可退而求其次使用
hash(对已知内联脚本内容做 sha256 计算后填入策略)
针对性加固 API 和敏感路径
API 接口通常不需要执行脚本,可进一步收窄权限:
- 对
/api/、/graphql等路径单独配置更严策略:location ^~ /api/ { add_header Content-Security-Policy "script-src 'none'; object-src 'none'; frame-ancestors 'none';"; } - 禁止
script-src 'none'后,即使接口返回 HTML 内容,浏览器也不会执行其中任何脚本 - 搭配
frame-ancestors 'none'可防止被嵌入第三方 iframe,降低点击劫持风险











