Introducción a la deserialización insegura: una amenaza oculta en aplicaciones
En el mundo del desarrollo de software, la comunicación y almacenamiento de datos entre diferentes sistemas es esencial. Esta transferencia de datos frecuentemente se realiza mediante serialización y deserialización, procesos que transforman objetos en flujos de bytes y viceversa. Sin embargo, esta práctica puede convertirse en uno de los vectores más críticos de ataque si no se implementa de manera segura. La deserialización insegura es una vulnerabilidad que pasa desapercibida a menudo, pero que permite a un atacante ejecutar código arbitrario en el servidor, comprometiendo toda la arquitectura de la aplicación.
Este artículo técnico y detallado tiene como objetivo explicar paso a paso el fenómeno de la deserialización insegura, especialmente en aplicaciones web basadas en Python, profundizando en conceptos clave, ejemplos prácticos, riesgos asociados, y cómo prevenirlos. Si trabajás en desarrollo o seguridad informática, esta guía te permitirá entender a fondo esta vulnerabilidad y cómo afrontarla eficazmente.
¿Qué es la serialización y la deserialización?
Antes de entender el problema, es fundamental dominar los conceptos de serialización y deserialización. Imaginemos que jugamos un videojuego complejo como Cyberpunk 2077: los datos de nuestro personaje están almacenados en memoria RAM, pero al cerrar el juego, esa información se perdería. Por eso, necesitamos serializar esos datos, es decir, convertir el objeto del personaje lleno de propiedades en un flujo de bytes que pueda guardarse en disco o transmitirse a través de la red.
El proceso inverso es la deserialización: cuando volvemos a abrir el juego, esos bytes guardados se convierten nuevamente en un objeto en memoria con todas sus propiedades intactas. Este concepto es aplicable en múltiples contextos, desde el almacenamiento de modelos de aprendizaje automático hasta la gestión de sesiones en aplicaciones web.
Usos comunes de la serialización en aplicaciones web
- Guardar estados complejos de sesión en cookies para facilitar la gestión sin consultas constantes a la base de datos.
- Comunicación entre servicios mediante APIs y sistemas distribuidos.
- Persistencia de objetos en archivos para recuperación posterior.
El peligro de la deserialización insegura
El riesgo emerge cuando se permite que un usuario malintencionado envíe datos serializados al servidor para deserializarlos sin validar debidamente su origen o contenido. En este escenario, el atacante puede manipular el flujo de bytes para ejecutar código malicioso durante el proceso de deserialización.
Se denomina deserialización insegura a esta vulnerabilidad que ocurre cuando la aplicación procesa datos serializados sin seguridad suficiente, lo que puede derivar en ejecución remota de código, escalación de privilegios, corrupción de datos y otros tipos de ataques críticos.
Principales vectores de ataque
- Cookies u otros datos enviados desde el cliente que contienen información serializada.
- APIs que aceptan objetos serializados como entrada para operar en el backend.
- Almacenamiento indirecto de sesiones o estados que luego se deserializan sin filtros.
Ejemplo práctico en Python: la librería pickle
Python ofrece la librería pickle
para trabajar con serialización y deserialización de objetos. Su ventaja es la simplicidad para convertir estructuras complejas de objetos en flujos de bytes y luego revertir el proceso. Sin embargo, esta flexibilidad implica riesgos al aceptar entradas externas.
Creando un objeto y serializándolo
Supongamos que tenemos una clase User
con dos propiedades: nombre y edad, y un método que ofrece un resumen del objeto.
class User: def __init__(self, name, age): self.name = name self.age = age def summary(self): return f"User {self.name} is {self.age} years old."
Luego, podemos crear una instancia de esta clase, por ejemplo, un usuario llamado Keanu Reeves de 49 años, serializarla y observar el flujo de bytes:

