Now that we understand how OAuth is intended to work, we must look at how it is actually broken. Because OAuth relies on redirects between different domains, it introduces a massive attack surface centered around the transit of the authorization code.
If an Authorization Server does not strictly validate the `redirect_uri` parameter, an attacker can change it to a domain they control. The server will then send the authorization code directly to the attacker's server.
Open Redirects on the client's domain can be used to bypass strict redirect URI whitelisting.
In this example, the victim clicks a link, authorizes the app, and the Authorization Server sends the sensitive `code` to the attacker's server because the URI was not strictly validated.
Without a 'state' parameter, an attacker can trick a user into linking the attacker's account to the user's session on the client app.
// Secure Request with State
const state = crypto.randomBytes(16).toString('hex');
localStorage.setItem('oauth_state', state);
const authUrl = `https://auth.com/auth?client_id=abc&state=${state}&redirect_uri=...`;The `state` parameter acts as a CSRF token. When the callback arrives, the app compares the returned state with the stored state. If they don't match, the request is rejected.
| Attack | Vulnerability | Impact | Mitigation |
|---|---|---|---|
| URI Manipulation | Loose Redirect Validation | Token Theft | Exact Match White-listing |
| OAuth CSRF | Missing 'state' param | Account Linking | Cryptographic State Value |
| Code Injection | Lack of PKCE | Auth Code Interception | Implement PKCE (S256) |
| Token Leakage | Tokens in URLs | Full Account Access | Use Post-Message/Headers |
Modern OAuth implementations must move away from the 'Implicit Flow' and adopt 'Authorization Code Flow with PKCE' to ensure the code cannot be swapped for a token by an interceptor.
Never trust a token that arrives via a GET request without verifying the state and the source.
Verify exercises to earn โ 230 XP and unlock next lab level.