如何在 Java 中使用启用的 SecurityManager 创建 newInstance
Posted
技术标签:
【中文标题】如何在 Java 中使用启用的 SecurityManager 创建 newInstance【英文标题】:How to create newInstance with enabled SecurityManager in Java 【发布时间】:2017-07-11 18:37:37 【问题描述】:我需要创建从不受信任的类文件加载的类的新实例。 现在我执行以下操作:
classLoader.loadClass(UNSTRUSTED_CLASS).newInstance()
问题是,如果我启用安全管理器,它不允许调用 newInstance,但如果我禁用安全管理器,则可以将恶意代码放入初始化块中,并且它可以毫无问题地执行。
如何完成创建不受信任类的新实例?
【问题讨论】:
可能与***.com/questions/36091323/…重复 @Akash 我看过那个问题。有足够的区别,因为我可以隔离方法调用,但不能隔离实例化。不幸的是,回答这个问题也无济于事。 您不能将受信任的调用类型与潜在的不受信任的被调用者隔离开来,以便可以授予前者的ProtectionDomain
(通过Policy
或ClassLoader
)必要的实例化权限,而后者仍然受到(严格)访问控制?
这就是我试图实现的目标,不知道现在我是如何知道并作为答案分享的
为什么你会有一个SecurityManager
并且不希望它应用于不受信任的代码?
【参考方案1】:
嗯,我用的。 至于我有从特定位置加载不受信任代码的自定义类加载器,我可以在策略文件中为我的受信任代码定义代码库,我授予使用反射的权限。因此,来自另一个代码库的不受信任的代码没有此权限。 即
grant codeBase "file:/C:/path/to/trusted/code/classes"
permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
;
使用此策略文件,从 codeBase 中指定以外的其他位置加载的所有代码都将没有任何权限。
【讨论】:
【参考方案2】:一个类的静态初始化程序和构造函数将始终在堆栈上与该类一起执行,因此AccessControlContext
中的适当ProtectionDomain
。这并不是说可能存在其他问题,例如,实际上从父类加载器获取一个类,授予对当前Thread
/ThreadGroup
/AppContext
/ThreadLocal
s 的访问权限。
除此之外,三参数Class.forName
允许在不初始化的情况下加载类。但是,使用父类加载器中的代码加载类可能更为典型。
【讨论】:
以上是关于如何在 Java 中使用启用的 SecurityManager 创建 newInstance的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Java Servlet 在 WebSphere 7 中启用 CORS