沙箱安全机制的应⽤层⾯:360沙箱、win10沙箱、包括VMware Workstation、Oracle VM VirtualBox都可以充当沙箱去使⽤,沙箱中的操作与本机⽆关,进⽽保证本机的安全性那什么是Java沙箱安全机制呢?
组成Java沙箱的基本组件
1.类加载体系结构(类的双亲委托机制)2.class⽂件检验器
3.内置于Java虚拟机(及语⾔)的安全特性4.安全管理器及Java API
Java安全模型的前三个部分——类加载体系结构、class⽂件检验器、Java虚拟机(及语⾔)的安全特性⼀起达到⼀个共同的⽬的:保持Java虚拟 机的实例和它正在运⾏的应⽤程序的内部完整性,使得它们不被下载的恶意代码或有漏洞的代码侵犯。
相反,这个安全模型的第四个组成部分是安全管理器,它主要 ⽤于保护虚拟机的外部资源不被虚拟机内运⾏的恶意或有漏洞的代码侵犯。这个安全管理器是⼀个单独的对象,在运⾏的Java虚拟机中,它在对于外部资源的访 问控制起中枢作⽤。
类加载体系结构
类加载器要加载⼀个类,它⾸先检查此类是否已被加载,然后再委托双亲加载器加载此类,它的双亲加载器再委托它的双亲,这样⼀直委托到启动加载器,启动加载 器在从核⼼API查找此类,如果有就返回此类,否则就他的⼦加载器就查找此类,如果都没有就抛出ClassNotFound的异常。如下图所⽰:
这种委托双亲的模式好处是:
1.启动类加载器可以抢在标准扩展类装载器之前去装载类,⽽标准扩展类装载器可以抢在类路径加载器之前去装载那个类,类路径装载 器⼜可以抢在⾃定义类加载器之前去加载它。所以Java虚拟机先从最可信的Java核⼼API查找类型,这是为了防⽌不可靠的类扮演被信任的类,试想⼀ 下,⽹络上有个名叫java.lang.Integer的类,它是某个⿊客为了想混进java.lang包所起的名字,实际上⾥⾯含有恶意代码,但是这种伎俩在双亲模式加载体系结构下是⾏不通的,因为⽹络类加载器在加载它的时候,它⾸先调⽤双亲类加载器,这样⼀直向上委托,直到启动类加载器,⽽启动类加载 器在核⼼Java API⾥发现了这个名字的类,所以它就直接加载Java核⼼API的java.lang.Integer类,然后将这个类返回,所以⾃始⾃终⽹络上的 java.lang.Integer的类是不会被加载的。
2.但是如果这个移动代码不是去试图替换⼀个被信任的类(就是前⾯说的那种情况),⽽是想在⼀个被信任的包中插⼊⼀个全新的类型,情况会怎样呢?⽐如⼀个名为 java.lang.Virus的类,经过双亲委托模式,最终类装载器试图从⽹络上下载这个类,因为⽹络类装载器的双亲们都没有这个类(当然没有了,因为 是病毒嘛)。假设成功下载了这个类,那你肯定会想,Virus和lang下的其他类痛在java.lang包下,暗⽰这个类是Java API的⼀部分,那么是不是也拥有修改Java.lang包中数据的权限呢?答案当然不是,因为要取得访问和修改java.lang包中的权 限,java.lang.Virus和java.lang下其他类必须是属于同⼀个运⾏时包的,什么是运⾏时包?运⾏时包是指由同⼀个类装载器装载的、属 于同⼀个包的、多个类型的集合。考虑⼀下,java.lang.Virus和java.lang其他类是同⼀个类装载器装载的吗?不是 的!java.lang.Virus是由⽹络类装载器装载的!
class⽂件校验器
通过四趟扫描,保证了class⽂件正确
第⼀趟是,检查class⽂件的结构是否正确。⽐较典型的就是,检查class⽂件是否以魔数OxCAFEBABE打头(CA FE BA BE)。通过这趟检查,可以过滤掉⼤部分可能损坏的,或者压根就不是class的⽂件,来冒充装载。
第⼆趟是,检查它是否符合java语⾔特性⾥的编译规则。⽐如发现⼀个类的超类不是Object,就抛出异常。
第三趟是,检查字节码是否能被JVM安全的执⾏,⽽不会导致JVM崩溃。这⾥提到了⼀个停机的问题。内容是这样的,“即不可能写出⼀个
程序,⽤它来判定作为其输⼊⽽读⼊的某个程序,是否会停机”。意思是,不可能写⼀个程序,让它告诉你,另外⼀个程序会不会中断或崩溃。
第四趟是,符号引⽤验证。⼀个类⽂件,它会包含它引⽤的其他类的全名和描述符,并跟他们建⽴符号引⽤(⼀种虚拟的,⾮物理连接的⽅式)。当程序第⼀次执⾏到需要符号引⽤的位置时,jvm会检查这个符号链接的正确性,然后建⽴真正的物理引⽤(直接引⽤)。
内置于Java虚拟机(及语⾔)的安全特性
这些都是基础的java语⾔特性,他们降低了java程序出现内存混乱,崩溃的⼏率。·结构化内存访问(不使⽤指针,⼀定程度上让⿊客⽆法篡改内存数据)·⾃动垃圾收集·数组边界检查·空引⽤检查·数据类型安全
安全管理器及Java API
这是安全沙箱中,离我们程序员最接近的⼀环。
1.securityMananger,是⼀个api级别的,可⾃定义的安全策略管理器,它深⼊到java api中,在各处都可以见到它的⾝影。⽐如
SecurityClassLoader。默认情况下,java应⽤程序是不设置 securityManager 实例的(意味着不会起到安全检查),这个实例需要我们在程序启动时通过 System.setSecurityManager 来设置。
2.⼀般情况下,检查权限是,通过 SecurityManager.checkPermission(Permission perm) 来完成的。外部程序通过,创建Permission实例,传递给前⾯的check。Permission是⼀个抽象类,需要继承它实现不同的权限验证,⽐如 FilePermission,代表对某个⽂件的读写权限。new FilePermission(\"test.txt\
因篇幅问题不能全部显示,请点此查看更多更全内容