csp 通过阻断不安全执行通道和限定可信脚本来源防御 xss,需禁用 'unsafe-inline' 与 'unsafe-eval',仅允许 'self' 或显式 cdn 加载脚本,并配合 nonce、事件监听器迁移及 dompurify 清洗,上线前须用 report-only 模式验证。

CSP 本身不“防御”XSS 漏洞的产生,而是大幅降低已注入的恶意脚本被执行的可能性。关键在于切断不安全的执行通道,并强制脚本来源可信。
必须禁用不安全的执行方式
内联脚本和动态代码执行是 XSS 利用最直接的路径,CSP 必须明确阻断:
-
移除 'unsafe-inline':所有
<script>...</script>和内联事件(如onclick="...")将被浏览器拒绝 -
移除 'unsafe-eval':
eval()、setTimeout(string)、setInterval(string)、Function(string)全部失效 - 哪怕只保留其中一个,核心防护就形同虚设——攻击者可轻易绕过
严格限定脚本加载来源
仅允许脚本从预设的可信地址加载,杜绝外部注入执行:
- 至少包含 'self':确保自有域名下的 JS 文件可加载
-
显式列出第三方 CDN:如
https://cdn.example.com,不能简写为example.com -
避免宽泛通配符:不用
*或http:,防止意外引入不可信资源
适配常见开发场景
直接删除 unsafe-inline 后页面白屏?说明代码依赖未迁移。需同步调整:
-
内联事件改监听器:把
<button onclick="do()"></button>改为element.addEventListener('click', do) -
富文本渲染加清洗:对
v-html或dangerouslySetInnerHTML的内容,先用 DOMPurify 过滤 -
需要内联逻辑时用 nonce:后端每次响应生成唯一值,写入
<script nonce="abc"></script>并配script-src 'nonce-abc'
验证与上线前关键检查
策略写完不等于生效,务必确认实际运行环境符合要求:
-
必须走 HTTP/S 协议:
file://下 Chrome/Firefox 完全忽略 CSP -
优先用 HTTP 响应头:
Content-Security-Policy头比<meta>更完整(支持report-to、frame-ancestors等) -
先用 Report-Only 模式灰度:部署
Content-Security-Policy-Report-Only头收集违规日志 1–3 天,再切到强制模式










