En Python, se utilizan los módulos pickle y json para la serialización (convertir objetos en una secuencia de bytes o una cadena para almacenamiento/transmisión):
Usar Pickle para almacenar/enviar datos entre partes no controladas es peligroso, ya que al deserializar se puede ejecutar código malicioso arbitrario. json no tiene esta desventaja.
Ejemplo de uso:
import pickle import json # Pickle (serialización binaria) data = {'x': 10, 'func': lambda x: x + 1} with open('data.pkl', 'wb') as f: pickle.dump(data, f) # JSON (solo objetos simples) data = {'x': 10, 'y': [1, 2, 3]} with open('data.json', 'w') as f: json.dump(data, f)
Pregunta: ¿Se puede usar pickle para serializar y guardar cualquier objeto de Python entre sesiones? ¿Por qué este mecanismo no se recomienda para guardar datos de usuarios?
Respuesta:
No, usar pickle de forma generalizada es una mala práctica. Además de la seguridad (al cargar un objeto pickled "ajeno", la ejecución puede verse comprometida), hay un problema de incompatibilidad entre versiones de Python o clases: los objetos serializados pueden no cargarse o comportarse de manera incorrecta si la estructura de las clases ha cambiado.
Ejemplo:
# Cargando un archivo pickle, la estructura de la clase ha cambiado import pickle with open('old_version.pkl', 'rb') as f: obj = pickle.load(f) # AttributeError o discrepancia en la estructura
Historia
En un gran proyecto, se utilizó pickle para almacenar perfiles de usuarios. Después de actualizar la versión de Python y cambiar las clases, la estructura de los objetos serializados perdió compatibilidad, lo que llevó a la falla del sistema y la pérdida de la mayoría de los datos de los usuarios.
En un servicio web se utilizó pickle para las sesiones de usuarios. Un malintencionado cargó un objeto pickled malicioso, lo que permitió ejecutar una inyección de código en el servidor.
El intento de serializar funciones a través de pickle para su transmisión en red fracasó en varios entornos: una lambda pickled no se puede transferir entre máquinas con diferentes configuraciones/versiones de Python.