Запретить потоку выполнять определенные методы

У меня есть система шаблонов, позволяющая пользователю вводить исходный код шаблона и выполнять его. Исходный код шаблона может обращаться к любому произвольному объекту Java, включая классы System,Runtime и IO.

Вопрос состоит в том, как предотвратить выполнение потоком определенных методов, таких как System.exit, new FileOutputStream и т.п.

3 ответа

Один (довольно тяжелый, но выполнимый) способ сделать это заключается в следующем:

  1. С помощью агента Java преобразуйте все загруженные (в прошлом и будущем) классы, чтобы вызовы ваших методов, занесенных в черный список, фактически перенаправлялись в другой метод. Вы можете использовать ClassFileTransformer и ASM для него. Так, например, звонок в System.exit теперь будет вызывать MySystem.exit, Конечно MySystem не должен быть преобразован.
  2. Код 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 (код);
            }
        }
    }
  1. Для потоков, которые вы хотите вызвать оригинальные вызовы, установите это ThreadLocal в trueдля других no,

Возможно, вы захотите взглянуть на исходный код библиотеки машины времени для аналогичного решения.

Предполагая, что мы говорим о интерпретаторе, а не сгенерированном коде. С SecurityManager Установленные привилегии могут быть уменьшены при наличии политики, которая уменьшает разрешения кода интерпретатора.

Если вы используете формы с двумя аргументами java.security.AccessController.doPrivilegedзатем возникают проблемы с вызовом методов, которые проверяют непосредственный вызывающий и игнорируют все, что было передано (например, AccessController.doPrivileged).

Очевидно, что хостинг ненадежного кода обнажает огромную поверхность атаки. Вы можете скрыть часть своего собственного кода, используя загрузчики классов, которые являются одноранговыми в иерархии загрузчиков классов. Свойство security package.access также полезно (хотя вам все еще нужны отдельные загрузчики классов).

О, есть несколько способов сделать это. Но самый приличный способ - использовать Менеджер безопасности и написать свой собственный загрузчик классов (это не займет много времени, так как поиск в Google даст вам много примеров:)). Когда вы загружаете класс (который был скомпилирован и загружен во время выполнения) в загрузчик классов, вам нужно указать Security Manager. В этом коде вы можете указать ограничения.

Я не знаю, является ли это юридической ссылкой или нет, но это должно помочь.

Это также может помочь.

Другие вопросы по тегам