3

是否可以在 Java 中对我的 Runnable 进行沙箱处理?给定一个 Runnable,我希望它内部的代码(以及它产生的任何线程)在沙箱中运行,只允许代码访问文件系统上的特定路径。一旦 Runnable 完成,线程应该回到它拥有的任何正常权限,而任何剩余的衍生线程仍将应用文件系统限制。

我想在运行时执行此操作。这意味着我想避免创建策略文件并将自定义参数传递给 JVM。到目前为止,我已经能够将沙盒应用于我的整个应用程序,但我还没有找到一种方法将其范围限定为仅在当前线程中运行的 Runnable ......

if (System.getSecurityManager() == null) {
    System.setSecurityManager(new SecurityManager());
}

CodeSource nullSource = new CodeSource(null, (CodeSigner[]) null);

PermissionCollection perms = new Permissions();
perms.add(new FilePermission(path.toAbsolutePath().toString() + "/*", "read"));

ProtectionDomain domain = new ProtectionDomain(nullSource, perms);
AccessControlContext safeContext = new AccessControlContext(
        new ProtectionDomain[]{domain});

AccessController.doPrivileged((PrivilegedAction) () -> {
    try {
        r.run();
    } catch (Exception e) {
        throw new IllegalStateException(e);
    }
    return null;
}, safeContext);
4

1 回答 1

3

限制权限的doPrivileged技术仅适用于不滥用其位置的可信代码(例如,通过调用doPrivileged自身)。例如,作为防止包含 XML 的层非常有用,但不是不受信任的插件。

您可以使用 custom 在运行时加载具有特定权限ClassLoader的代码,但如果您需要权限,则必须重新加载代码。

对象能力模型给出了一个“纯”的动态解决方案。容器向插件传递一个能够执行特权操作的对象。在内部,对象的方法可以只是被 a 包围的动作doPrivileged。至关重要的是,这些操作只能通过实例使用,并且不允许非特权代码实例化它。这类似于,比如说,FileOpenService在 JNLP/WebStart 中,如果你忽略ServiceMangaer. 在 JDK 内部,您可能会看到 和 之类的Unsafe东西SharedSecrets,尽管这些更多是为了避免重复的安全检查。

于 2020-04-11T06:36:33.190 回答