Why BinaryFormatter Was Deprecated in Modern C

Binary serialization converts complex in-memory object graphs into a compact stream of bytes for storage or network transport. For years, BinaryFormatter was the standard implementation in the .NET ecosystem, prized for its ability to serialize entire object graphs, including private fields and cyclical references, with minimal configuration. However, Microsoft has completely deprecated and disabled BinaryFormatter in modern .NET (.NET 7, 8, and 9) because it possesses critical, unfixable security vulnerabilities that allow remote code execution, alongside tight runtime coupling that limits cross-platform interoperability.

What Is Binary Serialization?

Binary serialization is the process of mapping an application's in-memory object state directly into a compact binary format. Unlike text-based formats like JSON or XML, binary representations omit human-readable formatting, whitespace, and structural delimiters.

In early .NET implementations, binary serialization captured not only an object's public properties but also its exact runtime type definitions, assembly versions, private fields, and complex reference graphs. This made it effortless to save and restore complex object structures without writing custom mapping logic or defining strict data contracts.

Why BinaryFormatter Was Deprecated

Despite its convenience, BinaryFormatter contains foundational architectural choices that make it hazardous in modern distributed environments.

Inherent Remote Code Execution (RCE) Vulnerabilities

The primary reason for the deprecation of BinaryFormatter is security. BinaryFormatter deserializes payloads by reading type metadata directly embedded inside the incoming byte stream. When it instantiates these types, it automatically invokes constructors, finalizers, or specialized deserialization callbacks before the consuming application can validate the data.

Attackers exploit this mechanism by injecting carefully crafted "gadget chains"—sequences of standard .NET framework classes present in the application's runtime. When instantiated or finalized during deserialization, these gadget chains can execute arbitrary system commands, bypass security controls, and compromise the host machine.

Impossibility of Remediation

Microsoft determined that BinaryFormatter cannot be secured against deserialization attacks. Traditional mitigation techniques, such as using custom SerializationBinder implementations to whitelist safe types, routinely fail because:

  • Gadget chains continuously evolve as new framework libraries and dependencies are discovered.
  • The deserializer needs access to generic framework types that can be leveraged to circumvent validation logic.
  • Vulnerabilities exist at the architectural level rather than as isolated implementation bugs.

Because the component was designed to trust the incoming stream implicitly, the official guidance states that BinaryFormatter should never be used with untrusted data, and no patch can make it safe.

Versioning and Cross-Platform Incompatibilities

BinaryFormatter deeply ties serialized payloads to specific .NET internal types, assembly versions, and namespaces. A change to a private field name or an update to a framework assembly version often invalidates previously serialized data. Furthermore, because it relies on .NET-specific runtime characteristics, it offers virtually no interoperability with applications written in other programming languages.

Phased Removal in Modern .NET

Due to these architectural risks, Microsoft progressively phased out BinaryFormatter:

  • .NET 5 and .NET 6: Marked the API as obsolete with compilation warnings and introduced runtime switches to disable it.
  • .NET 7 and .NET 8: Deprecated the component by default in most project templates and disabled it in ASP.NET Core applications.
  • .NET 9: Completely removed the implementation from the shared framework runtime, causing BinaryFormatter methods to throw a PlatformNotSupportedException unless legacy compatibility packages are explicitly forced.

Modern, Secure Alternatives

Applications relying on BinaryFormatter must migrate to modern serialization frameworks that separate data from behavioral logic:

  • System.Text.Json: The default, high-performance JSON serializer built into modern .NET. It uses explicit data contracts and does not deserialize arbitrary types by default, eliminating code-execution exploits.
  • Protocol Buffers (protobuf-net): A contract-based binary format developed by Google that produces compact payloads, provides rapid serialization speeds, and supports cross-language environments.
  • MessagePack: An efficient binary format that mirrors JSON data models but provides the performance and payload size advantages of binary data.
  • MemoryPack: A high-speed, zero-encoding binary serializer specifically optimized for modern C# that avoids polymorphic deserialization vulnerabilities through compile-time code generation.