Mitigation of server-side request forgery (SSRF) attacks
using System;
using System.Net.Http;
using Microsoft.AspNetCore.Mvc;
namespace VulnerableApp.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class SSRFController : ControllerBase
{
[HttpGet]
public async Task Get(string url)
{
using (var httpClient = new HttpClient())
{
var response = await httpClient.GetAsync(url);
return await response.Content.ReadAsStringAsync();
}
}
}
}
The above code snippet represents a simple ASP.NET Core controller that accepts a URL as a parameter and makes a GET request to that URL. The response from this request is then returned to the client.
This is a classic example of a Server-Side Request Forgery (SSRF) vulnerability. An attacker can exploit this vulnerability by providing a URL that leads to an internal resource, which the server has access to but should not be exposed to the client. For example, an attacker could provide a URL to an internal service, a file on the server, or even cloud metadata services, causing the server to retrieve and return sensitive information.
The vulnerability lies in the
Get
method, which accepts any URL and makes a request to it without any validation or restriction. This means that an attacker can make the server perform requests to arbitrary domains, potentially leading to data exposure, service disruption, or other security issues.
using System;
using System.Net.Http;
using System.Text.RegularExpressions;
using Microsoft.AspNetCore.Mvc;
namespace VulnerableApp.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class SSRFController : ControllerBase
{
private static readonly Regex urlRegex = new Regex(@"^https?:\\/\\/(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{2,256}\\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*)$");
private static readonly HashSet whitelist = new HashSet { "trusteddomain1.com", "trusteddomain2.com" };
[HttpGet]
public async Task Get(string url)
{
if (string.IsNullOrEmpty(url) || !urlRegex.IsMatch(url) || !IsWhitelisted(url))
{
return "Invalid or untrusted URL";
}
using (var httpClient = new HttpClient())
{
var response = await httpClient.GetAsync(url);
return await response.Content.ReadAsStringAsync();
}
}
private bool IsWhitelisted(string url)
{
var uri = new Uri(url);
return whitelist.Contains(uri.Host);
}
}
}
The updated code includes several measures to mitigate the Server-side Request Forgery (SSRF) vulnerability:
1. Input Validation: The code checks if the 'url' parameter is null or empty. If it is, the function returns an error message.
2. URL Validation: The code uses a regular expression to validate the format and structure of the 'url' parameter. If the URL does not match the regular expression, the function returns an error message.
3. URL Filtering: The code checks if the domain of the 'url' parameter is in a whitelist of trusted domains. If it is not, the function returns an error message. This is done in the
IsWhitelisted
function, which extracts the host from the URL and checks if it is in the whitelist.
These measures ensure that the application only makes requests to valid and trusted URLs, preventing SSRF attacks.
Please note that this code does not include all the recommended measures, such as using a proxy server, implementing rate limiting, or providing training to developers. These measures should be implemented as part of the application's overall security strategy.