Внешние классы, получающие доступ к закрытым для пакета методам

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

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

Другими словами, могу ли я что-нибудь сделать, чтобы предотвратить это?


person Jake    schedule 21.05.2010    source источник
comment
Возможно, стоит отредактировать заголовок, чтобы в нем не использовалось слово «защищено», учитывая, что оно имеет очень конкретное значение.   -  person Jon Skeet    schedule 21.05.2010


Ответы (4)


Вы можете запечатать пакет в файле jar. Хотя он не пуленепробиваемый.

Главное, не полагаться на модификаторы доступа и т. д. с точки зрения безопасности. Если кто-то запускает код с неограниченными разрешениями, у него будет доступ ко всему. Модификаторы доступа просто помогают предотвратить случайное попадание себя в ногу.

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

person Jon Skeet    schedule 21.05.2010

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

person Asaph    schedule 21.05.2010

Во-первых, это сценарий «DRM»: в конечном счете, кто-то достаточно решительный может обойти любую защиту, которую вы установили, предоставив причудливо модифицированную среду выполнения или другие подобные вещи. Обратный сценарий — когда среде выполнения доверяют, а некоторым пакетам — нет, — правильно решается Java с помощью подходящих ClassLoader ограничений, но это может работать только там, где есть что-то, что может обеспечить соблюдение ограничений доверенным образом; вот почему ваш сценарий в основном обречен.

Однако, если мы предполагаем, что сама среда выполнения является надежной, вы можете попытаться с помощью своего сверхсекретного метода получить трассировку стека для текущего исполняемого стека (см. stackoverflow.com/questions/1069066/… для того, как) и проверить, является ли вызывающий объект текущего метода одним которому вы доверяете, чтобы получить доступ. Менеджер безопасности был бы еще более подходящим, но вы не можете доверять среде, чтобы установить один из тех, которые вам нравятся (он гораздо более явно находится под контролем злоумышленника). Обратите внимание, что я не пробовал варианты в этом абзаце!

Другая альтернатива — поместить свои секреты в службу, которой вы управляете, и предлагать только удаленный доступ к ним. Или перестаньте беспокоиться об использовании технических механизмов для решения проблемы, которая в основном связана с деловыми и юридическими вопросами (например, почему вы имеете дело с людьми, которым не можете доверять?)

person Donal Fellows    schedule 21.05.2010
comment
Вы не можете использовать структуру java.security.Permission, потому что пользователь может предоставить себе полную власть. - person Donal Fellows; 21.05.2010

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

person cthulhu    schedule 21.05.2010