Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/459.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么这么严重?_Javascript_Json_Security - Fatal编程技术网

Javascript 为什么这么严重?

Javascript 为什么这么严重?,javascript,json,security,Javascript,Json,Security,在阅读了关于为什么谷歌/脸谱网等网站的问题后,添加了一些无法形容的污点,如: while(1) (;;)的 &&&&START&&&&&&&结束&& 1和3合并 对于他们的JSON回应,我已经理解了动机。但我仍然不清楚为什么会使用这种相对复杂的机制,而类似的效果可以通过类似的方法实现 在开头添加额外的),以使整行无效并出现语法错误 在注释中包装JSON 现在,这种对无限循环和(奇怪的)语法错误的额外保护似乎是为了绕过旧的、允许的javascript解析器,但我似乎找不到任何说明这种情况的

在阅读了关于为什么谷歌/脸谱网等网站的问题后,添加了一些无法形容的污点,如:

  • while(1)
  • (;;)的
  • &&&&START&&&&&&&结束&&
  • 1和3合并
对于他们的JSON回应,我已经理解了动机。但我仍然不清楚为什么会使用这种相对复杂的机制,而类似的效果可以通过类似的方法实现

  • 在开头添加额外的
    ,以使整行无效并出现语法错误
  • 在注释中包装JSON
现在,这种对无限循环和(奇怪的)语法错误的额外保护似乎是为了绕过旧的、允许的javascript解析器,但我似乎找不到任何说明这种情况的引用。还有另一种方法甚至在(1)的时候分解了
变通方法(说明1可能被删除)并拒绝另一种形式为
{}&
的变通方法,但没有解释原因或引用任何来源

其他参考资料:

  • ,建议将JSON包装在
    /*-secure-\n...*/

关于“1可以被击倒”的问题:

如果您执行以下操作(在webkit中):

理论上可能存在这样一种可能性,即有一种方法可以修改window.Number或其原型,使
1
的值不会是
1

window.Number.prototype.toString = function() { return 0 };
window.Number.prototype.valueOf = function() { return 0 }; 
幸运的是,这不起作用。但我认为这正是作者想要说的

编辑
通常,我也倾向于使用将内容包装到注释中的方法(但必须确保json对象不包含类似以下内容:
{“test”:“*/”}
因为这样会产生语法错误。即使抛出的错误也可能是一个问题,如果它是可捕获的,并且可能会暴露有关错误发生行的一些信息。或者如果错误对象本身可以更改。

我想有几个细节与不可解析的积垢的形式有关:

  • {}&
    前缀可以追溯到
    JSON
    解析器(显然&例如旧版本中的Dojo)不验证
    JSON
    字符串是否为有效的
    JSON
    语法。我知道的所有
    JSON
    解析器库现在都进行验证,但从2008年开始,建议上述版本的dojo将允许
    JSON。正常解析
    JSON,而
    eval
    将失败,这将为您提供方便的保护针对
    JSON
    劫持的检查

  • while(1)
    可以使用
    Number
    原型,通过将
    0
    指定为
    1
    的值,使其无效

  • 用于(;)
    while(1)
    两者都会使被劫持的站点崩溃,这在一定程度上增加了保护,因为任何脚本的每次进一步执行都会被有效地停止而不会出错。这一点很重要,因为在javascript中定义的错误并不表示脚本执行的结束,而(;;)的
    确保之后不会执行任何脚本。这是为了防止(假设)攻击者利用
    窗口中的漏洞成功拦截脚本错误。onerror
    、覆盖
    eval
    或代理错误对象实例化(如覆盖
    Error.prototype的
    构造函数

    更新

    还有人建议不要对(;)
    while(1)使用
    因为这可能意味着你的网站是DoS攻击客户端CPU或触发恶意软件扫描程序。我认为现代浏览器没有严重的DoS问题,因为它们以沙盒和每个标签为基础运行。但这确实是旧浏览器的问题。恶意软件扫描程序是一个真正的问题,可能会报告你的网站受到攻击

  • &&&START&&&&
    (以及相应的
    &&&END&&&&
    标记)使接收json的客户端解析比仅使用
    更容易
    或可能被无意关闭的注释,可能会提高程序员的可读性和可见性。在注释中包装只是其中的一种变化,因为它提供了
    /*
    开始和
    */
    结束标记。在我看来,在开始和结束处有一个清晰的标记有助于注意到积垢的含义.使用评论并不能真正做到这一点


事实上,您关于语法错误泄漏信息的观点可能就是为什么仅仅在JSON前面加一个无效字符串是个坏主意的原因。因此,这排除了我建议的第一个选项(在JSON前面加一个简单的
前缀),但是
&&&START&&&&&&&&&&&结束(&&&
执行。@Manav有一件事,但这只是猜测,使用(;)
,而(1)
&&&&START(&&&
结合使用,首先是尝试停止脚本的执行,并出现语法错误。如果这不起作用,至少用无休止的循环阻止恶意站点。但老实说,我还需要再做一些进一步的阅读。但我认为所有可以被解析为代码或抛出异常的东西都可能是坏的。@Manav另一个注意事项是(但这也只是一个猜测):因为当前的js引擎在最初执行代码之前做了很多预处理和优化,在不了解引擎代码的内部结构的情况下,不清楚代码中的对象何时以及如何初始化。这就是为什么我会认为将json结果封装到注释中是更好的解决方案。是我一个人,还是这感觉像是隐晦中的安全性,甚至对于任何编写合理的XSS攻击都不会是问题?parse()真的调用eval()吗?一个相关的问题是为什么它们不返回JSON对象
window.Number.prototype.toString = function() { return 0 };
window.Number.prototype.valueOf = function() { return 0 };