Отключить отражение Java для текущего потока - PullRequest
18 голосов
/ 21 апреля 2009

Мне нужно вызвать некоторый полу-заслуживающий доверия Java-код и отключить возможность использования отражения во время выполнения этого кода.

try{
   // disable reflection somehow
   someObject.method();
}
finally{
   // enable reflection again
}

Можно ли это сделать с помощью SecurityManager, и если да, то как?

Пояснение / Контекст: Это продолжение другого вопроса об ограничении пакетов, которые можно вызывать из JavaScript / Rhino. Принятый ответ ссылается на запись в блоге о том, как это сделать, и требует двух шагов: первый с использованием Rhino API (ClassShutter), второй с отключением отражения и Class.forName (). Я думал, что смогу сделать этот второй шаг более аккуратно, используя SecurityManager (узнавая о SecurityManager, который, как уже указывалось, является сложным зверем, попутно).

Подводя итог, я хочу (из кода, а не из файла настроек) отключить Class.forName () и любой доступ ко всему пакету отражения.

Ответы [ 3 ]

18 голосов
/ 21 апреля 2009

Это зависит от того, что вы пытаетесь ограничить.

В общем, общедоступный API не ограничен. Однако, пока вы не предоставите ненадежному коду разрешение ReflectPermission("suppressAccessChecks"), он не сможет получить доступ к непубличному API в другом пакете.

Если у вас есть список пакетов, доступ к которым вы хотите ограничить, есть два шага. Во-первых, в свойствах Security, включает ограниченный пакет в список package.access . Затем введите свой доверенный код RuntimePermission("accessClassInPackage." + pkg).

Обычный способ отличить ненадежный код - загрузить его из другого места и при предоставлении разрешений обращаться к различным кодовым базам в файле политики.

Архитектура безопасности Java очень мощная, но я знаю, что она также сложна; если вам нужен более конкретный пример, опишите, какие именно вызовы вы хотите ограничить, и я постараюсь быть более точным.


Сделать то, что вы хотите, без изменения файла java.policy и / или файла java.security будет очень сложно, а может быть, и невозможно. java.security.Policy представляет информацию в java.policy, но не предоставляет права на запись. Вы можете создать собственную реализацию Policy и установить ее во время выполнения, если это разрешено любым существующим SecurityManager.

С другой стороны, вы можете указать пользовательский файл java.policy в качестве параметра командной строки. Если вы предоставляете законченное приложение с каким-то средством запуска, это может быть легко выполнено. Это также обеспечивает некоторую прозрачность для ваших пользователей. Опытный пользователь может просмотреть разрешения, которые вы хотели бы предоставить приложению.

4 голосов
/ 21 апреля 2009

Ну, вы можете переопределить SecurityManager.checkMemberAccess и дать более строгое определение. Однако на самом деле это не так. Что происходит, например, если код определяет финализатор?

Пояснение: другие API используют рефлексию и другие API. Например, java.beans, LiveConnect и Rhino. Например, злоумышленник из сценария может создать новый контекст Rhino без затвора и, таким образом, загрузить его в полную версию JRE. С открытой системой черный список никогда не может быть закончен.

В итоге: для использования модели безопасности Java вам нужно работать с ней, а не с ней.

1 голос
/ 27 июля 2010

Я написал замену ClassShutter, которая позволяет детально контролировать доступ, для каждого экземпляра, для метода, для поля:

http://riven8192.blogspot.com/2010/07/java-rhino-fine-grained-classshutter.html

...