Deserialization Attack in Aspnet
How Deserialization Attack Manifests in Aspnet
Deserialization attacks in Aspnet occur when an application untrustingly converts serialized data (like binary, JSON, or XML) back into object instances. Attackers exploit this by injecting malicious payloads that, upon deserialization, execute arbitrary code, escalate privileges, or trigger denial-of-service. Aspnet’s ecosystem provides multiple deserialization pathways, each with unique risks.
BinaryFormatter in Aspnet Framework
Legacy Aspnet Framework applications often use BinaryFormatter for state management (e.g., ViewState) or custom data processing. BinaryFormatter is inherently insecure because it can instantiate any type present in the application’s loaded assemblies, including those with dangerous deserialization callbacks (e.g., System.Windows.Data.ObjectDataProvider). An attacker can craft a binary payload that, when deserialized, runs OS commands or loads malicious assemblies.
// Vulnerable Aspnet Framework example: Deserializing ViewState or request body
using System.Runtime.Serialization.Formatters.Binary;
public void ProcessRequest(HttpRequest request)
{
var formatter = new BinaryFormatter();
var objectData = formatter.Deserialize(request.InputStream); // Dangerous: no type restrictions
// ... use objectData
}Newtonsoft.Json with TypeNameHandling in Aspnet Core
Aspnet Core’s default JSON serializer (System.Text.Json) does not support type name handling and is safe. However, many projects integrate Newtonsoft.Json (Json.NET) for advanced features. If TypeNameHandling is enabled (e.g., TypeNameHandling.All), the JSON parser respects $type properties to reconstruct polymorphic types. An attacker can specify a fully qualified type name (e.g., System.Diagnostics.Process) to instantiate arbitrary .NET types, leading to remote code execution.
// Vulnerable Aspnet Core controller using Newtonsoft.Json with unsafe settings
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
[HttpPost]
public IActionResult Upload([FromBody] object data)
{
var settings = new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.All // Risky: allows $type in JSON
};
var obj = JsonConvert.DeserializeObject(data.ToString(), settings);
// ... obj could be a Process object that starts calc.exe
return Ok();
}XML Serialization with XmlSerializer
XmlSerializer can also be exploited if an endpoint accepts XML payloads and the serializer processes DTDs (Document Type Definitions). While primarily an XXE vector, XML deserialization can indirectly lead to RCE if the XML includes object graphs referencing dangerous types. Additionally, DataContractSerializer (used in WCF/ASP.NET Web API) may allow arbitrary type instantiation if KnownType attributes are overly permissive.
These patterns often appear in API endpoints that accept complex objects (object parameters), file uploads, or any route that processes serialized client data. The attack surface is amplified in microservices that exchange binary or JSON messages with loose type constraints.
Aspnet-Specific Detection
Detecting deserialization vulnerabilities in Aspnet requires examining both configuration and runtime behavior. Manually, you would inspect Startup.cs (or Program.cs) for formatter settings, check controller actions for [FromBody] object parameters, and search for BinaryFormatter usage. However, automated scanning is more efficient.
middleBrick’s Approach
middleBrick’s Input Validation check actively probes for deserialization flaws during its 5–15 second black-box scan. It targets every discoverable endpoint that accepts POST, PUT, or PATCH requests (e.g., /api/upload, /api/process) and sends crafted payloads designed to trigger unsafe deserialization in Aspnet environments. The scanner analyzes responses for:
- Error messages that reveal type names or stack traces (e.g.,
System.TypeLoadException,BinaryFormattererrors). - Time delays indicating code execution (e.g.,
Thread.Sleepin a deserialization gadget). - Unexpected status codes (e.g., 500 errors after sending a malicious payload).
For BinaryFormatter, middleBrick sends binary payloads generated from known gadget chains (like those in ysoserial.net). For Newtonsoft.Json with TypeNameHandling, it submits JSON containing $type properties pointing to common exploit types (e.g., System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0). The scanner also checks for XML deserialization issues by sending DTD-containing XML and monitoring for XXE-like errors.
Because middleBrick operates without credentials, it focuses on unauthenticated endpoints. However, deserialization flaws are often exposed without authentication, making them detectable in a standard scan. The results are mapped to OWASP’s Insecure Deserialization (A8:2017) and include severity ratings (critical for RCE risks) and remediation steps.
Example Scan Output
After scanning an Aspnet API, middleBrick’s report might highlight:
| Endpoint | Parameter | Issue | Severity |
|---|---|---|---|
| POST /api/upload | body (object) | Newtonsoft.Json TypeNameHandling enabled | Critical |
| POST /api/deserialize | binary payload | BinaryFormatter.Deserialize used | Critical |
Aspnet-Specific Remediation
Remediating deserialization vulnerabilities in Aspnet involves eliminating unsafe deserializers, restricting type resolution, and validating input. Below are framework-specific fixes.
Avoid BinaryFormatter EntirelyBinaryFormatter is obsolete and insecure. Microsoft recommends against its use for any untrusted data. Replace it with safe alternatives like System.Text.Json, DataContractSerializer (with a strict KnownType list), or custom DTOs. If you must maintain legacy ViewState, enable ViewStateUserKey and use MAC (Message Authentication Code) validation.
// Safe Aspnet Framework alternative: Use DataContractSerializer with known types
[DataContract]
[KnownType(typeof(SafeType1))]
[KnownType(typeof(SafeType2))]
public class MyDataContract { }
var serializer = new DataContractSerializer(typeof(MyDataContract));
var obj = serializer.ReadObject(request.InputStream); // Only SafeType1/2 allowedNewtonsoft.Json: Disable TypeNameHandling and Use a Binder
In Aspnet Core, if you must use Newtonsoft.Json, configure TypeNameHandling to None. Additionally, implement a custom SerializationBinder to whitelist permissible types. This prevents attackers from specifying arbitrary types via $type.
// Aspnet Core: Secure Newtonsoft.Json configuration
services.AddControllers()
.AddNewtonsoftJson(options =>
{
options.SerializerSettings.TypeNameHandling = TypeNameHandling.None;
options.SerializerSettings.SerializationBinder = new KnownTypesBinder
{
// Whitelist only the types you expect
KnownTypes = new List<Type> { typeof(UserDto), typeof(ProductDto) }
};
});
public class KnownTypesBinder : ISerializationBinder
{
public List<Type> KnownTypes { get; set; }
public Type BindToType(string assemblyName, string typeName)
{
return KnownTypes.FirstOrDefault(t => t.Name == typeName);
}
public void BindToName(Type serializedType, out string assemblyName, out string typeName)
{
assemblyName = null; typeName = serializedType.Name;
}
}Validate and Sanitize Input
Even with safe serializers, validate incoming data against expected schemas. Use [FromBody] with concrete DTO classes instead of object. In Aspnet Core, leverage System.Text.Json’s built-in polymorphism support via JsonDerivedType attributes (available in .NET 7+) instead of $type.
// Aspnet Core 7+: Safe polymorphism with System.Text.Json
[JsonDerivedType(typeof(DerivedType1), 1)]
[JsonDerivedType(typeof(DerivedType2), 2)]
public abstract class BaseDto { }
[HttpPost]
public IActionResult Upload([FromBody] BaseDto data) // System.Text.Json handles type discrimination safely
{
// ...
return Ok();
}General Hardening
- Disable XML formatters if not needed (services.AddControllers().AddXmlSerializerFormatters() → remove).
- Set XmlReaderSettings.DtdProcessing to Prohibit to prevent XXE.
- Keep dependencies updated; .NET 8+ includes additional deserialization safeguards.
- Use static analysis tools (e.g., SonarQube, Roslyn analyzers) to flag BinaryFormatter usage in code.
After applying fixes, rescan with middleBrick’s Input Validation check to verify the vulnerability is resolved. The scanner will no longer detect the deserialization patterns, and your risk score should improve.