JSON不可解析的cruft:为什么这么认真?
在阅读这个问题后,为什么谷歌/ Facebook等添加不可解析的cruft像:
while(1);
for(;;);
&&&START&&& ... &&&END&&&
对他们的JSON回应,我已经理解了动机。 但我仍然不清楚为什么会使用这种相对复杂的机制,而类似的效果可以通过类似的方式实现
)
在开始时渲染整个行无效,并出现语法错误 现在,似乎这增加了对无限循环和(怪异)语法错误的保护,以避免旧的和宽容的JavaScript解析器,但我似乎无法找到任何引用,指出这种情况。 while(1);
还有另外一个SO问题即将消失while(1);
解决方法(声明1可以被破坏)并拒绝表单{}&&
&&&的另一个解决方法,但不能解释为什么或引用任何来源。
其他参考:
/*-secure-n...*/
包装JSON 我认为有几个细节与不可解析的cruft形式有关:
{}&&
前缀可以追溯到JSON
解析器(显然,例如旧版本的Dojo)并不会将JSON
字符串验证为有效的JSON
语法。 我所知道的所有JSON
解析器库现在都在进行验证,但是从2008年开始的这篇博客文章表明,所述的dojo版本将允许JSON.parse
正常的json,而eval
只会失败,这将为您提供便捷的防范,防止JSON
劫持。
while(1)
可以使用Number
原型,通过将0
赋值为1
来使其无效。
for(;;)
和while(1)
两者都具有使被劫持站点崩溃的效果,因为任何脚本的每一次进一步执行都可以在没有错误的情况下被有效地停止,从而增加了保护。 这很重要,因为根据定义的错误不会在JavaScript中标记脚本执行的结束 ,而for(;;)
确保在脚本之后不会执行任何脚本。 这是为了防止攻击者通过利用window.onerror
,覆盖eval
或代理错误对象实例化(如覆盖Error.prototype
的constructor
Error.prototype
)成功拦截脚本错误(afaik假设)的情况。
UPDATE
security.stackexchange也存在这个问题,建议不要for(;;)
或while(1)
因为它可能暗示您的站点是DoS攻击客户端CPU或触发恶意软件扫描程序。 我没有看到现代浏览器出现严重的DoS问题,因为他们运行沙盒和每个Tab选项。 但它确实是旧版浏览器的问题。 恶意软件扫描程序是一个真正的问题,可能会将您的网站报告为攻击。
&&&START&&&
(以及相应的&&&END&&&
标记)使接收json的客户端的解析比使用更容易)
或可能无意中关闭的注释,并且可能会提高程序员的可读性和可见性。 包装在注释中只是其中的一个变种,因为它提供了/*
start和*/
end标签。 在我看来,在开始和结束时有一个清晰明确的标记,有助于注意到残留物的含义。 使用评论并不是真的提供这一点。
关于'1可以被击倒':
如果您执行以下操作(在webkit中):
var test = 1;
console.log(test.constructor == window.Number); //true is logged
理论上可能有这样的可能性,即有一种方法可以修改window.Number或其原型,以使1
的值不会为1
:
window.Number.prototype.toString = function() { return 0 };
window.Number.prototype.valueOf = function() { return 0 };
幸运的是这不起作用。 但我认为那是作者想要说的。
编辑通常我也倾向于使用的方法,你把内容包装到一个评论(但然后它必须确保你的json对象不包含这样的事情{"test":"*/"}
因为这将创建一个语法错误,甚至抛出的错误都可能是一个问题,如果它是可捕获的,并且可能暴露有关发生错误的行的一些信息,或者如果错误对象本身可以被改变。