Insecure Deserialisation in .NET Applications

Insecure Deserialisation in .NET Applications

Deserialisation turns data back into objects, and if the data came from a user, it can turn into objects you never intended to create. In .NET the consequence is usually remote code execution in the context of the application pool. It sits in the OWASP Top 10 as a software and data integrity failure, and it remains one of the highest impact findings a tester can report on a mature application.

Where the untrusted data comes in

Anywhere the application accepts a blob it later reconstructs. View state in older web forms applications is the classic example, along with authentication cookies containing serialised objects, cached values retrieved from a shared store, message queue payloads and data pulled from a database that another system writes to. The last two are the ones teams overlook, because the input feels internal. If any component upstream can be influenced by a user, the data reaching your deserialiser is untrusted. Import features that accept a file exported from another instance of the same product are worth checking for the same reason.

See also: The Importance of Cloud Technology for Modern Businesses

Why the risk is so high

Exploitation does not need a vulnerability in your code. Publicly available gadget chains use classes already present in the framework, so an attacker constructs a payload that runs a command during reconstruction. Tooling automates the payload generation, which means the gap between finding the entry point and demonstrating code execution is short. Microsoft has been steadily removing the legacy binary formatter from the platform for precisely this reason, and applications still using it are running on borrowed time as well as unsafe ground.

“When we find this it is usually in the oldest part of the application, in a component that has worked reliably for a decade and nobody wants to touch. That is exactly why it survives. Search your codebase for the legacy formatters this week and you will find out in an hour whether you have this problem.”

William Fieldhouse, Director, Aardwolf Security Ltd

Fixing it properly

Move to a serialiser that only handles data, such as the modern JSON options that will not instantiate arbitrary types. Where a library offers type handling for convenience, keep it switched off, since permissive type handling recreates the same problem in a different format. For view state, ensure it is signed and encrypted with keys that are protected and rotated, because a disclosed machine key turns a signed blob back into an execution path. Where legacy code cannot be replaced immediately, restrict the types that may be reconstructed to a strict allowlist. Rotate machine keys after any incident touching the web servers, since a leaked key undoes the signing entirely.

Finding it before somebody else does

Code review is the efficient route, because the dangerous calls are searchable and a grep across the repository takes minutes. Black box detection is harder and relies on recognising serialised formats in parameters and on out-of-band signals when a payload triggers a network callback. A web application penetration testing engagement should cover both angles for a .NET estate, and it is worth asking penetration testing experts directly whether their methodology includes deserialisation, since it is the sort of finding that requires deliberate effort rather than a scan.

Frequently asked questions about deserialisation

These questions come up when this finding reaches a development team.

Is JSON safe by default?

Safer, yes. It becomes unsafe when a library is configured to embed and honour type information, which reintroduces the ability to instantiate arbitrary classes from attacker-controlled data.

Does a web application firewall help?

It can block known payload patterns and it is not a fix. Encoding variations and novel gadget chains get past signature matching, so treat filtering as a delay rather than a control.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *