nginx 中配置严格 csp 必须与 https 协同,分阶段推进:先用 report-only 模式采集行为 3–7 天,禁用 unsafe-inline/unsafe-eval,改用 nonce 或 hash;确保所有响应(含错误页、静态资源)携带带 always 参数的 csp;统一在 http/server 级配置,关闭后端重复输出;并配合 hsts、x-content-type-options 等头实现纵深防御。

在 Nginx 中配置严格的 CSP 响应头,必须与 HTTPS 协同落地——HTTPS 保障传输不被窃听,CSP 则约束浏览器只加载可信资源,二者缺一不可。直接写死策略容易导致页面白屏或功能异常,关键在于分阶段推进、全覆盖生效、避免后端干扰。
先用 Report-Only 模式采集真实行为
上线阻断型 CSP 前,务必启用报告模式观察 3–7 天,确认哪些脚本、样式、CDN 是业务必需的:
- 在 http 或 server 块中添加:
add_header Content-Security-Policy-Report-Only "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https:; img-src 'self' data: https:; style-src 'self' 'unsafe-inline'; connect-src 'self' https:; report-uri /csp-report;" always; - 确保后端已部署
/csp-report接口接收并解析违规日志 - 重点关注
script-src和style-src下的'unsafe-inline'、'unsafe-eval'及第三方域名调用
禁用 unsafe-inline,改用 nonce 或 hash 控制内联资源
保留 'unsafe-inline' 会让 CSP 形同虚设。生产环境必须替换为可审计的方式:
- 后端为每个 HTML 响应生成唯一 base64 nonce(如
nonce="Ea8mLk3q"),注入到<script nonce="Ea8mLk3q"></script>标签中 - Nginx 同步注入该值:
add_header Content-Security-Policy "script-src 'self' 'nonce-Ea8mLk3q' https://cdn.example.com; default-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self';" always; - 若无法改造后端,对内联脚本内容计算 SHA256 hash,写入
script-src 'sha256-xxx'
确保所有响应都携带 CSP,不留盲区
CSP 必须作用于全部 HTTP 响应,包括 404 错误页、重定向响应、静态资源(.js/.css/.svg/.woff2)等,否则攻击者可绕过:
- 所有
add_header必须加always参数,例如:
add_header Content-Security-Policy "default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'; base-uri 'self'; form-action 'self';" always; - 统一在 http 或 server 级别配置,避免多个
location块重复定义造成覆盖 - 检查 PHP/Node.js/Java 等后端是否也输出 CSP 头,如有则必须关闭,只由 Nginx 单一源头管理
配合 HTTPS 的其他必要加固项
CSP 是核心,但需与其他安全头协同形成纵深防御:
- 强制 HTTPS:在 HTTP server 块中配置
return 301 https://$host$request_uri; - HSTS 头防止协议降级:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; - 禁用 MIME 类型嗅探:
add_header X-Content-Type-Options nosniff always; - 防止点击劫持:
add_header X-Frame-Options SAMEORIGIN always;











