小编Geo*_*Geo的帖子

是否应该使用自定义SecurityManager来沙箱javax.script.ScriptEngine?

JSR-223的javax.script包的一个大问题是没有任何明显的方法来沙箱运行的脚本.所以显而易见的问题是:你如何沙箱JSR-223脚本?有人问过,甚至有几次尝试答案.

以下是关于这个问题的两个有趣的问题,但不幸的是忽略了这一点:

关键在于,这不仅仅是设置正确的安全策略或使用正确的ClassLoader,因为您尝试保护的代码不是Java代码,也没有类.您可以尝试通过使用ClassLoader为其提供一个特殊的ProtectionDomain来保护ScriptEngine,但只有在系统ClassLoader无法通过加载具有错误的ProtectionDomain的类来找到ScriptEngine来破坏您的工作时才会起作用.与作为JRE一部分的任何有用的ScriptEngine一起发生.

这是另一个看起来不错的资源,但忽略了这一点:简单的JVM沙盒.它告诉粗心大意他们可以通过doPrivileged在包含具有极少权限的ProtectionDomain的自定义AccessControlContext中使用沙箱来编写沙箱,但当然这样做是没有意义的,因为doPrivileged它只对获取权限有用,而对拒绝权限没有用.如果不受信任的代码已经存在于沙盒ProtectionDomain中,则该doPrivileged技巧根本不会执行任何操作,如果不受信任的代码位于非沙箱ProtectionDomain中,则它只能调用doPrivileged并完全绕过沙盒尝试.

在真正的问题是如何做一个解决这些问题?假设我们打算使用ProtectionDomains,似乎唯一的选择是给ScriptEngineManager一个自定义的ClassLoader,故意隐藏系统ClassLoader中的某些类.在这种情况下,我们如何决定将哪些类放入沙箱以及从系统ClassLoader获取哪些类?似乎没有任何可靠的方法来了解哪些类可能负责为脚本提供打破沙箱的方法,特别是对于尚不存在的ScriptEngines.

我能想到的唯一选择是我真正想问的问题.简单地忽略ProtectionDomains并实现具有用于评估脚本的沙箱模式的自定义SecurityManager是否是更好的解决方案?例如:

public final class SandboxMan extends SecurityManager {
    private int sandboxDepth = 0;
    @Override public void checkPermission(Permission permission) {
        if(sandboxDepth > 0) throw new SecurityException("Sandboxed: " + permission);
        else super.checkPermission(permission);
    }
    @Override public void checkPermission(Permission permission, Object context) {
        if(sandboxDepth > 0) throw new SecurityException("Sandboxed: " + permission);
        else super.checkPermission(permission, context);
    }
    public Object eval(ScriptEngine engine, String script) …
Run Code Online (Sandbox Code Playgroud)

java security permissions scripting sandbox

6
推荐指数
1
解决办法
1745
查看次数

标签 统计

java ×1

permissions ×1

sandbox ×1

scripting ×1

security ×1