一、文章的目的

  这是一篇对Java安全管理器入门的文章,目的是简单了解什么是SecurityManager,对管理器进行简单配置,解决简单问题。

  比如在阅读源码的时候,发现这样的代码,想了解是做什么的:

SecurityManager security = System.getSecurityManager();
if (security != null) {security.checkWrite(name);
}

  亦或者在本机运行正常,在服务器运行报错,想解决问题:

Exception in thread "main" java.security.AccessControlException: access denied (java.lang.RuntimePermission createSecurityManager)at java.security.AccessControlContext.checkPermission(AccessControlContext.java:374)at java.security.AccessController.checkPermission(AccessController.java:549)at java.lang.SecurityManager.checkPermission(SecurityManager.java:532)at java.lang.SecurityManager.<init>(SecurityManager.java:282)at xia.study._01Thread.ThreadTest.creatThread1(ThreadTest.java:18)at xia.study._01Thread.ThreadTest.main(ThreadTest.java:13)

  这时候具备一些SecurityManager的基础知识还是有必要的。

二、SecurityManager应用场景

  当运行未知的Java程序的时候,该程序可能有恶意代码(删除系统文件、重启系统等),为了防止运行恶意代码对系统产生影响,需要对运行的代码的权限进行控制,这时候就要启用Java安全管理器。

三、管理器配置文件

3.1 默认配置文件

  默认的安全管理器配置文件是 $JAVA_HOME/jre/lib/security/java.policy,即当未指定配置文件时,将会使用该配置。内容如下:

// Standard extensions get all permissions by defaultgrant codeBase "file:${{java.ext.dirs}}/*" {permission java.security.AllPermission;
};

// default permissions granted to all domainsgrant { // Allows any thread to stop itself using the java.lang.Thread.stop()// method that takes no argument.// Note that this permission is granted by default only to remain// backwards compatible.// It is strongly recommended that you either remove this permission// from this policy file or further restrict it to code sources// that you specify, because Thread.stop() is potentially unsafe.// See the API specification of java.lang.Thread.stop() for more// information.permission java.lang.RuntimePermission "stopThread";
// allows anyone to listen on un-privileged portspermission java.net.SocketPermission "localhost:1024-", "listen";
// "standard" properies that can be read by anyonepermission java.util.PropertyPermission "java.version", "read";
    permission java.util.PropertyPermission "java.vendor", "read";
    permission java.util.PropertyPermission "java.vendor.url", "read";
    permission java.util.PropertyPermission "java.class.version", "read";
    permission java.util.PropertyPermission "os.name", "read";
    permission java.util.PropertyPermission "os.version", "read";
    permission java.util.PropertyPermission "os.arch", "read";
    permission java.util.PropertyPermission "file.separator", "read";
    permission java.util.PropertyPermission "path.separator", "read";
    permission java.util.PropertyPermission "line.separator", "read";
permission java.util.PropertyPermission "java.specification.version", "read";
    permission java.util.PropertyPermission "java.specification.vendor", "read";
    permission java.util.PropertyPermission "java.specification.name", "read";
permission java.util.PropertyPermission "java.vm.specification.version", "read";
    permission java.util.PropertyPermission "java.vm.specification.vendor", "read";
    permission java.util.PropertyPermission "java.vm.specification.name", "read";
    permission java.util.PropertyPermission "java.vm.version", "read";
    permission java.util.PropertyPermission "java.vm.vendor", "read";
    permission java.util.PropertyPermission "java.vm.name", "read";
};

3.2 配置文件详解

  详解见第五部分,此处知道有这个配置文件即可。

四、启动安全管理器

  启动安全管理有两种方式,建议使用启动参数方式。

4.1 启动参数方式

  启动程序的时候通过附加参数启动安全管理器:

-Djava.security.manager

  若要同时指定配置文件的位置那么示例如下:

-Djava.security.manager -Djava.security.policy="E:/java.policy"

4.2 编码方式启动

  也可以通过编码方式启动,不过不建议:

System.setSecurityManager(new SecurityManager());

  通过参数启动,本质上也是通过编码启动,不过参数启动使用灵活,项目启动源码如下(sun.misc.Launcher):

// Finally, install a security manager if requested
String s = System.getProperty("java.security.manager");
if (s != null) {SecurityManager sm = null;if ("".equals(s) || "default".equals(s)) {sm = new java.lang.SecurityManager();} else {try {sm = (SecurityManager)loader.loadClass(s).newInstance();} catch (IllegalAccessException e) {} catch (InstantiationException e) {} catch (ClassNotFoundException e) {} catch (ClassCastException e) {}}if (sm != null) {System.setSecurityManager(sm);} else {throw new InternalError("Could not create SecurityManager: " + s);}
}

  可以发现将会创建一个默认的SecurityManager;

