Как ограничить 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.
}