Вопрос по reflection, private, access-modifiers, java – Частные методы действительно безопасны?

92

В Javaprivate Модификатор доступа считают безопасным, поскольку он не виден за пределами класса. Тогда внешний мир неЯ тоже не знаю об этом методе.

Но я думал, что отражение Java можно использовать, чтобы нарушить это правило. Рассмотрим следующий случай:

public class ProtectedPrivacy{

  private String getInfo(){
     return "confidential"; 
  }

}  

Теперь из другого класса я собираюсь получить информацию:

public class BreakPrivacy{

   public static void main(String[] args) throws Exception {
       ProtectedPrivacy protectedPrivacy = new ProtectedPrivacy();
       Method method = protectedPrivacy.getClass().getDeclaredMethod("getInfo", null);
       method.setAccessible(true);
       Object result = method.invoke(protectedPrivacy);
       System.out.println(result.toString());
   }
} 

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

Но моя точка становится недействительной, так как ниже строки кода.

Method method[] = new ProtectedPrivacy().getClass().getDeclaredMethods();

Теперь этоmethod[] содержит все вещи, которые нужно сделать выше вещи. У меня вопрос, есть ли способ избежать такого рода вещей, используя отражение Java?

Я цитирую какой-то пункт изДокументация Java уточнить мой вопрос.

Советы по выбору уровня доступа:

Если другие программисты используют ваш класс, вы хотите, чтобы ошибки от неправильного использования не возникали. Уровни доступа могут помочь вам в этом. Используйте наиболее ограниченный уровень доступа, который имеет смысл для конкретного участника. Используйте личное, если у вас нет веских причин не делать этого.

Частный, защищенный общественный и т. Д. Не для безопасности, а для того, чтобы не допустить ошибок, совершаемых людьми, имеющими хорошие намерения. Не используйте его в качестве меры безопасности Richard Tingle
Использование обфускатора может помочь, потому чтоgetDeclaredMethods вернет имена, которые выглядят как мусор. dasblinkenlight
может быть ссылка поможет вамstackoverflow.com/questions/7566626/... Nikesh
Код Java в любом случае декомпилируем. An 'атакующий» может просто скачать декомпилятор Java и прочитать ваш код, или изменитьчастный' кобщественности. 11684

Ваш Ответ

7   ответов
5

не может делать, & вещи, которые выМожно делай но тыне должен делать.

Закрытый модификатор предоставляется / используется как / наиболее ограниченным образом. Члены, которые не должны быть видны за пределами класса, должны быть определены как частные. Но это может быть нарушено с помощью Reflection, как мы видим. Но это не значит, что вы не должны использовать частные - или они небезопасны. Речь идет о вас разумно или конструктивно использовать вещи (например, отражение).

95

безопасный", Если ты'Если вы работаете с менеджером безопасности, который допускает подобные вещи, то да, вы можете делать все неприятные вещи с помощью рефлексии. Но тогда в такой среде библиотека, вероятно, может быть просто модифицирована, чтобы в любом случае сделать метод общедоступным.

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

@Gray: экземплярМенеджер по безопасности который бросает исключения на соответствующиеcheck* звонки, в основном. Jon Skeet
Тангенциальный, я знаю, но не могли бы вы немного рассказать о том, каким будет более ограничительный менеджер в этом смысле? Gray
5

что вы доверяете клиентскому программисту вашего API, можно взглянуть на это с другой стороны.безопасный' это для них, чтобы использовать эти конкретные функции.

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

Если клиентский программист изо всех сил пытается обойти эти абстракции, они в некотором смысле заявляют, что знают, что делают. Что еще более важно, они понимают, что это не поддерживается и могут перестать работать с будущими версиями вашего кода.

6

спасти это из. По моему мнению, такой клиент вашего кода здесь один в недоумении.

Любой фрагмент кода (написанный вами или другими лицами), который пытается получить доступ кprivate член вышеуказанного класса по сути копает свою могилу.private Члены нене может быть частьюобщественности API и могут быть изменены без предварительного уведомления. Если клиент использует одного из таких закрытых членов способом, описанным выше, он 'сломается, если он обновится до более новой версии API, в которой был изменен закрытый член.

40

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

Наряду со знанием данных и методов вашего кода, появляется возможность узнать, когда и как его использовать. Ты нене используйте приватный метод inIt, чтобы кто-то не узнал об этом, вы делаете это потому, что (а) они нене буду знать, что вы называете это только после foo и только если bar = 3.1415 и (b), потому что это не дает им никакой пользы, чтобы знать об этом.

Модификаторы доступа можно обобщить простой фразойTMI, чувак, ятак А не было»Не нужно это знать ".

Отличный ответ, но мне нужно было зайти в Google, чтобы узнать, что TMI означает слишком много информации. Я думаю, мне нужно больше времени проводить в долине :-) mikelong
5

private это не для безопасности, это для поддержания чистоты кода и предотвращения ошибок. Это позволяет пользователям модулировать код (и как он разрабатывается), не беспокоясь овсе детали других модулей

Как только вы выпустите свой код, люди смогут понять, как он работает. Там'нет никакого способа "скрывать" логика, если вы хотите, чтобы код запускался на компьютере. Даже компиляция в двоичный файл - это лишь уровень запутывания.

Так что'Вы не можете настроить свой API для выполнения специальных задач, которые вы не делаетене хочу, чтобы другие могли звонить. В случае веб-API вы можете разместить методы, которые вы хотите контролировать, на стороне сервера.

7

безопасный'вы защищаете себя или других разработчиков, которые используют ваш API, чтобы не навредить объекту, вызывая ваш закрытый метод. Но если вам или им действительно нужно вызвать этот метод, они могут сделать это с помощью Reflection.

Похожие вопросы