← Back to Blog
Authentication Security April 3, 2026 22 min read

OAuth Security Testing Checklist: Finding High-Impact Authentication Bugs

OAuth 2.0 vulnerabilities consistently top the charts for critical-severity bug bounty payouts. A single account takeover via OAuth misconfiguration can cascade into complete organizational compromise — and these bugs appear in applications used by billions of people.

$10K-$100K
OAuth ATO Payouts
Critical
Impact Classification
4.2B+
Users Affected Globally
OWASP A07
ID & Auth Failures

OAuth 2.0 Fundamentals for Security Testing

ℹ️ The OAuth 2.0 Flows

Understanding which flow a target uses determines which attacks to test. The Authorization Code flow (with PKCE) is the most secure and most common. The now-deprecated Implicit flow has numerous vulnerabilities. Client Credentials (machine-to-machine) has its own attack surface. Never-use-in-production: Resource Owner Password Credentials.

Key OAuth Components


Section 1: Authorization Code Interception

Test 1.1 — Open Redirect in redirect_uri

If the authorization server validates redirect_uri with insufficient precision, an attacker can redirect the authorization code to their controlled server.

# Legitimate request
https://auth.example.com/oauth/authorize?
  client_id=app123&
  redirect_uri=https://app.com/callback&
  response_type=code&state=xyz

# Attack attempts
# 1. Path traversal
redirect_uri=https://app.com/callback/../../../evil.com/steal

# 2. Additional path
redirect_uri=https://app.com.evil.com/callback

# 3. Fragment bypass
redirect_uri=https://app.com/callback%23@evil.com

# 4. Query string bypass
redirect_uri=https://app.com/callback?next=https://evil.com

Test 1.2 — State Parameter Validation

⚠️ Missing/Weak State = CSRF on OAuth

The state parameter prevents CSRF attacks during OAuth flows. If absent or predictable, an attacker can force victims to connect their accounts to attacker-controlled identities — enabling account takeover.

# Check if state is:
# 1. Present in authorization request
# 2. Validated on callback
# 3. Cryptographically random (not sequential/predictable)
# 4. Single-use (replayed states should be rejected)

# Test: replay the same state parameter
curl -s "https://app.com/oauth/callback?code=VALID_CODE&state=PREVIOUSLY_USED_STATE"
# Should return: error (state already used)

Test 1.3 — Code Reuse

# Authorization codes must be single-use
# Test by replaying the code after first exchange:

# First use (legitimate)
POST /oauth/token
code=AUTH_CODE_123&grant_type=authorization_code&...

# Second use (should fail)
POST /oauth/token
code=AUTH_CODE_123&grant_type=authorization_code&...
# Expected: {"error": "invalid_grant"}

Section 2: PKCE Bypass Testing

Test 2.1 — PKCE Enforcement

PKCE prevents authorization code interception attacks. If a server that supports PKCE doesn't enforce it, public clients are vulnerable.

# Start flow WITH PKCE (legitimate)
code_verifier = generate_random_string(64)
code_challenge = base64url(sha256(code_verifier))

GET /authorize?
  code_challenge=abc123&
  code_challenge_method=S256&...

# Attack: exchange code WITHOUT providing code_verifier
POST /token
grant_type=authorization_code&
code=INTERCEPTED_CODE&
redirect_uri=https://legitimate-app.com/callback
# Missing: code_verifier
# If this succeeds -> PKCE not enforced -> Critical vulnerability

Test 2.2 — code_challenge_method Downgrade

# Attempt to downgrade from S256 to plain (less secure)
GET /authorize?
  code_challenge=ACTUAL_CODE_VERIFIER&
  code_challenge_method=plain&...
  
# If accepted: server may be using plain instead of S256
# Then exchange with code_verifier = original plain text
POST /token
code_verifier=ORIGINAL_PLAIN_TEXT&...

Section 3: Token Vulnerabilities

Test 3.1 — Access Token Leakage via Referrer

⚠️ Fragment vs Query Token Handling

