为什么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
然后你就定了我认为eval预防是为了确保人们编写安全的JSON解析代码。
我已经在其他几个地方看到了这种情况,但谷歌(邮件,日历,联系人等)的情况更是如此。奇怪的是, 谷歌文档 以。。开始 &&&START&&&
相反,谷歌联系人似乎开始 while(1); &&&START&&&
。
这里发生了什么?
它阻止了 JSON劫持。
举例说明:谷歌有一个像这样的网址 mail.google.com/json?action=inbox
它以JSON格式返回收件箱的前50条消息。由于同源策略,其他域上的邪恶网站无法通过AJAX请求获取此数据,但它们可以通过以下方式包含URL <script>
标签。访问该URL 你的 饼干和 覆盖全局数组构造函数或访问器方法 只要设置了对象(数组或散列)属性,它们就可以有一个方法,允许它们读取JSON内容。
该 while(1);
要么 &&&BLAH&&&
防止这种情况:一个AJAX请求 mail.google.com
将完全访问文本内容,并可以将其删除。但是一个 <script>
标记插入盲目地执行JavaScript而不进行任何处理,从而导致无限循环或语法错误。
这并没有解决这个问题 跨站请求伪造。
它可以防止通过JSON劫持泄露响应。
理论上,HTTP响应的内容受同源策略保护:来自一个域的页面无法从其他域上的页面获取任何信息(除非明确允许)。
攻击者可以代表您在其他域上请求网页,例如通过使用 <script src=...>
要么 <img>
标记,但它无法获取有关结果(标题,内容)的任何信息。
因此,如果您访问攻击者的页面,它无法从gmail.com读取您的电子邮件。
除了使用脚本标记来请求JSON内容之外,JSON在攻击者的受控环境中作为Javascript执行。如果攻击者可以替换数组或对象构造函数或对象构造期间使用的其他方法,则JSON中的任何内容都将通过攻击者的代码并被披露。
请注意,这在JSON作为Javascript执行时发生,而不是在解析时。
有多种对策:
确保JSON永远不会执行
通过放置一个 while(1);
在JSON数据之前的声明中,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)将数据泄漏到解析错误中。
谷歌的方式需要客户端库,以便它支持自动反序列化,并且可以被认为是更安全的浏览器错误。
这两种方法都需要服务器端更改,以避免开发人员意外发送易受攻击的JSON。
这是为了确保其他一些网站无法做出令人讨厌的技巧来试图窃取您的数据。例如,通过 替换数组构造函数,然后通过一个包含这个JSON URL <script>
标记,恶意第三方网站可能会窃取JSON响应中的数据。通过投入 while(1);
在开始时,脚本将挂起。
另一方面,使用XHR和单独的JSON解析器的同一站点请求很容易忽略 while(1);
字首。
这将使第三方难以将JSON响应插入HTML文档中 <script>
标签。记得那个 <script>
标签免于 同源政策。
它可以防止它被用作简单的目标 <script>
标签。 (好吧,它并没有阻止它,但它让它变得令人不快。)这样坏人就不能把这个脚本标签放在他们自己的网站上,而是依靠一个活动的会话来获取你的内容。
编辑 - 注意评论(和其他答案)。这个问题与颠覆的内置设施有关,特别是 Object
和 Array
构造函数。这些可以被修改,以便在解析时无关紧要的JSON可以触发攻击者代码。
自从 <script
>标签免于同源策略,这是网络世界中的安全必需品,而(1)当添加到JSON响应时,防止在其中滥用它 <script>
标签。