flawopen.com/Unsichere Deserialisierung/TypeNameHandling
Newtonsoft.Json TypeNameHandling: sichere Konfiguration für nicht vertrauenswürdiges JSON?
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.
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);
// 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
Nicht allein. Auto kann beim Deserialisieren $type lesen. Nutzen Sie TypeNameHandling.None oder einen strikten ISerializationBinder, der nur geprüfte Typen zulässt.
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.
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
- Json.NET — Serialisierungseinstellungen: TypeNameHandling und SerializationBinder
- Json.NET-API — ISerializationBinder
- Microsoft Learn — Polymorphie in System.Text.Json
- CWE-502 — Deserialisierung nicht vertrauenswürdiger Daten
- FlawOpen — Ist .NET BinaryFormatter sicher?