Javascript 为什么谷歌在前面加上 while(1); 到他们的 JSON 响应?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2669690/
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
Why does Google prepend while(1); to their JSON responses?
提问by Jess
Why does Google prepend while(1);to their (private) JSON responses?
为什么 Google 会while(1);在他们的(私人)JSON 响应之前添加?
For example, here's a response while turning a calendar on and off in Google Calendar:
例如,这是在Google 日历中打开和关闭日历时的响应:
while (1);
[
['u', [
['smsSentFlag', 'false'],
['hideInvitations', 'false'],
['remindOnRespondedEventsOnly', 'true'],
['hideInvitations_remindOnRespondedEventsOnly', 'false_true'],
['Calendar ID stripped for privacy', 'false'],
['smsVerifiedFlag', 'true']
]]
]
I would assume this is to prevent people from doing an eval()on it, but all you'd really have to do is replace the whileand then you'd be set. I would assume the eval prevention is to make sure people write safe JSON parsing code.
我认为这是为了防止人们eval()对其进行操作,但您真正需要做的就是替换while,然后您就可以设置了。我认为 eval 预防是为了确保人们编写安全的 JSON 解析代码。
I've seen this used in a couple of other places, too, but a lot more so with Google (Mail, Calendar, Contacts, etc.) Strangely enough, Google Docsstarts with &&&START&&&instead, and Google Contacts seems to start with while(1); &&&START&&&.
我在其他几个地方也看到过这种用法,但在 Google(邮件、日历、通讯录等)中使用的更多。奇怪的是,Google Docs以 开头,&&&START&&&而 Google 通讯录似乎以while(1); &&&START&&&.
What's going on here?
这里发生了什么?
回答by rjh
It prevents JSON hiHymaning, a major JSON security issue that is formally fixedin all major browsers since 2011with ECMAScript 5.
它可以防止JSON 劫持,这是一个主要的 JSON 安全问题,自 2011 年以来,ECMAScript 5 已在所有主要浏览器中正式修复。
Contrived example: say Google has a URL like mail.google.com/json?action=inboxwhich returns the first 50 messages of your inbox in JSON format. Evil websites on other domains can't make AJAX requests to get this data due to the same-origin policy, but they can include the URL via a <script>tag. The URL is visited with yourcookies, and by overriding the global array constructor or accessor methodsthey can have a method called whenever an object (array or hash) attribute is set, allowing them to read the JSON content.
人为示例:假设 Google 有一个类似的 URL mail.google.com/json?action=inbox,它以 JSON 格式返回收件箱的前 50 条消息。由于同源策略,其他域上的恶意网站无法通过 AJAX 请求获取此数据,但它们可以通过<script>标签包含 URL 。URL 使用您的cookie访问,通过覆盖全局数组构造函数或访问器方法,他们可以在设置对象(数组或哈希)属性时调用一个方法,允许他们读取 JSON 内容。
The while(1);or &&&BLAH&&&prevents this: an AJAX request at mail.google.comwill have full access to the text content, and can strip it away. But a <script>tag insertion blindly executes the JavaScript without any processing, resulting in either an infinite loop or a syntax error.
的while(1);或&&&BLAH&&&防止这样的:在一个AJAX请求mail.google.com将具有完全访问的文本内容,并且可以去除它扔掉。但是<script>标签插入盲目地执行 JavaScript 而不进行任何处理,导致死循环或语法错误。
This does not address the issue of cross-site request forgery.
这并没有解决跨站点请求伪造的问题。
回答by Arnaud Le Blanc
It prevents disclosure of the response through JSON hiHymaning.
它可以防止通过 JSON 劫持泄露响应。
In theory, the content of HTTP responses are protected by the Same Origin Policy: pages from one domain cannot get any pieces of information from pages on the other domain (unless explicitly allowed).
理论上,HTTP 响应的内容受同源策略保护:来自一个域的页面无法从另一个域的页面获取任何信息(除非明确允许)。
An attacker can request pages on other domains on your behalf, e.g. by using a <script src=...>or <img>tag, but it can't get any information about the result (headers, contents).
攻击者可以代表您请求其他域上的页面,例如通过使用<script src=...>或<img>标记,但它无法获得有关结果的任何信息(标题、内容)。
Thus, if you visit an attacker's page, it couldn't read your email from gmail.com.
因此,如果您访问攻击者的页面,它就无法从 gmail.com 读取您的电子邮件。
Except that when using a script tag to request JSON content, the JSON is executed as Javascript in an attacker's controlled environment. If the attacker can replace the Array or Object constructor or some other method used during object construction, anything in the JSON would pass through the attacker's code, and be disclosed.
除了使用脚本标签请求 JSON 内容时,JSON 在攻击者的受控环境中作为 Javascript 执行。如果攻击者可以替换对象构造过程中使用的数组或对象构造函数或其他一些方法,那么 JSON 中的任何内容都将通过攻击者的代码并被披露。
Note that this happens at the time the JSON is executed as Javascript, not at the time it's parsed.
请注意,这发生在 JSON 作为 Javascript 执行时,而不是在解析时发生。
There are multiple countermeasures:
有多种对策:
Making sure the JSON never executes
确保 JSON 永远不会执行
By placing a while(1);statement before the JSON data, Google makes sure that the JSON data is never executed as Javascript.
通过while(1);在 JSON 数据之前放置一条语句,Google 可确保 JSON 数据永远不会作为 Javascript 执行。
Only a legitimate page could get the whole content, strip the while(1);, and parse the remainder as JSON.
只有合法的页面才能获取全部内容,剥离while(1);,并将剩余部分解析为 JSON。
Things like for(;;);have been seen at Facebook for instance, with the same results.
for(;;);例如,在 Facebook 上已经看到了类似的事情,结果相同。
Making sure the JSON is not valid Javascript
确保 JSON 不是有效的 Javascript
Similarly, adding invalid tokens before the JSON, like &&&START&&&, makes sure that it is never executed.
同样,在 JSON 之前添加无效令牌,例如&&&START&&&,确保它永远不会被执行。
Always return JSON with an Object on the outside
始终返回带有外部对象的 JSON
This is OWASPrecommended wayto protect from JSON hiHymaning and is the less intrusive one.
这是防止 JSON 劫持的OWASP推荐方法,并且是侵入性较小的方法。
Similar to the previous counter-measures, it makes sure that the JSON is never executed as Javascript.
与之前的对策类似,它确保 JSON 永远不会作为 Javascript 执行。
A valid JSON object, when not enclosed by anything, is not valid in Javascript:
一个有效的 JSON 对象,当没有被任何东西包围时,在 Javascript 中是无效的:
eval('{"foo":"bar"}')
// SyntaxError: Unexpected token :
This is however valid JSON:
然而,这是有效的 JSON:
JSON.parse('{"foo":"bar"}')
// Object {foo: "bar"}
So, make sure you always return an Object at the top level of the response makes sure that the JSON is not valid Javascript, while still being valid JSON.
因此,请确保始终在响应的顶层返回一个对象,以确保 JSON 不是有效的 Javascript,同时仍然是有效的 JSON。
As noted by @hvd in the comments, the empty object {}is valid Javascript, and knowing the object is empty may itself be valuable information.
正如@hvd 在评论中所指出的,空对象{}是有效的 Javascript,知道对象为空本身可能是有价值的信息。
Comparison of above methods
以上方法的比较
The OWASP way is less intrusive, as it needs no client library changes, and transfers valid JSON. It is unsure whether past or future browser bugs could defeat this, however. As noted by @oriadam, it is unclear whether data could be leaked in a parse error through an error-handling or not (e.g. window.onerror).
OWASP 方式的侵入性较小,因为它不需要更改客户端库,并传输有效的 JSON。然而,不确定过去或未来的浏览器错误是否可以解决这个问题。正如@oriadam 所指出的,目前尚不清楚数据是否会通过错误处理(例如 window.onerror)在解析错误中泄漏。
Google's way requires the client library for it to support automatic de-serialization and can be considered to be safer about browser bugs.
谷歌的方式需要客户端库支持自动反序列化,可以认为对浏览器bug更安全。
Both methods require server-side changes to avoid developers from accidentally sending vulnerable JSON.
这两种方法都需要服务器端更改,以避免开发人员意外发送易受攻击的 JSON。
回答by bdonlan
This is to ensure some other site can't do nasty tricks to try to steal your data. For example, by replacing the array constructor, then including this JSON URL via a <script>tag, a malicious third-party site could steal the data from the JSON response. By putting a while(1);at the start, the script will hang instead.
这是为了确保某些其他站点不能采取令人讨厌的技巧来尝试窃取您的数据。例如,通过替换数组构造函数,然后通过<script>标签包含此 JSON URL ,恶意第三方站点可以从 JSON 响应中窃取数据。通过将 awhile(1);放在开头,脚本将挂起。
A same-site request using XHR and a separate JSON parser, on the other hand, can easily ignore the while(1);prefix.
另一方面,使用 XHR 和单独的 JSON 解析器的同站点请求可以轻松忽略while(1);前缀。
回答by Daniel Vassallo
That would be to make it difficult for a third-party to insert the JSON response into an HTML document with the <script>tag. Remember that the <script>tag is exempt from the Same Origin Policy.
这将使第三方难以将 JSON 响应插入到带有<script>标记的 HTML 文档中。请记住,<script>标签不受同源策略的约束。
回答by Pointy
Note: as of 2019, many of the old vulnerabilities that lead to the preventative measures discussed in this question are no longer an issue in modern browsers. I'll leave the answer below as a historical curiosity, but really the whole topic has changed radically since 2010 (!!) when this was asked.
注意:截至 2019 年,导致本问题中讨论的预防措施的许多旧漏洞在现代浏览器中不再是问题。我将在下面留下答案作为历史好奇心,但实际上,自 2010 年 (!!) 被问到这个问题以来,整个主题已经发生了根本性的变化。
It prevents it from being used as the target of a simple <script>tag. (Well, it doesn't prevent it, but it makes it unpleasant.) That way bad guys can't just put that script tag in their own site and rely on an active session to make it possible to fetch your content.
它防止它被用作简单<script>标签的目标。(好吧,它并不能阻止它,但它会让它变得不愉快。)这样坏人就不能将脚本标签放在他们自己的站点中并依靠活动会话来获取您的内容。
edit— note the comment (and other answers). The issue has to do with subverted built-in facilities, specifically the Objectand Arrayconstructors. Those can be altered such that otherwise innocuous JSON, when parsed, could trigger attacker code.
编辑- 注意评论(和其他答案)。这个问题与被破坏的内置设施有关,特别是Object和Array构造函数。这些可以被改变,这样原本无害的 JSON 在解析时可能会触发攻击者代码。
回答by Krishna Ganeriwal
Since the <script>tag is exempted from the Same Origin Policy which is a security necessity in the web world, while(1)when added to the JSON response prevents misuse of it in the <script>tag.
由于<script>标签不受 Web 世界安全需要的同源策略的约束,因此while(1)当添加到 JSON 响应时可以防止在<script>标签中滥用它。
回答by JSON C11
After authentication is in place, JSON hiHymaning protection can take a variety of forms. Google appends while(1)into their JSON data, so that if any malicious script evaluates it, the malicious script enters an infinite loop.
身份验证到位后,JSON 劫持保护可以采用多种形式。Google 将while(1)附加到他们的 JSON 数据中,这样如果任何恶意脚本对其进行评估,恶意脚本就会进入无限循环。
Reference: Web Security Testing Cookbook: Systematic Techniques to Find Problems Fast

