为什么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()
,但是您真正要做的就是替换while
,然后进行设置。 我认为评估的目的是确保人们编写安全的JSON解析代码。
我已经看到了这个用在其他几个地方也一样,但很多更使谷歌(邮件,日历,联系人等),奇怪的是, 谷歌文档开头&&&START&&&
,而是和谷歌联系人似乎开始与while(1); &&&START&&&
while(1); &&&START&&&
。
这里发生了什么?
#1楼
它可以防止通过JSON劫持泄露响应。
从理论上讲,HTTP响应的内容受同一起源策略保护:来自一个域的页面无法从另一域的页面获取任何信息(除非明确允许)。
攻击者可以代表您请求其他域上的页面,例如,使用<script src=...>
或<img>
标记,但它无法获取有关结果的任何信息(标题,内容)。
因此,如果您访问攻击者的页面,则无法从gmail.com读取您的电子邮件。
除了使用脚本标记请求JSON内容时,JSON是在攻击者的受控环境中作为Javascript执行的。 如果攻击者可以替换对象构造期间使用的Array或Object构造函数或其他某种方法,则JSON中的任何内容都将通过攻击者的代码,并被披露。
请注意,这是在JSON作为Javascript执行时发生的,而不是在解析时发生的。
有多种对策:
确保JSON从不执行
通过放置while(1);
在JSON数据之前的声明,Google确保JSON数据永远不会作为Javascript执行。
除去while(1);
只有合法的页面才能真正获取全部内容while(1);
,并将其余部分解析为JSON。
像for(;;);
例如在Facebook上看到的结果相同。
确保JSON无效的Javascript
同样,在JSON之前添加无效令牌,例如&&&START&&&
,以确保它永远不会执行。
始终返回带有外部对象的JSON
OWASP
建议使用这种方法来防止JSON劫持,并且这种方法的侵入性较小。
与以前的对策类似,它可以确保JSON永远不会作为Javascript执行。
有效的JSON对象(未用任何东西括起来)在Javascript中无效:
eval('{"foo":"bar"}')
// SyntaxError: Unexpected token :
但是,这是有效的JSON:
JSON.parse('{"foo":"bar"}')
// Object {foo: "bar"}
因此,请确保始终在响应的顶级返回一个Object,以确保JSON无效,而JSON仍然有效。
正如@hvd在评论中指出的那样,空对象{}
是有效的Javascript,知道该对象为空可能本身就是有价值的信息。
以上方法比较
OWASP方式具有较低的侵入性,因为它不需要更改客户端库,并且可以传输有效的JSON。 但是,不确定过去或将来的浏览器错误是否可以解决这个问题。 如@oriadam所指出的,目前尚不清楚是否可以通过错误处理(例如window.onerror)在解析错误中泄漏数据。
Google的方法需要客户端库才能支持自动反序列化,并且可以认为它相对于浏览器错误更安全。
两种方法都需要在服务器端进行更改,以避免开发人员意外发送易受攻击的JSON。
#2楼
注意 :从2019年开始,导致该问题中讨论的预防措施的许多旧漏洞不再是现代浏览器中的问题。 我将以下答案保留为历史上的好奇心,但实际上自2010年问起以来,整个主题已发生了根本变化(!!)。
它防止将其用作简单<script>
标记的目标。 (嗯,这并不能阻止它,但是它使它不愉快。)那样,坏蛋就不能只将脚本标记放在自己的站点中,而是依靠活动会话来获取内容。
编辑 -注意评论(和其他答案)。 这个问题与颠覆的内置功能有关,尤其是Object
和Array
构造函数。 可以对其进行更改,以使否则解析时无害的JSON可能会触发攻击者代码。
#3楼
这将使第三方很难使用<script>
标签将JSON响应插入HTML文档。 请记住, <script>
标记不受相同来源策略的限制 。
#4楼
它可以防止JSON劫持 ,这是自2011年以来使用ECMAScript 5在所有主要浏览器中正式修复的主要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,而不进行任何处理,从而导致无限循环或语法错误。
这不能解决跨站点请求伪造的问题 。
#5楼
由于<script>
标记免于在网络世界中的安全性必需的Same Origin Policy,因此while(1)
当添加到JSON响应时,可以防止在<script>
标记中滥用它。
#6楼
这是为了确保其他某些站点无法采取令人讨厌的手段来窃取您的数据。 例如,通过替换数组构造函数 ,然后通过<script>
标记包括此JSON URL,恶意的第三方站点可能会从JSON响应中窃取数据。 通过放置while(1);
在开始时,脚本将挂起。
另一方面,使用XHR和单独的JSON解析器的同一站点请求可以轻松地忽略while(1);
字首。