TL;DR: OAuth 2.0 is the backbone of modern application authentication — and its misconfigurations are among the highest-severity findings in web application penetration tests. The vulnerabilities are rarely exotic. They are implementation shortcuts that developers make under delivery pressure: loose redirect_uri validation, missing state parameters, legacy implicit flows, and absent PKCE on mobile clients. Each one is a potential account takeover.
Why OAuth Gets Misimplemented So Often
OAuth 2.0 is a delegation framework — it was designed to allow a third-party application to act on a user's behalf without knowing the user's credentials. When implemented correctly, it provides a secure, auditable authorization layer for modern applications. The problem is that "implemented correctly" requires understanding a specification with multiple flows, several security extensions, and a set of non-obvious requirements that are easy to skip under development pressure.
Most OAuth vulnerabilities are not caused by attackers exploiting unknown flaws in the protocol itself. They are caused by developers who implement the happy path — the flow that works in the demo — without implementing the security requirements around it. The result is an authentication system that appears to work correctly until a security team tests it properly.
OAuth Flow Security Properties
| Flow | Use Case | Security Properties | Status |
|---|---|---|---|
| Authorization Code + PKCE | Web apps, mobile apps, SPAs | Code never exposed in browser; PKCE prevents interception; client secret not required for public clients | Recommended for all cases |
| Authorization Code (no PKCE) | Server-side web apps with confidential clients | Code not exposed in URL; requires client secret; vulnerable to interception on public clients | Acceptable for confidential server-side clients only |
| Implicit Flow | Legacy SPAs (pre-PKCE) | Token returned in URL fragment — exposed in browser history, Referer headers, server logs | Deprecated — do not use |
| Client Credentials | Machine-to-machine (M2M) | No user involved; depends entirely on secure storage of client secret; no redirect flows | Appropriate for service-to-service auth only |
Attack Technique 1: Open redirect_uri Enabling Token Theft
How it works: The authorization request includes a redirect_uri parameter specifying where the authorization server should send the authorization code after the user authenticates. If the server validates this parameter loosely — checking only that it starts with the registered domain, or allowing wildcard matching — an attacker can craft an authorization URL with a redirect_uri pointing to an attacker-controlled subdomain or path on the same domain.
Business impact: Account takeover. The authorization code is delivered to the attacker's server. If the application uses the implicit flow, the access token itself is delivered directly.
Pentest finding method: Modify the redirect_uri parameter in the authorization request — try adding path traversal, appending a different subdomain, or using a registered domain with an additional path. Observe whether the server accepts the modified URI.
Remediation: Enforce exact-match validation of redirect_uri against a pre-registered whitelist. Do not allow wildcard or prefix matching. Reject any authorization request where the redirect_uri does not exactly match a registered value.
Attack Technique 2: Missing State Parameter — CSRF on the Authorization Flow
How it works: The state parameter in an OAuth authorization request serves as a CSRF token. When a user clicks "Login with Google," the application generates a random state value, stores it in the session, and includes it in the authorization URL. After authentication, the server returns the state value in the callback — and the application verifies it matches the stored value before proceeding.
When the state parameter is absent or predictable, an attacker can perform a CSRF attack on the authorization callback: they trick the victim's browser into completing an OAuth flow initiated by the attacker, linking the victim's account to the attacker's identity provider session.
Business impact: Account takeover through forced account linking. If the attacker can link their own identity provider identity to the victim's application account, they gain full access.
Remediation: Always generate a cryptographically random state value per authorization request, store it server-side, and verify it on callback before processing the authorization code.
Attack Technique 3: Authorization Code Interception Without PKCE
How it works: On public clients — mobile apps and single-page applications — there is no secure way to store a client secret. Without PKCE (Proof Key for Code Exchange), if an attacker can intercept the authorization code (through a malicious app registered to handle the same custom URI scheme, or through Referer header leakage), they can exchange it for an access token without knowing any additional secret.
PKCE closes this gap by requiring the client to prove, at token exchange time, that it holds a secret value it committed to at authorization time — without that secret ever leaving the client.
Remediation: PKCE is mandatory for all public clients. It should also be used for confidential clients as defense in depth. The OAuth 2.1 draft makes PKCE mandatory for all authorization code flows.
Attack Technique 4: Scope Escalation via Parameter Tampering
How it works: Some OAuth implementations do not strictly validate the scope parameter against what the registered client is authorized to request. An attacker modifies the scope parameter in the authorization request — adding elevated scopes such as admin, offline_access, or API-specific administrative scopes — and observes whether the authorization server grants them.
This can also manifest at the token exchange or refresh step if scope validation is inconsistent across endpoints. A token issued with limited scope may be accepted by resource servers at elevated-scope endpoints if per-endpoint scope enforcement is missing.
Remediation: Validate the requested scope against the registered client's allowed scopes on every authorization request. Enforce scope restrictions at the resource server on every API call — do not rely solely on what was issued at authorization time.
Attack Technique 5: Subdomain Takeover Enabling redirect_uri Bypass
How it works: Many organizations register redirect_uri values that include subdomains — for example, https://app.example.com/callback or https://legacy-api.example.com/oauth/callback. If the subdomain is decommissioned but the DNS record is not removed, it becomes vulnerable to subdomain takeover — an attacker can claim the subdomain by deploying to the hosting platform it previously pointed to.
Once the attacker controls the subdomain, the previously registered redirect_uri now delivers authorization codes directly to attacker-controlled infrastructure. The authorization server sees a registered redirect_uri and accepts the request.
Remediation: Maintain an inventory of all OAuth-registered redirect_uri values and audit them against live DNS records. Remove redirect_uri registrations when services are decommissioned. Implement attack surface monitoring to detect subdomain takeover opportunities. Lorikeet Security's attack surface management service continuously monitors for these conditions.
Attack Technique 6: Token Leakage via Referer Headers
How it works: The implicit flow delivers access tokens in the URL fragment — for example, https://app.example.com/callback#access_token=eyJ.... While the fragment is not sent to the server in the Referer header directly, if the page at that URL loads third-party resources (analytics, CDN assets, error tracking), some browsers may include the full URL (including fragment) in Referer headers sent to those third parties.
Additionally, authorization codes delivered as URL query parameters — rather than fragments — are logged in web server access logs, CDN logs, and browser history, creating persistent token exposure risk.
Remediation: Do not use the implicit flow. Use the authorization code flow with PKCE. Deliver authorization codes as query parameters only over HTTPS connections, and ensure they are short-lived and single-use at the server. Use Referrer-Policy: no-referrer headers on callback pages.
Key Remediation Priorities
Enterprise development and security teams auditing their OAuth implementations should prioritize in this order:
- Audit all redirect_uri registrations — exact match validation only, no wildcards, check for subdomain takeover risk
- Verify state parameter is present, cryptographically random, and validated on every callback
- Migrate any implicit flow usage to authorization code + PKCE
- Implement PKCE on all public clients — mobile apps, SPAs, Electron apps
- Audit scope validation at both authorization and resource server layers
- Review token storage — access tokens should not be stored in localStorage; prefer httpOnly cookies or secure in-memory storage
At Lorikeet Security, our web application and API penetration testing engagements include comprehensive OAuth flow review — validating all of these controls against a live application rather than relying on code review alone.
Get Your OAuth Implementation Tested by Experts
Lorikeet Security's web application and API penetration testing identifies OAuth misconfigurations, authentication bypass vulnerabilities, and authorization flaws that automated scanners consistently miss. Book a consultation to scope your assessment.