CSP必须通过HTTP响应头配置才真正生效,<meta>标签在生产环境基本无效;响应头需双引号包裹、单引号标识源关键字、分号分隔指令,含nonce时须服务端动态注入。

CSP 必须通过 HTTP 响应头配置才真正生效,Content-Security-Policy 头里写错一个空格或漏个单引号,整条策略就被浏览器静默忽略——它不会报错,只会彻底失效。
为什么meta标签配置CSP基本不可靠
浏览器执行顺序是:HTTP 响应头 > meta 标签。只要服务端返回了任何 Content-Security-Policy 头(哪怕值为空或语法错误),meta 就完全不参与策略计算。
-
file://协议下,meta和响应头都无效,CSP 全面关闭 - Chrome 124+ 已禁用
meta对script-src、frame-ancestors、base-uri等关键指令的支持 -
report-uri和report-to在meta中完全无效,你配了也收不到违规日志 - Android WebView 可能跳过含
nonce-或sha256-的script-src规则,导致脚本全部白屏
Content-Security-Policy响应头的书写规范
整条策略必须用双引号包裹,内部源关键字(如 'self'、'none')必须用单引号,指令之间用分号 + 空格分隔,末尾不能有多余空格或分号。
- 语法错误(比如漏引号、多空格、非法字符)会导致整条头被浏览器静默忽略,不报错也不拦截
-
default-src 'none'是安全基线,但启用后所有资源类型(img-src、style-src等)都需显式声明,否则静默 404 - 含
nonce时必须由后端每次请求动态生成并注入,硬编码固定值等于形同虚设 - 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}必须被真实 nonce 值替换
script-src禁用内联脚本的真实代价与补救
只写 script-src 'self' https://cdn.example.com 并不能阻止 <script>alert(1)</script> 或 onclick="doSomething()",因为默认允许内联——必须显式排除 'unsafe-inline' 和 'unsafe-eval'。
立即学习“前端免费学习笔记(深入)”;
- 去掉
'unsafe-inline'后,合法内联脚本会直接白屏,必须用nonce或hash显式放行 -
nonce:服务端每次响应生成唯一随机字符串(如abc123def456),HTML 中写<script nonce="abc123def456"></script>,响应头配script-src 'nonce-abc123def456' -
hash:对脚本内容(不含<script>标签)做 SHA256 摘要,转 Base64 后写入头中,如script-src 'sha256-BzLdO9X';动态拼接的脚本无法预计算 hash - 别混用
nonce和hash到同一策略里——浏览器只匹配其一,没匹配上的脚本仍被拦截
容易被忽略却关键的指令:base-uri、form-action、frame-ancestors
CSP 对这些指令默认宽松,不显式配置就可能被利用,且它们不继承父页面策略,iframe、worker、fetch 返回的 HTML 片段也得各自带头。
-
base-uri 'self'防止攻击者注入<base href="http://attacker.com">劫持所有相对 URL -
form-action 'self'确保表单只能提交到当前域名,防 CSRF 和数据外泄 -
frame-ancestors 'none'或'self'阻止页面被嵌入恶意 iframe,抵御点击劫持 -
object-src 'none'必须显式设置,否则 Flash/Java 插件可能被滥用(现代应用已无需支持)
上线前务必验证所有动态生成的脚本——比如富文本渲染、模板引擎插值、第三方 SDK 注入的 inline 脚本——是否被 nonce 或 hash 覆盖;否则策略看似收紧,实际留着巨大缺口。



















