Java沙箱和ProcessBuilder

时间:2018-07-04 13:40:17

标签: java sandbox processbuilder

我遵循此tutorial来实现插件代码的Java沙箱。插件代码已获得以下权限运行:

private PermissionCollection pluginPermissions() {
    Permissions permissions = new Permissions(); 
    permissions.add(new FilePermission("/projects", "read,write,execute"));
    return permissions;
}  

工作正常。但是,我希望允许插件启动一个进程,这些进程也将受到这些权限的限制。例如,只要脚本在/ projects目录中并且不能在其他任何地方访问,它就可以通过运行命令“ python test.py”来运行python脚本。类似于以下cmnd为“ python”的代码,mainFilePath是位于该进程限制目录中的python脚本。

public static File startProcess(String cmnd, String mainFilePath, String directory){
        try {
            ProcessBuilder pb =
                    new ProcessBuilder( cmnd, mainFilePath);

            pb.directory(new File(directory));
            File f = pb.directory();
            System.out.println(f.exists());

            File log = new File(directory,"log.txt");

            pb.redirectErrorStream(true);
            pb.redirectOutput(ProcessBuilder.Redirect.appendTo(log));

            Process p = pb.start();
            return log;
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

如果我从插件运行此代码,则会收到以下异常:

java.security.AccessControlException: access denied ("java.io.FilePermission" "<<ALL FILES>>" "execute")
    at java.security.AccessControlContext.checkPermission(AccessControlContext.java:472)
    at java.security.AccessController.checkPermission(AccessController.java:884)
    at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
    at java.lang.SecurityManager.checkExec(SecurityManager.java:799)
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1018)
    at engine.LogHelper.startProcess(LogHelper.java:28)
    at engine.ZEngine.build(ZEngine.java:13)
    at Main.main(Main.java:29)

这表明我需要授予所有文件“执行”权限。但是我只需要对指定目录中的文件进行限制。那么如何在允许ProcessBuilder在受限目录中启动进程的同时实现沙箱功能?

更新:

插件权限如下:

permissions.add(new FilePermission("/Users/ziadalhalabi/IdeaProjects/JarDummy/projects/-", "read,write"));            
permissions.add(new FilePermission("/Users/ziadalhalabi/IdeaProjects/JarDummy/projects/", "read,write,execute"));     
permissions.add(new FilePermission("/usr/local/bin/python", "execute"));

它可以工作,但是python脚本能够读取目录外部的文件。我希望将沙箱应用于python脚本中的任何内容。

1 个答案:

答案 0 :(得分:1)

您运行命令python(不合格),因此start()不知道文件在哪里,因此请检查是否允许execute访问<<ALL FILES>> 。由于您不在,因此被拒绝。

如果您指定python 的完整(绝对)路径,并且授予对python文件的访问权限,那么它将起作用。

有关权限检查的说明,请参见SecurityManager.checkExec​(String cmd)的javadoc:

  

如果不允许调用线程创建子进程,则抛出SecurityException

     

exec的{​​{1}}方法为当前的安全管理器调用此方法。

     

此方法具有Runtime权限的情况下调用checkPermission 如果cmd是绝对路径,否则它以FilePermission(cmd,"execute")调用checkPermission