ProgrammatieBackend ontwikkelaar

Leg uit hoe het ingebouwde mechanisme voor gegevensserialisatie in Python werkt (modules pickle en json). Wat zijn de verschillen, waarvoor worden ze gebruikt, welke gevaren brengt ondoordachte serialisatie met zich mee?

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord

In Python worden de modules pickle en json gebruikt voor serialisatie (het omzetten van objecten naar een reeks bytes of een string voor opslag/verzending):

  • pickle serialiseert elk Python-object (zelfs klassen en functies!), maar het resultaat is een binaire reeks. Werkt alleen binnen het Python-ecosysteem.
  • json serialiseert alleen eenvoudige gegevensstructuren (dict, list, str, int, float), maar het resultaat is een string (universeel formaat), compatibel met andere talen.

Het gebruik van pickle voor het opslaan/verzenden van gegevens tussen ongecontroleerde partijen is gevaarlijk, omdat bij deserialisatie willekeurige kwaadaardige code kan worden uitgevoerd. json heeft dit nadeel niet.

Voorbeeld van gebruik:

import pickle import json # Pickle (binaire serialisatie) data = {'x': 10, 'func': lambda x: x + 1} with open('data.pkl', 'wb') as f: pickle.dump(data, f) # JSON (alleen eenvoudige objecten) data = {'x': 10, 'y': [1, 2, 3]} with open('data.json', 'w') as f: json.dump(data, f)

Vraag met een trucje

Vraag: Kan pickle worden gebruikt voor het serialiseren en opslaan van willekeurige Python-objecten tussen sessies? Waarom wordt dit mechanisme niet aanbevolen voor het opslaan van gebruikersgegevens?

Antwoord:

Nee, het overal gebruiken van pickle is een slechte praktijk. Naast beveiliging (bij het laden van een "vreemd" pickled-object kan de uitvoering in gevaar komen), is er een probleem met versie-inconsistentie van Python of klassen — geserialiseerde objecten kunnen niet worden geladen of zich vreemd gedragen als de structuur van de klassen is gewijzigd.

Voorbeeld:

# Laden van een pickle-bestand, de structuur van de klasse is veranderd import pickle with open('old_version.pkl', 'rb') as f: obj = pickle.load(f) # AttributeError of structuurverschil

Geschiedenis

Voorbeeld 1

In een groot project werd pickle gebruikt voor het opslaan van gebruikersprofielen. Na een upgrade van de Python-versie en wijziging van klassen verloor de structuur van de geserialiseerde objecten zijn compatibiliteit, wat leidde tot systeemfouten en het verlies van de meeste gebruikersgegevens.


Voorbeeld 2

In een webdienst werd pickle gebruikt voor gebruikerssessies. Een kwaadwillende gebruiker laadde een kwaadaardig pickled-object, waardoor code-injectie op de server mogelijk werd.


Voorbeeld 3

De poging om functies te serialiseren via pickle voor netwerkoverdracht mislukte in verschillende omgevingen: pickled-lambdas kunnen niet worden overgedragen tussen machines met verschillende configuraties/versies van Python.