HIGH spring4shellaspnethmac signatures

Spring4shell in Aspnet with Hmac Signatures

Spring4shell in Aspnet with Hmac Signatures — how this specific combination creates or exposes the vulnerability

The Spring4shell (CVE-2022-22965) vector in an ASP.NET context becomes notable when HMAC-based signatures are used to bind request data to a server-side model without strict validation of the target type. In such setups, an attacker can supply crafted form data or JSON that leverages model binding to invoke arbitrary method execution, for example via a POST to an endpoint that expects a simple DTO but receives nested properties like __type or polymorphic deserialization hints. When HMAC signatures are applied to protect integrity, the signature may cover only selected headers or a subset of the payload, leaving the bound model open to manipulation if the server deserializes unexpected types.

ASP.NET’s default model binders can be coerced into mapping attacker-supplied values to constructors or methods if the application uses permissive binding sources (e.g., BindingSource.Any) and does not explicitly whitelist expected types. Even when an HMAC signature confirms the request came from a trusted client, the server may still process maliciously modified parameters because the signature does not guarantee semantic correctness of the bound object graph. This mismatch between integrity protection (HMAC) and type safety (model binding) can lead to unauthorized operations, reflected in middleBrick’s findings for BOLA/IDOR and Property Authorization when the scan detects over-permissive binding or missing type constraints.

Consider an endpoint that validates an HMAC header but does not restrict the deserialized type:

// Risk: model binding may instantiate unexpected types despite HMAC validation
[HttpPost("update")]
public IActionResult Update([FromBody] UpdateModel model)
{
    if (!VerifyHmac(model)) return Forbid();
    // Proceed with update using model properties
    return Ok();
}

private bool VerifyHmac(UpdateModel model)
{
    var computed = ComputeHmac(model.SensitiveData, _secretKey);
    return TimingSafeEquals(computed, model.ClientHmac);
}

If UpdateModel is replaced during binding with a malicious subtype that overrides behavior, the HMAC may still pass (because the attacker can echo back the signature over the modified payload if the key is exposed or the scope is too broad), while the server performs unintended actions. MiddleBrick’s LLM/AI Security checks can surface prompt injection or data exfiltration patterns that parallel this risk when endpoints expose functionality that can be tricked via crafted inputs.

Moreover, if the HMAC is computed over only selected fields (e.g., headers or a subset of the JSON), an attacker can modify unchecked properties to trigger path traversal, SSRF, or insecure deserialization patterns that the scanner flags under Data Exposure and Input Validation. The combination of weak binding rules and partial integrity checks creates a scenario where the application believes the request is authentic but processes it unsafely.

Hmac Signatures-Specific Remediation in Aspnet — concrete code fixes

To reduce risk, ensure that HMAC validation covers all inputs that affect behavior and that model binding is constrained to known types. Prefer explicit DTOs with strict binding rules and validate the entire payload before acting.

1) Validate the full payload and use strict binding

Avoid [FromBody] with permissive sources. Use a concrete type and disable inference of complex types from query strings or form data.

[HttpPost("update")]
public IActionResult Update([Bind(Prefix = "payload")] UpdateRequest request)
{
    if (request == null || !VerifyHmacFullPayload(request)) return Forbid();
    // Safe processing
    return Ok();
}

private bool VerifyHmacFullPayload(UpdateRequest request)
{
    var json = JsonSerializer.Serialize(request, _jsonOptions);
    var computed = HmacSha256(json, _secretKey);
    return TimingSafeEquals(computed, request.ClientHmac);
}

public class UpdateRequest
{
    public required string Action { get; set; }
    public required int ItemId { get; set; }
    public string? Metadata { get; set; }
    public required string ClientHmac { get; set; }
}

2) Use a fixed binding source and disable formatters you don’t need

In Program.cs, restrict input formatters to JSON only and avoid allowing form-data to bind to sensitive commands.

builder.Services.Configure<MvcOptions>(options =>
{
    options.InputFormatters.RemoveType<SystemTextJsonInputFormatter>();
    options.InputFormatters.Add(new SystemTextJsonInputFormatter(
        new JsonSerializerOptions(JsonSerializerDefaults.Web)));
});

3) Include all relevant data in the HMAC and enforce type constraints

Compute HMAC over the canonical JSON representation of the full DTO, and enforce a closed type model to prevent polymorphic deserialization.

private string ComputeHmacForDto(object dto, byte[] key)
{
    var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
    var utf8 = JsonSerializer.SerializeToUtf8Bytes(dto, dto.GetType(), options);
    using var hmac = new HMACSHA256(key);
    return Convert.ToBase64String(hmac.ComputeHash(utf8));
}

On receipt, recompute over the raw JSON body (preserving order and casing) and compare before model binding proceeds to a specific known type. This approach aligns with the scanner’s checks for Encryption and Data Exposure by ensuring integrity covers the entire message.

4) Add anti-tampering checks for model metadata

Validate that no unexpected type hints (e.g., __type, $type) are present and reject requests that attempt to bind to base types or interfaces unless explicitly supported.

if (request.Metadata != null && request.Metadata.Contains("__type", StringComparison.OrdinalIgnoreCase))
{
    ModelState.AddModelError("Metadata", "Type hints are not allowed");
}

Frequently Asked Questions

Does using HMAC on a subset of fields still protect against Spring4shell-style attacks in ASP.NET?
No. If the HMAC does not cover the full request used for binding and processing, an attacker can modify unchecked fields to invoke unintended behavior. Always include all data that affects server-side logic in the HMAC computation.
Can the ASP.NET Core model binder be hardened against polymorphic deserialization even when HMAC is applied?
Yes. Use strict type binding, avoid permissive sources like BindingSource.Any, disable unnecessary formatters, and reject requests containing type metadata (e.g., __type). Combine this with full-payload HMAC validation to ensure integrity and type safety.