Aunque diferentes lenguajes de programación usan diferentes palabras clave y funciones para la serialización, el principio subyaciente permanece constante. La serialización es el proceso de convertir el estado de un objeto a un formato que pueda ser fácilmente almacenado o transmitido y luego reconstruído.
Al contrario que otras vulnerabilidades comunes que explotan el procesamiento inmediato de los inputs del usuario, los problemas de deserialización insegura involucran una interacción más profunda con la lógica principal de la aplicación.
Exploremos cómo se maneja explícitamente la serialización en diferentes lenguaje, junto a su funcionalidad, sintaxis y cualidades particulares.
Serialización PHP
En PHP, la serialización se consigue usando la función serialize(). Esta convierte un objeto o array de PHP a un stream de bytes representando la información y estructura del objeto. El byte stream resultante puede incluir varios tipos de datos, como strings, arrays y objetos. Para ilustrarlo, consideremos una aplicación de notas donde los usuarios pueden guardar y recuperar sus notas. Crearemos una clase PHP llamada Notes para representar cada nota y manejar la serialización y deserialización.
class Notes { public $Notescontent; public function __construct($content) { $this->Notescontent = $content; } }
En nuestra aplicación Notes, cuando un usuario guarda una nota, la serializamos usando serialize(). Esto convierte el objeto en una representación de string que puede ser guardada en un archivo o base de datos. Echemos un vistazo al siguiente trozo de código que serializa los objetos de la clase Notes.
$note = new Notes("Welcome to THM"); $serialized_note = serialize($note);
Entramos en http://IP/phptest/ e introducimos cualquier string para serializazr o deserializar. Por ejemplo, si introduces la string Welcome to THM, generará el output: O:5:"Notes":1:{s:7:"content";s:14:"Welcome to THM";}.

Vamos a decodear el output:
O:5:"Notes":1:: Esta parte indica que la información serializada erpresenta un objeto de la clase Notes, que tiene una propiedad.s:7:"content": Esto representa la propiedad llamada "content" con una longitud de 7 caracteres. En información serializada, las strings se representan consseguido de la longitud de la string y la string entre comillas. Los enteros se representan con unaiseguido del valor numérico sin comillas.s:14:"Welcome to THM": Este es el valor de la propiedad content con una longitud de 14 caracteres.
Métodos Mágicos
PHP ofrece varios métodos mágicos que juegan varios roles en el proceso de serialización. Algunos de estos métodos importantes se mencionan debajo:
___sleep(): Este método se llama en un objeto antes de la serialización. Limpia recursos, como conexiones a bases de datos y se espera que devuelva un array de nombres de propiedades que deberían ser serializadas.__wakeup(): Este método es llamado al deserializar. Puede restablecer cualquier conexión que el objeto pueda necesitar para operar correctamente.__serialize(): En PHP 7.4 este método permite personalizar la información de serializazción devolviendo un array representando la forma serializada del objeto.__unserialize(): Es la contraparte de__serialize()y permite personalizar la restauración de un objeto desde su información serializada.
Python
Python usa un módulo llamado Pickle para serializar y deserializar objetos. Este módulo convierte un objeto Python en un byte stram (y viceversa), permitiendo que sea guardado en un archivo o transmitido a través de la red. Maneja casi todos los tipos de objetos Python sin intervención manual. Seguiremos el mismo ejemplo de Notes de PHP con Python con app.py:
import pickle import base64 ... serialized_data = request.form['serialized_data'] notes_obj = pickle.loads(base64.b64decode(serialized_data)) message = "Notes successfully unpickled." ... elif request.method == 'POST': if 'pickle' in request.form: content = request.form['note_content'] notes_obj.add_note(content) pickled_content = pickle.dumps(notes_obj) serialized_data = base64.b64encode(pickled_content).decode('utf-8') binary_data = ' '.join(f'{x:02x}' for x in pickled_content) message = "Notes pickled successfully."
Pickling Process
- Creando la clase Notes: Esta clase maneja una lista de notas. Ofrece métodos para añadir una nota y recuperar todas, haciendo fácil manejar el estado de la aplicación.
- Serialización (Pickling): Cuando un usuario sube una nota, la instancia de clase Notes se serializa (todas las notas) usando
pickle.dumps(). Esta función transforma el objeto Python en formato binario que puede reconvertirse más adelante.
Mostrando la Información Serializada (Base64 Encoding)
- Por qué usar base64: La información serializazda es binaria y no segura de mostrar en todos los entornos. La información binaria puede contener bytes que pueden interferir con protocolos de comunicación (como HTTP). Base64 es un esquema de encodeado que convierte información binaria en texto plano. Sólo usa caracteres legibles haciéndolo seguro de transmitir por canales que no soportan información binaria.
- Proceso de Encoding: Después de serializar el objeto
Notes, la información binaria se encodea en base64 usandobase64.b643ncode(). Esta string es segura de mostrar en HTML y fácil de guardar o transmitir.
Deserialización
- Base64 decoding: Al hacer unpickling, la string base64 se decodea de vuelta a un formato binario usando
base64.b64deconde(). - Unpickling: Los datos binarios se pasan a
pickle.loads()lo que reconstruye el objeto original de Python del binary stream.
De nuevo, si visitamos el link http://IP:5000 e introducimos la string Welcome to THM:

- Pickling: Cuando la string se picklea se convierte en formato binario que no es legible por humanos.
- Base64 encoding: El binario se encodea en Base64.
En Java la serialización de objetos la lleva a cabo Serializable. Para .NET, inicialmente fue BinaryFormatter y ahora System.Text.Json para serializaciones JSON o System.Xml.Serialization para tareas XML. Ruby ofrece simplicidad con su módulo Marshal.
