利用JSONP绕过CSP:JSONPeek与CSP B Gone工具详解

本文深入解析如何利用JSONP端点绕过内容安全策略(CSP),详细介绍JSONPeek检测工具与CSP B Gone自动化绕过工具的工作原理及使用方法,帮助安全研究人员识别和利用CSP安全漏洞。

利用JSONP绕过CSP:引入JSONPeek和CSP B Gone

| Jack Hyland

Jack Hyland自大学毕业后一直从事信息安全领域工作,并利用空闲时间深入学习新技术。他现在主要从事开源项目创建和贡献,同时执行企业网络和基础设施的安全评估。

内容安全策略基础

内容安全策略(CSP)是由Web服务器实现并由浏览器执行的安全机制,主要用于防止各种类型的攻击,特别是跨站脚本(XSS)攻击。CSP通过限制网页上的资源(脚本、样式表、图像等)只能从批准的来源执行来工作。然而,与安全领域的大多数事物一样,CSP并非无懈可击。我们将探讨CSP最常见的弱点之一——JSONP端点,并介绍两种供安全研究人员识别和利用CSP弱点的新工具。

内容安全策略可以通过两种方式应用:

HTTP头

1
Content-Security-Policy: script-src *.example.com

HTML文档中的元标签

1
<meta http-equiv="Content-Security-Policy" content="script-src *.example.com">

内容安全策略具有多个指令,允许对各种互联网资源进行精细控制。在本博客中,我们将主要关注下面列出的两个指令,因为它们与JSONP相关。

  • default-src:为其他指令设置回退
  • script-src:控制JavaScript来源

JSONP技巧

JSONP代表"带填充的JSON"。这个名字意义不大,但它是开发人员用来从不同来源加载带有任意JavaScript资源的技巧。这个技巧利用了脚本标签的source属性可以指向和使用跨域资源而不会被同源策略阻止的事实。

为了向您证明这一点,下面的简单HTML文件尝试获取google.com,但被浏览器阻止。开发者控制台确认请求被阻止,因为Google没有返回跨源资源共享(CORS)头来放宽同源策略(SOP)。

1
2
3
4
5
<html>
    <script>
    	    fetch("https://google.com/ ");
    </script>
</html>

跨源资源共享错误

如果我们修改HTML页面,使用<script>标签的src属性请求google.com,我们不再看到CORS错误,请求成功,由200 OK HTTP响应代码指示。这是浏览器的预期功能,因为在Web开发中从其他域包含静态JavaScript文件很常见。

1
2
3
<html>
    <script src="https://google.com/"></script>
</html>

跨源请求成功

现在,如果我们配置一个Web服务器来接受动态更改返回的JavaScript的GET参数呢?这就是JSONP端点的工作方式。如下所示,google.com在/complete/search有一个JSONP端点,我们可以修改jsonp GET参数来包含任意JavaScript。返回的内容类型是text/javascript,如果被脚本标签引用,它将被执行。

Google JSONP端点的HTTP请求和响应

JSONP如何绕过CSP?

配置了严格CSP只允许从google.com加载脚本的网站在初看时似乎相当安全。

1
"script-src https://google.com/;"

此策略阻止内联脚本标签执行,甚至不允许来自同一源的JavaScript文件!但是,如果google.com托管任何JSONP端点,CSP对XSS不提供任何保护。下面的简单HTML文件使用上面的CSP。然后它尝试从example.com加载JavaScript资源,然后从当前源加载/test.js,最后加载google.com上的JSONP端点,其中jsonp参数中包含alert()有效负载。

1
2
3
4
5
6
<html>
    <meta http-equiv="Content-Security-Policy" content="script-src https://google.com/;">
    <script src="https://example.com/"></script>
    <script src="/test.js"></script>
    <script src="https://google.com/complete/search?client=chrome&jsonp=alert(`CSP-BYPASS`)"></script>
</html>

如下所示,前两个资源请求被强大的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扩展并单击利用按钮来试用它。

1
https://www.w3schools.com/js/tryit.asp?filename=tryjson_jsonp_callback

结果表应在每个测试的回调URL旁边有绿色复选标记。只需一个绿色复选标记即可成功绕过。恭喜,您发现了一个JSONP端点!

JSONP利用页面结果

众包JSONP端点

JSONP端点可以在网站的任何地方,这使得它们难以找到。为了解决这个问题,我使用BigQuery5在Internet Archive6中搜索包含潜在JSONP参数的请求,使用以下GoogleSQL脚本:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
SELECT
  REGEXP_EXTRACT(req_host, r'([^\.]+\.[^\.]+)$') as req_domain,
  MAX(url) as url,
FROM 
  `httparchive.summary_requests.2024_10_01_desktop` requests
WHERE
  type IN ('script', 'json', 'html')
AND
  REGEXP_CONTAINS(url, r'callback=|jsonpCallback=|jsonp=|callback_func=|func=|handler=|jsonp_handler=|cbfn=|onload=|j=|oncomplete=')
GROUP BY req_domain

查询返回了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/ ↩︎

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计