关于javascript:为什么google在(1);对他们的JSON响应做准备?

Why does Google prepend while(1); to their JSON responses?

为什么google会预先准备好while(1);的(私有)json响应?

例如,在Google日历中打开和关闭日历时,有一个响应:

1
2
3
4
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劫持,这是一个主要的JSON安全问题,自2011年以来,所有主要浏览器都已通过EcmaScript 5正式解决了这一问题。

人为的例子:假设Google有一个类似于mail.google.com/json?action=inbox的URL,它以JSON格式返回收件箱的前50条消息。其他域上的邪恶网站由于相同的源站策略而无法发出Ajax请求来获取这些数据,但它们可以通过标记包含URL。使用cookie访问URL,通过重写全局数组构造函数或访问器方法,可以在设置对象(数组或哈希)属性时调用方法,从而允许它们读取JSON内容。

while(1);&&&BLAH&&&防止了这种情况:mail.google.com上的Ajax请求将具有对文本内容的完全访问权,并且可以将其剥离。但是,标记插入会盲目地执行javascript而不进行任何处理,从而导致无限循环或语法错误。

这并不能解决跨站点请求伪造的问题。


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

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

攻击者可以代表您请求其他域上的页面,例如,使用


这是为了确保其他一些网站不能做一些卑鄙的把戏来窃取你的数据。例如,通过替换数组构造函数,然后通过标记包含此JSON URL,恶意的第三方站点可以从JSON响应中窃取数据。通过将while(1);放在开头,脚本将挂起。

另一方面,使用XHR和单独的JSON解析器的同一个站点请求很容易忽略while(1);前缀。


这将使第三方很难将JSON响应插入带有标记的HTML文档中。请记住,标签不受同一来源政策的限制。