沙箱模型成就了java的
安全性,沙箱基本组件有:
类装载器结构
class文件检验器
jvm和java语言本身具有的安全特性
安全管理器和java API
不同的类装载器装载的类具有不同的命名空间,jvm维护这个命名空间,同一个命名空间里不可能有两个相同名字的类。同一个命名空间里的类可以直接进行交互,不同命名空间的则不行,除非显示提供允许
他们交互的机制。
用户
自定义的类装载器通常需要依赖其他装载器,至少要依赖jvm刚启动时创建的启动类装载器。类装载器请求另一个类装载器来装载类型,这个过程被叫做
双亲委派模式。也就是说,出了启动类装载器,其他装载器都有一个“双亲”类装载器。当特定的装载器需要装载一个类型时,会默认将这个任务“委派”给它的双亲,委派的过程一直向上继续,直到启动类装载器(装载了核心的java API的class文件)。如果一个类装载器的双亲类装载器有能力装载这个类型,则双亲装载器返回这个类型,否则,这个类装载器自己装载。
还有一个
运行时包的概念,指的是同一个类装载器装载,属于同一个包的多个类型的集合。比如,用户的类装载器装载了一个java.lang.Virus的类(假设是一个有害类)前面说到同一个命名空间的类可以直接进行交互,那这个类可以得到java.lang这个包的
访问权限吗?肯定是不能的,因为他们不是一个运行时包。
我们也可以简单的通过拒绝装载特定的类型来保护被信任的类库(启动类装载器的java API)的边界。我们可以编写自己的装载器,让它做的第一件事就是确保这个类不是某个被禁止包的成员。这样的类如果请求被装载,我们的类转载器就会抛出安全
异常,而不是向上委派。
class文件检验器通过进行四趟独立的扫描来完成任务。第一次是类被装载时进行的,主要检查内部结构,看是否能通过编译;第二和第三是在连接过程中进行,确定数据类型是否遵守java的语义,包括检查字节码的完整性;第四趟是在动态连接的过程中
解析符号引用时进行,主要确认被引用的类,方法和字段确实存在。
jvm装载了一个类,并对他进行了三趟的class文件检验,这些字节码就可以运行了。除了对符号引用的检验,jvm还会进行一些其他的内在安全机制的操作。
*类型安全的引用转换
*结构化的
内存访问
*自动垃圾收集
*数组边界检查
*空引用检查
这些jvm的特性都能保证java程序的健壮性。
安全管理器主要是保护jvm的外部资源不被内部运行的恶意或有漏洞的代码侵犯,定义了沙箱的外部边界,是用户可自定制的。安全管理器主要负责两个任务:说明一个安全策略以及执行这个策略。安全策略指明了哪种代码能执行哪种操作,由安全管理器中的‘check’方法定义。当他们被调用时,这个策略将被这个’check‘方法所实施。
另外,java安全模型很重要的一点是支持认证。认证功能加强了用户的能力,使用户能够通过一个沙箱建立多种安全策略,这个沙箱可以依赖于为这个代码提供担保的对象来改变。这样,能够一定程度上简化沙箱对代码的
限制。