programowanieProgramista Backend

Wyjaśnij, jak działa wbudowany mechanizm serializacji danych w Pythonie (moduły pickle i json). Czym się różnią, do czego są używane, jakie zagrożenia niesie nierozważna serializacja?

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź

W Pythonie do serializacji (przekształcania obiektów w ciąg bajtów lub łańcuch do przechowywania/przesyłania) używane są moduły pickle i json:

  • pickle serializuje dowolne obiekty Pythona (nawet klasy i funkcje!), ale rezultatem jest sekwencja binarna. Działa tylko w ekosystemie Pythona.
  • json serializuje tylko proste struktury danych (dict, list, str, int, float), za to rezultatem będzie łańcuch (uniwersalny format), kompatybilny z innymi językami.

Używanie Pickle do przechowywania/przesyłania danych między niekontrolowanymi stronami jest niebezpieczne, ponieważ podczas deserializacji można wykonać dowolny złośliwy kod. json nie ma tej wady.

Przykład działania:

import pickle import json # Pickle (serializacja binarna) data = {'x': 10, 'func': lambda x: x + 1} with open('data.pkl', 'wb') as f: pickle.dump(data, f) # JSON (tylko proste obiekty) data = {'x': 10, 'y': [1, 2, 3]} with open('data.json', 'w') as f: json.dump(data, f)

Pytanie z pułapką

Pytanie: Czy można używać pickle do serializacji i przechowywania dowolnych obiektów Pythona między sesjami? Dlaczego ten mechanizm nie jest zalecany do przechowywania danych użytkowników?

Odpowiedź:

Nie, używanie pickle wszędzie to zła praktyka. Oprócz bezpieczeństwa (przy załadowaniu "cudzych" obiektów pickle'owanych wykonanie może być skompromitowane), istnieje problem zgodności wersji Pythona lub klas — zserializowane obiekty mogą nie załadować się lub zachować się niepoprawnie, jeśli struktura klas się zmieniła.

Przykład:

# Ładowanie pliku pickle, struktura klasy się zmieniła import pickle with open('old_version.pkl', 'rb') as f: obj = pickle.load(f) # AttributeError lub rozbieżność struktury

Historia

Przykład 1

W dużym projekcie do przechowywania profili użytkowników używany był pickle. Po aktualizacji wersji Pythona i zmianie klas struktura zserializowanych obiektów straciła kompatybilność, co doprowadziło do awarii systemu i utraty większości danych użytkowników.


Przykład 2

W serwisie internetowym pickle był używany do sesji użytkowników. Złośliwy użytkownik załadował złośliwy obiekt pickle, co pozwoliło na wykonanie wstrzyknięcia kodu na serwerze.


Przykład 3

Próba serializacji funkcji za pomocą pickle w celu ich przesłania przez sieć zakończyła się niepowodzeniem w niektórych środowiskach: pickle'owane lambdy nie mogą zostać przeniesione między maszynami o różnych konfiguracjach/wersjach Pythona.