最可靠方式是在 nginx.conf 中统一配置 csp——通过 http 或 server 块的 add_header content-security-policy "...” always; 实现源头管控,禁用后端重复输出,并先用 report-only 模式观测、再逐步收紧策略,禁用 unsafe-inline 时需配合 nonce 或 hash,对 api/上传等非 html 路径差异化加固。

直接在 nginx.conf 里配 CSP 是最可靠的方式——它不依赖后端代码,由浏览器强制执行白名单规则,能从根本上阻断 XSS 类脚本注入。但不能只加一行就完事,关键在策略合理、覆盖完整、避免冲突。
统一在 server 或 http 块配置,禁用后端重复输出
CSP 头必须由 Nginx 单一源头管理,否则后端(如 PHP、Node.js)自己也输出同名头,会导致策略被覆盖或失效:
- 在
http或server块顶层写add_header Content-Security-Policy "..." always; - 检查所有后端服务,移除手动设置
Content-Security-Policy的代码,包括框架默认行为(如 Express 的 helmet、Laravel 的中间件) - 特别注意:错误页(404/500)、重定向响应(301/302)、静态资源(
.js/.css)默认不继承 CSP,必须加always参数才能生效
先用 Report-Only 模式观察,再逐步收紧
上线前别直接启用阻断模式,先收集真实流量中的违规行为:
- 临时替换为
add_header Content-Security-Policy-Report-Only "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; report-uri /csp-report;" always; - 部署后持续采集 3–7 天日志,重点关注哪些内联脚本、CDN 域名、
eval调用是业务必需的 - 确认无误后,把
Content-Security-Policy-Report-Only改回Content-Security-Policy,再分步移除'unsafe-inline'和'unsafe-eval'
禁用 unsafe-inline,改用 nonce 或 hash
生产环境不允许 'unsafe-inline',但又不能简单禁止所有内联脚本——需前后端协同:
- 后端渲染 HTML 时,为每个请求生成唯一 base64 nonce(如
nonce="Ea8kLz3q"),并注入到<script nonce="Ea8kLz3q"></script> - Nginx 配置中同步写入该值:
add_header Content-Security-Policy "script-src 'self' 'nonce-Ea8kLz3q' https://cdn.example.com;" always; - 若无法改造后端,可用 SHA256 hash 替代:对内联脚本内容计算 hash,填入
script-src 'sha256-xxx'
对 API、上传等非 HTML 路径做差异化加固
这些路径不返回可执行 HTML,没必要开放脚本加载权限,可大幅缩小攻击面:
- 在
location /api/块中单独配置:add_header Content-Security-Policy "default-src 'none';" always; - 上传目录(如
location /uploads/)可设为default-src 'none'; img-src 'self';,禁用脚本、样式、字体等加载 - 配合
X-Content-Type-Options: nosniff防止 MIME 嗅探绕过