import pickle keanu = User("Keanu Reeves", 49) serialized_obj = pickle.dumps(keanu) print(serialized_obj)
Volviendo al objeto original: deserialización
Con pickle.loads()
, convertimos el flujo binario en el objeto original y podemos llamar a su método como si nada hubiese pasado:
deserialized_obj = pickle.loads(serialized_obj) print(deserialized_obj.summary()) # Output: User Keanu Reeves is 49 years old.
¿Por qué la deserialización puede ser insegura?
Si observamos el proceso, el servidor convierte los bytes recibidos en objetos ejecutables. Cuando dichos bytes provienen de usuarios no confiables y contienen serializaciones maliciosas, el servidor puede terminar ejecutando comandos arbitrarios. Esto se debe a que Python, a través de pickle
, permite definir en una clase un método especial llamado __reduce__
que controla cómo se serializa el objeto, incluyendo la posibilidad de ejecutar funciones durante el proceso de deserialización.
Esto se traduce en vulnerabilidades críticas si no se valida la fuente o el contenido de los datos serializados antes de procesarlos.
Cómo crear un payload para explotación usando __reduce__
Para ilustrar esto, definiremos una clase con un método __reduce__
que ejecuta comandos de sistema durante la deserialización. El método debe devolver una tupla donde el primer elemento es una función ejecutable y el segundo son los argumentos de esa función.
class Malicious: def __reduce__(self): import os return (os.system, ('id',))
Al serializar una instancia de Malicious
y deserializarla, Python ejecutará el comando id
, mostrando información del usuario del sistema:
payload = pickle.dumps(Malicious()) pickle.loads(payload)
El resultado puede ser la ejecución arbitraria de cualquier comando, en función de lo que el atacante haya puesto en el payload.
Aplicación práctica del ataque: sesión serializada en cookies
En las aplicaciones web, las cookies pueden almacenar información serializada para mantener el estado o sesiones sin necesidad de realizar consultas constantes a bases de datos. Si estas cookies son manipulables por el usuario y el servidor las deserializa sin validación ni protección, se abre un vector para una ejecución remota de código.
Supongamos una aplicación web escrita en Python que serializa objetos de sesión para almacenarlos en cookies codificadas en base64. Un atacante puede:
- Construir un objeto malicioso con
__reduce__
definido para ejecutar código arbitrario. - Serializar ese objeto usando
pickle
. - Codificar el flujo en base64 para que sea aceptado por la cookie.
- Enviar la cookie al servidor.
- Al refrescar la página, el servidor deserializa el objeto malicioso, desencadenando la ejecución de código.
Ejemplo de payload para reverse shell
Más allá de comandos simples, un atacante puede construir payloads para establecer conexiones reversas, permitiendo controlar el servidor remotamente. Esto incrementa enormemente el alcance del ataque y las consecuencias.

Comparativa: Seguridad en deserialización según lenguaje
Lenguaje | Complejidad de la serialización | Facilidad para explotación | Principales riesgos | Medidas comunes |
---|---|---|---|---|
Python | Alta eficiencia y facilidad (pickle) | Alta facilidad con pickle y cPickle | Ejecución remota, toma de control | Validar fuentes, evitar cargar objetos directamente |
PHP | Objetos complejos y serialización específica | Mediana; requiere manipulación avanzada | Elevación de privilegios, ejecución remota | Deshabilitar funciones peligrosas, filtro rigoroso |
Java | Múltiples clases y políticas estrictas | Baja facilidad; requiere chaining (gadgets) | Ejecución remota, ataques mediante librerías externas | Sandboxing, listas blancas de clases, librerías seguras |
Ruby | Serialización con Marshal y YAML | Mediana a alta; depende de la configuración | Code injection, ejecución remota | Validación estricta, evitar carga directa |
Buenas prácticas para protegerse de ataques de deserialización insegura
Para blindar aplicaciones frente a esta amenaza, se recomiendan:
- No deserializar datos provenientes de fuentes no confiables. Siempre validar o evitar aceptar input serializado externo.
- Utilizar mecanismos alternativos y seguros, como formatos JSON seguros para la transmisión y almacenamiento.
- Implementar listas blancas de clases y objetos permitidos durante la deserialización para minimizar riesgos.
- Aislamiento y sandboxing de los procesos que deserializan datos, limitando el impacto potencial.
- Auditorías periódicas de seguridad y actualización de librerías para corregir vulnerabilidades conocidas.
- Codificación y firmas digitales para detectar manipulación de datos.
Ejemplo de prevención en Python
En Python, evitar usar pickle
en inputs no confiables. En su lugar, utilizar módulos como json
para estructuras de datos simples o bibliotecas que manejan serialización segura.
Conceptos clave explicados: serialización, deserialización, y vulnerabilidades asociadas
Serialización
Proceso de convertir un objeto en una secuencia de bytes para almacenamiento o transmisión. Fundamental para sistemas distribuidos, persistencia y sesiones.
- Clave para la interoperabilidad entre sistemas heterogéneos.
- Diferentes formatos: binarios (pickle, protobuf) y texto (JSON, XML).
Deserialización
Conversión inversa: bytes a objetos en memoria. Aquí radica el riesgo: si no se controla el contenido, puede ejecutarse código malicioso.
Deserialización insegura
Es la aceptación y procesamiento sin validación de datos serializados no confiables, origen de ataques críticos como ejecución remota, manipulación de lógica y escalación de privilegios.
Payload
Objeto o datos manipulados que, al ser procesados, ejecutan acciones maliciosas. En deserialización insegura, un payload puede ser un objeto cuya deserialización desencadena comandos arbitrarios.
Método __reduce__
Especialmente en Python, permite definir cómo serializar un objeto complejo, posibilitando ejecutar funciones en la deserialización. Por ello, su uso indebido es la raíz del exploit de deserialización insegura.
Ejemplo paso a paso: cómo se ejecuta un ataque real
- El atacante construye un objeto malicioso con método
__reduce__
que llama a comandos de sistema. - Serialize el objeto utilizando
pickle.dumps()
. - Codifique el resultado en base64 para evadir controles y enviarlo en una cookie HTTP.
- Coloca la cookie maliciosa en el navegador y accede o refresca la aplicación víctima.
- El servidor recibe la cookie, decodifica base64 y deserializa con
pickle.loads()
. - Durante la deserialización, el método
__reduce__
ejecuta el código arbitrario. - El atacante obtiene ejecución remota o controla el servidor.
Consideraciones específicas sobre lenguajes y entornos
En Python, la vulnerabilidad es relativamente fácil de explotar gracias a la flexibilidad del módulo pickle. Otros lenguajes como Java, PHP o Ruby requieren un esfuerzo más sofisticado, debido a:
- Restricciones en serialización y mecanismos propios.
- Complejidad en la cadena de gadgets o funciones necesarias.
- Disponibilidad de mitigaciones y políticas de seguridad.
Sin embargo, la gravedad en todos los casos es alta debido a las implicaciones de control remoto.

