可能重复:
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"}
答案 0 :(得分:157)
我怀疑它存在控制的主要原因。它强制你通过Ajax检索数据,而不是通过JSON-P或类似的(使用script
标签),因此会失败因为for
循环是无限的),从而确保Same Origin Policy启动。这使他们可以控制哪些文档可以向API发出调用 - 具体来说,只有与API调用具有相同来源的文档,或者Facebook专门授予访问权限的文档{ {3}}(在支持CORS的浏览器上)。因此,您必须通过浏览器强制执行SOP的机制来请求数据,并且您必须知道该前言并在反序列化数据之前将其删除。
所以是的,它是关于控制(有用)访问该数据的。
答案 1 :(得分:105)
eval
(有时效率低,可以说是不安全)或JSON.parse
那样复杂和微妙(符合条件但是不是普遍实现的扩展)而不是“已知良好”的JSON解码器,重要的是找出方法来轻松地对这个开发人员实施最佳实践。
为了应对这一挑战,Facebook最近一直在“全力以赴”内部项目,旨在优雅地执行这些最佳实践,说实话,对于这个具体案例真正有意义的唯一解释就是:有人内部决定所有JSON解析都应该通过其核心库中的单个实现,并且强制执行该操作的最佳方法是在每个API响应中自动添加for(;;);
。
这样做,开发人员不能“懒惰”:他们会注意立即如果他们使用eval()
,想知道是什么,然后意识到他们的错误并使用已批准的JSON API。
提供的其他答案似乎都属于以下两类之一:
第一类中的人依赖于攻击者能够以某种方式向不支持它的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帖子将其发送回自己的服务器。