Los peligros de Serializable

Serializable tiene una serie de problemas que hacen que, aunque nos intenten sugerir lo contrario, no deberíamos utilizarlo como método de almacenamiento primario a largo plazo de nuestros programas. El principal problema de Serializable es que no está pensado para almacenar a largo plazo y que cualquier atisbo de corrupción en la estructura de datos provoca que los datos queden irrecuperables.

La serialización en Java mediante la interfaz Serializable presenta dos problemas fundamentales que debemos tener muy presentes antes de decidir utilizarla en nuestros proyectos. El primero, y más conocido, es que Serializable no es adecuado para almacenar datos a largo plazo. Aunque todavía encontramos cursos, libros y tutoriales que lo enseñan como una opción válida para guardar datos en archivos, la realidad es que el formato que genera es demasiado rígido y propenso a romperse con cualquier cambio en las clases que se serializan.

Cuando escribimos un objeto con ObjectOutputStream, no suele haber problemas, pero al intentar leer ese mismo objeto con ObjectInputStream en el futuro, cualquier modificación en la estructura de la clase —como añadir, eliminar o cambiar el tipo de un campo— puede hacer que la lectura falle o que el archivo quede corrupto. Esto se debe a que el formato de serialización no está pensado para ser un estándar estable a lo largo del tiempo, sino para transmitir datos de forma rápida y temporal.

El caso de uso para Serializable es, en realidad, la transmisión de objetos a través de la red en un corto periodo. Por ejemplo, si tenemos un socket TCP y enviamos un objeto de un programa a otro que está ejecutando la misma versión, la serialización funciona bien. Pero no está diseñada para guardar datos en disco y luego leerlos meses o años después. Cualquier cambio en la clase o incluso en el archivo puede hacer que la deserialización falle.

El segundo problema, que ha cobrado relevancia en los últimos años, es el riesgo de seguridad que implica usar Serializable. Cuando permitimos que una aplicación reciba una secuencia de bytes y la convierta en una instancia de una clase, estamos abriendo la puerta a posibles ataques. Un atacante con conocimientos puede enviar datos maliciosos que, al ser deserializados, provoquen comportamientos inesperados o peligrosos en la aplicación, comprometiendo la integridad de los datos o la seguridad del sistema.

Un aspecto importante es que, aunque en Java definamos campos como private para protegerlos, la serialización con ObjectOutputStream ignora esta protección y guarda el estado interno completo del objeto, incluyendo esos campos privados. Esto significa que alguien con acceso a los datos serializados puede intentar decodificarlos, entender la estructura interna de nuestras clases y buscar vulnerabilidades para explotarlas.

Por todo esto, aunque Serializable sigue siendo útil para casos muy concretos y controlados, como la comunicación rápida entre procesos o máquinas que ejecutan el mismo programa, no es recomendable usarlo para almacenamiento a largo plazo ni en contextos donde la seguridad sea crítica.

En lugar de Serializable, es preferible optar por serializadores más robustos y flexibles que generen formatos más amigables y estables, como JSON o XML. Herramientas como Jackson permiten convertir objetos a estos formatos, que son legibles, fáciles de versionar y menos propensos a romperse con cambios en las clases. Además, estos formatos facilitan la inspección y el control de los datos, reduciendo riesgos de seguridad.

En definitiva, debemos ser conscientes de las limitaciones y peligros de Serializable y elegir alternativas más adecuadas para preservar nuestros datos y proteger nuestras aplicaciones.

Lista de reproducción
  1. 1
    Introducción al taller
    2 minutos
  2. 2
    Qué es la entrada y salida
    4 minutos
  3. 3
    Streams de entrada y salida en Java
    7 minutos
  4. 4
    FileOutputStream
    9 minutos
  5. 5
    FileInputStream
    13 minutos
  6. 6
    try-with-resources
    2 minutos
  7. 7
    ObjectOutputStream y OutputInputStream
    6 minutos
  8. 8
    Object streams con Strings y Objects
    6 minutos
  9. 9
    Serializando clases
    7 minutos
  10. 10
    Los peligros de Serializable
    4 minutos
  11. 11
    BufferedOutputStream
    6 minutos
  12. 12
    Envolviendo varios OutputStreams
    2 minutos
  13. 13
    BufferedInputStream y rebobinado de streams
    9 minutos
  14. 14
    Readers y Writers en Java
    3 minutos
  15. 15
    Writer y FileWriter
    4 minutos
  16. 16
    Reader, FileReader y BufferedReader
    4 minutos
  17. 17
    InputStreamReader y OutputStreamWriter
    6 minutos
  18. 18
    PrintStream y PrintWriter
    5 minutos