您的位置:首页 > Web前端 > JavaScript

JSON并没有人们想象中的那样安全

2011-12-22 19:04 495 查看
原文:http://getahead.org/blog/joe/2007/03/05/json_is_not_as_safe_as_people_think_it_is.html

作者:Joe Walker

译者:Tony Qu

我最近看到过一些有关把JSON用于保密数据的讨论,而且我也不是很清楚有多少人了解其中的风险。

我个人认为JSON只能用于可公开的数据,其他数据都不能使用JSON,除非你使用的URL无法预测,JSON才是安全的。

这里有两个问题。一个是CSRF(Cross Site Request Forgery,跨站点伪造请求攻击),它允许攻击者绕过基于cookie的身份认证,前些天我曾在Blog上介绍过这种攻击。另外,维基百科也说到了这个东西,你可以用CSRF在一个远程服务器上调用由cookie保护着的数据。“恶魔“先生可以利用这项技术把“无辜”女士的银行账号里的钱转到他的账户中。

还有一种则鲜为人知,那就是JSON/数组攻击,这可以让某个用户在Mozilla上偷取JSON数据,其实只要是任何使用当代的JavaScript解释器的平台都会都可以实施该攻击。

更新:不单单可以从Array偷数据,还可以从Object偷

有很多种从一个服务器获得数据的方法,但这其中比较有趣的是XHR、iframe、脚本标签。如果不了解 JSON/数组 攻击,那很容易产生如下的结论:

XHR:浏览器跨域规则一开始就阻止了攻击者发出请求

iframe:攻击者可以嵌入一个指向一些远程服务器的iframe(在上面的例子中这个远程服务器就是银行的服务器),并用它来发送一些JSON,但是浏览器跨域规则阻止了来自攻击者所在域的脚本,这段脚本是用来读取响应的,因此这个JSON是安全的,因为它从来没有被eval过。

脚本标签:攻击者会嵌入一个指向远程服务器的脚本标签,而浏览器会把你的回复eval一把,然后浏览器会丢弃响应,这个JSON就是全部的相应,所以这是安全的。

这些参数的最后一个值得怀疑,JavaScript的动态特性将允许你重新浏览器对JSON赋值的方式。

下面是它的工作原理,你可以用任何JavaScript控制台跟踪这段代码:

1. 重新定义Array构造器

function Array() { alert("hi"); }

2. 验证一下在创建数组时,这个构造器是否被调用

var a = [ 43 ];

3. 使用新功能修改这个数组

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->function Array() {

this[1] = 50;

}

var a = [40];

alert(a[0] + a[1]); //结果是90

所以我们能用一个script标签来调用保密的JSON数据,使用CSRF绕过cookie身份认证,然后用JSON/数组攻击在浏览器处理那个script标签时偷取JavaScript数据。

因此我们重新定义了Array构造器,实际情况下我们如何获得数据呢?下面的语法在当前版本的FireFox运行正常,虽然在我的知识范围内,这并不是JavaScript2标准的一部分,但是这段代码无法在IE/Safari/Opera下顺利运行。

在evil.com创建一个网页,用下面这段script标签:

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--><script type='text/javascript'>

function Array() {

var obj = this;

var ind = 0;

var getNext = function(x) {

obj[ind++] setter = getNext;

if (x) alert(Data stolen from array: " + x.toString());

};

this[ind++] setter = getNext;

}

</script>

<script type='text/javascript' src='http://bank.com/jsonservice'> </script>

出于演示目的,我已经重新定义了这个页面中的Array构造器,如果你在Firefox上,你将看到一个alert窗口。(译者注:演示示例请见原文)。

(如果你在blog聚集器中读取这个例子,上面的脚本会被过滤掉,所以它无法正常工作。你可以试一下这个页面,如果这段脚本没有被过滤掉,那我建议你马上更换一个新的聚合器,因为它有很严重的安全问题。)

总之一句话:JSON在使用cookie来做身份认证的任何系统上都不安全。

有了DWR,虽然我们使用的是纯JavaScript它与JSON一样脆弱,但是DWR的CSRF保护能自动使用双重提交cookie模式来提供额外的保护。

我并不是提出这个问题的第一个人,Jeremiah Grossman在一年前用它黑了GMail
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: