利用JSONP绕过CSP:引入JSONPeek和CSP B Gone
| Jack Hyland
Jack Hyland自大学毕业后一直从事信息安全领域工作,并利用空闲时间深入学习新技术。他现在主要从事开源项目创建和贡献,同时执行企业网络和基础设施的安全评估。
内容安全策略基础
内容安全策略(CSP)是由Web服务器实现并由浏览器执行的安全机制,主要用于防止各种类型的攻击,特别是跨站脚本(XSS)攻击。CSP通过限制网页上的资源(脚本、样式表、图像等)只能从批准的来源执行来工作。然而,与安全领域的大多数事物一样,CSP并非无懈可击。我们将探讨CSP最常见的弱点之一——JSONP端点,并介绍两种供安全研究人员识别和利用CSP弱点的新工具。
内容安全策略可以通过两种方式应用:
HTTP头
|
|
HTML文档中的元标签
|
|
内容安全策略具有多个指令,允许对各种互联网资源进行精细控制。在本博客中,我们将主要关注下面列出的两个指令,因为它们与JSONP相关。
default-src
:为其他指令设置回退script-src
:控制JavaScript来源
JSONP技巧
JSONP代表"带填充的JSON"。这个名字意义不大,但它是开发人员用来从不同来源加载带有任意JavaScript资源的技巧。这个技巧利用了脚本标签的source属性可以指向和使用跨域资源而不会被同源策略阻止的事实。
为了向您证明这一点,下面的简单HTML文件尝试获取google.com,但被浏览器阻止。开发者控制台确认请求被阻止,因为Google没有返回跨源资源共享(CORS)头来放宽同源策略(SOP)。
|
|
跨源资源共享错误
如果我们修改HTML页面,使用<script>
标签的src属性请求google.com,我们不再看到CORS错误,请求成功,由200 OK HTTP响应代码指示。这是浏览器的预期功能,因为在Web开发中从其他域包含静态JavaScript文件很常见。
|
|
跨源请求成功
现在,如果我们配置一个Web服务器来接受动态更改返回的JavaScript的GET参数呢?这就是JSONP端点的工作方式。如下所示,google.com在/complete/search有一个JSONP端点,我们可以修改jsonp GET参数来包含任意JavaScript。返回的内容类型是text/javascript,如果被脚本标签引用,它将被执行。
Google JSONP端点的HTTP请求和响应
JSONP如何绕过CSP?
配置了严格CSP只允许从google.com加载脚本的网站在初看时似乎相当安全。
|
|
此策略阻止内联脚本标签执行,甚至不允许来自同一源的JavaScript文件!但是,如果google.com托管任何JSONP端点,CSP对XSS不提供任何保护。下面的简单HTML文件使用上面的CSP。然后它尝试从example.com加载JavaScript资源,然后从当前源加载/test.js,最后加载google.com上的JSONP端点,其中jsonp参数中包含alert()有效负载。
|
|
如下所示,前两个资源请求被强大的CSP阻止,但第三个成功并允许我们执行任意JavaScript。
通过Google JSONP端点绕过内容安全策略
当网站的CSP允许来自托管JSONP端点的域的脚本时,这些端点成为CSP绕过的向量。
使用JSONPeek检测JSONP端点
希望您现在了解如何利用JSONP端点绕过网站的内容安全策略并实现跨站脚本。但是您究竟应该如何找到这些端点?
不幸的是,没有完美的方法来指纹识别这些端点,但它们通常使用独特的参数名称1,我们可以在HTTP请求中寻找这些参数。手动执行此操作很繁琐,因此我编写了一个简单的Firefox扩展程序JSONPeek2,用于观察页面发出的请求,并查找包含JSONP回调参数的请求。
JSONPeek浏览器扩展
为了验证可疑端点是否使用JSONP,扩展中有一个利用按钮,将URL提交到一个特殊网页。我设置了一些花哨的钩子3,页面将使用多个有效负载检查提交的URL,尝试触发alert()函数,并在表中更新结果。
JSONPeek.com成功触发
安装JSONPeek扩展4后,您可以通过浏览到下面的URL,打开JSONPeek扩展并单击利用按钮来试用它。
|
|
结果表应在每个测试的回调URL旁边有绿色复选标记。只需一个绿色复选标记即可成功绕过。恭喜,您发现了一个JSONP端点!
JSONP利用页面结果
众包JSONP端点
JSONP端点可以在网站的任何地方,这使得它们难以找到。为了解决这个问题,我使用BigQuery5在Internet Archive6中搜索包含潜在JSONP参数的请求,使用以下GoogleSQL脚本:
|
|
查询返回了10,000多个结果,需要单独测试误报。我不会详细介绍我是如何做到的,因为这本身可能是一篇博客,但它涉及多个Python脚本和创建一个在无头Chrome实例中钩住alert()函数的测试工具。此过程的结果将10,000个端点过滤到仅2,000多个真正阳性。我将结果输出到数据集7,并将其与Renniepak8管理的那个合并。
使用CSP B Gone自动化CSP绕过
现在我们有了一个大的CSP绕过数据集,我想要一个浏览器扩展来自动告诉我网站何时有易受攻击的CSP以及如何绕过它。为了实现这一点,我创建了CSP B Gone9,这是一个由全面的JSONP端点数据集驱动的Firefox扩展。此扩展自动分析您当前站点的内容安全策略,识别数据库中是否存在任何绕过,并生成即用型概念验证有效负载。
下图显示了CSP B Gone的实际操作,提供概念验证有效负载以绕过facebook.com上的内容安全策略。只需复制有效负载并将其插入您发现XSS漏洞的任何位置。
CSP B Gone对Facebook的CSP绕过
结束语
希望这篇博客有助于阐明JSONP是什么、如何使用以及它经常被滥用的方式。使用提供的两个扩展JSONPeek和CSP B Gone,您应该能够被动扫描网站以查找JSONP端点并发现CSP绕过。这远非绕过CSP的唯一方法,但它是最有效的方法之一。
最后,我要感谢cspbypass.com的创建者Renniepak10,他的工作启发了这项研究。他们愿意分享见解并回答我的问题是无价的。
脚注
1 https://github.com/ACK-J/JSONPeek/blob/c4d1f22aad47aee1b87581f207080d41354584f0/popup.js#L7-L10 ↩︎ 2 https://addons.mozilla.org/en-US/firefox/addon/jsonpeek/ ↩︎ 3 https://github.com/ACK-J/JSONPeek/blob/ ↩︎ 4 https://addons.mozilla.org/en-US/firefox/addon/jsonpeek/ ↩︎ 5 https://cloud.google.com/bigquery ↩︎ 6 https://archive.org/ ↩︎ 7 https://github.com/ACK-J/CSP-B-Gone/blob/main/data.tsv ↩︎ 8 https://github.com/renniepak/CSPBypass/blob/main/data.tsv ↩︎ 9 https://addons.mozilla.org/en-US/firefox/addon/csp-b-gone/ ↩︎ 10 https://github.com/renniepak/ ↩︎