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:
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: È 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
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.
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.
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.