JSONP劫持漏洞
JSONP的介绍
JSONP(JSON with Padding)是JSON的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题。由于同源策略,一般来说位于 server1.example.com 的网页无法与不是 server1.example.com的服务器沟通,而 HTML 的<script> 元素是一个例外。利用 <script> 元素的这个开放策略,网页可以得到从其他来源动态产生的 JSON 资料,而这种使用模式就是所谓的 JSONP。用 JSONP 抓到的资料并不是 JSON,而是任意的JavaScript,用 JavaScript 直译器执行而不是用 JSON 解析器解析。
有关JSONP的产生与实现推荐参考下面这篇文章,讲的非常清楚易懂:
JSONP劫持
JSON 劫持又为“ JSON Hijacking ”,最开始提出这个概念大概是在 2008 年国外有安全研究人员提到这个 JSONP 带来的风险。其实这个问题属于 CSRF( Cross-site request forgery 跨站请求伪造)攻击范畴。当某网站听过 JSONP 的方式来快域(一般为子域)传递用户认证后的敏感信息时,攻击者可以构造恶意的 JSONP 调用页面,诱导被攻击者访问来达到截取用户敏感信息的目的。
JSONP劫持的攻击过程有点类似于CSRF,只不过CSRF只管发送http请求,但是json-hijack的目的是获取敏感数据。

靶场演示
漏洞测试
我们基于DVWA靶场简单写了一个获取当前用户信息的接口。
源代码如下:
1 |
|
编写PoC文件,通过回调函数去请求用户信息:
1 | <script>function test(data){ alert(JSON.stringify(data)) }</script> |
访问PoC文件,页面会执行脚本,请求http://hackrock.com:812/vulnerabilities/jsonp/?callback=test,拿到的请求内容
然后将请求的内容作为参数,执行test函数,test函数将请求的内容alert出来。最终的结果如下

漏洞利用
修改一下PoC文件:
1 | <script>function test(data){ |
创建接收用户数据的文件
1 |
|
当用户点开恶意链接的时候,就可以自动获取用户的敏感数据了。
Tips:既然是窃取敏感信息,那么敏感信息除了一些 email 手机号 用户名等还有什么呢?没错,甚至可以是 CSRF Token 信息,有时候在 CSRF token 获取不到但是又找不到 XSS 的攻击点的时候不妨考虑一下 jsonp 劫持。
JSONP中的反射型XSS
由于callback参数可以自定义,所以就有了所有注入漏洞都有的通病:“输入在输出中回显”,其中导致的一个问题就是XSS,前提是返回包Content-Type:text/html而不是Content-Type: application/json。

从响应头中可以看到Content-Type字段的值为text/html,再加上源代码中并没有对callback这个输出点进行实体化编码或过滤,这就导致了反射型XSS。

防御方法:
- 严格定义Content-Type: application/json
- 对callback的值进行实体化编码或过滤
JSONP漏洞挖掘技巧
Google语法搜索jsonp接口
1 | site:target.com inurl:?callback |

在浏览器调试中寻找关键字
收集接口:找到返回数据格式是JSONP的接口(可以在数据包中检索关键词callback/json/jsonp/email/cb 等)

加参数看返回信息:加上callback参数,观察返回值是否变化,是否返回jsonp格式的信息

JSONP漏洞的防御
JSONP劫持属于CSRF的攻击范畴,所以解决的方法和解决CSRF的方法一样。
- 限制来源Referer
- 部署一次性 Token
- 严格安装 JSON 格式标准输出 Content-Type 及编码( Content-Type : application/json; charset=utf-8 ),预防XSS
- 过滤callback函数名与长度以及JSON数据输出,预防XSS