Para complementar esta explicación, te invitamos a ver este video donde se muestra una demostración práctica de un ataque de deserialización insegura en una aplicación web desarrollada en Python. Es una gran oportunidad para visualizar el proceso completo en un entorno real.
Preguntas frecuentes (FAQ)
¿Qué es la deserialización insegura?
La deserialización insegura ocurre cuando se utilizan datos no confiables para abusar de la lógica de una aplicación, lo que da lugar a diversos tipos de ataques, como ejecución remota de código, ataques de repetición, ataques de inyección y escalada de privilegios. Esta vulnerabilidad tiene como origen el procesamiento sin precaución de objetos serializados provenientes de usuarios o sistemas externos no validados.
¿Qué es insecure deserialization?
El término en inglés insecure deserialization se refiere a lo mismo que deserialización insegura: el problema que surge cuando aplicaciones aceptan y procesan flujos de datos serializados de forma insegura, permitiendo la ejecución de código arbitrario y comprometiendo la lógica y seguridad del sistema.
¿Qué es la deserialización de datos?
La deserialización de datos es el proceso de convertir un flujo de bytes, almacenado o transmitido, de nuevo en un objeto en memoria. Es fundamental para muchas aplicaciones, pero si no se realiza con las debidas precauciones, puede ser aprovechada para ejecutar código malicioso o manipular la ejecución interna de una aplicación, definiéndose así la vulnerabilidad conocida como deserialización insegura.
¿Cómo puedo detectar si mi aplicación es vulnerable a deserialización insegura?
Revisá si tu aplicación acepta objetos serializados de fuentes externas sin validación. Pueden ser cookies, datos en peticiones HTTP, APIs o archivos. Herramientas de análisis estático y dinámico de seguridad pueden ayudarte a detectar puntos vulnerables. También verificá si se utiliza pickle
, Marshal
o serializadores similares con datos no confiables.
¿Cuáles son los riesgos principales de este tipo de ataques?
Incluyen ejecución remota de código en el servidor, acceso o manipulación de datos sensibles, escalación de privilegios dentro del sistema, y en entorno web, la posibilidad de comprometer toda la infraestructura o realizar movimientos laterales dentro de la red.
¿Qué alternativas seguras a pickle existen para Python?
Para datos simples, utilizar serialización en formatos tipo JSON
o XML
con validación estricta. Bibliotecas especializadas que implementan serialización segura y controlada pueden ser usadas para objetos más complejos.
¿Se puede evitar la deserialización insegura en sistemas existentes?
Sí, a través de:
- Implementación de listas blancas de clases autorizadas para deserialización.
- Uso de firmas digitales para validar la integridad y autenticidad de los datos antes de deserializar.
- Reemplazo paulatino de serialización insegura por métodos más seguros en el código.
¿Existen herramientas o librerías para proteger aplicaciones contra este tipo de ataques?
Dependiendo del lenguaje, existen soluciones y librerías que limitan el riesgo. En Python, proyectos como restrictedpickle
o el uso combinado de json
para datos simples son recomendados. También, escaners de vulnerabilidades pueden identificar puntos débiles relacionados.

¿Qué pasos debo seguir si detecto una vulnerabilidad de deserialización insegura en mi app?
Primero, deshabilitar la funcionalidad vulnerable si es posible. Segundo, reemplazar la deserialización no segura por métodos seguros o validaciones estrictas. Tercero, realizar pruebas exhaustivas para comprobar que no hay más vectores de ataque. Cuarto, actualizar dependencias y documentar las correcciones. Finalmente, formar al equipo en mejores prácticas de seguridad.
Conclusión
La deserialización insegura es una vulnerabilidad crítica que puede comprometer totalmente la seguridad de una aplicación y su infraestructura. Comprender cómo funciona la serialización y deserialización, identificar vectores de ataque y aplicar controles estrictos es fundamental para desarrolladores y especialistas en seguridad.
¿Querés mantenerte actualizado con las últimas tendencias en automatización, inteligencia artificial y transformación digital? Visitá nuestro blog de Código6 y descubrí guías, casos de éxito y noticias relevantes para potenciar tu empresa. Ingresá al blog y explorá los recursos más recientes.
Leave A Comment