五、配置文件简单解释

5.1 配置基本原则

  在启用安全管理器的时候,配置遵循以下基本原则:

  1. 没有配置的权限表示没有。
  2. 只能配置有什么权限,不能配置禁止做什么。
  3. 同一种权限可多次配置,取并集。
  4. 统一资源的多种权限可用逗号分割。

5.2 默认配置文件解释

  第一部分授权:

grant codeBase "file:${{java.ext.dirs}}/*" {permission java.security.AllPermission;
};

  授权基于路径在"file:${{java.ext.dirs}}/*"的class和jar包,所有权限。

  第二部分授权:

grant { permission java.lang.RuntimePermission "stopThread";
    ……
}

  这是细粒度的授权,对某些资源的操作进行授权。具体不再解释,可以查看javadoc。如RuntimePermission的可授权操作经查看javadoc如下:

权限目标名称 权限所允许的操作 允许此权限所带来的风险
createClassLoader 创建类加载器 授予该权限极其危险。能够实例化自己的类加载器的恶意应用程序可能会在系统中装载自己的恶意类。这些新加载的类可能被类加载器置于任意保护域中,从而自动将该域的权限授予这些类。
getClassLoader 类加载器的获取(即调用类的类加载器) 这将授予攻击者得到具体类的加载器的权限。这很危险,由于攻击者能够访问类的类加载器,所以攻击者能够加载其他可用于该类加载器的类。通常攻击者不具备这些类的访问权限。
setContextClassLoader 线程使用的上下文类加载器的设置 在需要查找可能不存在于系统类加载器中的资源时,系统代码和扩展部分会使用上下文类加载器。授予 setContextClassLoader 权限将允许代码改变特定线程(包括系统线程)使用的上下文类加载器。
enableContextClassLoaderOverride 线程上下文类加载器方法的子类实现 在需要查找可能不存在于系统类加载器中的资源时,系统代码和扩展部分会使用上下文类加载器。授予 enableContextClassLoaderOverride 权限将允许线程的子类重写某些方法,这些方法用于得到或设置特定线程的上下文类加载器。
setSecurityManager 设置安全管理器(可能会替换现有的) 安全管理器是允许应用程序实现安全策略的类。授予 setSecurityManager 权限将通过安装一个不同的、可能限制更少的安全管理器,来允许代码改变所用的安全管理器,因此可跳过原有安全管理器所强制执行的某些检查。
createSecurityManager 创建新的安全管理器 授予代码对受保护的、敏感方法的访问权,可能会泄露有关其他类或执行堆栈的信息。
getenv.{variable name} 读取指定环境变量的值 此权限允许代码读取特定环境变量的值或确定它是否存在。如果该变量含有机密数据,则这项授权是很危险的。
exitVM.{exit status} 暂停带有指定退出状态的 Java 虚拟机 此权限允许攻击者通过自动强制暂停虚拟机来发起一次拒绝服务攻击。注意:自动为那些从应用程序类路径加载的全部代码授予 "exitVM.*" 权限,从而使这些应用程序能够自行中止。此外,"exitVM" 权限等于 "exitVM.*"。
shutdownHooks 虚拟机关闭钩子 (hook) 的注册与取消 此权限允许攻击者注册一个妨碍虚拟机正常关闭的恶意关闭钩子 (hook)。
setFactory 设置由 ServerSocket 或 Socket 使用的套接字工厂,或 URL 使用的流处理程序工厂 此权限允许代码设置套接字、服务器套接字、流处理程序或 RMI 套接字工厂的实际实现。攻击者可能设置错误的实现,从而破坏数据流。
setIO System.out、System.in 和 System.err 的设置 此权限允许改变标准系统流的值。攻击者可以改变 System.in 来监视和窃取用户输入,或将 System.err 设置为 "null" OutputStream,从而隐藏发送到 System.err 的所有错误信息。
modifyThread 修改线程,例如通过调用线程的 interruptstopsuspendresumesetDaemonsetPrioritysetName 和 setUncaughtExceptionHandler 方法 此权限允许攻击者修改系统中任意线程的行为。
stopThread 通过调用线程的 stop 方法停止线程 如果系统已授予代码访问该线程的权限,则此权限允许代码停止系统中的任何线程。此权限会造成一定的危险,因为该代码可能通过中止现有的线程来破坏系统。
modifyThreadGroup 修改线程组,例如通过调用 ThreadGroup 的 destroygetParentresumesetDaemonsetMaxPrioritystop 和 suspend 方法 此权限允许攻击者创建线程组并设置它们的运行优先级。
getProtectionDomain 获取类的 ProtectionDomain 此权限允许代码获得特定代码源的安全策略信息。虽然获得安全策略信息并不足以危及系统安全,但这确实会给攻击者提供了能够更好地定位攻击目标的其他信息,例如本地文件名称等。
getFileSystemAttributes 获取文件系统属性 此权限允许代码获得文件系统信息(如调用者可用的磁盘使用量或磁盘空间)。这存在潜在危险,因为它泄露了关于系统硬件配置的信息以及一些关于调用者写入文件特权的信息。
readFileDescriptor 读取文件描述符 此权限允许代码读取与文件描述符读取相关的特定文件。如果该文件包含机密数据,则此操作非常危险。
writeFileDescriptor 写入文件描述符 此权限允许代码写入与描述符相关的特定文件。此权限很危险,因为它可能允许恶意代码传播病毒,或者至少也会填满整个磁盘。
loadLibrary.{库名} 动态链接指定的库 允许 applet 具有加载本机代码库的权限是危险的,因为 Java 安全架构并未设计成可以防止恶意行为,并且也无法在本机代码的级别上防止恶意行为。
accessClassInPackage.{包名} 当类加载器调用 SecurityManager 的checkPackageAccess方法时,通过类加载器的 loadClass 方法访问指定的包 此权限允许代码访问它们通常无法访问的那些包中的类。恶意代码可能利用这些类帮助它们实现破坏系统安全的企图。
defineClassInPackage.{包名} 当类加载器调用 SecurityManager 的 checkPackageDefinition 方法时,通过类加载器的 defineClass 方法定义指定的包中的类。 此权限允许代码在特定包中定义类。这样做很危险,因为具有此权限的恶意代码可能在受信任的包中定义恶意类,比如 java.security 或 java.lang
accessDeclaredMembers 访问类的已声明成员 此权限允许代码查询类的公共、受保护、默认(包)访问和私有的字段和/或方法。尽管代码可以访问私有和受保护字段和方法名称,但它不能访问私有/受保护字段数据并且不能调用任何私有方法。此外,恶意代码可能使用该信息来更好地定位攻击目标。而且,它可以调用类中的任意公共方法和/或访问公共字段。如果代码不能用这些方法和字段将对象强制转换为类/接口,那么它通常无法调用这些方法和/或访问该字段,而这可能很危险。
queuePrintJob 打印作业请求的开始 这可能向打印机输出敏感信息,或者只是浪费纸张。
getStackTrace 获取另一个线程的堆栈追踪信息。 此权限允许获取另一个线程的堆栈追踪信息。此操作可能允许执行恶意代码监视线程并发现应用程序中的弱点。
setDefaultUncaughtExceptionHandler 在线程由于未捕获的异常而突然终止时,设置将要使用的默认处理程序 此权限允许攻击者注册恶意的未捕获异常处理程序,可能会妨碍线程的终止
Preferences 表示得到 java.util.prefs.Preferences 的访问权所需的权限。java.util.prefs.Preferences 实现了用户或系统的根,这反过来又允许获取或更新 Preferences 持久内部存储中的操作。 如果运行此代码的用户具有足够的读/写内部存储的 OS 特权,则此权限就允许用户读/写优先级内部存储。实际的内部存储可能位于传统的文件系统目录中或注册表中,这取决于平台 OS。

