OAuth 2.0 Security: Misconfigurations That Lead to Account Takeover
"Sign in with Google" and similar buttons are convenient and generally more secure than passwords. But OAuth has many moving parts, and small implementation mistakes regularly lead to full account takeover.
Quick refresher
In the authorisation code flow:
- Your app redirects the user to the identity provider with a
client_id,redirect_uri,scopeandstate. - The user logs in and consents.
- The provider redirects back to your
redirect_uriwith an authorisation code. - Your server exchanges the code for tokens.
Most vulnerabilities live in steps 1, 3 and what you do after step 4.
Mistake 1: Loose redirect URI validation
If the provider accepts any redirect_uri that starts with your domain, or uses wildcards, attackers can send the authorisation code to a page they control, or to an open redirect on your domain that forwards it.
Fix: register exact redirect URIs and avoid wildcards. Remove open redirects from your domain.
Mistake 2: Missing or unchecked state
The state parameter ties the OAuth response to the browser that started the flow. Without it, an attacker can complete a flow with their own account and trick the victim into finishing it, logging the victim into the attacker's account or linking the attacker's identity to the victim's account.
Fix: generate a random state, store it in the session, and reject callbacks that do not match.
Mistake 3: No PKCE
PKCE (Proof Key for Code Exchange) protects the code exchange from interception. It is required for mobile and single-page apps and recommended for all clients by current OAuth guidance.
Fix: use PKCE with the S256 method for every client.
Mistake 4: Trusting unverified emails
Some apps log users in, or link accounts, based on the email address returned by the provider. If the provider allows unverified emails, an attacker can create an identity with the victim's email and gain access to their account.
Fix: only trust emails the provider marks as verified, and prefer the provider's stable user ID (sub) for account linking.
Mistake 5: Using the implicit flow
The implicit flow returns tokens in the URL fragment, where they can leak via browser history, referrers and logs. It is deprecated in current best practice.
Fix: use the authorisation code flow with PKCE.
Mistake 6: Over-broad scopes
Requesting more scope than needed increases the damage if tokens leak. Request the minimum and store provider tokens securely, encrypted at rest.
Mistake 7: Token leakage
Tokens or codes can leak through Referer headers when the callback page loads third-party resources, through logs, or through analytics. Keep callback pages minimal and exchange codes immediately.
OAuth security checklist
- Exact redirect URIs, no wildcards.
- Random
state, verified on callback. - PKCE with S256.
- Authorisation code flow only.
- Link accounts by provider
sub, trust only verified emails. - Minimal scopes.
- No third-party resources on callback pages.
Testing OAuth flows
SecurityInfinity agents test redirect URI handling, state validation, account linking logic and token leakage paths. Start free.
Frequently asked questions
Is OAuth an authentication protocol?
OAuth 2.0 is for authorisation. OpenID Connect builds on it to provide authentication, with an ID token describing the user.
Is PKCE needed for server-side apps?
Current best practice recommends PKCE for all clients, including confidential server-side clients, as defence in depth.
Can OAuth bugs be found by scanners?
Rarely. They depend on flow logic, which requires interactive testing across multiple accounts.