必须通过HTTP响应头配置CSP,meta标签在生产环境无效;浏览器优先执行响应头策略,且Chrome 124+已禁用部分指令的meta支持,真正生效路径是后端动态注入响应头。

Content-Security-Policy 必须走 HTTP 响应头, 标签在生产环境无效
浏览器对 CSP 的执行优先级是:HTTP 响应头 > <meta http-equiv="Content-Security-Policy">。只要服务端返回了任何 Content-Security-Policy 响应头(哪怕值为空或语法错误), 就被完全忽略。Chrome 124+ 已禁用 对 script-src、frame-ancestors、base-uri 等关键指令的支持;Safari 16.4 之前版本会静默丢弃含 nonce- 或 sha256- 的整条策略;Android WebView 可能跳过整条 script-src 规则导致白屏。
真正起效的配置只有一种路径:由后端服务动态生成并注入响应头。Nginx 示例必须带双引号包裹整个值,单引号用于源关键字:
add_header Content-Security-Policy "default-src 'none'; script-src 'self' 'nonce-{random}'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src 'self'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'; object-src 'none'; report-to csp-endpoint";
-
{random}必须由后端每次请求生成新随机字符串,硬编码或复用等于没设 - 本地
file://协议下 CSP 全面失效,DevTools 里看到的策略不等于线上生效 - 确认是否生效:Chrome DevTools → Network → HTML 请求 → Response Headers → 查看是否存在
content-security-policy(全小写)
script-src 'self' 不防 XSS,必须配合 nonce 或 hash 才能拦住内联脚本
只写 script-src 'self' 是典型误判——它只限制外链脚本,对 <script>alert(1)</script>、onclick="doSomething()"、eval() 完全放行。真正起效的前提是:不写 'unsafe-inline'、不写 'unsafe-eval',再显式授权合法内联脚本。
- 用
nonce:服务端生成随机值(如abc123),响应头写script-src 'nonce-abc123',HTML 中对应<script nonce="abc123">;复用或固定值即失效 - 用
hash:对脚本内容(不含<script>标签)做 SHA256 摘要,如sha256-BzLdO9X,写进响应头;仅适用于构建时确定的静态内联脚本,动态拼接无法预计算 - 别混用:一个策略里同时存在
'nonce-xxx'和'sha256-...'是允许的,但浏览器只匹配其一;未匹配的脚本仍被拦截
漏掉 default-src 'none' 或关键指令,会导致资源静默失败或留后门
设 default-src 'none' 是严格策略的起点。它让所有资源类型(图片、样式、字体、连接等)默认被禁,必须显式声明才能加载。否则资源静默 404,控制台只报 CSP violation,不提示缺哪条指令。
立即学习“前端免费学习笔记(深入)”;
-
img-src漏data:→ base64 图片炸掉 -
connect-src没覆盖 API 域名 →fetch()或 WebSocket 连接失败 -
font-src漏 CDN → 字体图标不显示 -
base-uri 'self'不设 → 攻击者可注入<base href="http://attacker.com">劫持所有相对 URL -
form-action 'self'不设 → 表单可提交到第三方,构成 CSRF 风险 -
frame-ancestors 'none'不设 → 页面可被嵌入钓鱼页,点击劫持防护失效 -
object-src 'none'不设 → Flash/Java 插件可能被滥用(老漏洞温床)
开发期必须先用 Content-Security-Policy-Report-Only 观测,不能直接上线 blocking 模式
一上来就用 Content-Security-Policy(blocking 模式)极易炸掉页面功能。正确路径是先用 Content-Security-Policy-Report-Only + report-to 或 report-uri 收集真实违规日志,观察 3–7 天,确认所有合法脚本、样式、字体、API 请求都被覆盖,再切为阻断模式。
-
report-uri已废弃,应改用report-to配合Report-To响应头 -
不支持
report-uri和report-to,无法做灰度观测 - CSP 不继承父页面策略:iframe、Worker、fetch 返回的 HTML 片段也得各自带头,否则策略失效
- 富文本渲染、模板引擎插值、动态
innerHTML注入的脚本,不会继承父页面 CSP,必须单独验证是否匹配策略



