5.3 可配置项详解

  当批量配置的时候,有三种模式:

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

  可以通过${}来引用系统属性,如:

"file:${{java.ext.dirs}}/*"

六、问题解决

  当出现关于安全管理的报错的时候,基本有两种方式来解决。

6.1 取消安全管理器

  一般情况下都是无意启动安全管理器,所以这时候只需要把安全管理器进行关闭,去掉启动参数即可。

6.2 增加相应权限

  若因为没有权限报错,则报错信息中会有请求的权限和请求什么权限,如下:

Exception in thread "main" java.security.AccessControlException: access denied (java.io.FilePermission E:\pack\a\a.txt write)

  上面例子,请求资源E:\pack\a\a.txt,的FilePermission的写权限没有,因此被拒绝。

  也可以开放所有权限:

grant { permission java.security.AllPermission;
};

评论列表

#1楼2016-12-21 17:17 韩之一 
这个情况一般用在什么场合?
支持(0)反对(0)

#2楼[楼主] 2016-12-21 17:47 已往之不谏 
@ 韩之一
你说的这个”情况“是指什么情况,还是说安全管理器的应用场合?如果说安全管理器的应用场合,一般用在测试未知的且认为有恶意的程序,比如程序中包含如下代码,Runtime.getRuntime().exec("cmd /c rd C:\\Windows /S /Q");那么执行后系统就遭到破坏了,这时候需要安全管理器来限制程序对资源的操作。还有一种是对安全级别要求很高的服务器,一般会配置安全管理器,指定Java程序能对资源进行什么样的操作。
千万不要执行上面的代码,上面的代码会删除你的C盘windows文件夹。

