就其本身而言,Java 具有很好的安全性,即其固有的对缓冲区溢出和内存管理错误的抵抗力:
所有数组访问都根据分配的数组长度进行检查。因此,缓冲区溢出被可靠地捕获,并触发异常,这更好(这将远程代码执行漏洞转变为纯粹的拒绝服务)。
内存分配是通过垃圾收集器管理的,它可以防止释放后使用和双重释放错误。此外,GC 允许更轻松地处理字符串(字符串在 Java 中是不可变的),这消除了大多数情况下的缓冲区溢出错误。
强制输入严格;代码无法访问它们不是的数据字节。这再次防止了漏洞(数据类型被违反的错误将在编译时报告,或者在最坏的情况下,作为运行时报告ClassCastException
)。
这使得 Java在安全性方面比许多编程语言(尤其是地狱般的 C/C++)强大得多。
然而,Java 设计者试图利用这种增强的安全性来制作一些困难的东西,例如applet。问题是攻击面:由于小程序是潜在的恶意代码,它所做的一切都必须受到控制。但是恶意代码必须能够使用“标准 Java 类”才能执行任何操作,因此必须在每个单独的标准 Java 类上强制执行“控制点”。因此,攻击面由数百个包含数千个方法的类组成,并且所有这些类都必须强制执行足够的检查。
Java 设计者因野心而犯了罪:在不搞砸任何检查的情况下实现数千次检查的难度比他们想象的要高得多。所有的“Java bug”都来自这个事实。
我们可以在这里比较 Java 和 Javascript;例如,Java 允许访问磁盘上的文件,但不得将这种权利授予小程序,除非小程序要求并且用户同意(这涉及整个小程序签名业务)。Javascript,不那么雄心勃勃,只是缺少任何文件访问方法:如果函数实际上不存在,则无法正确实现函数的访问控制!
总结一下: Java 很好而且很安全。Java小程序意味着一个巨大的攻击面,其安全性很难保证。但是,对于独立的应用程序和服务器,如果您需要安全性,使用 Java 是一个好主意(这同样适用于 C#)。