HIGH dns rebindingaspnethmac signatures

Dns Rebinding in Aspnet with Hmac Signatures

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

DNS rebinding is a client-side attack that manipulates DNS responses to make a browser believe a malicious host is the same origin as a trusted one. In an ASP.NET application that uses HMAC signatures for request validation, this interaction can bypass integrity checks when the server relies on the request’s perceived origin rather than on cryptographic proof of the client’s authority.

Consider an ASP.NET endpoint that performs sensitive operations (for example, changing a user’s email or initiating a fund transfer) and validates an HMAC signature included in a header or query parameter. The server computes the expected HMAC using a shared secret and compares it with the value sent by the client. If the server also applies a same-origin policy based on the HTTP Referer or Origin header, DNS rebinding can undermine this defense. An attacker can craft a page on a domain like evil.com that first resolves to a trusted IP such as 203.0.113.10 (your application) and then switches to a private IP like 127.0.0.1 after the page loads. The browser will include cookies and other credentials for the trusted domain, while the malicious JavaScript can forward crafted requests to the same endpoint.

Because the request still appears to come from the trusted origin, the ASP.NET application may accept the HMAC signature as valid. The signature itself remains intact because the attacker can include the correct HMAC value obtained from a prior legitimate interaction or by leveraging a predictable nonce or timestamp. The key weakness is not the HMAC algorithm but the context in which the server evaluates the request. If the server treats the Origin or Referer header as an authorization signal rather than strictly validating the HMAC and the business intent of each operation, the rebinding can lead to unauthorized actions being executed on behalf of the authenticated user.

In some configurations, ASP.NET middleware may also use the host header or forwarded headers to make routing or policy decisions. An attacker can exploit DNS rebinding to send a request where the Host header points to an internal or trusted service while the HMAC is computed over a subset of the message that does not cover the effective target. This mismatch allows the request to pass HMAC verification while being processed by a component that the client should not interact with directly. The attack surface expands when the application exposes endpoints that perform sensitive operations with only HMAC validation and without additional context checks such as binding the token to a specific scope, audience, or session identifier.

To detect this class of issue during scanning, middleBrick checks whether endpoints that validate HMAC signatures also corroborate origin information with robust anti-rebinding measures. The tool examines whether the application binds cryptographic tokens to a verified source, uses strict referer or origin validation in combination with signature checks, and applies consistent host verification. These checks help identify whether an ASP.NET implementation correctly isolates HMAC verification from potentially malleable HTTP metadata that an attacker can influence through DNS rebinding.

Hmac Signatures-Specific Remediation in Aspnet — concrete code fixes

Defending against DNS rebinding when HMAC signatures are used requires ensuring that the integrity check is authoritative, context-bound, and not undermined by mutable request metadata. In ASP.NET, you should treat the HMAC as the primary authorization mechanism and avoid using headers such as Origin or Referer for security decisions unless they are cryptographically tied to the signature.

The following example demonstrates a secure pattern in ASP.NET Core. The HMAC is computed over a canonical representation of the payload, a timestamp, and a per-request nonce. The server verifies the signature and then enforces additional context checks, including host validation and anti-rebinding guards.

using System;
using System.Security.Cryptography;
using System.Text;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;

public class HmacValidationMiddleware
{
    private readonly RequestDelegate _next;
    private readonly byte[] _sharedSecret;

    public HmacValidationMiddleware(RequestDelegate next, IConfiguration config)
    {
        _next = next;
        _sharedSecret = Convert.FromBase64String(config["Hmac:SharedSecret"]);
    }

    public async Task InvokeAsync(HttpContext context)
    {
        if (context.Request.Headers.TryGetValue("X-Request-Hmac", out var receivedHmac))
        {
            var nonce = context.Request.Headers["X-Nonce"];
            var timestamp = context.Request.Headers["X-Timestamp"];
            var payload = await new StreamReader(context.Request.Body).ReadToEndAsync();

            // Reconstruct the body stream for downstream use
            var bodyBuffer = Encoding.UTF8.GetBytes(payload);
            context.Request.Body = new MemoryStream(bodyBuffer);

            var dataToSign = $"{timestamp}:{nonce}:{payload}";
            var computedHmac = ComputeHmac(dataToSign, _sharedSecret);

            if (!CryptographicOperations.FixedTimeEquals(computedHmac, Convert.FromBase64String(receivedHmac)))
            {
                context.Response.StatusCode = 401;
                await context.Response.WriteAsync("Invalid signature");
                return;
            }

            // Additional anti-rebinding and host validation
            if (!IsValidHost(context.Request.Host.Host))
            {
                context.Response.StatusCode = 403;
                await context.Response.WriteAsync("Forbidden host");
                return;
            }

            // Ensure the request is not replayed (basic timestamp check)
            if (!IsTimestampValid(timestamp))
            {
                context.Response.StatusCode = 400;
                await context.Response.WriteAsync("Stale request");
                return;
            }
        }
        else
        {
            context.Response.StatusCode = 400;
            await context.Response.WriteAsync("Missing Hmac header");
            return;
        }

        await _next(context);
    }

    private static Hmac ComputeHmac(string data, byte[] key)
    {
        using var hmac = new HMACSHA256(key);
        var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(data));
        return new Hmac { Signature = hash };
    }

    private bool IsValidHost(string host)
    {
        // Enforce an allowlist of expected hosts to prevent rebinding to internal targets
        var allowedHosts = new[] { "api.yourdomain.com", "app.yourdomain.com" };
        return allowedHosts.Contains(host, StringComparer.OrdinalIgnoreCase);
    }

    private bool IsTimestampValid(string timestamp)
    {
        if (long.TryParse(timestamp, out var ts) && DateTimeOffset.Try.FromUnixTimeSeconds(ts, out var requestTime))
        {
            var window = TimeSpan.FromMinutes(5);
            return Math.Abs(DateTimeOffset.UtcNow.Subtract(requestTime).TotalMinutes) <= window.TotalMinutes;
        }
        return false;
    }

    private class Hmac
    {
        public byte[] Signature { get; set; }
    }
}

In this pattern, the HMAC covers a composite that includes a timestamp and a nonce, which mitigates replay and rebinding attempts. The server performs a constant-time comparison to avoid timing attacks and validates the host against an allowlist, which is essential when DNS rebinding could redirect the request to an internal address.

Additionally, you should ensure that HMAC verification occurs before any business logic that might be influenced by mutable headers. In scenarios where you use forwarded headers (e.g., behind a proxy), explicitly configure ASP.NET to trust only known proxies and to recompute host validation based on the original host provided in the signed payload. This approach ensures that even if DNS rebinding alters the apparent destination, the request will fail either the HMAC check or the host validation, preventing unauthorized operations.

Frequently Asked Questions

Why does using HMAC signatures not fully prevent DNS rebinding in ASP.NET?
HMAC signatures ensure integrity and authenticity of the data, but if the server uses mutable HTTP metadata such as Origin, Referer, or Host headers for authorization decisions, an attacker can manipulate these headers via DNS rebinding. The signature remains valid, but the context in which the server interprets the request changes, allowing unauthorized actions. Therefore, HMAC must be paired with strict host validation and anti-rebinding checks.
How can I test my ASP.NET application for DNS rebinding with HMAC validation?
You can use the middleBrick CLI to scan your endpoint: middlebrick scan . The tool checks whether HMAC-protected endpoints also enforce host verification and whether they bind tokens to a specific source. Review the findings to ensure your ASP.NET implementation does not rely on mutable headers for security decisions and that cryptographic signatures cover all necessary context.