为什么Google会在前面加上while(1);他们的JSON响应吗

dphi5xsq  于 2022-12-15  发布在  Go
关注(0)|答案(8)|浏览(431)

为什么Google要在他们的(私有)JSON响应前添加while(1);
例如,下面是在Google Calendar中打开和关闭日历时的响应:

while (1);
[
  ['u', [
    ['smsSentFlag', 'false'],
    ['hideInvitations', 'false'],
    ['remindOnRespondedEventsOnly', 'true'],
    ['hideInvitations_remindOnRespondedEventsOnly', 'false_true'],
    ['Calendar ID stripped for privacy', 'false'],
    ['smsVerifiedFlag', 'true']
  ]]
]

我会假设这是为了防止人们在它上面做eval(),但你真正要做的就是替换while,然后你就可以设置了。我会假设eval的预防是为了确保人们编写安全的JSON解析代码。
我也在其他一些地方看到过这种用法,但在Google(邮件、日历、联系人等)中使用得更多。奇怪的是,Google Docs&&&START&&&开头,而Google联系人似乎以while(1); &&&START&&&开头。
这是怎么回事?

u3r8eeie

u3r8eeie1#

它可以防止JSON hijacking,这是一个主要的JSON安全问题,自2011年以来,ECMAScript 5在所有主要浏览器中正式成为fixed
人工示例:假设Google有一个类似mail.google.com/json?action=inbox的URL,它以JSON格式返回收件箱中的前50封邮件。由于同源策略,其他域中的恶意网站无法发出 AJAX 请求来获取此数据,但它们可以通过<script>标签包含该URL。该URL通过 your cookie访问,通过overriding the global array constructor or accessor methods,只要设置了对象(数组或散列)属性,就可以调用一个方法,从而允许它们读取JSON内容。
while(1);&&&BLAH&&&可防止这种情况:在mail.google.com上的 AJAX 请求可以完全访问文本内容,并且可以将其剥离,但是<script>标记插入会盲目地执行JavaScript而不进行任何处理,从而导致无限循环或语法错误。
这并不能解决cross-site request forgery的问题。

8fq7wneg

8fq7wneg2#

它防止通过JSON劫持泄露响应。
理论上,HTTP响应的内容受同源策略保护:来自一个域的页面不能从另一个域的页面获得任何信息(除非明确允许)。
攻击者可以代表您请求其他域上的页面,例如使用<script src=...><img>标签,但无法获得任何有关结果的信息(标题、内容)。
因此,如果您访问攻击者的页面,它无法读取您的电子邮件。
除非使用脚本标记请求JSON内容,否则JSON将在攻击者控制的环境中作为JavaScript执行。如果攻击者可以替换Array或Object构造函数或对象构造过程中使用的其他方法,JSON中的任何内容都将通过攻击者的代码并被泄露。
请注意,当JSON作为JavaScript执行时会发生这种情况,而不是在解析它时。
对策有多种:

确保JSON永远不会执行

通过在JSON数据之前放置一个while(1);语句,Google确保JSON数据永远不会作为JavaScript执行。
只有合法的页面才能真正获取整个内容,剥离while(1);,并将剩余部分解析为JSON。
例如,像for(;;);这样的东西已经在Facebook上看到,结果是一样的。

确保JSON不是有效的JavaScript

类似地,在JSON之前添加无效的标记(如&&&START&&&)可以确保它永远不会被执行。

始终返回外部带有Object的JSON

这是OWASP推荐的防止JSON劫持的方法,而且是侵入性较小的方法。
与前面的对策类似,它确保JSON永远不会作为JavaScript执行。
一个有效的JSON对象,如果没有被任何东西包围,在JavaScript中是无效的,因为{ }被解释为一个代码块:

eval('{"foo":"bar"}')
// SyntaxError: Unexpected token :

但是这是有效的JSON:

JSON.parse('{"foo":"bar"}')
// Object {foo: "bar"}

因此,确保总是在响应的顶层返回一个Object,并确保JSON不是有效的JavaScript,但仍然是有效的JSON。
正如注解中的@hvd所指出的,空对象{}是有效的JavaScript,知道该对象为空本身可能是有价值的信息。

上述方法的比较

OWASP的方式侵入性较低,因为它不需要更改客户端库,并且传输有效的JSON。然而,不确定过去或未来的浏览器错误是否能够克服这一点。正如@oriadam所指出的,不清楚数据是否会通过错误处理在解析错误中泄漏(例如window.onerror)。
Google的方式需要一个客户端库,以便支持自动反序列化,并且可以被认为在浏览器错误方面更安全。
这两种方法都需要在服务器端进行更改,以避免开发人员意外发送易受攻击的JSON。

j5fpnvbx

j5fpnvbx3#

