Ajax调用响应如'for(;;); {json data}'是什么意思?

时间:2011-06-14 06:20:07

标签: ajax json facebook

  

可能重复:
  Why do people put code like “throw 1; <dont be evil>” and “for(;;);” in front of json responses?

我发现这种语法在Facebook上用于Ajax调用。我在回答开始的for (;;);部分感到困惑。它用于什么?

这是电话和回复:

GET http://0.131.channel.facebook.com/x/1476579705/51033089/false/p_1524926084=0

响应:

for (;;);{"t":"continue"}

5 个答案:

答案 0 :(得分:157)

我怀疑它存在控制的主要原因。它强制你通过Ajax检索数据,而不是通过JSON-P或类似的(使用script标签),因此会失败因为for循环是无限的),从而确保Same Origin Policy启动。这使他们可以控制哪些文档可以向API发出调用 - 具体来说,只有与API调用具有相同来源的文档,或者Facebook专门授予访问权限的文档{ {3}}(在支持CORS的浏览器上)。因此,您必须通过浏览器强制执行SOP的机制来请求数据,并且您必须知道该前言并在反序列化数据之前将其删除。

所以是的,它是关于控制(有用)访问该数据的。

答案 1 :(得分:105)

Facebook有很多开发人员在很多项目上进行内部工作,有人犯了一个小错误是很常见的。是否像简单而严重的那样简单而严重,无法将数据插入到HTML或SQL模板中,或者像使用eval(有时效率低,可以说是不安全)或JSON.parse那样复杂和微妙(符合条件但是不是普遍实现的扩展)而不是“已知良好”的JSON解码器,重要的是找出方法来轻松地对这个开发人员实施最佳实践。

为了应对这一挑战,Facebook最近一直在“全力以赴”内部项目,旨在优雅地执行这些最佳实践,说实话,对于这个具体案例真正有意义的唯一解释就是:有人内部决定所有JSON解析都应该通过其核心库中的单个实现,并且强制执行该操作的最佳方法是在每个API响应中自动添加for(;;);

这样做,开发人员不能“懒惰”:他们会注意立即如果他们使用eval(),想知道是什么,然后意识到他们的错误并使用已批准的JSON API。

提供的其他答案似乎都属于以下两类之一:

  1. 误解了JSONP,或
  2. 误解“JSON劫持”。
  3. 第一类中的人依赖于攻击者能够以某种方式向不支持它的API“使用JSONP”发出请求的想法。 JSONP是服务器和客户端都必须支持的协议:它要求服务器返回类似于myFunction({"t":"continue"})的内容,以便将结果传递给本地函数。你不能只是偶然“使用JSONP”。

    第二类中的那些人引用了一个非常真实的漏洞,该漏洞已被描述为允许通过标签对使用JSONP(例如此)的API进行跨站请求伪造,允许“JSON劫持”的形式。这是通过更改Array / Object构造函数来完成的,它允许用户在没有包装函数的情况下访问从服务器返回的信息。

    然而,在这种情况下根本不可能:它完全起作用的原因是裸阵列(许多JSON API的一种可能结果,例如着名的Gmail示例)是一个有效的表达式语句,它不是对于一个裸体来说是真实的。

    实际上,JSON定义的对象的语法(包括字段名称周围的引号,如本例所示)与块的语法冲突,因此不能在脚本的顶层使用。

    js> {"t":"continue"}
    typein:2: SyntaxError: invalid label:
    typein:2: {"t":"continue"}
    typein:2: ....^
    

    为了通过Object()构造函数重映射可以利用这个例子,它需要API在一组括号内返回对象,使其成为有效的JavaScript(但后来不是有效的JSON)。 p>

    js> ({"t":"continue"})
    [object Object]
    

    现在,可能是这个for(;;);前缀技巧只是“意外地”出现在这个例子中,并且实际上是由返回数组的其他内部Facebook API返回的;但是在这种情况下应该注意,因为那将是for(;;);出现在这个特定片段中的“真正”原因。

答案 2 :(得分:44)

for(;;);是一个无限循环(如果需要,您可以使用Chrome的JavaScript控制台在选项卡中运行该代码,然后在任务管理器中查看CPU使用情况直至浏览器杀死标签)。

所以我怀疑可能是因为它被用来阻止任何试图使用eval或任何其他执行返回数据的技术来解析响应的人。

为了进一步解释,通过使用JavaScript的eval()函数解析一些JSON格式的数据,通过以下方式执行以下操作相当普遍:

var parsedJson = eval('(' + jsonString + ')');

...这被认为是不安全的,但是,好像由于某种原因,您的JSON格式的数据包含可执行的JavaScript代码而不是(或除了)JSON格式的数据,那么该代码将由{{1 }}。这意味着,如果您正在与不受信任的服务器通信,或者有人危及受信任的服务器,那么他们可以在您的页面上运行任意代码。

因此,使用诸如eval()之类的东西来解析JSON格式的数据通常是不受欢迎的,而Facebook JSON中的eval()语句将阻止人们以这种方式解析数据。任何尝试的人都将获得无限循环。从本质上讲,就像Facebook试图强制人们使用其API一样,不会让他们容易受到试图劫持Facebook API用作矢量的未来漏洞的攻击。<​​/ p>

答案 3 :(得分:16)

我有点迟了T.J.基本上已经解开了这个谜团,但我想我会就这一特定主题分享一篇很好的论文,这篇论文有很好的例子,可以更深入地了解这种机制。

这些无限循环是对抗“Javascript劫持”的对策,这种攻击通过Jeremiah Grossman发布的对Gmail的攻击而引起公众注意。

这个想法就像美丽一样简单:许多用户倾向于永久登录Gmail或Facebook。所以你要做的就是设置一个站点并在恶意站点的Javascript中覆盖对象或数组构造函数:

function Object() {
    //Make an Ajax request to your malicious site exposing the object data
}

然后在该网站中添加<script>标记,例如

<script src="http://www.example.com/object.json"></script>

最后,您可以阅读恶意服务器日志中的所有JSON对象。

按照承诺,指向paper的链接。

答案 4 :(得分:13)

这看起来像是防止 CSRF 攻击的黑客攻击。有特定于浏览器的方法可以挂钩对象创建,因此恶意网站可以先使用,然后执行以下操作:

<script src="http://0.131.channel.facebook.com/x/1476579705/51033089/false/p_1524926084=0" />

如果在JSON之前没有无限循环,则会创建一个对象,因为JSON可以{j} eval() ed ,并且钩子会检测到它并嗅探对象成员。

现在,如果您从浏览器访问该网站,在登录Facebook时,它可以像您一样获取您的数据,然后通过例如AJAX或javascript帖子将其发送回自己的服务器。