
为什么加了 script-src 'self' 还会拦掉 <script></script> 块?
因为 script-src 'self' 只管外链脚本,不碰内联脚本——浏览器默认把 <script>console.log(1)</script>、onclick="doIt()"、javascript:void(0) 全算作“内联”,只要没显式放行,一律拒绝。报错信息通常是:Refused to execute inline script 或 Refused to execute inline event handler。这不是配置失败,是 CSP 正常工作。
怎么安全保留必需的内联脚本,又不打开后门?
别加 'unsafe-inline',用 nonce 机制:
- 服务端每次响应生成唯一随机值(如
b1967a39a02f45edbac95cbb4651bd12),拼进响应头:Content-Security-Policy: script-src 'self' 'nonce-b1967a39a02f45edbac95cbb4651bd12' - 对应 HTML 中的
<script></script>标签必须带属性:<script nonce="b1967a39a02f45edbac95cbb4651bd12">init();</script> -
nonce值不能硬编码、不能复用,否则等于白设;且它只对<script></script>标签有效,对onclick等属性无效
内联事件处理器(onclick、onload)怎么处理?
它们无法挂 nonce,也不能靠 'unsafe-inline' 救,唯一办法是重构:
- 把
<button onclick="submit()"></button>改成<button id="submit-btn"></button>,再用 JS 绑定:document.getElementById('submit-btn').addEventListener('click', submit) - 禁用
document.write()、innerHTML拼接用户输入;读取location.hash或 URL 参数时,先做 HTML 实体转义,再写入 DOM - 如果用了 HTMX,确认
htmx.config.allowEval = false;避免 JSONP 类加载方式(依赖内联回调)
上线前最容易被忽略的三个检查点
策略配得再严,漏掉这些就可能白忙:
- 富文本渲染、模板引擎插值生成的 HTML 片段(比如 CMS 后台编辑器输出),是否也带了 CSP 响应头?iframe、Worker、fetch 返回的 HTML 不继承父页策略
-
base-uri 'self'、form-action 'self'、object-src 'none'这些指令没显式写,攻击者就能用<base href="http://evil.com">劫持所有相对路径,或提交表单到钓鱼地址 - 开发期用
Content-Security-Policy-Report-Only+report-uri观测违规日志,但上线后忘了切回强制模式——只上报不拦截,等于没防
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











