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

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

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

И другие, используя конфигурацию веб-сервера соответственно.

Проблема:

Таким образом, я был удовлетворен настройкой только для того, чтобы встретить позже, что, независимо от ограничения, применяемого к тегу 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\ имеется специальная утилита GUI, называемая 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 библиотеку, которая реализует файл политики с помощью правила deny (ref.). Вы, несомненно, заменили бы <<ALL FILES>> на отдельный файл и соответственно установили разрешения или для лучшего управления использовали комбинацию <<ALL FILES>> и отдельных прав доступа к файлам.

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

Этот подход решает нашу основную проблему: отказ в выполнении файлов с использованием java runtime путем указания разрешений, разрешенных для файла. В другом подходе мы можем реализовать 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.
}