我遵循此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脚本中的任何内容。
答案 0 :(得分:1)
您运行命令python
(不合格),因此start()
不知道文件在哪里,因此请检查是否允许execute
访问<<ALL FILES>>
。由于您不在,因此被拒绝。
如果您指定python
的完整(绝对)路径,并且授予对python
文件的访问权限,那么它将起作用。
有关权限检查的说明,请参见SecurityManager.checkExec(String cmd)
的javadoc:
如果不允许调用线程创建子进程,则抛出
SecurityException
。类
exec
的{{1}}方法为当前的安全管理器调用此方法。此方法具有
Runtime
权限的情况下调用checkPermission
如果cmd是绝对路径,否则它以FilePermission(cmd,"execute")
调用checkPermission
。