flawopen.com/Deserialisasi tidak aman/TypeNameHandling
Newtonsoft.Json TypeNameHandling: konfigurasi aman untuk JSON tidak tepercaya?
JSON menjelaskan data; kode Anda memilih tipe .NET. Saat TypeNameHandling aktif, $type dapat memengaruhi resolusi tipe saat deserialisasi. Gunakan None untuk input yang tidak tepercaya. Jika polimorfisme diperlukan, validasi tipe dengan ISerializationBinder ketat atau gunakan pemetaan diskriminator tertutup yang dideklarasikan dalam kode.
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+).
Mengapa pengembang mengaktifkan TypeNameHandling
Alasan umum adalah data polimorfik: koleksi Shape mungkin perlu dipertahankan sebagai Circle atau Square. Json.NET membaca dan menulis nama tipe melalui $type. Pada input tak tepercaya, metadata ini dapat memengaruhi tipe runtime; risikonya bergantung pada tipe yang diizinkan dan perilakunya. Rantai berbahaya memerlukan tipe yang dapat dijangkau dan memiliki efek samping; JSON saja tidak cukup.
Batas kepercayaan sebaiknya dibalik: kode memilih subtipe dari kumpulan diskriminator tervalidasi yang tertutup. System.Text.Json mendukung polimorfisme opt-in melalui atribut seperti [JsonDerivedType]; fitur ini tidak mengaktifkan nama CLR sembarang dari JSON. Lihat panduan BinaryFormatter untuk batas terkait.
Apakah ISerializationBinder khusus sudah cukup?
Untuk data eksternal, ISerializationBinder ketat diwajibkan saat TypeNameHandling bukan None. Petakan hanya sedikit nama tipe persis milik aplikasi dan tolak sisanya. Tinjau tipe, converter, constructor, setter, serta callback yang diizinkan. Binder membatasi resolusi tetapi tidak membuat tipe sembarang aman. Jika protokol Anda kendalikan, utamakan None dan dispatch eksplisit.
Pertanyaan umum
Tidak dengan sendirinya. Auto dapat membaca $type saat deserialisasi. Gunakan TypeNameHandling.None atau binder ketat yang hanya mengizinkan tipe yang telah ditinjau.
Ya, secara opt-in dengan diskriminator dan tipe turunan yang dideklarasikan dalam kode, seperti [JsonDerivedType] pada .NET 7+. Kumpulan tipe dibatasi kode aplikasi.
Cari seluruh solusi untuk TypeNameHandling, SerializationBinder, dan JsonConvert.DeserializeObject. Periksa startup ASP.NET dan pengaturan bersama, telusuri aliran JSON eksternal, lalu pastikan binder ketat dipakai pada setiap jalur selain None.
Referensi
- Json.NET — Pengaturan serialisasi: TypeNameHandling dan SerializationBinder
- API Json.NET — ISerializationBinder
- Microsoft Learn — Polimorfisme di System.Text.Json
- CWE-502 — Deserialisasi data tidak tepercaya
- FlawOpen — Apakah .NET BinaryFormatter aman?