您现在的位置是:网站首页 > 使用 CSP(内容安全策略)防范 XSS文章详情
使用 CSP(内容安全策略)防范 XSS
陈川
【
前端安全
】
11659人已围观
3337字
XSS(跨站脚本攻击)是前端安全中最常见的威胁之一,攻击者通过注入恶意脚本窃取用户数据或破坏页面功能。CSP(内容安全策略)作为一种声明式机制,通过限制资源加载和执行来源,能有效降低XSS风险。以下是具体实现方法和实践细节。
CSP 的核心机制
CSP 通过 HTTP 响应头或 <meta>
标签定义资源加载规则,浏览器会强制执行这些策略。其核心逻辑是白名单机制,只有明确允许的来源才会被加载。例如:
Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.cdn.com
这条策略表示:
- 默认所有资源只能从当前域名加载(
'self'
) - 脚本仅允许来自当前域名和
https://trusted.cdn.com
关键指令详解
脚本控制指令
script-src
是最关键的指令,用于控制 JavaScript 执行来源:
'none'
完全禁止脚本'unsafe-inline'
允许内联脚本(会削弱防护)'unsafe-eval'
允许eval()
等动态执行- 哈希值或随机数可精确放行特定内联脚本
示例:允许特定内联脚本执行
<script nonce="EDNnf03nceIOfn39fn3e9h3sdfa">
console.log("这个脚本会被执行");
</script>
对应 CSP 头:
Content-Security-Policy: script-src 'nonce-EDNnf03nceIOfn39fn3e9h3sdfa'
其他资源指令
style-src
:控制 CSS 加载img-src
:限制图片来源connect-src
:限制 XHR/fetch 请求目标frame-src
:控制 iframe 嵌入font-src
:字体文件来源控制
防御 XSS 的具体实践
场景 1:彻底禁用内联脚本
最严格的策略配置:
Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self'
效果:
- 禁止所有内联脚本和事件处理器(如
onclick="alert(1)"
) - 禁止动态代码执行(如
eval()
) - 阻止非当前域的脚本加载
场景 2:渐进式迁移方案
对于遗留系统难以立即移除内联脚本的情况:
- 先启用报告模式:
Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-report
- 根据报告逐步修复问题
- 最终切换为强制执行模式
场景 3:第三方库集成
允许特定 CDN 的 React/Vue 等库:
Content-Security-Policy:
script-src 'self' https://unpkg.com/react@18/umd/react.production.min.js;
style-src 'self' 'unsafe-inline'
注意:现代框架通常需要 'unsafe-inline'
因其可能生成内联样式
高级防护技巧
随机数(Nonce)实现
每次页面请求生成唯一随机数:
// 服务器端生成
const nonce = crypto.randomBytes(16).toString('base64');
res.setHeader('Content-Security-Policy', `script-src 'nonce-${nonce}'`);
哈希(Hash)控制
对必须的内联脚本计算 SHA 哈希:
<script>alert('Allowed script');</script>
生成策略:
Content-Security-Policy: script-src 'sha256-qznLcsROx4GACP2dm0UCKCzCG+HiZ1guq6ZZDob/Tng='
严格动态(Strict-Dynamic)
现代 CSP 3.0 特性:
Content-Security-Policy: script-src 'nonce-abc123' 'strict-dynamic'
允许通过可信脚本动态加载的脚本执行
常见问题解决方案
问题 1:Google Analytics 被阻止
解决方案:
script-src 'self' https://www.google-analytics.com;
connect-src 'self' https://www.google-analytics.com
问题 2:Webpack 开发模式
开发环境特殊配置:
Content-Security-Policy:
script-src 'self' 'unsafe-eval';
style-src 'self' 'unsafe-inline'
问题 3:社交媒体插件
Twitter/Facebook 插件需要:
script-src 'self' https://platform.twitter.com https://connect.facebook.net;
frame-src https://platform.twitter.com https://www.facebook.com
监控与报告
违规报告配置
Content-Security-Policy:
default-src 'self';
report-uri https://your-api.com/csp-report;
report-to csp-endpoint
报告示例(JSON 格式):
{
"csp-report": {
"document-uri": "https://example.com/login",
"violated-directive": "script-src 'self'",
"blocked-uri": "https://evil.com/xss.js",
"line-number": 15
}
}
实时监控方案
- 将报告发送至 SIEM 系统(如 Splunk)
- 设置阈值告警(如 1 小时内超过 50 次违规)
- 分析攻击模式并调整策略
CSP 的局限性
- 不防护 DOM 型 XSS:通过
location.hash
等 DOM 操作的攻击需要其他措施 - 配置复杂性:过度严格可能破坏正常功能
- 浏览器兼容性:部分旧版本浏览器支持不完整
补充方案示例(DOM XSS 防护):
// 净化用户输入
function sanitize(input) {
const div = document.createElement('div');
div.textContent = input;
return div.innerHTML;
}