WebDefect
VulnerabilitiesSeptember 29, 20269 min read

Open Redirect: How It Works, How It Is Detected, and How to Fix It

An open redirect allows an attacker to craft a URL on your domain that sends users to any external destination. The vulnerability is used in phishing, OAuth token theft, and SSRF chains. This article explains the mechanics, attack scenarios, URL validation patterns that fail, and correct remediation.

W
WebDefect(Security Research)
Published September 29, 2026

An open redirect is a vulnerability where an application accepts a user-controlled URL parameter and redirects the browser to that URL without sufficient validation. The application's own domain appears in the original URL, lending the redirect a degree of legitimacy that makes it useful in phishing attacks and as a component in more complex attack chains.

This article explains the attack scenarios that open redirects enable, the URL validation patterns that are commonly bypassed, and the correct approaches to redirect validation.

What an Open Redirect Is

Many web applications redirect users to a return URL after an action: after login, after a password reset, after a payment. The destination URL is often passed as a query parameter:

https://example.com/login?next=https://example.com/dashboard
https://example.com/logout?returnTo=/home
https://example.com/auth/callback?redirect_uri=https://app.example.com/

When the application validates the next or redirect_uri parameter insufficiently, an attacker can substitute an external URL:

https://example.com/login?next=https://evil.attacker.com/phishing

If the application redirects to the attacker's URL after a successful login, the user sees their browser navigate to a page on example.com, enter their credentials, and then be redirected to a site they did not expect to visit.

Attack Scenarios

Phishing via Trusted Domain

The primary use of open redirects is phishing. An attacker sends a link to https://example.com/login?next=https://attacker.com/fake-login. Email security tools, link preview systems, and user inspection of the URL bar may all indicate a safe link because the URL starts with https://example.com. After visiting the real site, the user is redirected to the attacker's page.

The redirect destination can be a credential harvesting page, a malware download page, or a lookalike version of the legitimate site. The initial trust established by the legitimate domain increases the probability that users proceed without suspicion.

OAuth Token Theft

OAuth 2.0 authorization codes and tokens are delivered via the redirect_uri parameter. If the authorization server uses an open redirect on the legitimate domain as a registered redirect URI, an attacker can manipulate the flow to have authorization tokens delivered to an attacker-controlled endpoint.

The attack works when: the authorization server validates that redirect_uri starts with the registered domain, but the open redirect on that domain then forwards the token-bearing request to an external URL. This is why OAuth specifications (RFC 6749) require exact matching of redirect URIs, not prefix matching.

SSRF Chain Enablement

Server-Side Request Forgery (SSRF) attacks sometimes require the vulnerable server to make requests to attacker-controlled external URLs. Some SSRF mitigations block external URLs but allow requests to the application's own domain. An open redirect on the trusted domain can be used to forward the server's request to the internal or external destination the attacker actually wants to reach.

URL Validation Failures That Allow Bypasses

Most open redirect vulnerabilities exist not because the developer added no validation, but because the validation implemented has bypass vectors.

Scheme and Double-Slash Confusion

Checking that a URL starts with / is meant to restrict redirects to relative paths. But URLs starting with // are protocol-relative and resolve to the scheme of the current page, then navigate to the specified host:

// Vulnerable: only checks for leading slash
if (redirectUrl.startsWith('/')) {
  res.redirect(redirectUrl);
}

// Bypass: //attacker.com resolves to https://attacker.com
/login?next=//attacker.com/phishing

Similarly, URL parsers may interpret unusual sequences differently from simple string checks:

// These may pass a simple "no external URL" check:
///attacker.com
/\/attacker.com      // backslash treated as slash in some parsers
/%09/attacker.com    // tab character between slashes
//%09attacker.com

Domain Check Bypasses

Checking that the URL contains or starts with the trusted domain is insufficient:

// Vulnerable: checks that URL includes the trusted domain
if (redirectUrl.includes('example.com')) {
  res.redirect(redirectUrl);
}

// Bypass: https://attacker.com?ref=example.com
// or:     https://example.com.attacker.com

// Vulnerable: prefix check
if (redirectUrl.startsWith('https://example.com')) {
  res.redirect(redirectUrl);
}
// Bypass: https://example.com.attacker.com

Correct URL Validation

The Allowlist Approach

The most robust approach is an explicit allowlist of permitted redirect destinations. For applications where users may only be redirected to a known set of internal paths or partner domains, enumerate those destinations and reject anything else:

const ALLOWED_REDIRECT_ORIGINS = new Set([
  'https://app.example.com',
  'https://dashboard.example.com',
]);

function isSafeRedirect(url: string): boolean {
  try {
    const parsed = new URL(url, 'https://example.com');
    // For absolute URLs, check against allowlist
    if (parsed.hostname !== 'example.com' &&
        !parsed.hostname.endsWith('.example.com')) {
      return false;
    }
    // Reject URLs with unexpected schemes
    if (parsed.protocol !== 'https:') return false;
    return true;
  } catch {
    return false;
  }
}

Restricting to Relative URLs

If the application only needs to redirect within its own origin, restrict to path-only relative URLs. Parse the input with the URL constructor and verify it has no host component:

function isSafeRelativeRedirect(input: string): boolean {
  // Parse as relative URL against a base — if it resolves to a different origin, reject
  try {
    const base = 'https://example.com';
    const parsed = new URL(input, base);
    // Reject if the resolved URL leaves the expected origin
    if (parsed.origin !== base) return false;
    // Reject protocol-relative URLs (double slash)
    if (input.startsWith('//') || input.startsWith('\/')) return false;
    return true;
  } catch {
    return false;
  }
}

// Fallback: if validation fails, redirect to a safe default
const target = isSafeRelativeRedirect(requestedUrl) ? requestedUrl : '/dashboard';
res.redirect(target);

Always provide a safe default redirect destination that is used when the requested URL fails validation, rather than returning an error that might expose the redirect logic.

How WebDefect Detects Open Redirects

WebDefect checks for open redirect vulnerabilities by inspecting URL parameters discovered during the crawl phase and testing common redirect parameter names with controlled values. The check (redir-002) works as follows:

  • The crawler identifies URL parameters with names commonly used for redirect destinations:next, redirect, returnTo, return, url, goto, destination, target, and similar.
  • The scanner replaces the parameter value with a known safe external URL from an infrastructure controlled by WebDefect, then follows the redirect chain and checks whether the final destination is the injected URL.
  • If the application redirects to the injected URL without modification, the finding is reported as confirmed open redirect, medium severity.
  • The finding includes the vulnerable parameter name, the original URL, and the redirect destination that was followed.

Because the check is passive and non-destructive (the injected URL is infrastructure under WebDefect's control, not a third-party attacker domain), the test does not create any real risk to the scanned application.

References

Research Topics & Taxonomy

#open-redirect#url-validation#phishing#oauth#ssrf
Automated Vulnerability Detection

Audit your perimeter for these security conditions

WebDefect automatically analyzes your target domain across TLS 1.3, CSP Level 3, security headers, CORS, and DNS with raw evidence and remediation instructions.

Run Free Scan →