ProgrammationDéveloppeur Backend

Expliquez comment fonctionne le mécanisme de sérialisation de données intégré en Python (modules pickle et json). Quelles sont leurs différences, à quoi servent-ils, quels dangers peut comporter une sérialisation imprudente ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse

En Python, pour la sérialisation (conversion d'objets en séquence d'octets ou chaîne pour le stockage/transmission), on utilise les modules pickle et json:

  • pickle sérialise n'importe quel objet Python (même des classes et des fonctions !), mais le résultat est une séquence binaire. Fonctionne uniquement au sein de l'écosystème Python.
  • json sérialise uniquement des structures de données simples (dict, list, str, int, float), mais le résultat est une chaîne (format universel), compatible avec d'autres langages.

Utiliser Pickle pour stocker/transmettre des données entre des parties non contrôlées est dangereux, car lors de la désérialisation, on peut exécuter un code malveillant arbitraire. json ne présente pas cet inconvénient.

Exemple de fonctionnement :

import pickle import json # Pickle (sérialisation binaire) data = {'x': 10, 'func': lambda x: x + 1} with open('data.pkl', 'wb') as f: pickle.dump(data, f) # JSON (seulement des objets simples) data = {'x': 10, 'y': [1, 2, 3]} with open('data.json', 'w') as f: json.dump(data, f)

Question piège

Question : Peut-on utiliser pickle pour sérialiser et sauvegarder n'importe quel objet Python entre les sessions ? Pourquoi ce mécanisme n'est-il pas recommandé pour la sauvegarde des données utilisateurs ?

Réponse :

Non, utiliser pickle partout est une mauvaise pratique. En plus de la sécurité (lors du chargement d'un objet pickle "étranger", l'exécution peut être compromise), il y a le problème de compatibilité des versions de Python ou des classes — les objets sérialisés peuvent ne pas se charger ou se comporter de manière incorrecte si la structure des classes a changé.

Exemple :

# Chargement d'un fichier pickle, la structure de la classe a changé import pickle with open('old_version.pkl', 'rb') as f: obj = pickle.load(f) # AttributeError ou divergence de structure

Histoire

Exemple 1

Dans un grand projet, pour le stockage des profils utilisateurs, on a utilisé pickle. Après la mise à jour de la version de Python et les changements de classes, la structure des objets sérialisés a perdu sa compatibilité, ce qui a entraîné l'échec du système et la perte de la plupart des données utilisateurs.


Exemple 2

Dans un service web, pickle a été utilisé pour les sessions des utilisateurs. Un malveillant a téléchargé un objet pickle malveillant, permettant l'injection de code sur le serveur.


Exemple 3

Une tentative de sérialiser des fonctions via pickle pour les transmettre sur un réseau a échoué dans certains environnements : une lambda pickled ne peut pas être transférée entre des machines avec des configurations/versions de Python différentes.