When Microsoft removes a core API for security reasons, it’s worth paying attention.

In late 2024, Microsoft deprecated a long-standing serialization mechanism because it could enable remote code execution. This is one of the most severe classes of software vulnerabilities.

However, many enterprise applications built on .NET Framework 4.x still use this feature.

For organizations with legacy Microsoft workloads, this isn’t just a technical issue. It could be a way for attackers to get in.

This advisory explains the risk in plain English, why it shows up in real enterprise systems, and the practical next steps to reduce exposure. 

The bug, in plain English 

Why this matters:
If exploited, this vulnerability can allow an attacker to execute code inside your application. This might lead to data breaches, privilege escalation, or full system compromise.

Applications often serialize objects, store them somewhere, then deserialize them later. That is normal.

The danger is when the deserializer allows the incoming data to influence what object type gets constructed. If an attacker can control the serialized payload, they can sometimes steer the application into building unexpected object graphs. In the worst case, this can lead to remote code execution or privilege escalation.

Think of it like this: a warehouse gets a ‘build instruction’ in a package. A safe warehouse only builds approved items. An unsafe one builds anything it’s told, even a robot that opens the back door.

This is a well-known class of vulnerability: CWE-502, Deserialization of Untrusted Data.

Insecure deserialization with older .NET versions 

Two layers of risk that security reviews often miss

In legacy .NET estates, insecure deserialization typically shows up in two places.

Layer A: Your custom code

Many codebases contain at least one “sink” where untrusted data can reach an unsafe deserializer. Common hotspots include:

  • Schedulers and background jobs

  • Plugin or extension systems

  • Event handlers

  • Cache persistence logic

  • Database-stored blobs that later get deserialized

  • Message queue payloads that are “trusted” because they are internal

Layer B: The platform beneath your code.

Many enterprise platforms still run on .NET Framework and historically used unsafe serialization patterns internally. We see this pattern frequently in legacy CMS and ecommerce stacks, as well as older integration frameworks.

This is why a “clean scan” can be misleading. Many security scans focus on your custom code. The platform runtime, scheduler, event system, and plugin layer are often a blind spot, yet that is exactly where unsafe serialization may exist.

Microsoft's fix

Your stack

Status

.NET 9 / .NET 10

Safe by default. In .NET 9 and onward, Microsoft removed the legacy BinaryFormatter-style API surface from the runtime. The intent is to make it much harder to accidentally ship unsafe binary deserialization into new applications.

.NET Framework 4.x

Still exposed

.NET Framework 4.x still includes the legacy API. Microsoft has not removed it from .NET Framework. This is a critical nuance:

  • Supported does not mean “safe by default.”

  • .NET Framework 4.8 can remain supported for a long time, but it still contains the risky serialization surface.

Practical implication

If you still run production applications on .NET Framework, you should treat unsafe deserialization as an active risk category, even if you have not consciously written BinaryFormatter calls in your own code.

Do this week (Our practical checklist)

This is not just a developer concern. It is a governance and risk management issue in environments running legacy Microsoft workloads.

1

Inventory: which applications are on .NET Framework vs modern .NET

Create a list of all applications and services

Tag each as: .NET Framework 4.x or modern .NET


2

For modern .NET apps: verify unsafe compatibility has not been reintroduced

Confirm no legacy compatibility settings or dependencies were added that re-enable unsafe serialization behavior

Confirm teams are not using "type name in payload" patterns in JSON or other formats without strict allowlisting


3

For .NET Framework apps: search for common unsafe deserialization patterns

BinaryFormatter and similar legacy binary serializers

Json.NET settings that enable type construction from payload (e.g. TypeNameHandling.Auto and related patterns)

Any custom binder or resolver that uses payload-provided type names


4

Do not stop at your code: assess the platform layer

A "clean custom code scan" does not prove the application is safe if the platform beneath it is using unsafe APIs. This is particularly important for older CMS and ecommerce platforms, plugin systems, and schedulers.


5

Treat databases, caches, and queues as attack surface

If untrusted actors can influence what gets stored or replayed (directly or indirectly), then those stores are part of your threat model. This is not limited to public HTTP APIs.

Treat upgrade and modernization work as security work, not just engineering hygiene

Need a hand?

We can scan your stack (custom code and platform) and give you a prioritised remediation plan.

Contact us →

Link copied!