2010-11-01 17 views
7

me gustaría poder detectar problemas con la deserialización en código Java. ¿Que debería buscar? Por ejemplo, ¿cómo se determinaría si algún código de Java intenta explotar "java calendar bug"? Tenga en cuenta que no soy un programador de Java, pero entiendo los conceptos detrás de la serialización y la OOP bien. Estoy tratando de implementar algunas comprobaciones de seguridad (algo así como una herramienta de advertencia del compilador).¿Cómo detectar problemas de deserialización de Java?

EDIT: basado en los comentarios me gustaría cambiar la pregunta un poco: considero todo el código analizado "no confiable", hay una manera de cómo evaluar el peligro potencial? Quiero decir, ¿puedo decir que el código A es más peligroso que B con respecto a la falla de deserialización? ¿Que debería buscar?

Respuesta

5

En primer lugar, debe comprender su contexto para determinar las amenazas de seguridad. (Cuando hablo de "confianza", estoy tomando un atajo pequeño. Estoy hablando deliberadamente malicioso.)

Si los datos serializados fueron creados, guardados y leídos con la misma confianza, entonces no hay ningún problema real (que no sean errores estándar). Tenga en cuenta que si escribe cualquier información sensible, los datos serializados también son sensibles (parece obvio, pero hay una buena cantidad de indirección allí).

Si los datos serializados no son de confianza por alguna razón, entonces hay un poco más que considerar. La estructura interna de los objetos recreados puede ser "inusual". Los datos pueden no ser consistentes. Es posible que haya compartido objetos mutables que deberían estar separados. La deserialización puede causar un bucle infinito, o un bucle no infinito que simplemente no es completable antes de la muerte por calor del universo. Y, por supuesto, los datos pueden ser mentiras.

Si está escribiendo código de la biblioteca que se utiliza con el código de menos confianza, entonces las cosas se ponen más interesantes:

En el caso de "error de calendario" (y similares), que está a punto deserialising una corriente arbitraria con maliciosa datos y código malicioso. Las Directrices de codificación segura de Java sugieren realizar comprobaciones de seguridad (utilizando el "Modelo de seguridad Java2") en los métodos personalizados readObject, lo que implica que no debe llamar a la deserialización con más confianza que el código y los datos.

Del lado de los objetos deserializables, las cosas son más complicadas. Objetos proporcionados por ObjectInputStream a través de readObject, readUnshared, defaultReadObject, readFields o simplemente la deserialización predeterminada puede tener referencias capturadas por código malicioso o, para las clases no finales, subclase maliciosamente. Un objeto también se puede usar durante la deserialización, cuando se inicializa parcialmente. La deserialización no invoca a un constructor "real" de la clase deserializada (readObject/readObjectNoData es una especie de psuedo-constructor, que no puede establecer final s). Es todo una pesadilla, por lo que probablemente no desee que sus clases sensibles sean serializables.

Ha habido una serie de vulnerabilidades en la implementación de serialización y deserialización. Realmente no necesita preocuparse por esto, a menos que lo esté implementando usted mismo.

+0

+1 una respuesta minuciosa –

2

Hmm ... tu pregunta es un poco general. ¿Echó un vistazo al artículo this? Se trata del algoritmo de serialización de Java, pero de la memoria caché de Google porque la página principal parece estar inactiva por el momento.

+0

Gracias por el artículo, lo revisaré. Sé que mi pregunta es demasiado general, pero quiero tratar el tema de manera genérica. – PeterK

1

Hubiera pensado que la mejor manera de vencer el código que explota los agujeros de seguridad conocidos en Java es actualizar a una versión de Java que corrige el error. Y la siguiente mejor manera (para tratar los errores relacionados con la serialización) es tratar todos los datos seriados de fuentes desconocidas/no verificadas/inseguras como sospechosos.

Tratar de detectar problemas analizando el código java para los errores de seguridad no es fácil, y requiere una comprensión profunda de los mecanismos de Java que se están utilizando y podrían explotarse. Tratar de detectar intentos de explotación (en general) sería aún más difícil, especialmente si está buscando exploits para agujeros de seguridad de día cero. Tenga en cuenta que hay otros vectores potenciales.

(Si hubo formas fáciles de encontrar agujeros de seguridad desconocidos en Java, usted puede apostar que Sun y otros investigadores de seguridad ya habrían ellos utilizado.)

+0

¡Buen punto! Gracias por la respuesta. Por favor, mira la pregunta editada, la cambié un poco, quizás eso te lleve a alguna parte. – PeterK

+0

@PeterK - Honestamente, no sé qué buscar. Pero una vez más, si hubiera cosas conocidas que buscar, esperarías que Sun y otros ya las hayan buscado. Por ejemplo, imagino que el descubrimiento del agujero del calendario provocó una ráfaga de revisiones de código interno. –

+0

Será mejor que haga ambas cosas. Actualice y trate todos los datos serializados como no confiables. – Antimony

1

Si serializar el objeto Java para transferirla a un separado aplicación, ¿por qué no considerar la firma del objeto con una clave compartida entre las aplicaciones? Debería ser suficiente para defenderte del ataque de hombre en el medio.

Volviendo al núcleo del problema de verificación, la verificación es extremadamente difícil para los lenguajes de uso general. Deberías buscar publicaciones científicas sobre este tema. Creo que la técnica más comúnmente aplicada es sandboxing. El segundo enfoque es restringir el idioma y no permitir la ejecución de comandos peligrosos, por ejemplo, Yahoo Caja library utiliza esta técnica.

Cuestiones relacionadas