Ssrf Server Side in Aspnet with Hmac Signatures
Ssrf Server Side in Aspnet with Hmac Signatures — how this specific combination creates or exposes the vulnerability
Server-side request forgery (SSRF) in ASP.NET can be influenced by how an application uses HMAC signatures to protect request parameters. A common pattern is for the client to compute a signature over a set of query parameters or headers and send it in a header, for example X-API-Signature. The server then recomputes the signature using a shared secret and verifies it before processing the request. If the server uses the same secret and a permissive verification logic to decide whether to make an outgoing HTTP call — and that call is based on user-supplied input such as a target URL — the signature mechanism can inadvertently facilitate SSRF.
Consider an endpoint that accepts a fileId and a signature. The server validates the HMAC to ensure integrity, then internally fetches a resource from a backend service using a constructed URL derived from fileId. An attacker can supply a malicious fileId that points to an internal service, such as http://169.254.169.254/latest/meta-data/, and if the server follows the signature verification with an unvalidated redirect or internal resolution, the HMAC check may pass while the request reaches a sensitive internal endpoint. This happens because the signature authenticates the parameters but does not constrain the runtime target of the outbound call, allowing the server to be used as a proxy to internal resources.
In ASP.NET, this often manifests when developers use HttpClient to perform requests based on parameters that were authenticated with HMAC but not further validated for reachability or network scope. The signature ensures the parameters have not been tampered with, yet it does not prevent the server from contacting unintended hosts or ports. Attackers can leverage this to probe internal networks, reach metadata services, or interact with internal APIs that are not exposed publicly. The risk is compounded when the server performs redirects or uses libraries that follow location headers automatically, allowing SSRF to occur despite the presence of HMAC integrity checks.
Middleware or services that parse and forward requests after signature validation must treat the target of the outbound call as hostile. Even when the signature is valid, the resolved URL, headers, and network path must be constrained by a strict allowlist or network policy. Otherwise, the combination of HMAC-based integrity and unchecked outbound resolution creates a bypass where SSRF can be achieved under the guise of authenticated requests.
Hmac Signatures-Specific Remediation in Aspnet — concrete code fixes
To mitigate SSRF when using HMAC signatures in ASP.NET, ensure that the target of any outbound request is validated independently of the signature verification. Do not derive or redirect network calls based on parameters authenticated only by HMAC. Instead, maintain a strict mapping between allowed resource identifiers and their permissible destinations, and enforce network-level restrictions such as firewall rules or container network policies.
The following code example demonstrates a secure approach in an ASP.NET minimal API. The server computes a signature over selected parameters and verifies it before proceeding. Crucially, the target endpoint for any outbound call is taken from a preconfigured allowlist and not derived from user input, preventing SSRF while still using HMAC to protect parameter integrity.
using System.Security.Cryptography;
using System.Text;
using Microsoft.AspNetCore.Mvc;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpClient();
var app = builder.Build();
app.MapGet("/resource", (string fileId, string signature, [FromHeader] string xApiSignature, HttpClient httpClient) =>
{
const string sharedSecret = "super-secret-shared-key";
var computed = ComputeHmac(fileId, sharedSecret);
if (!CryptographicOperations.FixedTimeEquals(Encoding.UTF8.GetBytes(computed), Encoding.UTF8.GetBytes(signature)))
{
return Results.Unauthorized();
}
// Allowlist mapping: only known safe resources can be fetched
var allowedEndpoints = new Dictionary<string, string>
{
["file-123"] = "https://internal-backend.example.com/files/123",
["file-abc"] = "https://internal-backend.example.com/files/abc"
};
if (!allowedEndpoints.TryGetValue(fileId, out var targetUrl))
{
return Results.BadRequest("Invalid resource");
}
var response = await httpClient.GetAsync(targetUrl);
response.EnsureSuccessStatusCode();
var content = await response.Content.ReadAsStringAsync();
return Results.Ok(content);
});
static string ComputeHmac(string data, string key)
{
using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(key));
var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(data));
return Convert.ToBase64String(hash);
}
In this example, the HMAC signature protects the integrity of fileId, but the outbound URL is resolved from an allowlist rather than from user input. This prevents SSRF because an attacker cannot redirect the request to arbitrary internal addresses such as metadata services. Additionally, prefer using typed clients and configure HttpClient with appropriate timeouts and network policies to further reduce risk.
For more complex scenarios, validate outbound destinations against a network zone policy and avoid following redirects from user-influenced requests. Combine HMAC-based parameter integrity with these destination controls to achieve defense-in-depth against SSRF in ASP.NET applications.