ProgrammazioneSviluppatore Backend

Spiega come funziona il meccanismo di serializzazione dei dati incorporato in Python (moduli pickle e json). In cosa differiscono, a cosa servono, quali pericoli comporta una serializzazione imprudente?

Supera i colloqui con l'assistente IA Hintsage

Risposta

In Python, per la serializzazione (conversione di oggetti in una sequenza di byte o stringa per memorizzazione/trasmissione) si utilizzano i moduli pickle e json:

  • pickle serializza qualsiasi oggetto Python (anche classi e funzioni!), ma il risultato è una sequenza binaria. Funziona solo all'interno dell'ecosistema Python.
  • json serializza solo strutture dati semplici (dict, list, str, int, float), ma il risultato è una stringa (formato universale) compatibile con altri linguaggi.

Utilizzare pickle per memorizzare/inviare dati tra parti non controllate è pericoloso, poiché durante la deserializzazione potrebbe essere eseguito codice dannoso arbitrario. json non presenta questo difetto.

Esempio di utilizzo:

import pickle import json # Pickle (serializzazione binaria) data = {'x': 10, 'func': lambda x: x + 1} with open('data.pkl', 'wb') as f: pickle.dump(data, f) # JSON (solo oggetti semplici) data = {'x': 10, 'y': [1, 2, 3]} with open('data.json', 'w') as f: json.dump(data, f)

Domanda trabocchetto

Domanda: È possibile utilizzare pickle per serializzare e memorizzare qualsiasi oggetto Python tra sessioni? Perché questo meccanismo non è raccomandato per memorizzare dati degli utenti?

Risposta:

No, usare pickle ovunque è una cattiva pratica. Oltre alla sicurezza (il caricamento di un oggetto pickled "estraneo" potrebbe compromettere l'esecuzione), c'è il problema della compatibilità delle versioni di Python o delle classi: gli oggetti serializzati potrebbero non caricarsi o comportarsi in modo errato se la struttura delle classi è cambiata.

Esempio:

# Caricamento di un file pickle, la struttura della classe è cambiata import pickle with open('old_version.pkl', 'rb') as f: obj = pickle.load(f) # AttributeError o incongruenza nella struttura

Storia

Esempio 1

In un grande progetto, per memorizzare i profili degli utenti veniva utilizzato pickle. Dopo l'aggiornamento della versione di Python e la modifica delle classi, la struttura degli oggetti serializzati ha perso compatibilità, causando il fallimento del sistema e la perdita della maggior parte dei dati degli utenti.


Esempio 2

In un servizio web, pickle veniva utilizzato per le sessioni utente. Un malintenzionato ha caricato un oggetto pickled dannoso, consentendo l'iniezione di codice sul server.


Esempio 3

Il tentativo di serializzare funzioni tramite pickle per la loro trasmissione sulla rete è fallito in diversi ambienti: le lambda pickled non possono essere trasferite tra macchine con configurazioni/versioni di Python diverse.