Java Sandboxing и ProcessBuilder - PullRequest
       13

Java Sandboxing и ProcessBuilder

0 голосов
/ 04 июля 2018

Я следовал этому учебнику , чтобы реализовать java-песочницу для кода плагина. Код плагина запускается со следующим разрешением:

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

Работает нормально. Тем не менее, я хотел бы позволить плагину запускать процесс, который также будет ограничен этими разрешениями. Например, он должен иметь возможность запускать сценарий python, выполнив эту команду «python test.py», если сценарий находится в каталоге / 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)

Это говорит о том, что мне нужно дать разрешение «выполнить» для всех файлов. Но мне нужно это ограничение только для файлов в указанном каталоге. Итак, как добиться песочницы, позволяя ProcessBuilder запускать процесс в ограниченном каталоге?

UPDATE:

Плагин теперь имеет следующие разрешения:

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 голосов
/ 04 июля 2018

Вы запускаете команду python (неквалифицированную), поэтому start() не знает, где находится файл, и, следовательно, проверьте, разрешен ли execute доступ к <<ALL FILES>>. Поскольку это не так, он отклонен.

Если указать полный (абсолютный) путь к python и предоставить доступ к файлу python, он будет работать.

См. Описание Javadoc SecurityManager.checkExec​(String cmd) для проверки разрешения:

Выдает SecurityException, если вызывающему потоку не разрешено создавать подпроцесс.

Этот метод вызывается для текущего менеджера безопасности методами exec класса Runtime.

Этот метод вызывает checkPermission с разрешением FilePermission(cmd,"execute") , если cmd является абсолютным путем , в противном случае он вызывает checkPermission с FilePermission("<<ALL FILES>>","execute").

...