CSP是构建XSS防御最底层、最有效的手段,通过HTTP响应头硬隔离恶意脚本执行;它不防注入而防执行,需配合输入过滤与输出编码;基础策略禁用内联与eval,推荐nonce机制实现可控内联,并覆盖iframe、object、report等加固点。

直接通过 add_header Content-Security-Policy 设置 HTTP 响应头,是构建前端 XSS 防御屏障最有效、最底层的手段之一。它不依赖 JavaScript 运行时逻辑,也不受前端代码篡改影响,浏览器在解析 HTML 前就按策略执行拦截,属于“硬隔离”式防护。
核心作用:阻止恶意脚本执行
CSP 不过滤输入,也不清理 HTML,而是明确告诉浏览器:“哪些资源允许加载、哪些脚本允许执行、哪些内联行为一律禁止”。哪怕攻击者成功注入了 <script>alert(1)</script> 或 <img onerror="fetch('/steal?c='+document.cookie)" alt="如何通过 add_header Content-Security-Policy 构建前端防御 XSS 攻击屏障" >,只要不符合 CSP 规则,浏览器就不会执行。
关键点在于:CSP 是防御“执行”,不是防御“注入”。所以它必须和输入过滤、输出编码等其他手段配合,但它是最后一道不可绕过的铁闸。
基础配置:禁用内联与 eval
绝大多数 XSS 攻击依赖内联脚本(<script>...</script>、onclick=...)或动态执行(eval()、new Function())。一个强效的起步策略是:
立即学习“前端免费学习笔记(深入)”;
前端设计与 UI/UX 全方位优化专家。覆盖视觉层次、排版系统、色彩理论、响应式布局、交互体验、动画动效、无障碍访问、性能优化八大维度,帮助开发者将普通页面升级为高品质产品级界面。前端设计与 UI/UX 全方位优化专家。覆盖视觉层次、排版系统、色彩理论、响应式布局、交互体验、动画动效、无障碍访问、性能优化八大维度,帮助开发者将普通页面升级为高品质产品级界面。
-
禁止所有内联脚本和样式:用
'unsafe-inline'的反向逻辑——默认不允许,只通过nonce或hash显式放行可信内联 -
禁止
eval类函数:添加'unsafe-eval'到禁止列表(即不写它,或显式写script-src 'none') -
限制脚本仅来自自身域名:用
script-src 'self',拒绝从 CDN、第三方域名加载任意 JS
示例 Nginx 配置:
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'nonce-abc123'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; base-uri 'self'; form-action 'self';";进阶实践:用 nonce 实现可控内联
完全禁用内联虽安全,但会破坏部分合法场景(如服务端渲染的初始化脚本)。推荐方案是使用一次性随机值 nonce:
- 后端每次响应生成唯一 base64 编码字符串,例如
abc123 - 将该值写入响应头:
Content-Security-Policy: script-src 'nonce-abc123' - 同时在 HTML 中给可信内联脚本加上匹配的
nonce属性:<script nonce="abc123">initApp();</script> - 浏览器只执行带正确 nonce 的内联脚本,其余全部静默丢弃
这种方式既保留灵活性,又杜绝了攻击者伪造 nonce 的可能(因为攻击者无法读取响应头中的值)。
补充加固:覆盖常见攻击入口
除脚本外,XSS 还常利用其他载体。CSP 可一并约束:
-
禁止
javascript:伪协议:在script-src和default-src中不包含data:或javascript: -
限制 iframe 嵌入来源:用
frame-src 'none'或严格白名单,防点击劫持与沙箱逃逸 -
禁用插件与不安全对象:添加
object-src 'none',阻止 Flash、Java 等老旧插件加载 -
启用报告机制:追加
report-uri /csp-report或report-to,收集违规行为用于审计与调优
注意:避免使用 unsafe-inline 或 unsafe-eval,除非你有绝对可控且不可降级的运维能力;也不建议仅靠 script-src https: 开放全网 HTTPS 脚本——这等于放弃控制权。

