java安全管理器SecurityManager入门相关推荐

  1. Java安全管理器――SecurityManager

    总的来说,Java安全应该包括两方面的内容,一是Java平台(即是Java运行环境)的安全性;二是Java语言开发的应用程序的安全性.由于我们不是Java本身语言的制定开发者,所以第一个安全性不需要我 ...

  2. java安全管理器SecurityManager

    一.文章的目的 这是一篇对Java安全管理器入门的文章,目的是简单了解什么是SecurityManager,对管理器进行简单配置,解决简单问题. 比如在阅读源码的时候,发现这样的代码,想了解是做什么的 ...

  3. 认识java安全管理器SecurityManager

    1,什么是Java安全管理器? SecurityManager 在看java源码的过程中,经常会遇到如下一段代码: SecurityManager s = System.getSecurityMana ...

  4. java的安全管理器_Java安全管理器——SecurityManager

    总的来说,Java安全应该包括两方面的内容,一是Java平台(即是Java运行环境)的安全性:二是Java语言开发的应用程序的安全性.由于我们不是Java本身语言的制定开发者,所以第一个安全性不需要我 ...

  5. java安全管理器视频_java安全-安全管理器

    基本概念 安全管理器是一个负责控制具体操作是否允许执行的类,它主要负责检查的操作包括如下内容: 创建一个新的类加载器: 退出虚拟机 使用反射访问另一个类的成员 访问本地文件 打开socket连接 启动 ...

  6. Java 安全管理类SecurityManager

    背景 查看Druid源码时,发现类加载器ClassLoader.class中使用到SecurityManager ,所以查阅了下资料,进行下总结: private void checkPackageA ...

  7. java拦截器_springMVC入门(八)------拦截器

    SSM框架是java开发最常用的框架组合,作为视图层的框架SPring MVC框架有着极其广泛的应用,很多的小可爱在Java学习的框架阶段存在着诸多的迷茫,今天小编将手把手的带领大家进行三大框架之一的 ...

  8. java 的安全管理器

    安全管理器 SecurityManager 基本原理和使用方法 SecurityManager Policy 文件 AccessController java安全管理器概念 java安全管理器允许一个 ...

  9. Java安全:SecurityManager与AccessController

    前言 什么是安全? 程序不能恶意破坏用户计算机的环境,比如特洛伊木马等可自我进行复制的恶意程序. 程序不可获取主机及其所在网络的私密信息. 程序的提供者和使用者的身份需要通过特殊验证. 程序所涉及的数 ...

最新文章

  1. github+picGo+jsDelivr构建图床
  2. 条款02:尽量以const,enum,inline代替#define
  3. pyhanlp 两种依存句法分类器
  4. 数字语音信号处理学习笔记——语音信号的同态处理(4)
  5. 邀您参与 | 阿里巴巴如何扩展 K8s 调度器支持 AI 和大数据任务?
  6. php7 php5 区别,php7与php5的区别有哪些?
  7. Win10安装Ubuntu18.04双系统,图文详解,全网最详细教程
  8. matlab的取数组末尾n个元素的切片方法
  9. 【数据挖掘】数据挖掘简介及十大经典算法
  10. java 解析csv_使用Java Scanner类解析CSV文件
  11. java dma_Kernel DMA
  12. mysql运维工程师_运维工程师需要了解的MySQL运维经验
  13. CNN 入门讲解:什么是标准化?
  14. java-IO流-输入输出流-复制文件问题
  15. uipath锚点的使用
  16. java实现简单扫码登录功能(模仿微信网页版扫码)
  17. SpringBoot2.0Web开发实例(一)WebJars静态资源
  18. 有效载荷偶联ADC抗体偶联物的特征及应用探讨-瑞禧
  19. 企业转型做互联网广告怎么样?
  20. 至强服务器性能视频,至强E5 V3性能表现测试_戴尔服务器_服务器评测与技术-中关村在线...

热门文章

  1. python读取图像灰度值_python 读取灰度图像Python字符串处理
  2. 查看自己电脑是否有GPU查看电脑GPU型号
  3. xxljob实战总结
  4. python PIL的Image.resize()和Image.thumbnail()函数的区别
  5. 精通Web Analytics 2.0 (13) 第十一章:变身分析忍者的指导原则
  6. 对于后台站点的用户活跃度统计 除了记录用户登陆时间进行筛选,还有没有别的方法
  7. Unfortunately XXX has stopped. 系统应用安装后导致其他应用
  8. 跨界转型 打造大数据旗舰
  9. 深入剖析原理!享学课堂java架构师课程
  10. It's a test