语言的安全: 无指针地址操作,空指针检查,数组越界检查,类型转换检查,使得保证程序运行在jvm沙箱中,不会破坏其它区域的内存。
代码的安全:java文件编译后得到的class文件,jvm的classloader加载class文件中的bytecode时,会做一系列的检查
代码的合法性: jar包中包含整个java文件的签名,使用证书签署中心签署的合法私钥进行加密。使用公钥进行解密,验证java文件未被窃改过,且开发第三方合法。
classloader:类加载器自己保留的名字空间,以及双亲委托加载策略,保证第三方的java程序不会入侵jvm基础类,不同第三方的java程序互相不可见安全隔离。
实时权限检查:通过java.lang.SecurityManager完成,在jvm启动项中配置 -Djava.security.manager -Djava.security.policy=/home/admin/policy.file,默认是关闭的,所以默认状态下,是没有代码安全检查的
可以编辑策略文件,实现自定义安全。也可以通过System.setSecurityManager(new MySecurityMananger());实现自定义安全。
一个xx.policy文件,在jvm启动后,装载为Policy类,jvm中仅有唯一的一个Policy对象。Policy中定义了,CodeBase,标识class类属于哪个来源,并且定义每个codeBase下,能够拥有哪些Permission列表。通过xx.policy文件,完成这些安全模型后。jvm开始通过classloader加载class类。每加载一个class类,会去Policy中找到对应的codeBase和Permission列表,从而生成一个安全域,包含类的来源(codeBase),拥有的权限(Permission列表)。每个类都会有对应的SecurityDomain标识其安全属性。最后,执行程序时,PrivilegeController.checkAccess会去线程栈上找到每个类以及其对应的安全域,来做方法调用的安全检查。
protected限制:运行时包权限,意味着只能访问同一个加载器加载的同一个包中的类。比如第三方包中定义了java.lang.Virous这样的类,用于访问java.lang.*下面类的protected方法,试图入侵。然而protected不仅是同package可见,还必须是运行时包可见。