FlawOpen

flawopen.com/Unsichere Deserialisierung/Python-pickle-Sicherheit

Ist pickle.load() bei nicht vertrauenswürdigen Daten sicher?

CWE-502: Deserialisierung nicht vertrauenswürdiger DatenReferenzseite
Kurzantwort

Nein. Behandle pickle wie ein Programm in einem Paket, nicht wie einen passiven Datensatz: Beim Laden kann Rekonstruktionsverhalten ausgeführt werden, bevor die Anwendung das Objekt prüft. Verwende für Eingaben über Vertrauensgrenzen ein reines Datenformat.

UNSICHER — nicht vertrauenswürdige Bytes können beim Laden Code auslösen
import pickle

# Never accept pickle bytes from a request, upload,
# shared cache, or other untrusted source.
obj = pickle.loads(untrusted_bytes)
SICHERERE WAHL — Daten parsen und Schema prüfen
import json

def parse_profile(raw: bytes) -> dict[str, str]:
    if len(raw) > 65_536:
        raise ValueError("Payload too large")

    try:
        value = json.loads(raw)
    except (json.JSONDecodeError, UnicodeDecodeError):
        raise ValueError("Invalid JSON") from None

    if not isinstance(value, dict) or set(value) - {"display_name", "theme"}:
        raise ValueError("Invalid profile")

    name = value.get("display_name")
    theme = value.get("theme")
    if not isinstance(name, str) or len(name) > 80:
        raise ValueError("Invalid display name")
    if theme not in {"light", "dark"}:
        raise ValueError("Invalid theme")

    return {"display_name": name, "theme": theme}
Pickle-Stream:
Python-spezifische Bytefolge zur Objektrekonstruktion, einschließlich globaler Referenzen und Rekonstruktionsverhalten.
Unpickling:
Interpretieren des Streams und Wiederherstellen des Objektgraphen; dabei können Funktionen aufgerufen werden.
Vertrauensgrenze:
Stelle, an der Nutzer, Dienst, Upload oder gemeinsamer Speicher Bytes kontrollieren oder ändern kann.
CWE-502:
Deserialisierung nicht vertrauenswürdiger Daten; die Auswirkung hängt davon ab, ob Angreifer geladene Daten liefern oder verändern können.
Schritt 1

Nicht vertrauenswürdige Bytes erreichen pickle

Upload, Anfrage, Cache oder Artefakt kann vom Angreifer kontrollierte oder veränderte Pickle-Daten in den Prozess bringen.

Schritt 2

Der Unpickler löst Globals auf

Der Interpreter verarbeitet Rekonstruktionsanweisungen; find_class() kann benannte Globals einschließlich Funktionen importieren und zurückgeben.

Schritt 3

Das Laden löst Verhalten aus

Anweisungen können während load() oder loads() Funktionen aufrufen, bevor die Anwendung das Ergebnis prüft.

Schritt 4

Die Auswirkung folgt den Prozessrechten

Das Verhalten läuft mit den Rechten des Python-Prozesses. Netzwerk, Geheimnisse, Dateizugriff und Isolation begrenzen den Schaden.

Warum das Laden von pickle eine Codeausführungsgrenze überschreitet

Ein Pickle-Stream kann Globals und Rekonstruktionsfunktionen benennen. Beim Unpickling löst Unpickler.find_class() Globals einschließlich Funktionen auf; Opcodes können Rekonstruktion auslösen. Gefährlich ist bereits pickle.load() oder pickle.loads(); ein späterer separater execute-Aufruf ist nicht nötig. Der resultierende Code hat die Rechte des Prozesses. Das ist dokumentiertes Formatverhalten; nutze pickle nicht für den Austausch nicht vertrauenswürdiger Daten.

Was JSON behebt — und was nicht

Python warnt, dass das Laden nicht vertrauenswürdiger oder manipulierter Pickle-Daten Code ausführen kann; JSON-Decodierung erzeugt diesen Codeausführungspfad nicht von selbst. JSON validiert Eingaben nicht automatisch: Begrenze die Größe, fordere erwarteten Typ und Felder, prüfe Werte anhand eines Schemas und wende Autorisierung separat an. Muss ein Altprozess pickle laden, authentifiziere vorab die exakten Bytes mit einem geschützten Schlüssel. Eine Signatur belegt Herkunft und Integrität nur unter den Schlüsselannahmen und macht bösartige Daten eines vertrauenswürdigen Signierers nicht sicher. Migriere zu einem Datenformat.

Häufige Fragen

Macht ein eingeschränkter Unpickler angreiferkontrolliertes pickle sicher?

Eine Überschreibung von find_class() kann Globals einschränken, aber einen Loader für alle Protokolle und erreichbaren Verhaltensweisen als sicher zu beweisen ist schwierig. Für nutzerkontrollierte Bytes ist ein Datenformat vorzuziehen.

Muss auch JSON validiert werden?

Ja. JSON vermeidet pickle-artige Codeausführung beim Decodieren, doch Typen, Felder, Größe, Werte und Berechtigungen müssen geprüft werden. Trenne JSON-Parsing von Geschäftsregeln.

Primärquellen

Siehe auch Unsichere Deserialisierung: Risiken und Schutz Ist Ruby YAML.load sicher? Psych-Versionen und safe_load .NET BinaryFormatter: Risiken und Migration Java ObjectInputStream: Deserialisierung sicher gestalten Newtonsoft.Json TypeNameHandling: sichere Konfiguration? PHP unserialize() und nicht vertrauenswürdige Daten