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.
+1 una respuesta minuciosa –