Overview
SSRF vulnerabilities in ASP.NET Core can enable attackers to coerce the server into making requests to internal or external resources based on untrusted input. The CVE-2017-0247 DoS issue demonstrates how misbehavior in the framework’s request/response handling can lead to excessive CPU and memory consumption when encoding inputs, which in turn degrades or denies service for legitimate clients. While CVE-2017-0247 is framed as a denial-of-service vulnerability in the encoding path, it affects components commonly involved in processing untrusted data that can participate in SSRF flows in real apps.
The vulnerability revolves around a bug in the TextEncoder.EncodeCore implementation within System.Text.Encodings.Web. It incorrectly calculates the length when handling 4-byte Unicode characters in the Non-Character range. This mismatch can cause the encoding routine to consume more resources than expected, enabling an attacker to trigger sustained processing by sending inputs that exercise these code paths. The affected versions were ASP.NET Core MVC prior to v1.0.4 and v1.1.x prior to v1.1.3; the patch fixes the length calculation to prevent this DoS.
Exploitation in practice can occur in APIs that take user-provided data intended for output encoding (e.g., in HTML, redirects, or SSRF request paths) and process it through the framework’s encoding routines. In an SSRF scenario, an attacker could craft inputs designed to trigger heavy encoding work or large response generation, exhausting server resources and affecting availability. The fix reduces this DoS surface by shipping updated encodings libraries and by encouraging safer request handling patterns in apps that forward user-controlled data to outgoing requests.
Remediation for SSRF-focused ASP.NET Core apps should combine the patch with defensive design: upgrade to patched libraries, validate and constrain downstream requests, and implement egress protections like allowlists and gateways. This reduces both the DoS risk from encoding paths and the broader SSRF risk from untrusted inputs being used to compose outbound requests.
Affected Versions
ASP.NET Core MVC 1.0.0 - 1.0.3; ASP.NET Core MVC 1.1.0 - 1.1.2
Code Fix Example
ASP.NET Core API Security Remediation
Vulnerable pattern:
using System.Net.Http;
using Microsoft.AspNetCore.Mvc;
public class UrlController : Controller {
[HttpGet("fetch")] public async Task<IActionResult> Fetch(string url) {
using (var http = new HttpClient()) {
var resp = await http.GetAsync(url); // SSRF risk: untrusted user input used directly
var content = await resp.Content.ReadAsStringAsync();
return Content(content, "text/html");
}
}
}
Fixed pattern:
using System;
using System.Collections.Generic;
using System.Net.Http;
using Microsoft.AspNetCore.Mvc;
public static class UrlWhitelist {
private static readonly HashSet<string> AllowedHosts = new HashSet<string> { "example.com", "api.example.org" };
public static bool TryValidate(string url) {
if (!Uri.TryCreate(url, UriKind.Absolute, out var uri)) return false;
if (uri.Scheme != Uri.UriSchemeHttp && uri.Scheme != Uri.UriSchemeHttps) return false;
return AllowedHosts.Contains(uri.Host);
}
}
public class UrlController : Controller {
private readonly IHttpClientFactory _clientFactory;
public UrlController(IHttpClientFactory clientFactory) { _clientFactory = clientFactory; }
[HttpGet("fetch")] public async Task<IActionResult> Fetch(string url) {
if (!UrlWhitelist.TryValidate(url)) return BadRequest("URL not allowed");
var client = _clientFactory.CreateClient("Filtered");
var resp = await client.GetAsync(url);
var content = await resp.Content.ReadAsStringAsync();
return Content(content, "text/html");
}
}