JSONP存在的JSON Hijacking漏洞以及与csrf/xss漏洞的关

页面导航:首页 > 网络编程 > JavaScript > JSONP存在的JSON Hijacking漏洞以及与csrf/xss漏洞的关

JSONP存在的JSON Hijacking漏洞以及与csrf/xss漏洞的关

来源: 作者: 时间:2016-02-03 09:20 【

在实习过程中接触过所谓的JSON Hijacking 漏洞,但最近在写论文时发现理解得不深,好像跟xss与csrf又有点区别与联系,索性深入学习了下JSONP(JSON with Padding)。下面一段话截取自:www 2

在实习过程中接触过所谓的JSON Hijacking ,但最近在写论文时发现理解得不深,好像跟xss与csrf又有点区别与联系,索

性深入学习了下JSONP(JSON with Padding)。

 

下面一段话截取自:www.2cto.com仔细看看就比较清晰了。

 

Say you're on domain abc.com, and you want to make a request to domain xyz.com. To do so, you need to cross domain boundaries, a no-no in most of browserland.

The one item that bypasses this limitation is <script> tags. When you use a script tag, the domain limitation is ignored, but under normal circumstances, you can't really DO anything with the results, the script just gets evaluated.

|r|

|r| Enter JSONP. When you make your request to a server that is JSONP enabled, you pass a special parameter that tells the server a little bit about your page. That way, the server is able to nicely wrap up its response in a way that your page can handle.

|r|

|r| For example, say the server expects a parameter called callback to enable its JSONP capabilities. Then your request would look like:

|r|
http://www.xyz.com/sample.aspx?callback=mycallback|r|
|r|

|r| Without JSONP, this might return some basic JavaScript object, like so:

|r|
{ foo: 'bar' }|r|
|r|

|r| However, with JSONP, when the server receives the callback parameter, it wraps up the result a little differently, returning something like this:

|r|
mycallback({ foo: 'bar' });|r|
|r|

|r| As you can see, it will now invoke the method you specified. So, in your page, you define the callback function:

|r|
mycallback = function(data){|r|
  alert(data.foo);|r|
};|r|
|r|

|r| And now, when the script is loaded, it'll be evaluated, and your function will be executed. Voila, cross-domain requests!

|r|


|r|

|r|

大概解释一下。举例:在abc.com 有这么一段 <script src=http://www.xyz.com/sample.aspx?callback=mycallback></script>

在 xyz.com 的 sample.aspx 可能是如下实现的:

 

 

PHP Code
1
2
3
4
5
6
  header('Content-Type:text/html;charset=utf-8');
$callback = $_GET['callback'];
$data = {foo: 'bar'};
echo $callback . ( . $data . );;
?>

 

src 标签请求返回即 <script> mycallback({foo: 'bar'});</script>也就是会执行函数mycallback,这里需要明确的是mycallback 肯定是在

abc.com 上实现的,把 {foo: 'bar' } 作为参数传递,以便下一步操作。callback只是个key,也可以写成jsonp,当然server获取的key也得变换。

 

讲到这里,对于正常的请求,jsonp并没有什么安全问题。但是,对于一些在登陆态会暴露敏感信息如用户id和昵称的cgi来说,我们直接用访问

www.2cto.com虽然我们并没有实现loginInfoCallback ,但如上所述,server端会返

回 loginInfoCallback({ret:-1102321,data:{_id:1032412,_nick:jnusimba}}); 当然这是在 jnusimba 在浏览器的另一个tab已经登录过 a.com 的情

形下。所以攻击的手法是 在第三方站点通过“<script|r| src=http://www.a.com/json.php?mod=pay&func=openvip&callback=loginInfoCallback></script>”

的形式就可以在函数loginInfoCallback 参数里面取得当前用户的id号和昵称。

 

上述讲到的JSON Hijacking 漏洞可以认为是 csrf漏洞的一种,也就是 csrf 写-读 。基本原理还是因为浏览器的会话机制在第三方站点请求 a.com 时

也会把a.com 相关的cookie 发送出去。防御来说,校验refer/ 请求带上form token 都是比较好的办法,也就是带有第三方无法预测的值。

 

对于上面server端的php代码来说,返回 {foo: 'bar'} 没有带有登陆态信息,故没有什么实质的风险。但不知道有人注意到没有,它返回的头部

Content-Type:text/; 即类型设置错误了,应该是content-type:text/javascript; 设置成html格式,容易造成xss攻击,比如callback=

<script>alert('aaa')</script>,即浏览器会弹框(注意,在高版本的ie和chrome下面可能已经限制了xss攻击,测试在firefox下查看即可)。

如下面的例子是前10来天写论文时挖到的一个youku站点因为jsonp产生的反射xss漏洞,今天再次访问已经被修复了,可我找不到当初哥提交乌云的链

接了哭~。

 

如果大家想玩一玩,可以看 http://lorrylockie.github.io/2015/01/27/jsonp-safe/ 这里的一个例子,如下图:

访问链接 http://login.koudai.com/weidian/sendCodeToBuyerPhone?param=%20{%22telephone%22:%2218601662827%22,%22country_code%22:%2286%22}&callback=%3Cscript%3Ealert%28/xxs/%29;%3C/script%3E%3Cdiv%20style=%22font-size:100px;%22%3EKOU%20DAI%20TONG%20DA%20SHA%20B%3C/div%3E&ver=1031

注:搞安全的需要职业素养,原po主已经提交给乌云以及口袋通方面了,没修就不是白帽子的责任了,当然大家也别去恶搞呀。

 

data-cke-saved-src=/uploads/allimg/c160203/145446220V60-21041.jpg

 

可以看到响应头是html,故造成了xss攻击,查看网页源代码以及点击确定后的浏览器输出:

data-cke-saved-src=/uploads/allimg/c160203/145446220c40-35C9.jpg

data-cke-saved-src=/uploads/allimg/c160203/1454462210520-43953.jpg

从中也可以验证我们上面所说关于jsonp的应用,比如 正常的请求访问 http://login.koudai.com/weidian/sendCodeToBuyerPhone?param=%20{%22telephone%22:%2218601662827%22,%22country_code%22:%2286%22}&callback=mycallback&ver=1031

可以猜想 输入的telephone值在server端进行验证,用返回的status_code表示是否有效,进而作为mycallback的参数进行下一步操

作,比如正确则发送验证码之类。如果我们把号码换成18601662826 进行访问,返回的是

mycallback({status:{status_code:0,status_reason:}}) 基于猜想,我认为这个号码是真实存在的哈。

 

对于此类由jsonp引起的反射xss漏洞,一来响应头应该设置正确;二来应该对callback参数进行过滤或者编码,避免可以直接执行js。

 

 

Tags:

文章评论

最 近 更 新
热 点 排 行
Js与CSS工具
代码转换工具

<