jwtlisted
Install: claude install-skill Wulan234/agent
# JWT playbook
You have one or more `eyJ...` tokens. The goal is to forge an authenticated token that the server accepts.
Execution rule: use real tokens, URLs, and keys from the scoped target before running commands. Never write literal placeholders such as `<payload-b64>` or `<future>` to files; if a value is missing, ask once.
## 0. Decode every token you have
Base64url-decode header and payload. Note:
- `alg` — algorithm. `none`, `HS256`, `HS384`, `HS512`, `RS256`, `RS384`, `RS512`, `ES256`, `ES384`, `ES512`, `PS256`...
- `kid` — key identifier (path / id pointing at a key on the server).
- `jku` — URL to a JWK Set hosting the signing keys.
- `jwk` — embedded JWK.
- `x5u` — URL to an X.509 certificate.
- `x5c` — embedded X.509 chain.
```sh
echo "<payload-b64>" | base64 -d | jq .
```
Capture the user id / role field for later forgery (`sub`, `uid`, `role`, `isAdmin`, ...).
## 1. alg=none
Many libraries used to (and a few still do) accept `{"alg":"none"}` and skip signature verification. Forge:
```
header = base64url({"alg":"none","typ":"JWT"})
payload = base64url({"sub":"admin","role":"admin","exp":<future>})
signature = "" # empty, but the trailing dot stays
token = header + "." + payload + "."
```
Variants to try: `none`, `None`, `NONE`, `NoNe` (case fuzzing) — `read_payloads(skill="jwt", file="alg-none-variants.txt")`.
## 2. HS/RS algorithm confusion
If the server expects RS256 (asymmetric, verifies with public key) and you can obtain the public k