我正在弄清楚如何在没有权限的情况下运行外部代码(来自其他JAR),以免损害我的系统。我几乎可以正常工作了,但是我发现一个奇怪的情况,对System.exit(0)
的调用仍然会杀死整个系统。
这个想法是,在多线程环境中将加载不同的JAR,因此成功System.exit(0)
大约是可能发生的最糟糕的情况,其中包括服务器上的许多其他安全风险。
我有以下代码(在SSCEE中):
public class RestrictAccessControlContext {
private static final PermissionCollection ALLOWED_PERMISSIONS = new Permissions();
static {
//add permissions
}
private static final AccessControlContext RESTRICTED_ACCESS_CONTROL_CONTEXT =
new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, ALLOWED_PERMISSIONS)});
private static void executeSandboxed(final Runnable runnable) {
ExecutorService executorService = Executors.newSingleThreadExecutor();
Future<?> future = executorService.submit(() -> {
AccessController.doPrivileged((PrivilegedAction<Void>)() -> {
runnable.run();
return null;
}, RESTRICTED_ACCESS_CONTROL_CONTEXT);
});
try {
future.get();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
} catch (ExecutionException ex) {
throw new RuntimeException(ex.getCause());
} finally {
executorService.shutdown();
}
}
public static void main(String[] args) {
executeSandboxed(() -> {
AccessController.doPrivileged((PrivilegedAction<Void>)() -> {
System.exit(0);
return null;
});
});
}
}
您需要哪个作为VM参数运行:
-Djava.security.manager -Djava.security.policy = src / java.policy
其中
java.policy
是:grant {
permission java.security.AllPermission;
};
这个想法是我自己的代码仍然具有完全权限,但是沙盒代码具有受限(在这种情况下:无)权限。
但是,在给定的示例中,它只是退出,请注意,main方法的以下变体确实起作用:
public static void main(String[] args) {
executeSandboxed(() -> System.exit(0));
}
和
public static void main(String[] args) {
executeSandboxed(() -> new Thread(() -> System.exit(0)).start());
}
我在这里做错了什么,为什么以前曾经被限制过,但为什么可以执行一个引发权限的
AccessController.doPrivileged
调用呢?我希望以下其中一项是正确的:AccessController.doPrivileged
。 AccessController.doPrivileged
块中,权限将是“父” AccessControlContext
与给定权限的交集。 这两个选项都会导致给定的代码正确地抛出
AccessControlException
,但是没有发生,为什么会这样呢? 最佳答案
您没有任何沙盒代码。您的具有完全权限的代码正在使用它们。未经相关许可的代码将无法退出。解决方案应该是使用不受信任的ProtectionDomain
加载不受信任的代码。
拥有提高许可的权限将毫无意义。这相当于拥有所有权限。
在OpenJDK内部,有一种doPrivileged
变体,它允许交叉权限,但是当存在多个不信任源时,它用于降低权限。