flawopen.com/Insecure Deserialization/TypeNameHandling
No — any value other than TypeNameHandling.None is dangerous with untrusted JSON. It makes the parser honour a $type field in the document, letting the attacker choose which .NET type gets constructed. That turns a safe data format back into a deserialization vulnerability. Json.NET's own documentation carries a security warning about it.
var settings = new JsonSerializerSettings {
// Any of these is dangerous with
// untrusted input:
TypeNameHandling =
TypeNameHandling.All,
// .Auto, .Objects, .Arrays too
};
JsonConvert.DeserializeObject<Base>(
untrustedJson, settings);
// Attacker sends:
// { "$type": "SomeDangerousType,
// SomeAssembly", "prop": "..." }
// → that type is constructed with
// attacker-chosen property values.// Default — and the correct choice var settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.None, }; // Need polymorphism? Do the dispatch // yourself from a value you control: var probe = JObject.Parse(json); Base result = probe["kind"]?.ToString() switch { "circle" => probe.ToObject<Circle>(), "square" => probe.ToObject<Square>(), _ => throw new JsonException("kind"), }; // Or System.Text.Json polymorphic // serialization with [JsonDerivedType].
Almost always to support polymorphism — a list of Shape that must round-trip as Circle and Square, or a message bus carrying heterogeneous command objects. TypeNameHandling solves that neatly by writing the concrete type into the payload, and the failure mode is invisible until someone sends a $type you did not anticipate.
The structural problem is the same one that makes BinaryFormatter unfixable: the payload is deciding what code runs. The safe inversion is that your code decides the type, using a discriminator value that you validate against a closed set.
A custom binder that allowlists specific types substantially reduces the reachable surface and is much better than an unrestricted configuration. It is still a filter rather than a boundary — its safety depends on every permitted type, and everything those types construct during deserialization, being harmless. If you must use type handling on input that could be influenced by an attacker, combine a strict binder with the narrowest possible permitted set, and treat it as risk reduction pending a redesign.
Marginally narrower in what it writes, but it still honours $type on the way in for the cases it covers. Microsoft and Json.NET both treat any non-None value as requiring a security review. Do not treat Auto as a safe middle ground.
No. It has no equivalent "read the type from the document" mode. Its polymorphic support uses attributes such as [JsonDerivedType] with a discriminator, where the permitted set is declared in your code — the safe inversion described above.
Grep for TypeNameHandling across the solution, including global settings registered in ASP.NET startup — a single global configuration silently changes the behaviour of every controller that binds JSON.