Как ограничить createObject() для определенных классов или пакетов Java?

Я хочу создать безопасную среду ColdFusion, для которой я использую несколько конфигураций песочниц. Следующие задачи легко достижимы с помощью дружественного интерфейса администратора:

  • Ограничение CFtags, таких как: cfexecute, cfregistry и cfhttp.
  • Отключение доступа к внутренним компонентам ColdFusion Java.
  • Доступ только к определенным диапазонам серверов и портов сторонними ресурсами.

А остальные используют конфигурацию веб-сервера соответственно.

Эта проблема:

Таким образом, я был удовлетворен настройкой только для того, чтобы потом столкнуться с тем, что независимо от ограничения, примененного к cfexecute тег можно использовать java.lang.Runtime легко выполнять системные файлы или скрипты;

String[] cmd = {"cmd.exe", 'net stop "ColdFusion 10 Application Server"'};
Process p = Runtime.getRuntime().exec(cmd);

или используя java.lang.ProcessBuilder:

ProcessBuilder pb = new ProcessBuilder("cmd.exe", 'net stop "ColdFusion 10 Application Server"');
....
Process myProcess = pb.start();

Проблема в том, что я не могу найти какие-либо решения, которые позволяют мне отключить эти два класса: java.lang.Runtime & java.lang.ProcessBuilder для createObject(), Для заметки: я пробовал ограничение файлов в разрешениях sanbox и os, но, к сожалению, они, похоже, работают только с файловыми операциями ввода-вывода, и я не могу связываться с политиками безопасности системных библиотек, поскольку они могут использоваться для внутреннего использования. ColdFusion.

1 ответ

Решение

Следуя полезным предложениям @ Leigh и @ Miguel-F, я попробовал свои силы в реализации Security Manager а также Policy, Вот результат:

1. Указание дополнительного файла политики во время выполнения вместо внесения изменений по умолчанию java.policy файл. Чтобы включить это, мы добавляем следующие параметры в аргументы JVM, используя интерфейс CFAdmin или альтернативно добавляя его в jvm.args линия в jvm.config файл:

-Djava.security.manager -Djava.security.policy = "c: /policies/myRuntime.policy"

Внутри есть хорошая утилита с графическим интерфейсом jre\bin\ называется policytool.exe что позволяет легко и эффективно управлять записями политики.

2. Мы применили диспетчер безопасности и предоставили файл пользовательской политики безопасности, который содержит:

    grant codeBase "file:///D:/proj/secTestProj/main/-"{
        permission java.io.FilePermission 
        "<<ALL FILES>>", "read, write, delete";
    };

Здесь мы устанавливаем FilePermission для всех файлов read, write, delete исключая execute из списка, поскольку мы не хотим, чтобы какой-либо тип файла выполнялся с использованием среды выполнения Java.

Примечание. Кодовая база может быть установлена ​​в пустую строку, если мы хотим, чтобы политика применялась ко всем приложениям независимо от источника.

Я действительно хотел deny правило в файле политики, чтобы сделать вещи проще, как grant Правило, которое мы используем, но, к сожалению, нет. Если вам нужно создать набор сложных политик безопасности, вы можете использовать библиотеку Prograde, которая реализует файл политики с правилом запрета ( ссылка на стек). Вы могли бы наверняка заменить <<ALL FILES>> с отдельным файлом и установить права доступа соответственно или для лучшего контроля использовать комбинацию <<ALL FILES>> и отдельные права доступа к файлам.

Ссылки: Реализация политики по умолчанию и синтаксис файла политики, разрешения в JDK и управляющие приложения.

Этот подход решает нашу основную проблему: запрещение выполнения файлов с использованием среды выполнения Java путем указания разрешений, разрешенных для файла. В другом подходе мы можем реализовать Security Manager непосредственно в нашем приложении, чтобы определить файл политики оттуда, а не определять его в наших аргументах JVM.

//set the policy file as the system securuty policy
System.setProperty("java.security.policy", "file:/C:/java.policy");
// create a security manager
SecurityManager sm = new SecurityManager();
//alternatively, get the current securiy manager using System.getSecuriyManager() 
//set the system security manager
System.setSecurityManager(sm);

Чтобы установить его, нам нужны эти разрешения внутри нашего файла политики:

permission java.lang.RuntimePermission "setSecurityManager";
permission java.lang.RuntimePermission "createSecurityManager";
permission java.lang.RuntimePermission "usePolicy";

Использование объекта Security Manager внутри приложения имеет свои преимущества, так как предоставляет множество полезных методов. Например: CheckExec(String cmd) который проверяет, разрешено ли вызывающему потоку создавать подпроцесс или нет.

//perform the check
try{
  sm.checkExec("notepad.exe");
}
catch(SecurityException e){
  //do something...show warning.
}
Другие вопросы по тегам