Skip to content

CWE-601: URL Redirection to Untrusted Site (Open Redirect)

Overview

Open redirect vulnerabilities occur when an application accepts user-controllable input and uses it to redirect users to other websites without proper validation. Attackers exploit this by crafting malicious links that appear to come from trusted domains but redirect victims to attacker-controlled sites.

Example: User clicks https://trusted-site.com/login?redirect=http://evil-site.com and the application redirects to the attacker-controlled evil-site.com.

OWASP Classification

A01:2025 - Broken Access Control

Risk

Open redirect vulnerabilities enable various attacks:

  • Phishing attacks: Users trust the initial domain, click the link, and end up on a fake login page
  • Credential theft: Fake pages that mimic the trusted site to steal credentials
  • Malware distribution: Redirect to drive-by-download sites distributing malware
  • OAuth token theft: Intercept authorization codes or access tokens in OAuth flows
  • XSS bypass: Chain with XSS via javascript: or data: URL schemes
  • Business reputation damage: Trusted domain used to distribute spam or malicious content
  • SEO poisoning: Manipulate search rankings by abusing trusted domains

The impact is magnified because users see and trust the original domain in the link, lowering their guard.

Common Attack Vectors and Vulnerable Patterns

Attackers leverage open redirects to:

  • Bypass URL filters and spam blockers
  • Conduct phishing attacks that appear to originate from trusted domains
  • Steal credentials via fake login pages
  • Distribute malware from seemingly trusted sources
  • Bypass content security policies in some contexts

Open redirects are commonly found in:

  • Post-login redirect parameters (?next=, ?returnUrl=, ?redirect=)
  • Logout handlers that redirect to confirmation pages
  • OAuth/SAML flows with redirect parameters
  • Payment or checkout flows with "continue" URLs

Remediation Steps

Core principle: Never allow untrusted input to control navigation or redirect targets; all redirect destinations must be server-defined or selected from a strict allowlist.

Locate the open redirect vulnerability

  • Review the security findings to identify the specific file, line number, and redirect operation
  • Identify all parameters that control redirect destinations (?next=, ?redirect=, ?returnUrl=, ?continue=)
  • Trace how untrusted data (user input, external files, databases, network requests) flows to the redirect
  • Locate the code that performs redirects (Response.Redirect(), redirect(), header("Location:"), sendRedirect())
  • Check if the redirect destination is validated before use
  • Map all redirect endpoints and their input sources

Use allowlist of permitted redirect destinations (Primary Defense)

  • Define explicit allowlist: Specify permitted redirect URLs or paths in configuration
  • For internal redirects, allowlist relative paths only: /dashboard, /profile, /settings
  • For external redirects, allowlist specific full URLs: https://trusted-partner.com/callback
  • Store allowlist in configuration files: Never in untrusted data
  • Validate redirect parameter against allowlist: Check BEFORE redirecting
  • Use exact string matching or strict prefix matching: Not substring or regex that can be bypassed
  • Reject any redirect not in allowlist: Show error or use default redirect
  • Normalize URLs before comparison: Handle //, %2f encoding to prevent bypass
  • Why this works:
    • Allowlist enforcement prevents unauthorized redirects: Only pre-approved destinations can be accessed
    • Attackers cannot manipulate destination: Input validation rejects any URL not explicitly permitted

Eliminate direct use of untrusted data in redirects

  • Replace URL parameters with opaque identifiers: Use numeric IDs, tokens instead of URLs
  • Map identifiers to actual redirect URLs server-side: 1 → /dashboard, 2 → /profile
  • Accept only the identifier in redirect parameter: ?next=2
  • Look up actual URL from server-side mapping: User cannot specify arbitrary URLs
  • Redirect to the mapped URL: This prevents arbitrary destination specification
  • Benefits: Simple to validate (must be valid ID), easy to maintain and audit

Add strict URL validation if direct URLs are required (Defense in Depth)

  • Parse redirect URLs using proper URL parsing library: Not regex
  • Validate scheme is http:// or https:// only: Block javascript:, data:, file:
  • Verify domain exactly matches allowed domain: Prevent subdomain attacks
  • Reject URLs containing @ symbols: Bypass technique user@attacker.com:password@trusted.com
  • Normalize URLs before validation: Resolve ../, //, %00, URL encoding
  • Ensure exact domain matching: Not substring (evil.trusted.com or trusted.com.evil.com)
  • Perform validation server-side only: Never trust client-side validation

Use redirect confirmation for external destinations

  • For any redirect to external domains: Show an interstitial warning page
  • Display full destination URL to user: Not shortened or encoded
  • Require explicit user action to continue: Button click, not automatic redirect
  • Add rel="noopener noreferrer" to external links: Prevent window.opener exploitation
  • Log all external redirects: Security monitoring and abuse detection
  • Consider CAPTCHA for high-risk external redirects: Prevent automated abuse

Test and verify open redirect protection thoroughly

  • Test that only allowlisted destinations work
  • Test bypass attempts: //evil.com, /\\evil.com, https://evil.com@trusted.com
  • Test subdomain bypass: https://trusted.com.evil.com
  • Test protocol-relative URLs: //attacker.com
  • Test dangerous schemes: javascript:alert(1), data:text/html,<script>alert(1)</script>
  • Test URL encoding bypasses: %68%74%74%70%3a%2f%2fevil.com
  • Test double encoding: %2568%2574%2574%2570
  • Test path traversal in redirects: https://trusted.com/../attacker.com
  • Verify legitimate redirects to allowed destinations still work
  • Re-scan with the security scanner to confirm the issue is resolved
  • Check for any new findings introduced by the changes

Language-Specific Guidance

  • Python - Flask, Django, FastAPI - urlparse validation and allowlisting
  • Java - Servlets, Spring MVC, Jakarta EE - URI validation and redirect protection
  • JavaScript/Node.js - Express, Koa - URL parser validation and same-origin checks
  • C# - ASP.NET Core, MVC - Url.IsLocalUrl() and allowlist validation
  • PHP - Laravel, Symfony - parse_url validation and header redirects

Dynamic Scan Guidance

For guidance on remediating this CWE when detected by dynamic (DAST) scanners:

Additional Resources