这是为了确保其他网站无法通过卑鄙的手段窃取您的数据。例如,通过replacing the array constructor,然后通过<script>标记包含此JSON URL,恶意的第三方网站可以从JSON响应中窃取数据。通过在开头放置while(1);,脚本将挂起。
另一方面,使用XHR和单独的JSON解析器的同一站点请求可以很容易地忽略while(1);前缀。

bnl4lu3b

bnl4lu3b4#

这将使第三方难以将JSON响应插入到带有<script>标记的HTML文档中。请记住,<script>标记不受Same Origin Policy的约束。

nuypyhwy

nuypyhwy5#

注意:截至2019年,许多导致本问题中讨论的预防措施的旧漏洞在现代浏览器中已不再是问题。我将在下面留下答案作为历史好奇心,但实际上整个主题自2010年(!!)提出这个问题以来已经发生了根本变化。

它可以防止脚本被用作简单的<script>标记的目标。(当然,这并不能防止脚本被用作简单的<script>标记的目标,但这会让人感到不快。)这样一来,坏人就无法将脚本标记放在他们自己的站点中,并依赖于活动会话来获取您的内容。

  • edit* -注意注解(和其他答案)。这个问题与被破坏的内置工具有关,特别是ObjectArray构造函数。这些构造函数可以被修改,使得原本无害的JSON在解析时可能触发攻击者代码。
bprjcwpo

bprjcwpo6#

由于<script>标签不受同源策略的约束,而同源策略是网络世界中的安全必需品,因此while(1)在添加到JSON响应时可防止在<script>标签中误用它。

kdfy810k

kdfy810k7#

由于这是一个高流量的帖子,我希望在这里提供一个稍微不确定的原始问题的答案,从而提供进一步的背景JSON劫持攻击及其后果
顾名思义,JSON劫持是一种类似于跨站点请求伪造的攻击,攻击者可以从将敏感数据作为数组文本返回给GET请求的应用程序访问跨域敏感JSON数据。下面是返回数组文本的JSON调用示例:

[{"id":"1001","ccnum":"4111111111111111","balance":"2345.15"}, 
{"id":"1002","ccnum":"5555555555554444","balance":"10345.00"}, 
{"id":"1003","ccnum":"5105105105105100","balance":"6250.50"}]

此攻击可通过3个主要步骤实现:
步骤1:让经过身份验证的用户访问恶意页面。步骤2:恶意页面将尝试访问用户登录的应用程序中的敏感数据。这可以通过在HTML页面中嵌入脚本标记来实现,因为同源策略不适用于脚本标记。

<script src="http://<jsonsite>/json_server.php"></script>

浏览器将向json_server.php发出GET请求,用户的任何身份验证cookie都将随请求沿着发送。步骤3:此时,虽然恶意站点已执行脚本,但它无法访问任何敏感数据。可以通过使用对象原型设置器来访问数据。在下面的代码中,当尝试设置“ccnum“属性时,对象原型属性将绑定到定义的函数。

Object.prototype.__defineSetter__('ccnum',function(obj){
    secrets =secrets.concat(" ", obj);
});

此时,恶意站点已经成功劫持了返回byjson_server.php JSON的敏感财务数据(ccnum)
需要注意的是,并不是所有的浏览器都支持这种方法;概念验证是在Firefox 3.x上完成的。此方法现已弃用,并被useObject.defineProperty所取代。此攻击还有一个变种,可在返回全名JavaScript(例如pi=3.14159)而非JSON数组的所有浏览器上运行。
有几种方法可以防止JSON劫持:

  • 由于SCRIPT标记只能生成HTTPGET请求,因此它们只能向POST请求返回JSON对象。
  • 防止Web浏览器将JSON对象解释为有效的JavaScript代码。
  • 通过要求所有JSON请求都需要预定义的随机值来实现跨站点请求伪造保护。

因此,您可以看到While(1)位于最后一个选项之下,用最简单的术语来说,while(1)是一个无限循环,它将一直运行到显式发出break语句为止,因此可以将其描述为要应用的密钥的锁(google break语句)。因此,JSON劫持,其中黑客没有密钥,将始终被驳回。唉,如果使用解析器读取JSON块,while(1)循环将被忽略。
所以总而言之,while(1)循环可以更容易地被可视化为一个 * 简单 * break语句密码,google可以用它来控制数据流。
然而,该语句中的关键字是单词“simple ”。谢天谢地,自2010年以来,**由于 * 隔离 * 时,**验证无限循环的使用绝对减少了CPU使用 *,**已从基本实践中删除。(事实上,互联网已经远离了强制通过粗糙的“快速修复”)。今天,代码库已经嵌入了预防措施,系统不再重要或有效(部分原因是从JSON劫持转向了更有成效的数据耕作技术,我现在不会详细介绍)

ar5n3qh5

ar5n3qh58#

验证完成后,JSON劫持防护可以采取多种形式,Google会在JSON数据中附加while(1),这样,如果有恶意脚本对其进行求值,恶意脚本就会进入无限循环。
参考:Web安全测试指南:快速发现问题的系统技术

相关问题