gpt4 book ai didi

java - 动态类加载时如何保护 Java 应用程序?

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:32:17 25 4
gpt4 key购买 nike

我有一个 Java/Scala 应用程序,它执行磁盘 IO 并动态加载用户提交的类。动态类在它们自己的类加载器下运行。

加载这些类时应考虑哪些安全问题,以确保它们无权删除磁盘文件或执行任何恶意操作,而只是执行内存操作?

到目前为止我做了什么

  • 要删除的正则表达式检查java.io.*, java.nio.*, java.lang.reflect & java.lang.Runtime.* 相关导入。我正在尝试查看是否可以直接从类路径中删除这些导入而不是执行正则表达式。
  • 为每次执行动态加载类的实例设置超时。
  • 书面测试加载了 1000 个动态加载的类以检查 PermGen 问题并且没有内存泄漏。

另一种选择是在它们自己的 JVM 进程中运行它们并为每个进程设置文件系统 (Linux) 级别的权限,但这并不适合我的解决方案,因为我需要它们共享线程安全的内存中对象。

如果我在正确的轨道上,有人可以建议还应该考虑什么吗?

最佳答案

正如@Kayaman 所说,您应该尝试使用SecurityManager 处理这些动态类 权限,有一个最小的例子可以证明这一点,也许对你有帮助。

1.创建Dynamic Classes策略文件,这将用于限制权限,例如my.policy:

grant {
permission java.io.FilePermission "*", "read";
};

上述策略将为任何文件启用读取文件

2.创建自定义策略文件,可用于处理具有权限验证规则的动态类

class MyPolicy extends Policy {
//custom classes with policy mapping
private final Map<String, Policy> plugins;

MyPolicy(Map<String, Policy> plugins) {
this.plugins = plugins;
}

@Override
public boolean implies(ProtectionDomain domain, Permission permission) {
CodeSource codeSource = domain.getCodeSource();
if (codeSource == null) {
return false;
}

URL location = codeSource.getLocation();
if (location != null) {
//get the custom plugin policy rules and validate the permissions
Policy plugin = this.plugins.get(location.getFile());
if (plugin != null) {
return plugin.implies(domain, permission);
}
}
return defaultSystemPermissions().implies(permission);
}
private PermissionCollection defaultSystemPermissions() {
Permissions permissions = new Permissions();
permissions.add(new AllPermission()); // this will set the application default permissions, in there we enable all
return permissions;
}
}

在上面的代码中,会验证动态类权限,如果缺少对应的权限,在运行时会抛出:

java.security.AccessControlException: access denied ("java.io.FilePermission" "test.txt" "read")

还有为默认应用程序启用所有权限,也许应该在实际场景中考虑更多。

3.setPolicy 并为您的动态策略 安装SecurityManager

        // load the dynamic classes
URL pluginClass = new File("./myplugin").toURI().toURL();
// read my plugin security policy
URIParameter myPolicyPath = new URIParameter(MyClass.class.getResource("/my.policy").toURI());
Policy policy = Policy.getInstance("JavaPolicy", myPolicyPath);
MyPolicy myPolicy = new MyPolicy(ImmutableMap.of(pluginClass.getPath(), policy));
Policy.setPolicy(myPolicy);
// install the security manager
System.setSecurityManager(new SecurityManager());

4.完整示例:测试类:

public class TestClass {
public void foobar() throws IOException {
Path path = Paths.get("test.txt");
String lines = Files.readAllLines(path).stream().collect(Collectors.joining(","));

System.out.println(lines);
}
}

运行者:

public static void main(String[] args) throws Exception{
// create a new url class loader, this can be used to load a jar or classes directory
URL pluginClass = new File("./myplugin").toURI().toURL();
URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{pluginClass}, MyClass.class.getClassLoader());

// load a dynamic TestClass class
Class loadedMyClass = urlClassLoader.loadClass("TestClass");

// read my plugin security policy
URIParameter myPolicyPath = new URIParameter(MyClass.class.getResource("/my.policy").toURI());
Policy policy = Policy.getInstance("JavaPolicy", myPolicyPath);
MyPolicy myPolicy = new MyPolicy(ImmutableMap.of(pluginClass.getPath(), policy));
Policy.setPolicy(myPolicy);
// install the security manager
System.setSecurityManager(new SecurityManager());


System.out.println("Loaded class: " + loadedMyClass.getName());

Object myClassObject = loadedMyClass.getConstructor().newInstance();
Method method = loadedMyClass.getMethod("foobar");
System.out.println("Invoked method: " + method.getName());
method.invoke(myClassObject);

}

引用:

https://docs.oracle.com/javase/tutorial/essential/environment/security.html

关于java - 动态类加载时如何保护 Java 应用程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52001421/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com