'for (;;); 这样的 Ajax 调用响应是什么?{json 数据}'是什么意思?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6339790/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 17:53:19  来源:igfitidea点击:

What does a Ajax call response like 'for (;;); { json data }' mean?

ajaxjsonfacebook

提问by Mridul Kashatria

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

可能的重复:
为什么人们把代码写成“throw 1;” <不要作恶>”和“for(;;);” 在 json 响应之前?

I found this kind of syntax being used on Facebook for Ajax calls. I'm confused on the for (;;);part in the beginning of response. What is it used for?

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

This is the call and response:

这是调用和响应:

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

Response:

回复:

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

采纳答案by emboss

I'm a bit late and T.J. has basically solved the mystery, but I thought I'd share a great paper on this particular topic that has good examples and provides deeper insight into this mechanism.

我有点晚了,TJ 基本上解决了这个谜团,但我想我会分享一篇关于这个特定主题的好论文,其中有很好的例子,并提供了对这种机制的更深入的了解。

These infinite loops are a countermeasure against "Javascript hiHymaning", a type of attack that gained public attention with an attack on Gmail that was published by Jeremiah Grossman.

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

The idea is as simple as beautiful: A lot of users tend to be logged in permanently in Gmail or Facebook. So what you do is you set up a site and in your malicious site's Javascript you override the object or array constructor:

这个想法既简单又漂亮:许多用户倾向于永久登录 Gmail 或 Facebook。因此,您要做的是设置一个站点,然后在恶意站点的 Javascript 中覆盖对象或数组构造函数:

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

then you include a <script>tag in that site such as

然后您<script>在该站点中包含一个标记,例如

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

And finally you can read all about the JSON objects in your malicious server's logs.

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

As promised, the link to the paper.

正如所承诺的,该文件的链接。

回答by T.J. Crowder

I suspect the primary reason it's there is control. It forcesyou to retrieve the data via Ajax, not via JSON-P or similar (which uses scripttags, and so would fail because that forloop is infinite), and thus ensures that the Same Origin Policykicks in. This lets them control what documents can issue calls to the API — specifically, only documents that have the same origin as that API call, or ones that Facebook specifically grants access to via CORS(on browsers that support CORS). So you have to request the data via a mechanism where the browser will enforce the SOP, and you have to know about that preface and remove it before deserializing the data.

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

So yeah, it's about controlling (useful) access to that data.

所以是的,这是关于控制(有用的)对这些数据的访问。

回答by Jay Freeman -saurik-

Facebook has a ton of developers working internally on a lot of projects, and it is very common for someone to make a minor mistake; whether it be something as simple and serious as failing to escape data inserted into an HTML or SQL template or something as intricate and subtle as using eval(sometimes inefficient and arguably insecure) or JSON.parse(a compliant but not universally implemented extension) instead of a "known good" JSON decoder, it is important to figure out ways to easily enforce best practices on this developer population.

Facebook 有大量的开发人员在内部从事很多项目,犯一个小错误是很常见的;无论是像未能转义插入到 HTML 或 SQL 模板中的数据一样简单和严重的事情,还是像使用eval(有时效率低下且可以说是不安全的)或JSON.parse(合规但未普遍实现的扩展)而不是“已知好的” JSON 解码器,重要的是要找出在此开发人员群体中轻松实施最佳实践的方法。

To face this challenge, Facebook has recently been going "all out" with internal projects designed to gracefully enforce these best practices, and to be honest the only explanation that truly makes sense for this specific case is just that: someone internally decided that all JSON parsing should go through a single implementation in their core library, and the best way to enforce that is for every single API response to get for(;;);automatically tacked on the front.

为了应对这一挑战,Facebook 最近一直在“全力以赴”开展旨在优雅地执行这些最佳实践的内部项目,老实说,对于这个特定案例真正有意义的唯一解释就是:内部有人决定所有 JSON解析应该在他们的核心库中通过一个单一的实现,而强制执行的最好方法是让每个 API 响应for(;;);自动添加到前面。

