什么是Ajax调用响应,如'for(;;); {json data}'是什么意思?
可能重复:
为什么人们把代码如“扔1; <dont be evil>“和”for(;;);“在json响应之前?
我发现这种在Facebook上用于Ajax调用的语法。 我困惑于for (;;);
部分在响应的开始。 它是干什么用的?
这是呼吁和回应:
GET http://0.131.channel.facebook.com/x/1476579705/51033089/false/p_1524926084=0
响应:
for (;;);{"t":"continue"}
Facebook有很多开发人员在很多项目上进行内部开发,而且有人犯了一个小错误很常见; 无论是简单而严肃的事情,还是未能将数据插入到HTML或SQL模板中,或者使用eval
(有时效率低下且可证明不安全)或JSON.parse
(一种兼容但不是普遍实现的扩展)的复杂而细微的东西的“已知的好”JSON解码器,重要的是找出方法来轻松实施这个开发人员的最佳实践。
为了应对这一挑战,Facebook最近一直在全力以赴地推出内部项目,旨在优雅地实施这些最佳实践,并且说实话,对于这个特定案例真正有意义的唯一解释就是:有人在内部决定将所有JSON解析应该通过核心库中的单个实现,并且强制执行的最佳方式是针对每个API响应获取for(;;);
自动钉在前面。
这样做,开发人员不能“懒惰”:如果他们使用eval()
,他们会立即注意到,想知道是什么,然后意识到他们的错误并使用批准的JSON API。
提供的其他答案似乎都属于两类之一:
第一类攻击者依赖这样的想法:攻击者可以以某种方式向不支持它的API“使用JSONP”发出请求。 JSONP是一个必须在服务器和客户端都支持的协议:它要求服务器返回类似于myFunction({"t":"continue"})
东西myFunction({"t":"continue"})
,以便将结果传递给本地函数。 你不能只是偶然地“使用JSONP”。
第二类中的人引用了一个非常真实的漏洞,该漏洞允许通过标记向不使用JSONP的API(如本例)进行跨站点请求伪造,允许一种“JSON劫持”形式。 这是通过更改Array / Object构造函数完成的,该构造函数允许访问从服务器返回的信息,而不使用包装函数。
然而,在这种情况下根本不可能:它的工作原理是,一个裸数组(例如着名的Gmail示例中的许多JSON API的一个可能结果)是一个有效的表达式语句,这不是真的裸露的物体。
事实上,由JSON定义的对象的语法(其中包括字段名称周围的引号,如本例所示)与块的语法冲突,因此不能在脚本的顶层使用。
js> {"t":"continue"}
typein:2: SyntaxError: invalid label:
typein:2: {"t":"continue"}
typein:2: ....^
对于这个例子可以通过Object()构造函数重新映射来利用它,它会要求API将对象返回到一组括号内,使其成为有效的JavaScript(但不是有效的JSON)。
js> ({"t":"continue"})
[object Object]
现在,这可能是for(;;);
前缀技巧只是在本例中“意外”出现,实际上是由返回数组的其他内部Facebook API返回的; 但在这种情况下,应该真正注意到,因为那样会成为for(;;);
出现在这个特定的片段中。
我怀疑它存在的主要原因是控制。 它迫使你通过Ajax检索数据,而不是通过JSON-P或类似的方法(使用script
标签,因为for
循环是无限的,所以会失败),从而确保相同原点策略启动。这使他们能够控制哪些文档可以向API发出调用 - 具体而言,只有与该API调用具有相同来源的文档,或者Facebook专门授予通过CORS访问(在支持CORS的浏览器上)的文档。 因此,您必须通过浏览器强制实施SOP的机制来请求数据,并且在反序列化数据之前必须知道该序言并将其删除。
所以是的,这是关于控制(有用)访问该数据。
那么for(;;);
是一个无限循环(如果需要,可以使用Chrome的JavaScript控制台在选项卡中运行该代码,然后观察任务管理器中的CPU使用情况,直至浏览器终止该选项卡)。
所以我怀疑它可能被放在那里阻止任何试图使用eval
或任何其他执行返回数据的技术来解析响应的人。
为了进一步解释,过去用JavaScript的eval()
函数解析一些JSON格式的数据是相当普遍的,通过执行如下操作:
var parsedJson = eval('(' + jsonString + ')')
;
...然而,这被认为是不安全的,就好像出于某种原因,您的JSON格式的数据包含可执行的JavaScript代码,而不是JSON格式的数据(或除此之外),那么代码将由eval()
执行。 这意味着,如果您正在与不受信任的服务器交谈,或者某人泄露了受信任的服务器,那么他们可以在您的页面上运行任意代码。
因此,使用诸如eval()
来解析JSON格式的数据通常会被忽视,而for(;;);
Facebook JSON中的声明将阻止人们以这种方式解析数据。 任何尝试的人都会得到无限循环。 所以基本上,这就像Facebook正试图强制人们使用其API来处理,而不会让他们容易受到未来的劫持Facebook API用作媒介的攻击。
上一篇: What does a Ajax call response like 'for (;;); { json data }' mean?