# OAuth redirect URI validation bypass

Redirect target checked as raw string or on error paths, so codes leak to attacker-controlled URLs

_Area: Web authentication and account takeover. Seen in 3 disclosed reports; 3 confirmed bounties, median $1,000, range $400-$7,000; latest 2021-01-12. Updated 2026-10-23._

## How it works

An OAuth/SSO flow trusts that the redirect target is the client's own page. The check runs on the raw string (prefix match, origin regex, leading-slash test) before the browser normalizes it, or it runs only on the success path. The browser then parses `\`, `../`, or merges fragment/query differently than the validator, so the code or token lands somewhere the attacker controls or can read. The broken assumption: "the string I validated is the URL the browser will navigate to, and only on the paths I checked."

## Where it shows up

- Redirect/`.done` params validated by prefix or leading-slash only [E2](https://bugbountylibrary.com/r/blog%3Amishresec-wordpress-com-2017-10-13-yahoo-bug-bounty-chaining-3-minor-issues-to-takeover-flickr-accounts.md)
- Redirect handlers that concatenate user-controlled origin/baseUrl and check only an origin regex [E3](https://bugbountylibrary.com/r/h1%3A835437.md)
- Redirect handler merging `location.hash` and `location.search` into one param object [E3](https://bugbountylibrary.com/r/h1%3A835437.md)
- IdP app permitting response_type/response_mode combos the client doesn't use (fragment vs web_message) [E1](https://bugbountylibrary.com/r/h1%3A1567186.md)
- Tokens or codes placed in URL query/fragment on pages that load attacker-controlled subresources or scripts without CSP [E2](https://bugbountylibrary.com/r/blog%3Amishresec-wordpress-com-2017-10-13-yahoo-bug-bounty-chaining-3-minor-issues-to-takeover-flickr-accounts.md)[E4](https://bugbountylibrary.com/r/blog%3Aseekurity-com-blog-general-lets-steal-some-tokens.md)
- Error paths on `/authorize` that redirect to the supplied redirect_uri before rejecting the request [E5](https://bugbountylibrary.com/r/h1%3A3930.md)
- Adjacent: desktop/Electron allowlists that trust "same origin = safe" and case-sensitive scheme checks [E4](https://bugbountylibrary.com/r/blog%3Aseekurity-com-blog-general-lets-steal-some-tokens.md)

## How to review

Check the exact invariant: the validated URL must equal the URL the browser navigates to after normalization, and the destination must be an exact registered URI, not a prefix or origin. Verify:
- Comparison is on a parsed/normalized URL, not a raw string; backslash, case, `..`, and encoding are resolved before the check.
- Redirect targets are exact-match allowlisted, not prefix or regex-origin [E2](https://bugbountylibrary.com/r/blog%3Amishresec-wordpress-com-2017-10-13-yahoo-bug-bounty-chaining-3-minor-issues-to-takeover-flickr-accounts.md)[E3](https://bugbountylibrary.com/r/h1%3A835437.md).
- Error branches reject without redirecting to the supplied redirect_uri [E5](https://bugbountylibrary.com/r/h1%3A3930.md).
- No token/code appears in a URL that any same-origin page can cause to be fetched as a subresource; CSP present on those pages [E2](https://bugbountylibrary.com/r/blog%3Amishresec-wordpress-com-2017-10-13-yahoo-bug-bounty-chaining-3-minor-issues-to-takeover-flickr-accounts.md)[E4](https://bugbountylibrary.com/r/blog%3Aseekurity-com-blog-general-lets-steal-some-tokens.md).
- The IdP app restricts response_type/response_mode to what the client actually uses [E1](https://bugbountylibrary.com/r/h1%3A1567186.md).

## Variants seen

- Prefix-validated `.done` param plus `../` traversal to a token-leaking page [E2](https://bugbountylibrary.com/r/blog%3Amishresec-wordpress-com-2017-10-13-yahoo-bug-bounty-chaining-3-minor-issues-to-takeover-flickr-accounts.md)
- Origin-regex redirect handler merging hash into query, smuggling access_token [E3](https://bugbountylibrary.com/r/h1%3A835437.md)
- Unvalidated redirect_uri path plus referer leak via analytics/script field [E4](https://bugbountylibrary.com/r/blog%3Aseekurity-com-blog-general-lets-steal-some-tokens.md)
- Error-path redirect to supplied redirect_uri acting as open redirect [E5](https://bugbountylibrary.com/r/h1%3A3930.md)
- IdP response_mode/response_type switch leaking code via window.name [E1](https://bugbountylibrary.com/r/h1%3A1567186.md)
- Adjacent: case-sensitive scheme check causing redirect to raw URL in an Electron window [E4](https://bugbountylibrary.com/r/blog%3Aseekurity-com-blog-general-lets-steal-some-tokens.md)

## Impact and severity

Account takeover where codes/tokens are stolen [E1](https://bugbountylibrary.com/r/h1%3A1567186.md)[E2](https://bugbountylibrary.com/r/blog%3Amishresec-wordpress-com-2017-10-13-yahoo-bug-bounty-chaining-3-minor-issues-to-takeover-flickr-accounts.md)[E3](https://bugbountylibrary.com/r/h1%3A835437.md)[E4](https://bugbountylibrary.com/r/blog%3Aseekurity-com-blog-general-lets-steal-some-tokens.md). Severity is high because the leak needs little victim interaction beyond a crafted link, and worsens when tokens sit in URLs on CSP-less pages or when a second open redirect completes the chain [E2](https://bugbountylibrary.com/r/blog%3Amishresec-wordpress-com-2017-10-13-yahoo-bug-bounty-chaining-3-minor-issues-to-takeover-flickr-accounts.md)[E3](https://bugbountylibrary.com/r/h1%3A835437.md). E5 alone is an open redirect, not token theft; it matters as a chaining primitive.

## Evidence
- E1: https://bugbountylibrary.com/r/h1%3A1567186.md
- E2: https://bugbountylibrary.com/r/blog%3Amishresec-wordpress-com-2017-10-13-yahoo-bug-bounty-chaining-3-minor-issues-to-takeover-flickr-accounts.md
- E3: https://bugbountylibrary.com/r/h1%3A835437.md
- E4: https://bugbountylibrary.com/r/blog%3Aseekurity-com-blog-general-lets-steal-some-tokens.md
- E5: https://bugbountylibrary.com/r/h1%3A3930.md
