Java Security Manager полностью отключает отражение

#java #reflection #securitymanager #policies

#java #отражение #securitymanager #Политики

Вопрос:

Я прочитал довольно много вопросов в Stackoverflow по этому вопросу, но не смог найти решение или ответ на мою проблему. Если оно уже есть, я был бы признателен, если бы кто-нибудь дал подсказку…

Моя проблема / вопрос в том, возможно ли полностью отключить отражение для ненадежного кода? Такие функции, как getDeclaredMethods() (См. test.java ). У меня уже есть Java Security Manager, который выдает исключения безопасности, если код пытается записать / прочитать / и т.д. …

Если это возможно, может кто-нибудь показать мне, как?

Бруно

test.java

 TestClass cls = new TestClass();
Class c = cls.getClass();

// returns the array of Method objects 
Method[] m = c.getDeclaredMethods();
for(int i = 0; i < m.length; i  ) {
   System.out.println("method = "   m[i].toString());
}
  

Ответ №1:

Таким образом, я решил проблему не напрямую с помощью checkPermission (). Мой обходной путь — проверить, доступен ли пакет java.lang.reflect.

 @Override
public void checkPackageAccess(String pkg){

    // don't allow the use of the reflection package
    if(pkg.equals("java.lang.reflect")){
        throw new SecurityException("Reflection is not allowed!");
    }
}
  

Комментарии:

1. Возможно, я здесь ошибаюсь, но я совершенно уверен, что if (pkg.startsWith("java.lang.reflect")){ было бы намного безопаснее.

Ответ №2:

Расширьте свой SecurityManager и попросите его проверить наличие ReflectPermission и RuntimePermission . Затем вы должны решить, имеет ли вызывающий абонент разрешение на отражение:

 @Override
public void checkPermission(Permission perm) {
  if (perm instanceof ReflectPermission) {
    // called for Method.setAccessible(true)
    // determine whether caller is permitted    using getClassContext()
  }
  if (perm instanceof RuntimePermission) {
    if (perm.implies(new RuntimePermission("accessDeclaredMembers"))) {
      // called for Class.getDeclardFields()
      System.out.println("getDeclaredFields() called");
    }
}
  

Комментарии:

1. Я скопировал ваш код и добавил throw new SecurityException(...) но исключение не выдается… функция даже не вызывается …

2. Да, это не вызывается для getDeclaredMethods() , но если вы хотите получить доступ к частным / защищенным методам через Method.setAccessible(true) SecurityManager вызывается.

3. Я обновил answear для проверки на getDeclardXYZ() . Надеюсь, это поможет.

4. Это не работает так хорошо, я не знаю почему, но функция checkPermission даже не вызывается…

5. Является ли политика глобальной или вы можете установить ее для определенного пакета? Например, в ситуациях, когда у вас есть плагины, как вы могли бы ограничить только JAR плагина. Потому что возможно, что у нас могут быть другие библиотеки (ORM, Gson и т.д.), Которые зависят от отражения.

Ответ №3:

Пока мы не предоставляем security manager, частные члены класса могут быть доступны. Для доступа к закрытым членам класса вы должны установить значение setAccessible(true), это позволит вам получить доступ к закрытым членам. Чтобы ограничить доступ к закрытым элементам, сохраняйте нижеприведенную строку кода в вашем неизменяемом конструкторе класса.

System.setSecurityManager(новый SecurityManager());

Это вызовет исключение AccessControlException при попытке установить значение setAccessible(true).