目录

  1. 概述
  2. 不同 JDK 下沙箱的实现
    1. JDK1.0 时期
    2. JDK1.1 时期
    3. JDK1.2 时期
    4. JDK1.6 时期
  3. java 程序的安全性
  4. 总结
  5. 附录

概述

❓什么是沙箱?

在计算机安全中,沙箱是一种分离正在运行程序的安全机制,这么做的目的是为了:最大限度地减少系统故障或软件漏洞的传播(如果没有沙箱安全机制,一个程序的 BUG 可能由于传播造成整个系统的不可用)

❓沙箱安全机制可以用来做什么?

沙箱是一个独立的计算环境,程序或文件可以在其中执行,而不会影响其他运行的应用程序,软件开发人员可以使用沙箱来测试新的编程代码

✨沙箱安全模型特点

  • 沙箱能够为非本地程序提供一组严格控制的资源,例如磁盘和内存上的有限资源使用
  • 沙箱安全机制保证对 Java 核心源代码的保护

例如:自定义 String 类,但是在加载自定义 String 类的时候会率先使用引导类加载器加载(双亲委派机制),而引导类加载器在加载的过程中会先加载jdk自带的文件(由于 rt.jar 包中存在java\lang\String.class),所以自定义 String 类不起作用,也就避免了用户自定义的 String 类替代 JDK 中的 String 类

✨沙盒经常用于测试可能包含病毒或其他恶意代码的未经验证的程序,而不允许软件损害主机设备,平时遇到的沙箱机制还有

  • 在编程竞赛中测试程序的在线评判系统
  • HTML5 有一个用于 iframe 的“沙箱”属性
  • Linux 内核中的安全计算模式(seccomp)就是一种沙箱模式,激活后,seccomp 只允许 write()read()exit()sigreturn() 系统调用

本文主要还是讲解沙箱安全机制在 Java 中的实现细节,下图就是最初 Java 实现的沙箱安全机制

不同 JDK 下沙箱的实现

沙箱安全模型只是一种理论模型,在不同的 JDK 版本中都有更优秀的实现方式,接下来主要介绍 Java 发展过程中对沙箱模型的优化

JDK1.0 时期

✨JDK1.0 中将执行程序分成本地代码远程代码两种:

  • 本地代码默认视为可信任的,而远程代码则被看作是不受信的
  • 对于授信的本地代码,可以访问一切本地资源,而对于非授信的远程代码在早期的 Java 实现中,安全依赖于沙箱(Sandbox)机制

1.0

JDK1.1 时期

✨JDK1.0 中如此严格的安全机制也给程序的功能扩展带来障碍,比如:当用户希望远程代码访问本地系统的文件时候,就无法实现,因此在后续的 Java1.1 版本中,针对安全机制做了改进,增加了安全策略,允许用户指定代码对本地资源的访问权限

1.1

JDK1.2 时期

✨在 Java1.2 版本中,再次改进了安全机制,增加了代码签名。不论本地代码或是远程代码,都会按照用户设定的安全策略,由类加载器加载到虚拟机中权限不同的运行空间,实现差异化的代码执行权限控制

1.2

JDK1.6 时期

✨JDK1.6 是当前最新的安全机制实现,引入了域(Domain)的概念,虚拟机会把所有代码加载到不同的系统域应用域

  • 系统域:负责与关键资源进行交互
  • 应用域:通过系统域的部分代理对各种需要的资源进行访问

虚拟机中不同的受保护域(Protected Domain),对应不一样的权限(Permission),存在域中的类文件就具有当前域的全部权限

1.6

java 程序的安全性

✨沙箱安全机制只是保证 Java 程序的一种安全机制,Java 还存在其他保证安全性方法

  • Java 中通过多种机制提供整体安全性,比如:自动内存管理、垃圾收集以及字符串和数据的范围检查等语言功能,帮助 Java 开发人员减少这些额外操作的负担
  • 编译器和字节码验证器确保只执行合法的 Java 字节码,字节码验证器与 Java 虚拟机一起保证运行时的语言安全
  • 类加载器定义了一个本地命令空间,可以用来确保不受信任的小程序不会干扰其他程序的运行
  • 对关键系统资源的访问由 Java 虚拟机进行调解,并由 SecurityManager 类预先检查,该类将一段不受信任的代码的操作限制在最低限度

总结

📓Java 沙箱安全机制能够

  • 保证程序安全
  • 保护 Java 原生的 JDK 代码

附录

sandbox-security-model