In so doing, a developer can't be "lazy": they will notice immediatelyif they use eval(), wonder what is up, and then realize their mistake and use the approved JSON API.

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

The other answers being provided seem to all fall into one of two categories:

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

  1. misunderstanding JSONP, or
  2. misunderstanding "JSON hiHymaning".
  1. 误解 JSONP,或
  2. 误解“JSON劫持”。

Those in the first category rely on the idea that an attacker can somehow make a request "using JSONP" to an API that doesn't support it. JSONP is a protocol that must be supported on both the server and the client: it requires the server to return something akin to myFunction({"t":"continue"})such that the result is passed to a local function. You can't just "use JSONP" by accident.

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

Those in the second category are citing a very real vulnerability that has been described allowing a cross-site request forgery via tags to APIs that do notuse JSONP (such as this one), allowing a form of "JSON hiHymaning". This is done by changing the Array/Object constructor, which allows one to access the information being returned from the server without a wrapping function.

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

However, that is simply not possible in this case: the reason it works at all is that a bare array (one possible result of many JSON APIs, such as the famous Gmail example) is a valid expression statement, which is not true of a bare object.

然而,在这种情况下这是不可能的:它工作的原因是一个裸数组(许多 JSON API 的一个可能结果,例如著名的 Gmail 示例)是一个有效的表达式语句,对于裸对象。

In fact, the syntax for objects defined by JSON (which includes quotation marks around the field names, as seen in this example) conflicts with the syntax for blocks, and therefore cannot be used at the top-level of a script.

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

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

For this example to be exploitable by way of Object() constructor remapping, it would require the API to have instead returned the object inside of a set of parentheses, making it valid JavaScript (but then not valid JSON).

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

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

Now, it couldbe that this for(;;);prefix trick is only "accidentally" showing up in this example, and is in fact being returned by other internal Facebook APIs that are returning arrays; but in this case that should really be noted, as that would then be the "real" cause for why for(;;);is appearing in this specific snippet.

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

回答by aroth

Well the for(;;);is an infinite loop (you can use Chrome's JavaScript console to run that code in a tab if you want, and then watch the CPU-usage in the task manager go through the roof until the browser kills the tab).

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

So I suspect that maybe it is being put there to frustrate anyone attempting to parse the response using evalor any other technique that executes the returned data.

所以我怀疑它被放在那里是为了挫败任何试图使用eval或任何其他执行返回数据的技术来解析响应的人。

To explain further, it used to be fairly commonplace to parse a bit of JSON-formatted data using JavaScript's eval()function, by doing something like:

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

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

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

...this is considered unsafe, however, as if for some reason your JSON-formatted data contains executable JavaScript code instead of (or in addition to) JSON-formatted data then that code will be executed by the eval(). This means that if you are talking with an untrusted server, or if someone compromises a trusted server, then they can run arbitrary code on your page.

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

Because of this, using things like eval()to parse JSON-formatted data is generally frowned upon, and the for(;;);statement in the Facebook JSON will prevent people from parsing the data that way. Anyone that tries will get an infinite loop. So essentially, it's like Facebook is trying to enforce that people work with its API in a way that doesn't leave them vulnerable to future exploits that try to hiHyman the Facebook API to use as a vector.

正因为如此,使用诸如eval()解析 JSON 格式的数据之类的东西通常是不受欢迎的,而for(;;);Facebook JSON 中的语句将阻止人们以这种方式解析数据。任何尝试的人都会陷入无限循环。所以本质上,这就像 Facebook 试图强制人们使用它的 API 的方式不会让他们容易受到未来试图劫持 Facebook API 以用作向量的攻击。

回答by Jason

This looks like a hack to prevent a CSRFattack. There are browser-specific ways to hook into object creation, so a malicious website could use do that first, and then have the following:

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

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

If there weren't an infinite loop before the JSON, an object would be created, since JSON can be eval()edas javascript, and the hooks would detect it and sniff the object members.

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

Now if you visit that site from a browser, while logged into Facebook, it can get at your data as if it were you, and then send it back to its own server via e.g., an AJAX or javascript post.

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