flawopen.com/Insecure Deserialization/BinaryFormatter
No, and uniquely among the APIs on this site, its own vendor says so without qualification. Microsoft documented BinaryFormatter as insecure, obsoleted it, disabled it by default, and removed it from .NET 9. There is no configuration that makes it safe for untrusted input.
// Any of these with untrusted bytes var bf = new BinaryFormatter(); var obj = bf.Deserialize(stream); // Also affected, same family: new SoapFormatter().Deserialize(s); new NetDataContractSerializer() .Deserialize(s); new LosFormatter().Deserialize(s); ObjectStateFormatter // ViewState // A SerializationBinder narrows the // type set but is NOT a security // boundary — bypasses are published.
// System.Text.Json — data only, // no type information in the payload var obj = JsonSerializer .Deserialize<MyDto>(json); // Or an explicit contract serializer // with a known type var dcs = new DataContractSerializer( typeof(MyDto)); // Or MessagePack / protobuf-net with // a declared schema. // The principle: the payload says what // the VALUES are; your code decides // what the TYPE is.
BinaryFormatter was designed to faithfully reconstruct an arbitrary object graph, including the types involved, from a byte stream. That design goal is fundamentally incompatible with untrusted input: to do its job it must instantiate whatever types the payload names and invoke their deserialization callbacks. An attacker who controls the stream controls which types get built and with what state, which is exactly the gadget-chain precondition.
Publicly available tooling maintains ready-made chains against types present in the .NET base class library, so "my application has no dangerous classes" provides no protection.
A common mitigation is a custom SerializationBinder that allows only expected types. This reduces the reachable gadget surface and is better than nothing, but Microsoft is explicit that it is not a security boundary — published research has repeatedly found bypasses, often through types that were assumed harmless. Treat a binder as a temporary risk reduction while migrating, not as a solution.
Session state providers, ASP.NET ViewState (via LosFormatter / ObjectStateFormatter), distributed cache layers, message queue payloads, and "save object to disk" helpers written years ago. ViewState is especially worth auditing, because it is attacker-reachable by design and its protection depends entirely on the machine key remaining secret.
It is lower risk, but it depends on the data never being attacker-influenced anywhere along its path — including a database row, a cache entry, or a file an attacker can write. Given the API is now removed from the platform, migration is required eventually regardless.
The in-box implementation was removed, so affected code will fail at runtime. Plan the serializer migration as part of the upgrade rather than discovering it during it.
Yes with default settings. It becomes unsafe if TypeNameHandling is enabled, which reintroduces the same type-instantiation problem — see is TypeNameHandling safe?