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

Mri*_*ria 196 ajax json facebook

可能重复:
为什么人们把代码放在"抛出1; <dont be evil>"and"for(;;);"在json回应之前?

我发现这种语法在Facebook上用于Ajax调用.我在for (;;);回答开始时对此感到困惑.它是干什么用的?

这是电话和回复:

GET http://0.131.channel.facebook.com/x/1476579705/51033089/false/p_1524926084=0
Run Code Online (Sandbox Code Playgroud)

响应:

for (;;);{"t":"continue"}
Run Code Online (Sandbox Code Playgroud)

T.J*_*der 157

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

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

  • @mridkash:我唯一能想到的是他们不希望人们通过JSON-P使用该API,它使用`script`标签来绕过同源策略.而且,他们显然只想要知道`for`循环的人所消耗的结果,因为当然会破坏任何标准的JSON解码器(如果解码器依赖于'eval`,则真正意义上说).因此,除非通过ajax检索,并且知道要删除该前言的人,否则API无用.也许它只是被客户端代码使用,他们会定期更改标记... (9认同)
  • @Crowder:在旧版浏览器中,可以通过允许您捕获传递的数据的方式覆盖Array()函数.这意味着您不能总是假设在脚本标记中评估的JSON文字不会泄漏. (7认同)
  • @mridkash:是的,但请记住它只能控制通过网络浏览器*滥用数据*.任何想要手动获取数据的人,或者使用非基于浏览器的工具来检索文本并在自动化过程中使用它(甚至创建一个剥离前缀的反射器).所以它不是真的很安全,只是让它变得尴尬.反射器最终将作为一个显着活跃的客户端出现在您的日志中.:-) (4认同)

Jay*_*ik- 105

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

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

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

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

  1. 误解JSONP,或
  2. 误解"JSON劫持".

第一类中的那些人依赖于攻击者可以某种方式向不支持它的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: ....^
Run Code Online (Sandbox Code Playgroud)

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

js> ({"t":"continue"})
[object Object]
Run Code Online (Sandbox Code Playgroud)

现在,它可能是这个for(;;);前缀招只是"不小心"在这个例子中显示出来,实际上是在被其他内部的Facebook的API,在返回数组返回; 但在这种情况下应该注意,因为那将for(;;);是出现在这个特定片段中的"真正"原因.

  • **没有意义`for(;;);`将被用来禁止'eval`.**Facebook有更好的方法来控制自己的代码.并且`for(;;);`同样地打破所有JSON解析器,包括`eval`.开发人员必须在任何情况下手动删除它,但这几乎不会阻止`eval`.答案是JSON劫持企图.是的,单独的对象文字是无效的,但是在所有JSON之前插入(和稍后删除)`for(;;)`比使用条件语句更容易且更不容易出错. (15认同)

aro*_*oth 44

好吧,这for(;;);是一个无限循环(你可以使用Chrome的JavaScript控制台在选项卡中运行该代码,然后观察任务管理器中的CPU使用情况,直到浏览器终止选项卡).

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

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

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

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

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

  • 但是`JSON.parse('for(;;); {"t":"continue"}')`break(SyntaxError),这是在Javascript中解析Json的安全方式. (5认同)

emb*_*oss 16

我有点迟了,TJ基本上已经解开了这个谜团,但我想我会就这个特定的主题分享一篇很好的论文,这个论文有很好的例子,并提供了对这种机制的更深入的了解.

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

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

function Object() {
    //Make an Ajax request to your malicious site exposing the object data
}
Run Code Online (Sandbox Code Playgroud)

然后你<script>在该网站中包含一个标签,如

<script src="http://www.example.com/object.json"></script>
Run Code Online (Sandbox Code Playgroud)

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

正如所承诺的那样,链接到论文.


Jas*_*son 13

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

<script src="http://0.131.channel.facebook.com/x/1476579705/51033089/false/p_1524926084=0" />
Run Code Online (Sandbox Code Playgroud)

如果在JSON之前没有无限循环,则会创建一个对象,因为JSON可以作为javascript eval()编辑,并且钩子会检测它并嗅探对象成员.

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

  • @ dave1010数组文字是有效的JSON.对每个人强制实施CSRF保护要比希望构建JSON响应的人知道顶级数组是CSRF漏洞更明显且更不容易出错. (2认同)

归档时间:

查看次数:

48166 次

最近记录:

7 年,11 月 前