Turn a suspected or confirmed authentication/authorization bypass into impact — admin access, session takeover, privilege escalation, or cross-tenant read. Use when you find a missing auth check on a route, a weak JWT verifier, a session cookie that's predictable or reusable across users, a privilege field client-controllable, or an audit finding tagged CWE-287/CWE-863/CWE-639. Walks from probe to admin-equivalent capability and persists a finding with the highest-impact action you reached.
Installs into .claude/skills of the current project.
Are you the author of Escalate Auth Bypass?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/vigolium-escalate-auth-bypass)
---
name: escalate-auth-bypass
description: Turn a suspected or confirmed authentication/authorization bypass into impact — admin access, session takeover, privilege escalation, or cross-tenant read. Use when you find a missing auth check on a route, a weak JWT verifier, a session cookie that's predictable or reusable across users, a privilege field client-controllable, or an audit finding tagged CWE-287/CWE-863/CWE-639. Walks from probe to admin-equivalent capability and persists a finding with the highest-impact action you reached.
license: MIT
allowed-tools:
- query_records
- inspect_record
- replay_request
- list_auth_sessions
- auth_session_lookup
- attack_kit
- report_finding
- update_finding
- remember
- update_plan
---
# Auth Bypass → Impact Escalation
You have a suspected auth weakness. Your job is to turn it into the
strongest impact you can demonstrate — admin access, cross-tenant data
read, token forgery, or session takeover — and persist a finding with the
specific action that proves it. Reporting "missing auth check" without
showing what it gets you is not a finding.
## When this skill applies
- A route responds 200 with no `Authorization` / session cookie when it
should require auth (compare to a known-auth'd record's response).
- JWT verification accepts `alg: none`, a key-confused HMAC secret, or a
token signed with the public key as HMAC secret.
- A session ID is predictable (sequential, time-based, or short).
- A request body / query has a role/tenant/user field that, when changed,
changes the response (`role=user` → `role=admin`, `tenant=A` → `tenant=B`).
- Audit harness flagged CWE-287, CWE-862, CWE-863, CWE-639, CWE-284, or
CWE-639 — even theoretical.
## Workflow
### 1. Establish baselines
Use `list_auth_sessions` to see which auth contexts already exist for the
host. Use `auth_session_lookup` to pull the actual headers for at least
two roles if you have them (`anon` + `user` is enough; `user` + `admin`
is ideal). `remember` the role boundaries as `auth-roles`.
If only one role is available, use `query_records` to find an
unauthenticated record for the same endpoint to anchor the no-auth
baseline.
### 2. Classify the weakness
Pick **one** mechanism to attack — don't shotgun:
- **Missing auth on route**: pick the suspect endpoint, send the request
with `replay_request` and `extra_headers: {}` to strip cookies. If you
still get the privileged response, the route doesn't check auth at all.
- **Weak JWT**: decode the token (base64 each segment). Look at `alg`,
`iss`, `aud`, `exp`, `sub`, custom claims (`role`, `tenant`). Re-mint:
- `alg: none`: build header `{"alg":"none","typ":"JWT"}`, keep payload,
drop signature (empty 3rd segment).
- Key confusion: sign HMAC with the public key as the secret.
- Empty / weak HMAC secret: try `""`, `secret`, `key`, the app name.
- **Session prediction**: collect 5-10 valid session IDs from `query_records`
on login responses. If they're sequential, time-encoded, or short
hex/base64, forge a neighboring ID via `replay_request`.
- **Privilege field client-controlled**: send the request with the role
field flipped (`role=admin`, `is_admin=true`, `tenant_id=<other>`).
### 3. Confirm escalation, don't stop at "different"
A 200 with different content is *suspicious*, not proof. Confirm with
ONE of:
- The response body contains data the original role couldn't see (admin
email, another user's email, a hidden flag).
- A privileged action succeeds: `DELETE /api/users/X`, `POST /api/admin/X`,
`GET /api/users/all` returns a list of more than just the current user.
- A subsequent request using the forged session is accepted as that user
(look up the user's email or role in the response).
Send the **smallest privileged request that proves the boundary was
crossed**. `remember` it with key `auth-bypass-proof` and include the
exact request line.
### 4. Map the blast radius
Briefly enumerate the surface the bypass unlocks. Don't enumerate at
scale — show:
- 1 admin-only endpoint reachable.
- 1 cross-tenant record visible.
- 1 sensitive write that succeeds (if write paths exist; do **not**
destructively delete or modify real data — read or create-with-rollback
if possible).
This sizes the severity in the finding without spamming requests.
### 5. Persist the finding
Call `report_finding`:
- `severity`: `critical` if you reached admin or full cross-tenant; `high`
for same-tenant privilege escalation or read of another user's data.
- `title`: name the mechanism and the proven action — `"JWT alg=none
accepted; forged admin token reads /api/admin/users (1234 users)"`.
- `cwe_id`: CWE-287 (auth missing), CWE-863 (broken auth check),
CWE-639 (IDOR-style), CWE-345 (insufficient verification of data),
CWE-347 (weak signature) — pick the one that matches the mechanism.
- `description`: 3 sentences. Mechanism, proof, blast radius. Include the
decoded JWT header / forged session ID / mutated field value in the
description body so the reproduction is unambiguous.
If the audit harness already raised this, `update_finding` to triaged
status referencing the new proof.
## Pitfalls
- Do not perform destructive writes (`DELETE`, `PUT` overwriting,
password resets) on someone else's account. Read-only proofs are
sufficient for severity.
- A forged token that returns 200 with an empty body proves nothing.
The body must contain data the original role didn't have access to.
- Some apps return 200 with `error: "unauthorized"` in the JSON body —
read the body, not just the status, before claiming bypass.
- If the app has a "demo admin" account that's publicly accessible by
design, that's not a bypass — confirm by checking documentation or
a comment in the code (`--source` mode).
- IDOR (object-level missing auth) is a related but distinct pattern —
if your finding is "can read another user's order by changing the
ID", use `idor-blast-radius` instead.
## Output expectations
- One `report_finding` with the strongest proven impact.
- A `remember` note with the canonical bypass request.
- Plan item marked `done`.