Last updated: April 26, 2026
OAuth 2.0 is the de-facto authorisation framework for modern web and mobile applications. Implemented well, it provides delegated access without exposing credentials. Implemented carelessly — and most implementations are careless on at least one detail — OAuth turns into account-takeover primitives. This article covers the modern OAuth attack surface in 2026: redirect URI manipulation, authorisation code injection, state parameter abuse, PKCE downgrade, JWT-as-access-token issues, and the proven defences.
The OAuth flow recap
Standard authorisation code flow:
- Client redirects user to authorisation server (Google, GitHub, Auth0, Okta).
- User authenticates and consents.
- Authorisation server redirects back to client with an authorisation code.
- Client exchanges the code (server-to-server) for an access token.
- Access token used to call protected APIs.
Each step has attack surface.
Attack 1: Redirect URI manipulation
The authorisation server returns the code by redirecting to a URI. Most implementations accept a list of registered redirect URIs and require an exact match. Common errors:
- Wildcard or partial-match validation —
https://*.example.com/cbregistered, attacker useshttps://attacker.example.com/cb - Path traversal in URI —
https://example.com/../attacker/cbbypasses path validation - Open redirect chained — registered URI is a page with open-redirect parameter; attacker chains
- Subdomain takeover — registered URI is on a subdomain that has been abandoned
If the attacker can redirect the code to their server, they exchange it for the token = full account takeover.
Attack 2: Authorization code injection
Recent class of attack (CVE-2023-X disclosures): the attacker initiates an OAuth flow, captures the code, then injects it into the victim’s session — victim’s client exchanges the code, gets a token bound to attacker’s identity, and the victim is now logged into attacker’s account (or vice-versa, depending on flow direction).
Mitigation: PKCE (Proof Key for Code Exchange) — client generates a code_verifier, sends code_challenge with auth request, then sends code_verifier with token exchange. Without the original code_verifier, the code is useless to anyone else.
Attack 3: State parameter omission / replay
The state parameter is the OAuth CSRF token. If the client doesn’t generate or verify it, an attacker can:
- Initiate an OAuth flow against the target client
- Get the code redirected to victim’s session via crafted link
- Victim’s client accepts the code, exchanges, logs victim into attacker’s account
Also called Login CSRF. Mitigation: cryptographically-random state parameter, bound to user’s session, verified on callback.
Attack 4: PKCE downgrade
PKCE was originally for public clients (mobile apps); confidential clients (server-side) historically didn’t use it. If the auth server supports both PKCE and non-PKCE for the same client, an attacker can force the non-PKCE path and bypass code-injection protection.
Mitigation: enforce PKCE for all clients, even confidential ones (RFC 9700 recommendation).
Attack 5: Token leakage via referrer / logs
If access tokens are placed in URL fragments (implicit flow) or query strings, they leak through:
- Referrer headers when the page loads external resources
- Browser history / bookmarks
- Server access logs
- Mobile app logs
Mitigation: avoid implicit flow (deprecated since OAuth 2.1); use authorisation code flow with PKCE; tokens in HTTP headers, not URLs.
Attack 6: JWT access token weaknesses
If access tokens are JWTs (common with Auth0, Cognito), every JWT attack applies — alg:none, RS256-to-HS256, weak HMAC, JWKS injection. Covered separately in our JWT article.
Attack 7: Scope escalation
Some authorisation servers honour scope changes during refresh-token flows. Attacker requests a refreshed token with broader scope; if not validated, scope creeps up.
Attack 8: Cross-site WebSocket hijacking via OAuth state
If the OAuth callback page initiates a WebSocket connection without origin validation, attacker can establish a WebSocket from their site that inherits the just-completed OAuth session.
Practical workflow
- Identify OAuth in scope. Look for redirects to
auth.target.com,login.target.com, or third-party OAuth providers. - Capture the auth flow with Burp.
- Test redirect URI: try wildcards, path traversal, subdomain swap, append fragments.
- Test state: omit it; replay it; check if the client validates.
- Test PKCE: omit code_verifier; check if client allows.
- Test code reuse: exchange the same code twice; should fail.
- Test scope: request additional scopes during refresh.
- If JWT access token, run JWT attack chain.
Detection — what works
- Authorisation server logs — multiple failed code exchanges, unusual redirect URI patterns, scope-mismatch refresh attempts.
- Anomalous OAuth flow — same code attempted multiple times, code-exchange from unexpected IP after redirect.
- Strict redirect URI validation at the authorisation server.
The fix
- Use OAuth 2.1 (the consolidated, hardened version of OAuth 2.0).
- Authorisation code flow with PKCE for all clients.
- Exact-match redirect URI validation. No wildcards, no path traversal.
- Cryptographically-random state parameter, bound to session.
- Short access token lifetimes (5-15 min); refresh tokens with rotation.
- JWT access tokens validated correctly (algorithm pinned, signature verified).
- Scope validation on every refresh.
Compliance angle
- OWASP API Top 10 API2 (Broken Authentication) — OAuth implementation flaws are common findings.
- RFC 9700 — OAuth 2.0 Security Best Current Practice; the modern bar.
- DPDP §8(5) — OAuth bypass leading to account takeover is a defensible-security failure.
The takeaway
OAuth done correctly is fine. OAuth done with a 2017 implementation guide is broken. Audit your OAuth flows against OAuth 2.1 and RFC 9700. The fix is mostly configuration — PKCE, exact redirect match, state validation. The cost of skipping it is account takeover at scale.
Get a VAPT scoping call
Senior practitioner-led VAPT — not a checklist run by juniors. CVSS-scored findings, free retest, attestation letter. India's SMBs and SaaS teams.