为什么Google预先安装(1); 到他们的JSON响应?

为什么Google预先安装while(1); 到他们(私人)的JSON响应?

例如,以下是在Google日历中启用和停用日历时的响应:

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

我会认为这是为了防止人们对其进行eval() ,但是你所需要做的就是replace掉,然后就可以设置了。 我会假设eval预防是确保人们编写安全的JSONparsing代码。

我也看到过这种情况在其他几个地方也有使用,但Google(邮件,日历,联系人等)的情况更是如此。非常奇怪的是, Google文档以&&&START&&&开头,而Google Contacts似乎是以while(1); &&&START&&& while(1); &&&START&&&

这里发生了什么?

它可以防止JSON劫持 。

有争议的例子:假设Google有一个像mail.google.com/json?action=inbox这样的url,它以JSON格式返回收件箱中的前50条消息。 其他域名的恶意网站由于同源策略不能使AJAX请求获取这些数据,但可以通过<script>标签包含URL。 使用Cookie访问URL,通过覆盖全局数组构造函数或访问器方法 ,只要设置了对象(数组或哈希)属性,就可以调用该方法,从而允许他们读取JSON内容。

while(1); 或者&&&BLAH&&&可以防止这种情况发生: mail.google.com的AJAX请求可以完全访问文本内容,并可以将其删除。 但是<script>标记插入盲目地执行JavaScript而没有任何处理,导致无限循环或语法错误。

这并没有解决跨站请求伪造的问题 。

它防止通过JSON劫持泄露响应。

从理论上讲,HTTP响应的内容受同源策略的保护:来自一个域的页面不能从其他域的页面获取任何信息(除非明确允许)。

攻击者可以代表您在其他域上请求页面,例如使用<script src=...><img>标记,但是无法获取有关结果(标头,内容)的任何信息。

因此,如果您访问攻击者的页面,则无法从gmail.com读取您的电子邮件。

除了在使用脚本标记来请求JSON内容时,JSON在攻击者的受控环境中以Javascript执行。 如果攻击者可以replaceArray或Object构造函数或其他在构造对象时使用的方法,则JSON中的任何内容都将通过攻击者的代码并被泄露。

请注意,这发生在JSON作为Javascript执行时,而不是在parsing时。

有多种对策:

确保JSON永远不会执行

放置一段while(1); 声明JSON数据之前,Google确保JSON数据永远不会以Javascript的forms执行。

只有一个合法的页面才能真正得到整个内容,剥掉while(1); ,并将其余部分parsing为JSON。

for(;;); 已经在Facebook上看到了,例如,也有同样的结果。

确保JSON不是有效的Javascript

类似地,在JSON之前添加无效令牌,如&&&START&&& ,确保它永远不会被执行。

始终使用外部对象返回JSON

这是OWASP推荐的防止JSON劫持的方式,也是较less侵入的方式。

与之前的对策类似,它确保JSON永远不会以Javascript的forms执行。

一个有效的JSON对象,当没有被任何东西包围时,在Javascript中是无效的:

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

这是有效的JSON:

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

所以,确保你总是返回一个响应顶层的对象,确保JSON不是有效的Javascript,而仍然是有效的JSON。

正如注释中的@hvd所指出的,空对象{}是有效的Javascript,并且知道该对象是空的可能本身就是有价值的信息。

以上方法比较

OWASP的方式不那么干扰,因为它不需要客户端库更改,并传输有效的JSON。 但是,不确定过去或未来的浏览器错误是否能够击败这一点。 正如@oriadam指出的那样,通过error handling(例如window.onerror)是否可能泄露数据在parsing错误中是不清楚的。

谷歌的方式要求客户端库,以支持自动反序列化,可以被认为是更安全的浏览器错误。

这两种方法都需要服务器端的更改,以避免开发人员意外地发送易受攻击的JSON。

这是为了确保一些其他网站不能做恶作剧来试图窃取你的数据。 例如,通过replace数组构造函数 ,然后通过<script>标记包含这个JSON URL,恶意的第三方站点就可以从JSON响应中窃取数据。 放while(1); 在开始时,脚本将挂起。

另一方面,使用XHR和单独的JSONparsing器的同一站点请求可以很容易地忽略while(1); 字首。

这将使第三方很难通过<script>标记将JSON响应插入到HTML文档中。 请记住, <script>标签不受同源策略的限制 。

它阻止它被用作简单的<script>标签的目标。 (好吧,这并不妨碍它,但它使它不愉快。)这样,坏人不能只把脚本标签放在自己的网站,并依靠一个活跃的会话,以获取您的内容。

编辑 – 注意评论(和其他答案)。 这个问题与颠覆的内置工具,特别是ObjectArray构造函数有关。 这些可以被修改,否则无害的JSON在parsing时会触发攻击者代码。

由于该标签可以免除在Web世界中的安全需求的同源策略,而(1)添加到JSON响应时可以防止在<script>标签中滥用该标签。