为什么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>
标签的目标。 (好吧,这并不妨碍它,但它使它不愉快。)这样,坏人不能只把脚本标签放在自己的网站,并依靠一个活跃的会话,以获取您的内容。
编辑 – 注意评论(和其他答案)。 这个问题与颠覆的内置工具,特别是Object
和Array
构造函数有关。 这些可以被修改,否则无害的JSON在parsing时会触发攻击者代码。
由于该标签可以免除在Web世界中的安全需求的同源策略,而(1)添加到JSON响应时可以防止在<script>
标签中滥用该标签。