FlawOpen

flawopen.com/Deserialisasi tidak aman/TypeNameHandling

Newtonsoft.Json TypeNameHandling: konfigurasi aman untuk JSON tidak tepercaya?

CWE-502: Deserialization of Untrusted DataHalaman referensi
Jawaban singkat

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.

RENTAN
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);
DIPERBAIKI
// 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

Apakah TypeNameHandling.Auto aman untuk JSON tak tepercaya?

Tidak dengan sendirinya. Auto dapat membaca $type saat deserialisasi. Gunakan TypeNameHandling.None atau binder ketat yang hanya mengizinkan tipe yang telah ditinjau.

Apakah System.Text.Json mendukung polimorfisme aman?

Ya, secara opt-in dengan diskriminator dan tipe turunan yang dideklarasikan dalam kode, seperti [JsonDerivedType] pada .NET 7+. Kumpulan tipe dibatasi kode aplikasi.

Bagaimana mengaudit aplikasi .NET?

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

Lihat juga Deserialisasi tidak aman: risiko dan mitigasi PHP unserialize() dan input tak tepercaya Python pickle.load(): risiko data tak tepercaya Apakah Ruby YAML.load aman? Versi Psych dan safe_load .NET BinaryFormatter: Risiko dan Migrasi Keamanan ObjectInputStream Java: Cegah Risiko Deserialisasi