文档章节

java安全沙箱(四)之安全管理器及Java API

xionghuiCoder
 xionghuiCoder
发布于 2015/09/04 23:34
字数 1752
阅读 1548
收藏 15

java是一种类型安全的语言,它有四类称为安全沙箱机制的安全机制来保证语言的安全性,这四类安全沙箱分别是:

本篇博客主要介绍“类安全管理器及Java API”的基本原理,如需了解其它几类安全机制可以通过上面的博客链接进入查看

简介

java安全沙箱的前三类保证了jvm所运行程序的完整性,使得jvm不会因为运行有漏洞或恶意的代码而导致出现不可预期的状态。而第四类沙箱模型是“类安全管理器及Java API”,它能保护jvm在运行有漏洞或恶意的代码不会破坏外部资源。java通过称为安全管理器的一类API来保证这类安全性。

安全策略文件

首先介绍下安全策略文件,如果启用了安全管理器,默认会使用jre自带的安全策略文件$JAVA_HOME/jre/lib/security/java.policy来指定访问外部资源的权限,该策略文件也可以通过jvm参数-Djava.security.policy来指定。

Policy文件的主要格式如下:

keystore "some_keystore_url", "keystore_type";
grant [SignedBy "signer_names"] [, CodeBase "URL"] {
    Permission permission_class_name ["target_name"] [,"action"] [,SignedBy"signer_names"];
    … …
};

  1. "keystore"记录 

    一个keystore是一个私有密钥(private keys)数据库和相应的数字签名,例如X.509证书。Policy文件中可能只有一条keystore记录(也可能不含有该记录),它可以出现在文件中grant记录以外的任何地方。Policy配置文件中指定的keystores用于寻找grant记录中指定的、签名者的公共密钥(public keys),如果任何grant记录指定签名者(signer_names),那么,keystore记录必须出现在policy配置文件中。

    "some_keystore_url"是指keystore的URL位置,"keystore_type"是指keystore的类型。第二个选项是可选项,如果没有指定,该类型则假定由安全属性文件(java.security)中的"keystore.type"属性来确定。keystore类型定义了keystore信息的存储和数据格式,用于保护keystore中的私有密钥和keystore完整性的算法。Sun Microsystems支持的缺省类型为“JKS”。

  2. "grant"记录

    Policy文件中的每一个grant记录含有一个CodeSource(指定代码)及其permission(许可)Policy文件中的每一条grant记录遵循下面的格式,以保留字“grant”开头,表示一条新的记录的开始,“Permission”是另一个保留字,在记录中用来标记一个新的许可的开始。每一个grant记录授予一个指定的代码(CodeBase)一套许可(Permissions)。permission_class_name必须是一个合格并存在的全限定性类名,例如java.io.FilePermission

    target_name用来指定目标类的位置,action用于指定目标类拥有的权限。 target_name可以直接指定类名(可以是绝对或相对路径),目录名,也可以使用通配符/、/*或着/-。

    directory/ 表示directory目录下的所有.class文件,不包括.jar文件

    directory/* 表示directory目录下的所有的.class及.jar文件

    directory/- 表示directory目录下的所有的.class及.jar文件,包括子目录

下面是一个policy文件的demo:

grant codeBase "file:${{java.ext.dirs}}/*" {
        permission java.security.AllPermission;
};
grant {
        permission java.lang.RuntimePermission "stopThread";
        permission java.net.SocketPermission "localhost:1099", "listen";        
        permission java.util.PropertyPermission "java.version", "read";
        ... ...
};

例如:对于java.net.SocketPermissionaction可以是:listenacceptconnectreadwrite;对于java.io.FilePermission,action可以是:read, write, delete和execute。

安全管理器

java的安全管理器可以定制,也可以使用jdk的默认实现java.lang.SecurityManager,启动安全管理器的话有两种方式,一种是通过硬编码的方式启动,另外一种是通过jvm参数-Djava.security.manager启动。

下面的测试用例都使用jre的默认policy文件配置:

grant {
        ... ...       
        permission java.util.PropertyPermission "java.version", "read";
        ... ...
};

该策略文件指定了"java.version"的读权限,然后并没有指定写权限。参考以下测试用例:

public static void main(String... args) {
    String javaVersion=System.getProperty("java.version");
    System.err.println(javaVersion);
    System.setProperty("java.version","1.7.0_45");
    String javaNewVersion=System.getProperty("java.version");
    System.err.println(javaNewVersion);
  }

首先读"java.version"属性,然后把该属性改写为1.7.0_45,最后再读取它并打印出来,输出结果为:

1.8.0_45
1.7.0_45

可以看到默认的jdk版本为1.8.0_45(1.8.0是java的主版本号,45是次版本号)。

然后前面的policy文件只指定了read权限,为什么这里却write成功了?那是因为默认情况下java并不启动安全管理器,可以使用硬编码System.setSecurityManager()来启动安全管理器,参考以下测试用例:

public static void main(String... args) {
    // 启用安全管理器
    System.setSecurityManager(new SecurityManager());
    String javaVersion=System.getProperty("java.version");
    System.err.println(javaVersion);
    System.setProperty("java.version","1.7.0_45");
    String javaNewVersion=System.getProperty("java.version");
    System.err.println(javaNewVersion);
  }

此时的输出结果为:

1.8.0_45
Exception in thread "main" java.security.AccessControlException: access denied ("java.util.PropertyPermission" "java.version" "write")
	at java.security.AccessControlContext.checkPermission(AccessControlContext.java:457)
	at java.security.AccessController.checkPermission(AccessController.java:884)
	at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
	at java.lang.System.setProperty(System.java:792)
	at test.Test.main(Test.java:9)

结果很明确:可以读,但不能写,我们可以来修改policy文件,让它支持"java.version"的写操作:

grant {
        ... ...       
        permission java.util.PropertyPermission "java.version", "read";
        permission java.util.PropertyPermission "java.version", "write";
        ... ...
};

此时再执行上面的用例,输出结果为:

1.8.0_45
1.7.0_45

可以看到此时可以支持"java.version"的写操作了。

另外使用jvm参数-Djava.security.manager也能启用安全管理器,此时jvm启动时会设置"java.security.manager"系统属性为空字符串"",此时会在启动sun.misc.Launcher时初始化安全管理器,查看sun.misc.Launcher的源码:

public Launcher(){
        ExtClassLoader extclassloader;
        try {
            extclassloader = ExtClassLoader.getExtClassLoader();
        } catch(IOException ioexception) {
            throw new InternalError("Could not create extension class loader", ioexception);
        }
        try {
            loader = AppClassLoader.getAppClassLoader(extclassloader);
        } catch(IOException ioexception1) {
            throw new InternalError("Could not create application class loader", ioexception1);
        }
        Thread.currentThread().setContextClassLoader(loader);
        String s = System.getProperty("java.security.manager");
        if(s != null) {
            SecurityManager securitymanager = null;
            if("".equals(s) || "default".equals(s))
                securitymanager = new SecurityManager();
            else
                try {
                    securitymanager = (SecurityManager)loader.loadClass(s).newInstance();
                }
                catch(IllegalAccessException illegalaccessexception) { }
                catch(InstantiationException instantiationexception) { }
                catch(ClassNotFoundException classnotfoundexception) { }
                catch(ClassCastException classcastexception) { }
            if(securitymanager != null)
                System.setSecurityManager(securitymanager);
            else
                throw new InternalError((new StringBuilder()).append("Could not create SecurityManager: ").append(s).toString());
        }
    }

可以看到"java.security.manager"系统属性为空字符串""时会启用jdk的默认安全管理器SecurityManager。

Java API

java的安全机制api大部分都在java.security包下,因为源码很多,就不贴出来了,大家感兴趣的话可以研究下。以下是一些常用的类的api介绍:

  • java.security.AccessControlContext:基于它所封装的上下文作出系统资源访问决定,该类最常用于将代码标记为享有“特权”。

  • java.security.AccessController:用于与访问控制相关的操作和决定。java.security.SecureClassLoader此类扩展了 ClassLoader,支持使用相关的代码源和权限定义类,这些代码源和权限默认情况下可根据系统策略获取到。

  • java.security.Provider:此类表示 Java 安全 API "provider",这里 provider 实现了 Java 安全性的一部分或者全部。

  • java.security.Permission:表示访问系统资源的抽象类。所有权限都有一个名称(对它们的解释依赖于子类),以及用来定义特定 Permission 子类的语义的抽象方法。


© 著作权归作者所有

共有 人打赏支持
xionghuiCoder
粉丝 86
博文 34
码字总数 31340
作品 4
海淀
程序员
私信 提问
微软建议用户卸载 Java JRE 存在严重安全隐患

据外国媒体报道,微软恶意软件保护中心研究员Matt Oh在TechNet上发布了一篇文章,教用户如何保护自己基于Java系统漏洞上的恶意软件。同时Matt Oh也在Black Hat 2012的发言中表示,Java威胁着...

oschina
2012/07/31
1K
27
java安全沙箱(二)之.class文件检验器

java是一种类型安全的语言,它有四类称为安全沙箱机制的安全机制来保证语言的安全性,这四类安全沙箱分别是: 类加载体系 .class文件检验器 内置于Java虚拟机(及语言)的安全特性 安全管理器...

xionghuiCoder
2015/09/04
0
0
SAE Java 平台从即日起正式对外开放

来自新浪邮件的消息:SAE Java 平台从即日起正式对外开放啦!新平台全面升级了JDK和安全沙箱,改进了JVM漂移和自动回收、扩展的策略,同时完美支持SSH、Play等框架,支持外连数据库。 目前已...

狼狼A狗
2012/12/19
4.1K
52
Java 出现零时差漏洞 专家建议暂时禁用

目前多家资讯安全公司发布资讯安全通告表示,目前的Java含有未修补的漏洞,而且黑客已经在攻击中利用该漏洞,因此在甲骨文(Oracle)修补该漏洞之前,用户应该先禁用或解除安装Java。 首先披...

it224
2012/08/29
4.6K
35
java classloader 过程

jvm classLoader architecture : a, Bootstrap ClassLoader/启动类加载器 主要负责jdk_home/lib目录下的核心 api 或 -Xbootclasspath 选项指定的jar包装入工作. b, Extension ClassLoader/扩......

Idiot_s_Sky
2014/01/19
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Vert.x系列(二)--EventBusImpl源码分析

前言:Vert.x 实现了2种完成不同的eventBus: EventBusImpl(A local event bus implementation)和 它的子类 ClusteredEventBus(An event bus implementation that clusters with other Ve......

冷基
今天
1
0
Perl - 获取文件项目

参考:http://www.runoob.com/perl/perl-directories.html 下面返回JSON格式的文件列表 #!/usr/bin/perluse strict;use warnings;use utf8;use feature ':5.26';require Fi......

wffger
昨天
2
0
vue组件系列3、查询下载

直接源码,虽然样式样式不好看,逻辑也不是最优,但是可以留作纪念。毕竟以后类似的功能只需要优化就可以了,不用每次都重头开始。。。 <template> <div class="pre_upload"> <div ...

轻轻的往前走
昨天
2
0
java浅复制和深复制

之前写了数组的复制,所以这里继续总结一下浅复制和深复制。 浅拷贝:对基本数据类型进行值传递,对引用数据类型进行引用传递般的拷贝。 深拷贝:对基本数据类型进行值传递,对引用数据类型,...

woshixin
昨天
2
0
kubernetes 二进制包安装

环境 角色 主机名 内网 IP 集群 IP 操作系统 服务 执行目录 部署机 k8s-master master120 10.0.4.120 - CentOS kube-apiserver kube-scheduler kube-controller-manager /opt/kubernetes/ et......

Colben
昨天
10
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部