En Java el private
modificador de acceso se considera seguro ya que no es visible fuera de la clase. Entonces el mundo exterior tampoco conoce ese método.
Pero pensé que la reflexión de Java puede usarse para romper esta regla. Considere el siguiente caso:
public class ProtectedPrivacy{
private String getInfo(){
return "confidential";
}
}
Ahora de otra clase voy a obtener información:
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());
}
}
En este momento pensé que el método privado aún era seguro, ya que para hacer algo como el anterior debemos saber el nombre del método. Pero si la clase contiene un método privado escrito por otra persona, no tenemos visibilidad de ellos.
Pero mi punto se vuelve inválido desde debajo de la línea de código.
Method method[] = new ProtectedPrivacy().getClass().getDeclaredMethods();
Ahora bien, esto method[]
contiene todas las cosas que hay que hacer antes. Mi pregunta es, ¿hay alguna manera de evitar este tipo de cosas usando la reflexión de Java?
Cito algún punto de la documentación de Java para aclarar mi pregunta.
Consejos para elegir un nivel de acceso:
Si otros programadores usan su clase, querrá asegurarse de que no se produzcan errores por mal uso. Los niveles de acceso pueden ayudarlo a hacer esto. Utilice el nivel de acceso más restrictivo que tenga sentido para un miembro en particular. Use privado a menos que tenga una buena razón para no hacerlo.
fuente
getDeclaredMethods
que devolvería nombres que parecen basura.Respuestas:
Depende de lo que quieras decir con "seguro". Si está ejecutando con un administrador de seguridad que permite este tipo de cosas, entonces sí, puede hacer todo tipo de cosas desagradables con reflexión. Pero luego, en ese tipo de entorno, la biblioteca probablemente pueda modificarse para hacer público el método de todos modos.
El control de acceso es efectivamente un "aviso" en un entorno como ese: está confiando efectivamente en que el código se reproducirá bien. Si no confía en el código que está ejecutando, debe usar un administrador de seguridad más restrictivo.
fuente
check*
llamadas relevantes , básicamente.Los modificadores de acceso no tienen nada que ver con la seguridad. De hecho, puede y debe considerar los modificadores de acceso como lo contrario de la seguridad: no es para proteger sus datos o algoritmos, es para proteger a las personas del requisito de conocer sus datos y algoritmos. Esta es la razón por la que el modificador predeterminado es paquete: si están trabajando en el paquete, probablemente ya lo necesiten.
Junto con el conocimiento de los datos y los métodos de su código, viene la responsabilidad de saber cuándo y cómo usarlo. No pones privado en tu método inIt para evitar que alguien se entere, lo haces porque (a) no van a saber que solo lo llamas después de foo y solo si bar = 3.1415 y (b) porque no les sirve de nada saberlo.
Modificadores de acceso se pueden resumir en una simple frase "TMI, tío, por lo que no necesitaba saber eso".
fuente
Al decir "seguro", te estás protegiendo a ti oa otros desarrolladores, que están usando tu API para no dañar el objeto llamando a tu método privado. Pero si usted o ellos realmente necesitan llamar a este método, pueden hacerlo con Reflection.
fuente
La pregunta es a quién intentas salvar . En mi opinión, tal cliente de su código es el que está perdido aquí.
Cualquier fragmento de código (escrito por usted u otros) que intente acceder a un
private
miembro de la clase anterior está esencialmente cavando su propia tumba.private
los miembros no forman parte de la API pública y están sujetos a cambios sin previo aviso. Si un cliente consume uno de esos miembros privados de la manera indicada anteriormente, se romperá si se actualiza a una versión más nueva de la API en la que se modificó el miembro privado.fuente
Con facilidad, viene la responsabilidad. Hay cosas que no puedes hacer y cosas que puedes hacer pero no debes hacer.
El modificador privado se proporciona / utiliza como / de la manera más restringida. Los miembros que no deben ser visibles fuera de la clase se definirán como privados. Pero esto se puede romper con Reflection como vemos. Pero esto no significa que no deba usar los privados, o no son seguros. Se trata de que uses las cosas de manera juiciosa o constructiva (como la reflexión).
fuente
Suponiendo que confía en el programador cliente de su API, otra forma de verlo es qué tan 'seguro' es para ellos usar esas funciones particulares.
Sus funciones disponibles públicamente deben proporcionar una interfaz clara, bien documentada y que rara vez cambia en su código. Sus funciones privadas pueden considerarse un detalle de implementación y pueden cambiar con el tiempo, por lo que no es seguro utilizarlas directamente.
Si un programador cliente se esfuerza por eludir estas abstracciones, de alguna manera está declarando que sabe lo que está haciendo. Más importante aún, comprenden que no es compatible y pueden dejar de funcionar con versiones futuras de su código.
fuente
private
no es por seguridad, es para mantener limpio el código y evitar errores. Permite a los usuarios modularizar el código (y cómo se desarrolla) sin tener que preocuparse por todos los detalles de los otros módulos.Una vez que libera su código, la gente puede descubrir cómo funciona. No hay forma de "ocultar" la lógica si finalmente desea que el código se ejecute en una computadora. Incluso compilar en binario es sólo un nivel de ofuscación.
Por lo tanto, no hay forma de que pueda configurar su API para hacer cosas especiales que no desea que otros puedan llamar. En el caso de una API web, puede colocar los métodos que desea controlar en el lado del servidor.
fuente