【发布时间】:2019-12-25 23:42:39
【问题描述】:
我有一个用于受信任应用程序代码的 ClassLoader 和一个用于用户提交(不受信任)代码的单独 ClassLoader。
我希望安全管理器限制用户提交的代码。如何从 SecurityManager 中检查调用方来源?查看伪代码:
System.setSecurityManager(new SecurityManager() {
public void checkPermission(Permission permission) {
if (/*caller class is not loaded by the trusted classloader*/) {
throw new SecurityException("You do not have permissions.");
}
}
});
我已经尝试过的:
StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE).getCallerClass().getClassLoader()首先检查权限,因此会给出堆栈溢出异常。Thread.currentThread().getStackTrace()[2].getClassLoaderName()是不安全的,因为它只提供类加载器名称而不是类对象,如果不受信任的加载器的规范名称与受信任的加载器相同,那么这是一个安全问题。
【问题讨论】:
-
首先检查权限,因此它会给出堆栈溢出异常。 - 这不能通过特殊情况下的权限检查来解决,因此它不会导致递归?
-
@the8472 你能解释一下你想如何“特例”吗?因为您无法真正确定哪个类正在请求使用 StackWalker 的权限。可能是安全管理器,也可能是恶意代码。
-
好吧,您只需尽早获取 stackwalker,以确保不存在恶意代码,因此您可以在启动阶段确定该特定调用,而无需进一步检查。安全检查发生在
getInstance()期间,因此您只需授予一次。 -
用户提交的代码应该在自己的
ProtectionDomain/CodeSource中,因此有自己的权限(与您自己的代码分开)。然后你应该可以让SecurityManager完成它的工作。
标签: java java-security java-security-manager