How to fix SSRF (Server Side Request Forgery)
in ASP.NET Core
Executive Summary
SSRF in ASP.NET Core is the ultimate pivot. It occurs when your backend acts as a blind proxy, fetching attacker-controlled URLs. This allows unauthorized access to internal metadata services (like AWS 169.254.169.254), local services, or internal network segments that should be isolated. If you're passing a raw string from a query param into HttpClient, you're pwned.
The Vulnerable Pattern
[HttpGet("fetch")]
public async Task FetchRemote(string url)
{
using var client = new HttpClient();
// VULNERABLE: No validation on the URL. Attacker can pass http://localhost:5000/admin or metadata endpoints.
var response = await client.GetAsync(url);
var content = await response.Content.ReadAsByteArrayAsync();
return File(content, "image/jpeg");
}
The Secure Implementation
To kill SSRF, you need a multi-layered defense. First, enforce HTTPS to prevent protocol smuggling (like gopher:// or file://). Second, implement a strict Host Allowlist; never let the user determine the destination unless it is against a pre-defined set of domains. Third, perform manual DNS resolution and verify the IP isn't in a private range (RFC1918) to prevent DNS Rebinding attacks where a domain switches from a safe IP to a local one after the initial check.
[HttpGet("fetch")] public async TaskFetchRemote(string url) { if (!Uri.TryCreate(url, UriKind.Absolute, out var uri) || uri.Scheme != Uri.UriSchemeHttps) return BadRequest("Invalid protocol. HTTPS only."); // 1. Strict Allowlist var allowedHosts = new[] { "cdn.trusted.com", "api.partner.com" }; if (!allowedHosts.Contains(uri.Host.ToLower())) return BadRequest("Host not authorized."); // 2. Prevent DNS Rebinding & Internal IP Access var hostEntries = await Dns.GetHostAddressesAsync(uri.Host); foreach (var ip in hostEntries) { if (IsInternal(ip)) return BadRequest("Access to internal network is forbidden."); } var client = _httpClientFactory.CreateClient(); var response = await client.GetAsync(uri); return File(await response.Content.ReadAsByteArrayAsync(), "image/jpeg");}
private bool IsInternal(IPAddress ip) { if (IPAddress.IsLoopback(ip)) return true; byte[] bytes = ip.GetAddressBytes(); switch (bytes[0]) { case 10: return true; case 172: return bytes[1] >= 16 && bytes[1] <= 31; case 192: return bytes[1] == 168; default: return false; } }
Your ASP.NET Core API
might be exposed to SSRF (Server Side Request Forgery)
74% of ASP.NET Core apps fail this check. Hackers use automated scanners to find this specific flaw. Check your codebase before they do.
Free Tier • No Credit Card • Instant Report
Verified by Ghost Labs Security Team
This content is continuously validated by our automated security engine and reviewed by our research team. Ghost Labs analyzes over 500+ vulnerability patterns across 40+ frameworks to provide up-to-date remediation strategies.