Запретить потоку выполнять определенные методы
У меня есть система шаблонов, позволяющая пользователю вводить исходный код шаблона и выполнять его. Исходный код шаблона может обращаться к любому произвольному объекту Java, включая классы System,Runtime и IO.
Вопрос состоит в том, как предотвратить выполнение потоком определенных методов, таких как System.exit
, new FileOutputStream
и т.п.
3 ответа
Один (довольно тяжелый, но выполнимый) способ сделать это заключается в следующем:
- С помощью агента Java преобразуйте все загруженные (в прошлом и будущем) классы, чтобы вызовы ваших методов, занесенных в черный список, фактически перенаправлялись в другой метод. Вы можете использовать ClassFileTransformer и ASM для него. Так, например, звонок в
System.exit
теперь будет вызыватьMySystem.exit
, КонечноMySystem
не должен быть преобразован. - Код
MySystem.exit
может условно ссылатьсяSystem.exit
основанный, например, наThreadLocal
переменная.
открытый класс MySystem { приватная статическая финальная ThreadLocal callOriginal = new ThreadLocal (); static public final void exit (int code) { if (Boolean.TRUE.equals (callOriginal.get ())) { System.exit (код); } } }
- Для потоков, которые вы хотите вызвать оригинальные вызовы, установите это
ThreadLocal
вtrue
для другихno
,
Возможно, вы захотите взглянуть на исходный код библиотеки машины времени для аналогичного решения.
Предполагая, что мы говорим о интерпретаторе, а не сгенерированном коде. С SecurityManager
Установленные привилегии могут быть уменьшены при наличии политики, которая уменьшает разрешения кода интерпретатора.
Если вы используете формы с двумя аргументами java.security.AccessController.doPrivileged
затем возникают проблемы с вызовом методов, которые проверяют непосредственный вызывающий и игнорируют все, что было передано (например, AccessController.doPrivileged
).
Очевидно, что хостинг ненадежного кода обнажает огромную поверхность атаки. Вы можете скрыть часть своего собственного кода, используя загрузчики классов, которые являются одноранговыми в иерархии загрузчиков классов. Свойство security package.access также полезно (хотя вам все еще нужны отдельные загрузчики классов).
О, есть несколько способов сделать это. Но самый приличный способ - использовать Менеджер безопасности и написать свой собственный загрузчик классов (это не займет много времени, так как поиск в Google даст вам много примеров:)). Когда вы загружаете класс (который был скомпилирован и загружен во время выполнения) в загрузчик классов, вам нужно указать Security Manager. В этом коде вы можете указать ограничения.
Я не знаю, является ли это юридической ссылкой или нет, но это должно помочь.
Это также может помочь.