2010-06-09 7 views
17

Entonces, después de unas horas de solución, la limitación de la Reflexión está actualmente deshabilitada en Google App Engine, me preguntaba si alguien podría ayudarme a entender por qué la reflexión de objetos puede ser una amenaza. ¿Es porque puedo inspeccionar las variables privadas de una clase o hay otras razones más profundas?¿Cuál es el riesgo de seguridad de la reflexión de objetos?

+0

¿está deshabilitado, o hay un administrador de seguridad? – Bozho

+0

+1 pregunta asesina. No cierre esto todavía no estoy satisfecho con la respuesta. – rook

+0

Consulte [esta pregunta] (http://stackoverflow.com/questions/1160924/what-risk-does-reflection-pose-medium-trust). – dbyrne

Respuesta

19

1 - La reflexión (como concepto) es realmente ortogonal a la seguridad.

hubo un gran énfasis en el diseño de Java para que sea una plataforma segura, con estática escribir, gerente de seguridad, el uso disciplinado de cargador de clases, y no hay forma de tornillo punteros/memoria . Puede leer la entrevista de James Gosling en Masterminds of programming, que es interesante al respecto.

Pero cuanto más reflectante potencia más difícil es para garantizar que las cosas estén seguras como deberían. La reflexión derrota notablemente el tipado estático y puede conducir a errores en tiempo de ejecución.

Pero también pueden suceder cosas más sutiles. Por ejemplo, los cargadores de clase, que se pueden considerar como ganchos reflectantes, no se diseñaron correctamente en la versión anterior de Java, lo que condujo a la posible sustitución de tipos. El artículo Dynamic class loading in the JVM, de Gilad Bracha es perspicaz sobre estos temas.

La reflexión no se puede desactivar por completo; siempre es posible reflexionar sobre sus propios campos/métodos públicos. Sin embargo, la reflexión en estructuras privadas con AccessibleObject.setAccessible se puede deshabilitar, porque rompe la encapsulación . Con acceso a campos privados, etc., es posible la inspección y modificación de datos internos. Puede llevar a varios exploits maliciosos, p.

  • strings no son inmutables más y se puede cambiar (ver este question)
  • puede revelar información sensible de los objetos no es propietario
  • ... otras vulnerabilidades ...

Finalmente, existen otros mecanismos que ponen en peligro la seguridad, en especial sun.misc.Unsafe que da acceso directo a la memoria: los indicadores están de regreso.

2 - Ahora, la pregunta es si la reflexión (en la práctica) conduce a tantos riesgos.

He leído el enlace señalado por @dbyrne pero se trata principalmente de .net. Además, no sé exactamente qué está deshabilitado para la aplicación Google. ¿Es el ReflectPermission solamente, u otro permiso del gerente de seguridad? Un peligro es claramente tener acceso al sistema de archivos y perder el tiempo.

El problema del acceso a datos privados y la encapsulación de ruptura se puede argumentar en la práctica. Escribir un código de seguridad es realmente extremadamente difícil, e incluso sin cambiar el modificador de acceso, puede subclasificar las clases de manera inapropiada, a menos que sean final, o mejor aún, selladas, y pasarlas. Esto es por ejemplo lo que defensive copying intenta proteger.

La seguridad de tipo también se ve amenazada por el error de tiempo de ejecución debido a la bajada, por lo que este punto también se puede argumentar.

En un entorno compartido/alojado, la seguridad es relativa. En el nivel de idioma, por ejemplo, no puede evitar que un módulo consuma el 100% de la CPU o consuma toda la memoria hasta OutOfMemoryException. Estas preocupaciones deben abordarse por otros medios, generalmente en el nivel del sistema operativo, con virtualización y cuotas.

Así que mi respuesta personal sería: la reflexión es un riesgo de seguridad, pero no tan grande en la práctica si se compara con otros vectores de ataque potenciales.

+0

+1 por proporcionar un excelente enlace. Respetuosamente discrepo con su escenario de ataque aunque admito que todo lo que tenemos es especulación. – rook

+0

Gracias por la explicación detallada. Esta pregunta, de hecho, se deriva de mi otra pregunta: http://stackoverflow.com/questions/3002714/gson-on-google-app-engine-throws-a-security-exception. La respuesta proporcionada dice lo contrario, pero todavía no entiendo por qué GSON hace las cosas de la manera que lo hace. Terminé escribiendo mi propio pequeño método JSON pero este enfoque simplemente no es aceptable para objetos grandes. Eso me lleva a mi última pregunta: si no es reflejo, ¿hay alguna otra forma en que pueda hacer lo que estaba tratando de hacer? ¿Alguna idea? – Legend

+0

@Legend Aparentemente GSON intenta usar 'AccessibleObject.setAccessible' cuando no está permitido. No estoy familiarizado con GSON, y por qué necesita cambiar el modificador de acceso. Supongo que deberías mirar el código de GSON si quieres entender eso. Tal vez podría hacer su propia versión de GSON que usa la reflexión pero no usa 'AccessibleObject.setAccessible' y asegúrese de pasar objetos para la serialización donde todos los campos/métodos son públicos. – ewernli

2

Una aplicación puede usar las API de reflejo de Java para acceder y actualizar campos, y ejecutar métodos que están prohibidos por las reglas normales de acceso/visibilidad de Java. Con un poco de ingenio, esto es suficiente para:

  • acceder a la información que se supone que se oculta,
  • subvertir el entorno limitado de seguridad de Java para que pueda interferir con otras cosas que se ejecutan en la JVM, acceder a archivos en la máquina local, y así sucesivamente.

En determinadas circunstancias, incluso podría permitir la inyección de código nativo malicioso.

+0

Interesante, ¿podría proporcionar más detalles? Quizás un enlace. – rook

0

Una teoría mía es que Google está tratando de ocultar algo. Al deshabilitar Reflection Google podría ocultar nombres de variables, llamadas a funciones e incluso una API completa. Si Google esconde algo así como una API, entonces la certeza no le dirá al respecto.

Sé de sobra que la reflexión juega un papel muy importante en las pruebas de seguridad. Por ejemplo, puede generar automáticamente pruebas de Fuzz utilizando la reflexión. AxMan usa TypeLib para identificar todas las clases y sus llamadas a métodos que conforman un objeto COM. Usando esta información AxMan instanciará cada clase y llamará a cada método con permutaciones de cadenas largas y números grandes. Pruebas similares se llevan a cabo por SOAP Fuzzers usando el archivo WSDL para la reflexión.

2

En primer lugar, si no ha instalado un SecurityManager, entonces no estará seguro de todos modos.

En segundo lugar, la reflexión no abre agujeros significativos a menos que el setAccessible() esté habilitado, y que sí mismo esté sujeto a un control de seguridad (regido por el setAccessChecksreflection permission). Sin eso, aunque es posible que pueda saber que existe el campo o método privado (aunque eso sí requiere el accessDeclaredMembersruntime permission) no puede hacer mucho con ese conocimiento. Su mejor apuesta para atacar podría ser trabajar con objetos serializados, pero eso es una bola entera de cera.

Tenga en cuenta también que escribir un gestor de seguridad seguro y un cargador de clases no es trivial. Lo mejor es dejarlos a otros si no estás aspirando al mega-gurú-dom (o, más probablemente, niveles vergonzosos de fracaso).

1

GAE es un entorno de alojamiento compartido y aloja archivos WAR de varios usuarios. Es muy probable que varios archivos WAR estén alojados en la misma JVM, porque generar un proceso por WAR es simplemente ridículo. Por lo tanto, la única forma de proteger cada archivo war es a través de un cargador de clases personalizado para cada archivo WAR.

Supongamos que se permite la reflexión. Usted could then walk the classloader hierarchy y enumere clases/métodos de archivos WAR que pertenecen a diferentes usuarios. Obviamente, esa es una gran preocupación.

Cuestiones relacionadas