Uncontrolled external site redirect
Need
Controlled and secure external site redirection
Context
- Usage of C# for building robust and scalable applications
- Usage of Microsoft.AspNetCore.Mvc for building web applications with ASP.NET Core
Description
Non compliant code
public class RedirectController : Controller
{
public IActionResult Index(string url)
{
return Redirect(url);
}
}
The code above represents a Controller in an ASP.NET Core application that handles HTTP requests. The Index
method in this controller accepts a string parameter url
from the incoming request and uses it to perform a redirect operation.
The vulnerability lies in the fact that the application does not control or validate the url
parameter before using it in the Redirect
method. This means that an attacker could potentially manipulate the url
parameter to redirect users to a malicious external site. This is known as an Uncontrolled External Site Redirect vulnerability.
For instance, an attacker could craft a URL such as http://example.com/Redirect/Index?url=http://malicious-website.com
. If a user clicks on this link, they would be redirected to the malicious website.
This vulnerability could be exploited to perform phishing attacks, steal sensitive user information, or distribute malware, among other malicious activities. Therefore, it is crucial to validate and control redirects in your application to prevent such attacks.
Steps
- Validate and sanitize the input URL to ensure it is a trusted and valid URL.
- Implement a whitelist of allowed redirect URLs to restrict the redirection to trusted domains.
- Use a built-in redirect method provided by the framework instead of directly returning a redirect response.
- Consider implementing a confirmation step before performing the redirect to prevent automatic redirects without user consent.
- Implement proper error handling and logging to detect and mitigate any potential abuse of the redirect functionality.
Compliant code
public class RedirectController : Controller
{
private readonly List<string> _trustedDomains = new List<string> { "www.trusteddomain1.com", "www.trusteddomain2.com" };
public IActionResult Index(string url)
{
if (string.IsNullOrEmpty(url) || !IsUrlValidAndTrusted(url))
{
// Log the error, handle the error or return an error response
return BadRequest("Invalid or untrusted redirect URL");
}
return Redirect(url);
}
private bool IsUrlValidAndTrusted(string url)
{
Uri uriResult;
bool isValidUrl = Uri.TryCreate(url, UriKind.Absolute, out uriResult)
&& (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps);
if (!isValidUrl)
{
return false;
}
return _trustedDomains.Contains(uriResult.Host);
}
}
The updated code includes a method IsUrlValidAndTrusted
that validates the input URL. This method checks if the URL is a valid absolute URL and if the domain of the URL is in the list of trusted domains (_trustedDomains
).
The Index
method now uses this validation method to check the input URL before performing the redirect. If the URL is not valid or not trusted, the method returns a bad request response. This prevents uncontrolled external site redirects as the application now only redirects to URLs that are valid and trusted.
This solution mitigates the risk of an attacker manipulating the application's redirects. It also provides a way to detect and handle attempts to abuse the redirect functionality, as such attempts would result in a bad request response.
Remember to keep the list of trusted domains updated and as restrictive as possible to minimize the risk of redirects to malicious sites.
Also, consider implementing additional security measures, such as a user confirmation step before performing the redirect and proper logging of all redirect requests.