FlawOpen

flawopen.com/Unsichere Deserialisierung/TypeNameHandling

Newtonsoft.Json TypeNameHandling: sichere Konfiguration für nicht vertrauenswürdiges JSON?

CWE-502: Deserialization of Untrusted DataReferenzseite
Kurzantwort

JSON beschreibt Daten; Ihr Code wählt den .NET-Typ. Mit TypeNameHandling kann $type die Typauflösung beim Deserialisieren beeinflussen. Verwenden Sie für nicht vertrauenswürdige Eingaben None. Falls Polymorphie nötig ist, prüfen Sie Typen mit einem strikten ISerializationBinder oder einer geschlossenen, im Code deklarierten Diskriminatorzuordnung.

VERWUNDBAR
var settings = new JsonSerializerSettings {
    // Any non-None mode needs a strict binder
    TypeNameHandling = TypeNameHandling.Auto,
    // No binder: input $type can resolve CLR types
};

var value = JsonConvert.DeserializeObject<Base>(
    untrustedJson, settings);
BEHOBEN
// Safest default for untrusted JSON
var settings = new JsonSerializerSettings {
    TypeNameHandling = TypeNameHandling.None,
};

// For polymorphism, dispatch over a closed set:
var token = JObject.Parse(json);
Base value = token["kind"]?.ToString() switch {
    "circle" => token.ToObject<Circle>(),
    "square" => token.ToObject<Square>(),
    _ => throw new JsonException("Unknown kind"),
};

// System.Text.Json also supports opt-in derived
// types through [JsonDerivedType] (.NET 7+).

Warum Entwickler TypeNameHandling aktivieren

Der übliche Grund sind polymorphe Daten: Eine Shape-Sammlung muss eventuell als Circle oder Square erhalten bleiben. Json.NET liest und schreibt Typnamen über $type. Bei nicht vertrauenswürdigen Eingaben können diese Metadaten den aufgelösten Typ beeinflussen; das Risiko hängt von erlaubten Typen und ihrem Deserialisierungsverhalten ab. Eine gefährliche Kette benötigt einen erreichbaren Typ mit Nebenwirkungen; JSON allein genügt nicht.

Die Vertrauensgrenze sollte umgekehrt verlaufen: Der Anwendungscode wählt einen Untertyp aus einer geschlossenen Menge geprüfter Diskriminatoren. System.Text.Json unterstützt Opt-in-Polymorphie mit Attributen wie [JsonDerivedType]; beliebige CLR-Namen aus JSON werden nicht aktiviert. Siehe die BinaryFormatter-Anleitung zur verwandten Grenze.

Reicht ein eigener ISerializationBinder aus?

Ein strikter ISerializationBinder ist Json.NETs erforderliche Abwehr, wenn TypeNameHandling bei externen Daten nicht None ist. Ordnen Sie nur wenige exakte, anwendungseigene Namen zu und lehnen Sie alle anderen ab. Prüfen Sie Typen, Konverter, Konstruktoren, Setter und Callbacks. Der Binder begrenzt die Auflösung, macht beliebige Typen aber nicht harmlos. Wenn möglich, bevorzugen Sie None und explizite Auswahl.

FAQ

Ist TypeNameHandling.Auto für nicht vertrauenswürdiges JSON sicher?

Nicht allein. Auto kann beim Deserialisieren $type lesen. Nutzen Sie TypeNameHandling.None oder einen strikten ISerializationBinder, der nur geprüfte Typen zulässt.

Unterstützt System.Text.Json sichere Polymorphie?

Ja, opt-in mit Diskriminator und im Code deklarierten abgeleiteten Typen, etwa [JsonDerivedType] ab .NET 7. Der Code begrenzt die Menge statt beliebiger CLR-Namen aus der Nutzlast.

Wie prüfe ich eine .NET-Anwendung?

Suchen Sie lösungsweit nach TypeNameHandling, SerializationBinder und JsonConvert.DeserializeObject. Prüfen Sie ASP.NET-Startcode und gemeinsame Einstellungen; verfolgen Sie externe JSON-Eingaben und bestätigen Sie einen strikten Binder auf jedem Pfad außer None.

Referenzen

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