Java 沙盒和 ProcessBuilder
Java Sandboxing and ProcessBuilder
我按照此 tutorial 为插件代码实施 java 沙盒。插件代码获得 运行 具有以下权限:
private PermissionCollection pluginPermissions() {
Permissions permissions = new Permissions();
permissions.add(new FilePermission("/projects", "read,write,execute"));
return permissions;
}
它工作正常。但是,我想允许插件启动一个进程,该进程也将受到这些权限的限制。例如,它应该能够通过 运行 宁此命令 "python test.py" 运行 一个 python 脚本,只要脚本在 /projects 目录中并且它不访问其他任何地方。就像下面的代码,其中 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)
提示我需要对所有文件赋予"execute"权限。但我只需要对指定目录中的文件进行限制。那么如何在允许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 脚本中的任何内容。
你运行命令python
(不合格),所以start()
不知道文件在哪里,因此检查你是否被允许execute
访问至 <<ALL FILES>>
。因为你不是,它被拒绝了。
如果您指定 python
的完整(绝对)路径并且 授予对 python
文件的访问权限,它将起作用。
有关权限检查的说明,请参阅 SecurityManager.checkExec(String cmd)
的 javadoc:
Throws a SecurityException
if the calling thread is not allowed to create a subprocess.
This method is invoked for the current security manager by the exec
methods of class Runtime
.
This method calls checkPermission
with the FilePermission(cmd,"execute")
permission if cmd is an absolute path, otherwise it calls checkPermission
with FilePermission("<<ALL FILES>>","execute")
.
我按照此 tutorial 为插件代码实施 java 沙盒。插件代码获得 运行 具有以下权限:
private PermissionCollection pluginPermissions() {
Permissions permissions = new Permissions();
permissions.add(new FilePermission("/projects", "read,write,execute"));
return permissions;
}
它工作正常。但是,我想允许插件启动一个进程,该进程也将受到这些权限的限制。例如,它应该能够通过 运行 宁此命令 "python test.py" 运行 一个 python 脚本,只要脚本在 /projects 目录中并且它不访问其他任何地方。就像下面的代码,其中 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)
提示我需要对所有文件赋予"execute"权限。但我只需要对指定目录中的文件进行限制。那么如何在允许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 脚本中的任何内容。
你运行命令python
(不合格),所以start()
不知道文件在哪里,因此检查你是否被允许execute
访问至 <<ALL FILES>>
。因为你不是,它被拒绝了。
如果您指定 python
的完整(绝对)路径并且 授予对 python
文件的访问权限,它将起作用。
有关权限检查的说明,请参阅 SecurityManager.checkExec(String cmd)
的 javadoc:
Throws a
SecurityException
if the calling thread is not allowed to create a subprocess.This method is invoked for the current security manager by the
exec
methods of classRuntime
.This method calls
checkPermission
with theFilePermission(cmd,"execute")
permission if cmd is an absolute path, otherwise it callscheckPermission
withFilePermission("<<ALL FILES>>","execute")
.