FlawOpen
● CWE-502 / Unsafe Deserialization

Désérialisation non sécurisée : risques et défense

Risques de pickle, Java Serialization et PHP unserialize avec des données non fiables, et moyens de les remplacer ou limiter.

💡 Explication simple (ELI5)

La sérialisation ressemble à l’envoi d’instructions de montage d’une maquette. La désérialisation suit ces instructions pour reconstruire les données. Certains formats peuvent aussi nommer des classes ou appeler des hooks pendant la reconstruction ; accepter des instructions non fiables peut déclencher un comportement inattendu. L’impact dépend du format, du runtime, des classes accessibles et du contexte applicatif.

Core Concepts & Key Terms

Sérialisation / désérialisation
Conversion de données ou d’objets en représentation stockée ou transmise, puis analysée ou reconstruite par le programme.
Hooks de désérialisation
Callbacks comme Python __reduce__, Java readObject ou PHP __wakeup / __unserialize, susceptibles de s’exécuter pendant la reconstruction.
Gadget chain
Enchaînement de comportements de bibliothèques déjà présentes pouvant produire un effet inattendu. Sa disponibilité dépend de l’application et de ses versions.
Filtre de désérialisation
Politique limitant les classes ou métriques du graphe lors de la lecture d’objets. Elle réduit le risque sans rendre les flux objets natifs non fiables préférables.

How Unsafe Deserialization Can Become an Exploit Chain

Step 1

Des octets non fiables atteignent le décodeur

Un cookie, corps d’API, message de file ou enregistrement contient des données influençables par un attaquant.

Step 2

L’application appelle un format objet natif

Le code transmet ces octets à un décodeur comme Python pickle, Java ObjectInputStream ou PHP unserialize().

Step 3

La reconstruction déclenche le comportement du format

Selon le format et les classes accessibles, constructeurs, hooks, autoloading ou méthodes de bibliothèques peuvent s’exécuter avant la validation applicative.

Step 4

L’impact dépend du comportement accessible

Un gadget ou hook utilisable peut produire des effets non autorisés ; d’autres données échouent ou consomment seulement des ressources. L’exécution de code n’est pas automatique.

Python / Flask : chargement objet vulnérable et validation de JSON primitif

CODE VULNÉRABLE
# 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}
VALIDATION PLUS SÛRE
# 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}

Liste de vérification de sécurisation

JSON nécessite aussi des limites de taille et une validation de structure. Pour les anciens formats objets, ne vous fiez pas à une simple liste de classes : authentifiez les octets exacts avant désérialisation et protégez les clés. Un MAC ne chiffre pas les données et n’empêche pas le rejeu.

← Parcourir tout le répertoire sécurité Voir les guides de vulnérabilités →