HIGH insecure deserializationaspnetcsharp

Insecure Deserialization in Aspnet (Csharp)

Insecure Deserialization in Aspnet with Csharp

Insecure deserialization occurs when an application processes untrusted data without sufficient validation, allowing an attacker to manipulate object graphs during deserialization. In an ASP.NET context using C#, this commonly arises when the application uses BinaryFormatter, NetDataContractSerializer, or custom deserialization logic that reconstructs objects from byte streams or JSON. If the deserialized types are not strictly controlled, an attacker can craft payloads that execute code, bypass authorization, or alter runtime behavior.

ASP.NET applications often expose deserialization surfaces through webhooks, callback endpoints, file uploads, or state management mechanisms (e.g., ViewState in older Web Forms). When C# code uses BinaryFormatter.Deserialize on data from an untrusted source, an attacker can chain malicious payloads leveraging known gadget chains to achieve remote code execution. For example, the CVE-2020-1147 pattern has been observed in the wild involving manipulated object graphs that trigger arbitrary method calls during deserialization.

The OWASP API Security Top 10 lists Improper Restrictions on D deserialization as a relevant risk when API endpoints accept serialized objects. In C#, this can happen in controllers that bind complex types from the request body without validating the type hierarchy or using safe serializers. Even when using JSON input, if the application relies on polymorphic deserialization without type restrictions, an attacker can specify a malicious concrete type that executes logic during materialization.

To detect this with middleBrick, a scan targeting an endpoint that accepts serialized data without strict type constraints will flag insecure deserialization as part of the Input Validation and Unsafe Consumption checks. The scanner evaluates whether the API surface allows uncontrolled object reconstruction and reports findings with severity and remediation guidance mapped to frameworks such as OWASP API Top 10 and PCI-DSS.

For example, consider an endpoint that accepts a serialized object via JSON and uses polymorphic deserialization without restricting allowed types:

using System.Text.Json;
using System.Text.Json.Serialization;

app.MapPost("/process", (HttpRequest request) =>
{
    using var reader = new StreamReader(request.Body);
    var json = reader.ReadToEnd();
    var options = new JsonSerializerOptions
    {
        TypeInfoResolver = new DefaultJsonTypeInfoResolver()
    };
    var obj = JsonSerializer.Deserialize(json, options);
    return Results.Ok(obj?.ToString());
});

If the JSON contains a $type field that maps to a dangerous type, the runtime may instantiate unexpected classes. middleBrick’s LLM/AI Security checks also test whether endpoints that handle serialized data leak system prompts or enable prompt injection, which can complement deserialization risks in AI-integrated APIs.

In contrast, safe deserialization practices in C# favor immutable data transfer objects, strict type whitelisting, and avoiding runtime type resolution. Tools like middleBrick’s OpenAPI/Swagger analysis resolve $ref definitions and cross-reference them with runtime behavior to highlight mismatches that could enable insecure deserialization paths.

Csharp-Specific Remediation in Aspnet

Remediation focuses on avoiding dangerous serializers and enforcing strict type constraints. In C#, prefer System.Text.Json with configured JsonTypeInfo and explicitly declared allowed types. Disable polymorphic deserialization unless absolutely necessary, and validate concrete types against a whitelist.

Replace BinaryFormatter and NetDataContractSerializer entirely. If you must handle serialized data, use DTOs (Data Transfer Objects) that contain only primitive or simple nested types, and disable support for type metadata.

Here is a secure example using System.Text.Json with explicit type constraints:

using System.Text.Json;
using System.Text.Json.Serialization;

public class SafeOptions
{
    public string Name { get; set; }
    public int Version { get; set; }
}

app.MapPost("/process-safe", (HttpRequest request) =>
{
    using var reader = new StreamReader(request.Body);
    var json = reader.ReadToEnd();
    var options = new JsonSerializerOptions
    {
        // Do not allow polymorphic deserialization
        TypeInfoResolver = null
    };
    var safeObj = JsonSerializer.Deserialize<SafeOptions>(json, options);
    if (safeObj == null)
    {
        return Results.BadRequest("Invalid payload");
    }
    return Results.Ok(new { safeObj.Name, safeObj.Version });
});

For JSON payloads that must support inheritance, explicitly control allowed derived types using JsonTypeInfo and a custom JsonConverter instead of relying on runtime type resolution:

using System.Text.Json;
using System.Text.Json.Serialization;

public class AnimalConverter : JsonConverter<Animal>
{
    public override Animal Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        using var doc = JsonDocument.ParseValue(ref reader);
        var typeProperty = doc.RootElement.GetProperty("kind");
        var kind = typeProperty.GetString();
        return kind switch
        {
            "dog" => JsonSerializer.Deserialize<Dog>(doc.RootElement.GetRawText(), options),
            "cat" => JsonSerializer.Deserialize<Cat>(doc.RootElement.GetRawText(), options),
            _ => throw new JsonException("Unknown animal kind")
        };
    }

    public override void Write(Utf8JsonWriter writer, Animal value, JsonSerializerOptions options) =>
        throw new NotImplementedException();
}

app.MapPost("/animals", (string json, JsonSerializerOptions options) =>
{
    options.Converters.Add(new AnimalConverter());
    var animal = JsonSerializer.Deserialize<Animal>(json, options);
    return Results.Ok(animal?.Name);
});

In ASP.NET, also configure Kestrel and model binding policies to reject requests with unexpected content types or oversized payloads. middleBrick’s CLI tool can be used locally to validate that endpoints do not accept unsafe deserialization patterns by scanning them with the middlebrick scan <url> command, which reports findings for Authentication, BOLA/IDOR, and Input Validation checks.

For continuous assurance, the middleBrick Pro plan enables scheduled scans and GitHub Action integration to fail builds if insecure deserialization risks are detected. The MCP Server allows AI coding assistants to trigger scans from within the development environment, helping teams catch issues before deployment.

Frequently Asked Questions

Does middleBrick fix insecure deserialization issues automatically?
middleBrick detects and reports insecure deserialization with remediation guidance, but it does not automatically fix or patch code. Developers should apply the recommended secure coding practices and verify changes through testing.
Which C# serializers should be avoided to reduce deserialization risks?
Avoid BinaryFormatter and NetDataContractSerializer in C# due to their support for arbitrary type graphs and gadget chains that can lead to remote code execution. Prefer type-safe serializers like System.Text.Json with strict type constraints.