# OAuth redirect_uri validation bypass

redirect_uri trusted by raw string or unanchored regex instead of exact normalized origin match

_Area: Web authentication and account takeover. Seen in 3 disclosed reports; 2 confirmed bounties: $3,000 and $7,500; latest 2026-07-10. Updated 2026-10-24._

## How it works
An OAuth authorize or callback handler decides whether a `redirect_uri` is trusted by comparing the raw string — prefix, substring, or regex — instead of parsing the URL and comparing its normalized origin exactly. The assumption that "the string starts with / matches our host" equals "the URL points at our host" breaks: a crafted URL can satisfy the string check while its parsed host is attacker-controlled. Where tokens are appended to the redirect, they then go to the attacker [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-h29v-hj44-q8cv.md)[E4]; where only error paths redirect, the result is an open redirect without tokens [E3](https://bugbountylibrary.com/r/h1%3A26962.md).

## Where it shows up
- `redirect_uri` read and appended with token params without calling the origin validator [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-h29v-hj44-q8cv.md)
- Allowlist enforced by regex against `new URL(x).origin` where the regex is unanchored, so a path-embedded attacker host plus fragment still passes [E4]
- Error paths (invalid scope, etc.) that redirect to the registered `redirect_uri` pre-consent [E3](https://bugbountylibrary.com/r/h1%3A26962.md)
- Sibling handlers that consume `redirect_uri` but were omitted from a prior fix [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-h29v-hj44-q8cv.md)

## How to review
Parse the URI, extract the origin, and compare it exactly (scheme + host + port) against the registered value — never the raw string. The invariant: the redirect target's normalized origin must equal a registered origin, and no token may be emitted before that check passes. Enumerate every handler that reads `redirect_uri` and confirm each calls the same validator; diff against any prior patch for omissions [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-h29v-hj44-q8cv.md). For regex allowlists, confirm anchoring and that the host group cannot be satisfied by a path segment or fragment [E4].

## Variants seen
- Missing validator on one endpoint while siblings were patched [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-h29v-hj44-q8cv.md)
- Unanchored regex against `new URL(x).origin` fooled by a path-embedded attacker host plus fragment [E4]
- Spec-mandated error redirect acting as open redirect pre-consent, no tokens [E3](https://bugbountylibrary.com/r/h1%3A26962.md)

## Why fixes fail
E2 shows a partial fix: v2.0.1 added origin validation to several handlers but left `/authorize` unpatched, so the class survived. Fixes that patch one endpoint or one regex without auditing all consumers regress.

## Impact and severity
Leaked access, id and refresh tokens leading to account takeover [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-h29v-hj44-q8cv.md)[E4]; unauthenticated open redirect [E3](https://bugbountylibrary.com/r/h1%3A26962.md). High severity; worse when refresh tokens are exposed, giving durable access.

## Evidence
- E1: https://bugbountylibrary.com/r/blog%3Andevtk-github-io-writeups-2023-06-11-googlesource.md
- E2: https://bugbountylibrary.com/r/ghsa%3AGHSA-h29v-hj44-q8cv.md
- E3: https://bugbountylibrary.com/r/h1%3A26962.md
