《一种在JAVA虚拟机中安全运行第三方代码的方法.pdf》由会员分享,可在线阅读,更多相关《一种在JAVA虚拟机中安全运行第三方代码的方法.pdf(8页珍藏版)》请在专利查询网上搜索。
1、(10)申请公布号 CN 102902911 A (43)申请公布日 2013.01.30 C N 1 0 2 9 0 2 9 1 1 A *CN102902911A* (21)申请号 201210344765.8 (22)申请日 2012.09.18 G06F 21/51(2013.01) G06F 9/455(2006.01) G06F 9/445(2006.01) (71)申请人北京深思洛克软件技术股份有限公 司 地址 100084 北京市海淀区中关村南大街甲 6号铸诚大厦1906 (72)发明人不公告发明人 (54) 发明名称 一种在Java虚拟机中安全运行第三方代码 的方法 (57)。
2、 摘要 本发明公开了一种利用JVM提供的自定义类 加载器的技术实现安全运行不可控的第三方代码 的方法。通过控制第三方代码中可以使用的本地 模块和类,可以有效限制其对外部资源的访问,同 时也可以隔离多个同时运行的第三方代码。本发 明也提供了在第三方代码中以可控的方式透明访 问本地资源的方法。 (51)Int.Cl. 权利要求书1页 说明书5页 附图1页 (19)中华人民共和国国家知识产权局 (12)发明专利申请 权利要求书 1 页 说明书 5 页 附图 1 页 1/1页 2 1.一种在Java虚拟机中安全运行第三方类的方法,其特征在于,该方法包括: 创建自定义加载器,所述自定义加载器的父加载器为。
3、Java虚拟机当前线程的类加载 器; 通过所述自定义加载器来加载第三方类,由所述自定义加载器判断是否允许所述第三 方类加载特定的系统类; 如果允许,则所述自定义加载器委托其父加载器加载所述系统类; 若不允许,则抛出异常,从而控制所述第三方类中所能使用的类。 2.根据权利要求1所述的方法,其特征在于,根据需要,能够同时创建多个所述自定义 加载器以执行多份所述第三方类。 3.根据权利要求1所述的方法,其特征在于,关于所述第三方类所允许访问的类和/或 所不允许访问的类的信息存放在所述自定义类加载器能够找到的存放位置。 4.根据权利要求3所述的方法,其特征在于,所述信息存放在特定文件中,或所述信息 存。
4、放在数据库中,或所述信息直接写入在程序代码中。 5.根据权利要求2所述的方法,其特征在于,所述自定义类加载器加载所述第三方类 时,确定所述第三方类可使用和/或不可使用的类。 6.根据权利要求1-5所述的方法,其特征在于,如果所述自定义加载器判断出所述第 三方类加载不允许加载的类时,抛出异常。 7.根据权利要求2所述的方法,其特征在于,分别采用不同的加载器来分别加载所述 第三方类以防止恶意访问。 权 利 要 求 书CN 102902911 A 1/5页 3 一种在 Java 虚拟机中安全运行第三方代码的方法 技术领域 0001 本发明涉及信息安全领域,特别涉及一种安全运行不可控的第三方代码的方法。
5、。 背景技术 0002 软件或服务器往往需要允许用户执行自定义的代码以实现高度的可定制性或安 全性。但是由于第三方编写的代码的不可控性,限制其运行环境以保护服务器资源或上层 软件的正常运行就成了一个很重要的问题。 0003 JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备 的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能 来实现的。JVM屏蔽了与具体操作系统平台相关的信息,使Java程序只需生成在Java虚拟 机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。JVM在执行字节码 时,实际上最终还是把字。
6、节码解释成具体平台上的机器指令执行。 0004 在JVM中使用一个类时,该类的加载过程是唯一可以在外部进行干预的,这可以 通过JVM提供的自定义类加载器来实现。通常JVM中引入自定义类加载器的主要目的是实 现代码的热部署,如OSGi系统等。OSGi(Open Service Gateway Initiative)技术是面向 Java的动态模型系统。OSGi服务平台向Java提供服务,这些服务使Java成为软件集成和 软件开发的首选环境。OSGi技术提供允许应用程序使用精炼、可重用和可协作的组件构建 的标准化原语。这些组件能够组装进一个应用和部署中。 0005 JVM虚拟机提供的安全性主要通过虚。
7、拟机的安全策略文件实现,通过安全策略文 件控制JVM中类对资源的访问(如文件系统和网络资源等)。但是在实际应用中,往往需要控 制第三方代码本身不能直接访问一些外部资源(如文件、网络和一些本地模块的加载等), 但是可以通过调用本地提供的方法来访问,而且JVM同时运行多个不同的第三方代码时还 要实现代码间的相互隔离,这时只通过在JVM启动时静态地提供一个安全策略文件很难实 现。 发明内容 0006 有鉴于此,本发明提供了一种在JVM上安全运行第三方代码的方法,利用JVM提供 的自定义类加载器的技术来控制第三方代码的本地模块和类的加载,只允许第三方代码加 载和使用系统提供的已封装好业务逻辑的类,第三。
8、方代码对外部资源的访问只能通过上述 系统提供的已封装好的业务逻辑类的接口执行,第三方代码本身不能直接访问外部资源, 从而实现安全访问外部资源。 0007 根据本发明,提供一种在Java虚拟机中安全运行第三方类的方法,该方法包括: 创建自定义加载器,所述自定义加载器的父加载器为Java虚拟机当前线程的类加载 器; 通过所述自定义加载器来加载第三方类,由所述自定义加载器判断是否允许所述第三 方类加载特定的系统类; 说 明 书CN 102902911 A 2/5页 4 如果允许,则所述自定义加载器委托其父加载器加载所述系统类; 若不允许,则抛出异常,从而控制所述第三方类中所能使用的类。 0008 根。
9、据本发明的一个方面,根据需要,能够同时创建多个所述自定义加载器以执行 多份所述第三方类。 0009 根据本发明的一个方面,关于所述第三方类所允许访问的类和/或所不允许访问 的类的信息存放在所述自定义类加载器能够找到的存放位置。 0010 根据本发明的一个方面,所述信息存放在特定文件中,或所述信息存放在数据库 中,或所述信息直接写入在程序代码中。 0011 根据本发明的一个方面,所述自定义类加载器加载所述第三方类时,确定所述第 三方类可使用和/或不可使用的类。 0012 根据本发明的一个方面,如果所述自定义加载器判断出所述第三方类加载不允许 加载的类时,抛出异常。 0013 根据本发明的一个方面。
10、,分别采用不同的加载器来分别加载所述第三方类以防 止恶意访问。 附图说明 0014 图1为按照本发明的一种在JVM上安全运行第三方代码的方法的一优选实施例的 流程示意图。 0015 图2为图1所示实施例中结构框图。 具体实施方式 0016 当JVM需要加载第三方代码时,创建一个自定义的类加载器,其父加载器设置为 JVM当前线程的默认类加载器(根据本发明的一个实施例,通常就是SystemClassLoader), 通过自定义类加载器的一个实例来加载第三方代码。在自定义类加载器中通过一个可使用 类的列表(或不可使用类的列表)来控制第三方代码中外部类的使用,自定义类加载器的功 能如下: 1、对于允许。
11、使用的本地模块中的类(如java.lang.String等, 所有的java类都要继 承java.lang.Object类,下面不再赘述),直接委托其父加载器(SystemClassLoader)执 行,这也是JVM类加载器的默认行为,由此第三方代码可以正常使用这些类; 2、对于不允许使用的本地模块中的类(如.*和java.io.*等),自定义类加 载器将直接抛出ClassNotFound异常; 3、需要访问外部资源的业务逻辑封装于单独的功能类中(下文称为Function类),自定 义类加载器将直接由其父加载器加载Function类,由此Function类中再加载使用其它类 时(如.*等限制第。
12、三方代码使用的类)将直接使用父加载器,从而安全地绕过自定 义类加载器的限制。 0017 如此便可以实现第三方代码本身只能使用允许的类,可以轻易地断绝其访问外 部资源(此处指所有不允许访问的资源包含虚拟机自身内存等)的途径,同时可以通过 Function类提供的高级接口以可控的方式访问外部资源。 0018 通常JVM提供的非访问外部资源的类可以由第三方代码安全调用,如java.lang. 说 明 书CN 102902911 A 3/5页 5 String以及java.math模块中的等大部分的类都是如此。对待这些类的加载,根据本发明 的一个是实施例,自定义的类加载器MyClassLoader的行。
13、为即是JVM类加载器的默认行为, 即双亲代理模式(即,优先委托自己的父加载器加载,父加载器不能加载时才自己加载。)。 而对于java.io、以及java.thread等模块中的类,自定义类加载器将会打破JVM 的默认行为,从而拒绝加载这些类;自定义类加载器正常(委托其父加载器)加载Function 类后,Function类便属于自定义类加载器的父加载器,所以Function类中的类加载将由自 定义类加载器的父加载器负责,从而可以在Function中实现访问外部资源实现业务逻辑, Function代码由功能提供者实现,是可控的,而第三方代码只能通过这一条途径来访问外 部资源,因此也是可控的。 0。
14、019 自定义类加载器中的允许或不允许加载的类列表可以是预置的,所有的第三方类 代码使用相同的配置;也可以是加载不同的第三方类代码时现读取的,每个类有不同的权 限,由此在JVM中实现动态的代码权限控制。 0020 在JVM中,通过类加载器和类名才能确定一个类,对于不同的第三方代码,都创建 一个新的自定义类加载器实例来加载。由于第三方代码加载时需要不同的类加载器,所以 第三方代码之间无法相互访问,从而实现了不同第三方代码之间的隔离。当所执行的第三 方代码之间不需要隔离时(如是同一个用户的代码),则可以使用同一个类加载器加载,从 而节省系统资源。 0021 上述自定义类加载器通常可以通过重载Cla。
15、ssLoader类的findClass和 loadClass方法即可实现,此为Java中的标准方法,本发明中不再赘述。 0022 为使本发明的目的、技术方案及优点更加清楚明白,以下结合附图描述本发明的优选 实施例,对本发明进一步详细说明。 0023 如图1所示,本发明中自定义类加载器加载一个类包括如下步骤:其中,在该类的 实例创建时已经获得了哪些类可加载而哪些类不可加载的信息,在图1中已经略去): 步骤1:开始执行; 步骤2:判断是否允许加载该类;如果允许加载该类,则进入步骤3,否则抛出 ClassNotFound异常; 步骤3:判断加载的类是否是要限制使用的第三方类,如果是,则进入步骤4;如。
16、果不 是,则进入步骤5; 步骤4:从字节码直接加载第三方类; 步骤5:委托父加载器加载第三方类; 步骤6:结束加载过程。 0024 图2给出了实现本发明的结构示意图。 0025 图2虚线框中为第三方代码运行环境,该环境运行在JVM中。其中包括第三方类 代码本身和访问外部资源的业务逻辑封装类。 0026 第三方类代码需要通过自定义类加载器才能被系统类加载器所加载,而访问外部 资源的业务逻辑封装类则直接由系统类加载器加载。 0027 其中,第三方类代码在未加载到JVM前是文本形式的代码,而加载到JVM中之后是 一个类。 说 明 书CN 102902911 A 4/5页 6 0028 实施例1 该实。
17、施例中需要加载的第三方类是ThirdExample。第三方类ThirdExample的字节码 存在ThirdExample.class文件中,只允许直接使用java.lang.String类和默认的java. lang.Object类。而ThirdExample类只允许直接使用java.lang.String类的信息则存放 在ThirdExampleAccess.txt这个文本文件中。在ThirdExample类中需要访问外部资源/ tmp/example.db文件。该功能通过类example.FileAccessWrapper提供的公共方法(read 和write,即读写功能)实现,而exa。
18、mple.FileAccessWrapper是系统提供者提供的访问外 部资源的封装类,该封装类根据系统的安全需求以及业务逻辑编写。在本例中example. FileAccessWrapper通过使用java.io.*等在ThirdExample中不能使用的类来实现文件操 作,同时该类只能访问/tmp/example.db文件,从而防止了ThirdExample对其它资源的访 问。 0029 其中ThirdExampleAccess.txt文件的内容描述相应第三方代码可以加载的类, 形式可以根据需求进行选择,如其中记录可以加载的类,或只记录不可以加载的类,或两者 都记录等等。 0030 通过Th。
19、irdExample.class可以确定其对应的权限文件的位置,如本例中可以通 过文件名来找到ThirdExampleAccess.txt文件。ThirdExample类由自定义的类加载器 MyClassLoader加载,本例中MyClassLoader的工作流程如下: 1、创建MyClassLoader,以当前线程的加载器作为其父加载器; 2、若加载ThirdExample类,则从ThirdExample.class中读取类字节码,然后加载;同 时读取对应的ThirdExampleAccess.txt,确定ThirdExample可使用类的列表(或不可加载 类的列表);3、加载(都是从类Th。
20、irdExample中)其它类时,若ThirdExampleAccess.txt中 允许加载,则委托其父加载器加载,否则抛出ClassNotFound异常; 本例中只有java.lang.String和example.FileAccessWrapper可以加载, 在ThirdExample所有加载其它类的操作均会抛出ClassNotFound异常,从而使得 ThridExample没有途径直接访问外部资源,example.FileAccessWrapper提供了访问外部 资源途径的同时也隐藏了相关细节。 0031 4、当ThirdExample类执行完毕后,MyClassLoader便不再使用。
21、(可被回 收)。此外,根据本实施例,可以根据需要同时创建多个MyClassLoader以执行多份 ThirdExample代码,这些MyClassLoader之间的执行过程互不影响。 0032 实施例2 同上例,只是控制第三方类中可访问的资源不同。第三方类代码ThirdExample. class(存在文件中)允许直接使用除.*以外的所有类,此信息放在 ThirdExampleAccess.txt这个文本文件。外部需要通过网络访问TCP的80端口。该功能通 过类example.NetAccessWrapper提供的公共方法(open、send、recieve和close,即打开、 发送、接收和。
22、关闭功能)实现,example.NetAccessWrapper隐藏为网络访问的细节(如协 议、端口和底层实现等)。example. NetAccessWrapper是系统提供者提供的访问外部资源 的封装类,根据系统的安全需求以及业务逻辑编写。在本例中example. NetAccessWrapper 说 明 书CN 102902911 A 5/5页 7 通过使用.*等在ThirdExample中不能使用的类来实现文件操作,同时该类只能 访问TCP的80端口,从而防止了ThirdExample对其它网络资源的访问。 0033 自定义的类加载器MyClassLoader工作流程如下: 1、 创建。
23、MyClassLoader,以当前线程的加载器作为其父加载器; 2、 若加载ThirdExample类,则从ThirdExample.class中读取类字节码,然后加载; 同时读取对应的ThirdExampleAccess.txt,确定ThirdExample可使用类的列表(或不可加 载类的列表); 3、 加载(都是从类ThirdExample中加载)其它类时,若ThirdExampleAccess. txt中允许加载,则委托其父加载器加载,否则抛出ClassNotFound异常;本例中除java. net.*以外的所有类都可以加载,在ThirdExample所有加载任何.*类的操作均 会抛出。
24、ClassNotFound异常,从而使得ThridExample没有途径直接访问网络,example. NetAccessWrapper提供了访问外部资源途径的同时也隐藏了相关细节。 0034 4、 当ThirdExample类执行完毕后,MyClassLoader便不再使用(可被回收)。此 外,根据本实施例,可以根据需要同时创建多个MyClassLoader以执行多份ThirdExample 代码,这些MyClassLoader之间的执行过程互不影响。 0035 实施例3 此外,根据本发明的一个具体实施方式,除了上述两个具体实施例中通过读取 ThirdExampleAccess.txt,从而。
25、确定ThirdExample可使用类的列表(或不可加载类的列表) 的方式之外,本领域的技术人员完全可以采用其它的方式来确定所述第三方类所允许访问 的类和/或所不允许访问的类的信息,其中一种具体的方式就是将所述信息存放在数据库 中,或所述信息直接写入在程序代码中。这种变化对于本领域技术人员而言是容易实现的, 其相应的后续步骤与上述实施例1、2的后续步骤类似,不再赘述。 0036 以上所述仅为本发明的较佳实施例而已,并非用于限定本发明的保护范围。凡在本发 明的精神和原则之内,所作的任何修改、等同替换以及改进等,均应包含在本发明的保护范 围之内。 说 明 书CN 102902911 A 1/1页 8 图 1 图 2 说 明 书 附 图CN 102902911 A 。