Java原生安全管理器——SecurityManager
什么是SecurityManager
Java安全管理器(SecurityManager)是Java安全模型的核心组件,它负责检查程序运行时是否违反了安全策略。如果违反了安全策略,安全管理器会抛出一个SecurityException异常,阻止程序继续执行。
遇到的安全问题
读取信息文件
String userDir = System.getProperty("user.dir");
//直接读application.yml
String filePath = userDir + File.separator + "src/main/resources/application.yml";
List<String> allLines = Files.readAllLines(Paths.get(filePath));
System.out.println(String.join("\n", allLines));
植入木马病毒
String userDir = System.getProperty("user.dir");
//编写个程序并运行
String filePath = userDir + File.separator + "src/main/resources/木马程序.bat";
String errorProgram = " java -version 2>&1";
Files.write(Paths.get(filePath), Arrays.asList(errorProgram));
System.out.println("执行异常程序成功");
Java安全管理器的使用
目的:限制用户对文件、内存、CPU、网络等资源的操作和访问。
继承父类、实现方法
编写安全管理器,只需要继承 Security Manager,实现其中的方法即可。
- 所有权限放开:
/**
* 默认安全管理器
*/
public class DefaultSecurityManager extends SecurityManager {
// 检查所有的权限
@Override
public void checkPermission(Permission perm) {
// super.checkPermission(perm); 所有权限都禁止
}
}
- 限制读权限:
@Override
public void checkRead(String file) {
System.out.println(file);
//需要自己去判断哪些文件、包名 需要允许读写。粒度太细了,难以精细化控制
if (file.contains("C:\\...文件路径")) {
return;
}
throw new SecurityException("checkRead 权限异常:" + file);
}
- 限制写文件权限:
@Override
public void checkWrite(String file) {
throw new SecurityException("checkWrite 权限异常:" + file);
}
- 限制执行文件权限:
@Override
public void checkExec(String cmd) {
throw new SecurityException("checkExec 权限异常:" + cmd);
}
- 限制网络连接权限:
public void checkConnect(String host, int port) {
throw new SecurityException("checkConnect 权限异常:" + host + ":" + port);
}
启用自定义SecurityManager
在所需要使用的地方启用
System.setSecurityManager(new DefaultSecurityManager())
实际运用
实际情况下,不应该在主类中做限制,只需要限制子程序的权限即可。
启动子进程执行命令时,设置安全管理器,而不是在外层设置。
具体操作如下:
- 根据需要开发自定义的安全管理器(如
DefaultSecurityManager
) - 复制
DefaultSecurityManager
类到resources/security
目录下,移除类的包名 - 手动输入命令编译
DefaultSecurityManager
类,得到class
文件 - 在运行 java 程序时,指定安全管理器 class 文件的路径、安全管理器的名称。
命令如下:
java -Djava.security.manager=com.example.DefaultSecurityManager YourClassName
关于
从 Java 9开始,默认启用了模块化系统,安全管理器不再适用于所有应用程序。