In the Implicit flow (deprecated but still found), access tokens in URL fragments (#access_token=...) don't get sent in Referer headers — but tokens in query parameters (?access_token=...) do. Always check how tokens appear in URLs.

Test 3.2 — Token Scope Escalation

# Request minimal scope
GET /authorize?scope=read:email&...

# After getting access token, test unauthorized API calls
GET /api/user/delete
Authorization: Bearer ACCESS_TOKEN_WITH_READ_SCOPE
# Should return 403, not 200

Test 3.3 — JWT Access Token Vulnerabilities

# If access tokens are JWTs, test:

# 1. Algorithm confusion (RS256 -> HS256)
header = {"alg": "HS256", "typ": "JWT"}
# Sign with the public key as HMAC secret

# 2. None algorithm
header = {"alg": "none", "typ": "JWT"}
# Some libraries accept unsigned tokens

# 3. Kid injection (if 'kid' is used)
header = {"alg": "HS256", "kid": "' OR 1=1--"}
# SQL injection in kid parameter

# Tools:
# jwt_tool: python3 jwt_tool.py TOKEN -T (tamper)
# jwt-cracker: for weak secrets

Test 3.4 — Refresh Token Rotation Bypass

# Test if old refresh tokens are invalidated after rotation
POST /token
grant_type=refresh_token&refresh_token=OLD_REFRESH_TOKEN

# If this returns a new token -> old token not invalidated
# Attacker who stole old refresh token can still get new access tokens

Section 4: Account Takeover Scenarios

Test 4.1 — OAuth Account Linking Without Email Verification

💡 High-Impact Finding Pattern

If a victim signs up with email/password (email: victim@gmail.com) and an attacker can link a Google OAuth account with the same email to take over the victim's account — without Google verifying ownership — that's a critical account takeover. This is especially common in platforms that allow linking multiple auth providers.

Test 4.2 — Pre-Account Takeover

# Attack scenario:
# 1. Attacker creates account with victim@example.com (before victim registers)
# 2. Attacker links their OAuth provider to this email
# 3. When victim later registers with Google OAuth using victim@example.com
# 4. Victim gains access to attacker's pre-created account (or vice versa)

# Test by:
# 1. Register account with victim's email (before they exist)
# 2. Connect OAuth from different email
# 3. Try to access victim's future account

Test 4.3 — Token Fixation

# Some implementations allow specifying access_token in request
# or don't properly bind tokens to sessions

# Test: force a known token value
GET /oauth/callback?access_token=KNOWN_VALUE

# If the app accepts and uses this token -> token fixation

Test 4.4 — Sub/Email Claim Confusion

# If an application ties accounts to email (not sub):
# Register malicious OAuth provider with victim's email as their 'email' claim
# Some providers let you set arbitrary email claims

# Test by creating custom OAuth provider with:
{
  "sub": "attacker-unique-id",
  "email": "victim@example.com",
  "email_verified": true
}

Section 5: Authorization Server Vulnerabilities

Test 5.1 — Client Authentication Weakness

# Confidential clients must authenticate with client_secret
# Test if client_secret is optional:
POST /token
grant_type=authorization_code&
code=CODE&
client_id=CONFIDENTIAL_CLIENT_ID&
# Missing: client_secret
# If this works -> client authentication not enforced

Test 5.2 — Device Authorization Flow Abuse

# Device flow (for input-constrained devices) can be abused for phishing
POST /device/code
client_id=LEGITIMATE_CLIENT

# Returns user_code that victim enters at verification_uri
# Attacker uses this for social engineering:
# "Enter code XXXX-XXXX at accounts.target.com/activate"

Complete OAuth Testing Checklist

Pre-Authorization Phase

Authorization Request Tests

Token Exchange Tests

Token Security Tests

Account Linking Tests


Real-World OAuth Bug Examples

Bug TypePlatformImpactBounty
redirect_uri bypassFacebookAccount takeover$25,000
State parameter missingAirbnbCSRF → ATO$8,000
Code reuseMicrosoftReplay attack$15,000
JWT none algorithmAuth0Auth bypass$10,000
Email confusion ATOSlackAccount takeover$20,000
PKCE not enforcedMultipleCode interception$5,000+

Testing Tools

Automate OAuth Security Testing

KENSAI's AI-powered scanner tests your OAuth implementations for authorization code interception, PKCE bypass, token vulnerabilities, and account takeover scenarios automatically.

Start Free Scan →

Security is not optional.

🗡️ The KENSAI Team

Related Articles

Smart Slider WordPress-CVE betrifft 500K Websites, TP-Link & Cisco IOS patchen k الإنتربول يفكك 45,000 عنوان IP خبيث، جوجل تصلح CVE-2026-28756: Cross-Site Scripting (XSS) in Zohocorp ManageEngine Exchange Rep