SecureBlockLog inStart a pentest
Vulnerability Repository
HighAuthentication

OAuth 2.0 Misconfiguration

Flawed OAuth implementations using open redirect URIs, missing state parameters, or implicit flow grant attackers authorization codes and access tokens for victim accounts.

CVSS 8.1CWE CWE-601OWASP A07:2021 — Identification and Authentication Failures

Description

OAuth 2.0 misconfiguration encompasses a broad set of implementation flaws in the OAuth authorization framework that allow attackers to steal authorization codes, access tokens, or refresh tokens belonging to other users. OAuth is the de facto standard for delegated authorization and social login ("Sign in with Google/GitHub/Facebook"), and its complexity — multiple grant types, redirect flows, state parameters, and token exchange steps — creates numerous opportunities for subtle but critical security mistakes.

The most impactful OAuth vulnerabilities include: open redirect URI validation allowing tokens to be stolen via redirect to attacker-controlled domains; missing or predictable state parameter enabling CSRF against the authorization flow; authorization code interception via Referer header leakage; implicit flow exposing tokens in URL fragments (now deprecated in OAuth 2.1 for this reason); and misuse of redirect_uri path traversal to bypass strict URI matching.

These vulnerabilities fall under CWE-601 (Open Redirect) and OWASP A07:2021 (Identification and Authentication Failures). A successful OAuth attack against a major identity provider integration can lead to complete account takeover for any user of the application who uses the "Sign in with" feature.

How It Works

Open redirect_uri — code theft:

The authorization server validates that the redirect_uri in the authorization request matches a registered URI. Weak validation allows an attacker to register a URI on the same domain and abuse a redirect:

Registered URI: https://app.target.com/callback

Attacker crafts:

https://authserver.com/authorize?
  client_id=app123&
  redirect_uri=https://app.target.com/callback/../../../logout?next=https://attacker.com&
  response_type=code&
  scope=openid

If the server performs path normalization before comparison, the effective redirect URI becomes https://attacker.com. When the victim visits this link and authorizes, the authorization code is sent to attacker.com.

Missing state parameter — CSRF on OAuth flow:

The state parameter is a CSRF token for the OAuth flow. Without it, an attacker can initiate an authorization request, capture the code, and inject it into the victim's session:

  1. Attacker initiates OAuth authorization, captures the code without completing the flow
  2. Attacker tricks the victim into visiting /callback?code=ATTACKER_CODE
  3. The victim's browser exchanges the attacker's code for tokens, binding the attacker's identity to the victim's account

Authorization code leakage via Referer:

# Callback URL (contains the authorization code)
https://app.target.com/callback?code=AUTH_CODE&state=xyz

# Page includes an analytics script:
<script src="https://analytics.thirdparty.com/track.js"></script>

# Browser sends:
GET /track.js HTTP/1.1
Referer: https://app.target.com/callback?code=AUTH_CODE&state=xyz

The authorization code leaks to the third-party analytics provider in the Referer header.

Testing OAuth implementations is a specialty area in web application penetration testing. Burp Suite Pro includes a dedicated OAuth testing module. Manual testing following the OAuth Security BCP (RFC 9700) checklist is the gold standard.

Impact

  • Account Takeover — Stealing authorization codes or access tokens to authenticate as the victim user
  • Account Linking Hijack — Linking an attacker-controlled identity provider account to a victim's application account, gaining persistent access
  • Scope Creep — Obtaining access tokens with broader scopes than intended due to improper scope validation
  • Token Leakage — Authorization codes and tokens appearing in server logs, browser history, and third-party Referer headers

Detection

  1. Test redirect_uri validation — attempt path traversal (/callback/../attacker), parameter manipulation (/callback?extra=https://attacker.com), and subdomain variations (/callback vs https://evil.target.com/callback) against the authorization endpoint.
  2. Test missing state parameter — remove the state parameter from the authorization request. If the flow completes successfully, CSRF on the OAuth flow is possible.
  3. Test state predictability — if state is present, analyze multiple values for sequential patterns or timestamp-based generation.
  4. Test authorization code reuse — complete the OAuth flow normally, capture the code from the callback URL, and attempt to exchange it again at the token endpoint. It should be rejected after first use.
  5. Test token leakage via Referer — inspect outbound requests from the callback page using Burp Suite. Look for Referer headers sent to third-party domains that include the authorization code.
  6. Test implicit flow token exposure — if the application uses implicit flow (response_type=token), verify that access tokens in URL fragments are not logged or leaked.

Remediation

Implement strict redirect_uri validation. Perform exact string matching against a pre-registered allowlist. Reject any URI that doesn't match exactly — no path traversal, no wildcard subdomains:

REGISTERED_REDIRECT_URIS = {"https://app.target.com/callback"}

def validate_redirect_uri(uri):
    return uri in REGISTERED_REDIRECT_URIS

Always generate and validate the state parameter. Use a cryptographically random state value tied to the user's browser session. Reject any callback without a valid, matching state:

// Generate state
const state = crypto.randomBytes(32).toString('hex');
req.session.oauthState = state;

// Validate on callback
if (req.query.state !== req.session.oauthState) {
  return res.status(403).json({ error: 'Invalid state parameter' });
}

Use PKCE for all OAuth flows. Proof Key for Code Exchange (RFC 7636) prevents authorization code interception even if the code is leaked. It is mandatory for public clients (SPAs, mobile apps) and recommended for confidential clients.

Avoid the implicit flow. Use the authorization code flow with PKCE instead. The implicit flow is deprecated in OAuth 2.1.

Add Referrer-Policy: no-referrer to callback pages. Prevent authorization codes from leaking in Referer headers to third-party resources loaded on the callback page.

Ready when you are
Scope a pentest in the next two minutes.
Start scoping