2012-03-11 20 views
7

Estoy tratando de comprender el modelo de seguridad utilizado cuando se le pide a la JVM que cargue las clases.El modelo de seguridad de Java ClassLoader

A partir de la especificación de JVM en Sandboxing, tengo la creencia de que una implementación de JVM estándar debe mantener al menos otra ClassLoader, independiente de primordial ClassLoader. Esto se usa para cargar los archivos de la clase de aplicación (desde una ruta de clase proporcionada, por ejemplo).

Si se solicita la clase de la ClassLoader que no está en su espacio de nombres, java/lang/String por ejemplo, a continuación, reenvía la solicitud al primordial ClassLoader, que intenta cargar la clase de la API de Java, si no está allí, entonces arroja un NoClassDefFoundError.

¿Estoy en lo cierto al pensar que el ClassLoader primordial solo carga las clases desde el espacio de nombres de la API Java, y todas las demás clases se cargan a través de una implementación ClassLoader independiente?

Y que esto hace que la carga de las clases más seguros, ya que significa que una clase malicioso no puede hacerse pasar por un miembro de la API de Java (digamos que java/lang/Virus) porque se trata de un espacio de nombres protegidos, y no puede ser utilizado en la corriente ClassLoader ?

¿Pero hay algo para evitar que las clases de la API de Java sean reemplazadas por clases maliciosas, o se detectaría durante la verificación class?

+0

Básicamente correcto. El ClassLoader "primordial" se conoce como el "Cargador de clases de arranque" y carga clases desde el "classpath de arranque". La protección ofrecida por este es razonablemente "fuerte" siempre que el "oficial de seguridad" controle la invocación de JVM (por ejemplo, línea de comando) donde se especifica el classpath de arranque. –

+0

(Algunas JVM tienen seguridad adicional en la ruta de clase de arranque, lo que requiere que los JAR tengan un atributo privilegiado). –

+0

@HotLicks ¿El 'boot classpath' es el lugar donde se encuentra el tiempo de ejecución de Java? – Jivings

Respuesta

7

Por razones históricas, los nombres utilizados para los cargadores de clase son un poco peculiares. El cargador de clases de arranque carga las clases de sistemas. El cargador de clases del sistema, por defecto, carga las clases desde la ruta de clase, no las clases del sistema. Las clases del sistema se encuentran en jre/lib (principalmente en rt.jar), en los directorios endosados ​​y en cualquier lugar agregado a través de -Xbootclasspath.

En el Sun/Oracle JRE, rt.jar contiene clases con paquetes que comienzan con java., Javax., Sun., Com.sun., Org.omg, org.w3c y org.xml.

El código que no es de confianza (incluida la configuración) no debería poder agregarse a las clases del sistema. Algunos nombres de paquetes con prefijo pueden estar restringidos a través de una propiedad de seguridad. El java el prefijo está especialmente protegido por razones no técnicas.

En general, un cargador de clases delegará a su padre antes de definir una nueva clase, evitando que se reemplacen las clases de un cargador ancestro. Java EE recomienda (a pesar de que Java SE prohibe) que algunos cargadores de clases prefieran sus propias clases, generalmente para utilizar una API más actualizada o una implementación diferente. Esto permite sombrear las clases, pero solo como se ve a través de ese cargador (y sus hijos). Todas las otras clases continúan vinculadas al original.

+3

Suena como la especificación de JVM. 'Por razones históricas' es su excusa para todo;) – Jivings

+0

Gracias por esto, muy útil. – Jivings

+0

+1 "por razones históricas" – Javier

Cuestiones relacionadas