FlawOpen
● CWE-502 / Unsafe Deserialization

Deserialización insegura: riesgos y defensa

Riesgos de pickle, Java Serialization y PHP unserialize con datos no confiables, y cómo sustituirlos o limitarlos.

💡 Explicación sencilla (ELI5)

La serialización es como enviar por correo instrucciones para montar un modelo. La deserialización sigue esas instrucciones para reconstruir los datos. Algunos formatos también pueden nombrar clases o ejecutar hooks durante la reconstrucción; aceptar instrucciones no confiables puede activar comportamientos no previstos. El impacto depende del formato, runtime, clases disponibles y contexto de la aplicación.

Core Concepts & Key Terms

Serialización / deserialización
Convertir datos u objetos en una representación para almacenarlos o transmitirlos y luego analizarlos o reconstruirlos en el programa.
Hooks de deserialización
Callbacks como Python __reduce__, Java readObject o PHP __wakeup / __unserialize que pueden ejecutarse al reconstruir objetos.
Gadget chain
Secuencia de comportamientos de bibliotecas presentes que puede encadenarse para producir un efecto no previsto. Depende de la aplicación y de sus versiones.
Filtro de deserialización
Política que limita clases o métricas del grafo al leer objetos. Reduce el riesgo, pero no convierte los flujos nativos no confiables en un buen formato.

How Unsafe Deserialization Can Become an Exploit Chain

Step 1

Bytes no confiables llegan al decodificador

Una cookie, cuerpo de API, mensaje de cola o registro contiene datos que un atacante puede influir.

Step 2

La aplicación invoca un formato de objeto nativo

El código entrega esos bytes a un decodificador como Python pickle, Java ObjectInputStream o PHP unserialize().

Step 3

La reconstrucción activa comportamiento del formato

Según el formato y las clases alcanzables, constructores, hooks, autoloading o métodos de biblioteca pueden ejecutarse antes de la validación de la aplicación.

Step 4

El impacto depende del comportamiento alcanzable

Un gadget o hook disponible puede producir efectos no autorizados; otros datos solo fallan o consumen recursos. La ejecución de código no es automática en toda aplicación.

Python / Flask: carga insegura de objetos frente a validación de JSON primitivo

PATRÓN VULNERABLE
# VULNERABLE: pickle can execute behavior during unpickling.
from flask import Flask, request
import pickle

app = Flask(__name__)

@app.post("/api/session")
def load_session():
    # Never deserialize attacker-controlled bytes with pickle.
    session = pickle.loads(request.get_data())
    return {"user_id": session.user_id}
VALIDACIÓN MÁS SEGURA
# SAFER: parse JSON primitives, then validate expected shape.
from flask import Flask, abort, request

app = Flask(__name__)
app.config["MAX_CONTENT_LENGTH"] = 16 * 1024

@app.post("/api/session")
def load_session():
    payload = request.get_json()
    if not isinstance(payload, dict):
        abort(400, "Expected a JSON object")

    user_id = payload.get("user_id")
    if type(user_id) is not int or user_id <= 0:
        abort(400, "Invalid user_id")

    # Resolve authorization and session state server-side.
    return {"user_id": user_id}

Lista de comprobación de endurecimiento

JSON también requiere límites de tamaño y validación de estructura. En formatos de objetos heredados, no confíes solo en listas de clases: autentica los bytes exactos antes de deserializar y protege las claves. Un MAC no cifra los datos ni evita la repetición.

← Explorar el directorio completo de seguridad Ver guías de vulnerabilidades →