C# ASP.NET Open Redirect from Query Parameter

Medium Risk Web Security
csharpaspnetopen-redirectphishingsocial-engineeringurl-validationmvcweb-securitysemgrep

What it is

A critical security vulnerability where ASP.NET applications use user-controlled URL parameters in redirect operations without proper validation. This allows attackers to redirect users to malicious external domains, enabling phishing attacks, credential theft, session token leakage, and loss of user trust. Open redirects are commonly exploited in social engineering attacks and can bypass security awareness training.

// VULNERABLE: Direct redirect without validation
using Microsoft.AspNetCore.Mvc;

public class AccountController : Controller
{
    // SECURITY ISSUE: User-controlled redirect URL
    public IActionResult Login(string returnUrl)
    {
        // Vulnerable: Direct redirect to user-provided URL
        // Allows redirects to external malicious sites
        if (!string.IsNullOrEmpty(returnUrl))
        {
            return Redirect(returnUrl);  // VULNERABLE
        }
        
        return View();
    }
    
    // VULNERABLE: Logout with unvalidated redirect
    public IActionResult Logout(string redirectTo)
    {
        // Clear authentication
        HttpContext.SignOutAsync();
        
        // SECURITY ISSUE: No validation of redirect target
        if (!string.IsNullOrEmpty(redirectTo))
        {
            return Redirect(redirectTo);  // VULNERABLE
        }
        
        return RedirectToAction("Index", "Home");
    }
    
    // VULNERABLE: External link handler
    public IActionResult GoToExternal(string url)
    {
        // SECURITY ISSUE: Allows any external URL
        // Could be used for phishing attacks
        return Redirect(url);  // VULNERABLE
    }
    
    // VULNERABLE: Weak validation attempt
    public IActionResult WeakValidation(string returnUrl)
    {
        // SECURITY ISSUE: Inadequate validation
        // Can be bypassed with URLs like "http://evil.com@legitimate.com"
        if (returnUrl != null && returnUrl.Contains("mysite.com"))
        {
            return Redirect(returnUrl);  // STILL VULNERABLE
        }
        
        return RedirectToAction("Index", "Home");
    }
}
// SECURE: Proper redirect validation
using Microsoft.AspNetCore.Mvc;

public class SecureAccountController : Controller
{
    // SECURE: Local URL validation
    public IActionResult Login(string returnUrl)
    {
        // Validate that return URL is local to prevent open redirects
        if (!string.IsNullOrEmpty(returnUrl) && Url.IsLocalUrl(returnUrl))
        {
            return Redirect(returnUrl);  // SECURE: Only local URLs
        }
        
        // Default fallback for invalid URLs
        return RedirectToAction("Dashboard", "Home");
    }
    
    // SECURE: Logout with safe redirect
    public IActionResult Logout(string redirectTo)
    {
        // Clear authentication
        HttpContext.SignOutAsync();
        
        // Validate redirect URL is local
        if (!string.IsNullOrEmpty(redirectTo) && Url.IsLocalUrl(redirectTo))
        {
            return Redirect(redirectTo);
        }
        
        return RedirectToAction("Index", "Home");
    }
    
    // SECURE: External link with validation
    public IActionResult GoToExternal(string url)
    {
        // Only allow local URLs to prevent open redirects
        if (!string.IsNullOrEmpty(url) && Url.IsLocalUrl(url))
        {
            return Redirect(url);
        }
        
        // Reject external URLs
        return RedirectToAction("Index", "Home");
    }
    
    // SECURE: Proper validation instead of weak checks
    public IActionResult StrongValidation(string returnUrl)
    {
        // Use built-in security helper
        if (returnUrl != null && Url.IsLocalUrl(returnUrl))
        {
            return Redirect(returnUrl);  // SECURE
        }
        
        return RedirectToAction("Index", "Home");
    }
}

💡 Why This Fix Works

The vulnerable examples show direct redirect usage without validation, allowing attackers to redirect users to malicious sites. The secure implementations use Url.IsLocalUrl(), domain allowlists, and indirect mapping to prevent open redirect attacks while maintaining legitimate functionality.

Why it happens

ASP.NET controllers use query parameters directly in Redirect() calls without validating that the target URL is safe and local. This commonly occurs in authentication flows, logout pages, and navigation helpers where developers assume user-provided URLs are trustworthy or when implementing 'return URL' functionality without proper security controls.

Root causes

Unvalidated Query Parameter Redirects

ASP.NET controllers use query parameters directly in Redirect() calls without validating that the target URL is safe and local. This commonly occurs in authentication flows, logout pages, and navigation helpers where developers assume user-provided URLs are trustworthy or when implementing 'return URL' functionality without proper security controls.

Missing URL Validation Logic

Applications implement redirect functionality without using ASP.NET's built-in security methods like Url.IsLocalUrl(). This happens when developers are unaware of these security helpers or when implementing custom redirect logic without understanding the security implications of unrestricted redirects to external domains.

Inadequate Allowlist Implementation

Teams attempt to validate redirect URLs but implement inadequate checks that can be bypassed. This includes substring matching, incomplete domain validation, or regex patterns that don't account for URL encoding, protocol variations, or subdomain attacks. Proper URL allowlisting requires comprehensive validation logic.

Fixes

1

Use Url.IsLocalUrl() Validation

Always validate redirect URLs using ASP.NET's Url.IsLocalUrl() method before performing redirects. This built-in security helper ensures that redirects only go to local paths within the same application, preventing external redirects while maintaining functionality for legitimate internal navigation.

2

Implement Domain Allowlist

For applications that require external redirects, implement a strict allowlist of approved domains. Use Uri parsing to validate the scheme, host, and path components, and ensure the allowlist cannot be bypassed through encoding, protocol variations, or subdomain attacks. Regularly review and maintain the allowlist.

3

Use Indirect Redirect Mapping

Instead of accepting arbitrary URLs, use an indirect mapping system where query parameters reference predefined redirect targets. Store approved redirect URLs in configuration or a database, and use identifiers or keys to select the appropriate destination, eliminating the possibility of arbitrary external redirects.

Detect This Vulnerability in Your Code

Sourcery automatically identifies c# asp.net open redirect from query parameter and many other security issues in your codebase.