jwt-doctor-mcp
by Baneado98
README.md
# JWT Doctor — token security & forensics for AI agents (MCP)
Paste a **JWT, JWE, PASETO, Branca, a framework-signed session cookie
(Flask/Django/Rails/Express), or a SAML assertion** and get a security verdict an
LLM **cannot** reliably reason about from raw base64/XML: is the algorithm safe, is
the token **forgeable**, does the signature verify against the issuer's live keys,
is the signing secret a **publicly-known** value, and does it match real
JWT-library CVEs.
`SAFE` / `WEAK` / `DANGEROUS` + a concrete fix per finding. The token is never logged.
> **Hosted service:** https://jwt-doctor.vercel.app — the deep audit runs
> server-side. This package is a **thin MCP client**: it sends the token to the
> hosted endpoint and renders the verdict. No analysis logic ships to your machine.
## Why an MCP (the moat)
A model can base64-decode a JWT, but it **cannot**:
- **crack the HMAC secret** — JWT Doctor HMAC-verifies the token's real signature
against a **45,000+ corpus** of leaked/default/weak JWT secrets (framework
defaults, jwt.io samples, SecLists `jwt.secrets`, rockyou heads, leet/affix
mutations). A match is **cryptographic proof the token is forgeable**. The corpus
grows server-side with zero client update.
- **verify the signature live** — it resolves the issuer's JWKS over the network
(OIDC discovery / `jku` / `x5u`), **fetches it**, and cryptographically verifies
the `RS*/ES*/PS*/EdDSA` signature; flags `jku`/`x5u`/`jwk` pointing at attacker
domains (SSRF / key-injection). JWKS are cached by `iss` with **key rotation
recovery** and **`kid`-not-in-JWKS** detection (rotated-out/forged kid).
- **fingerprint real CVEs** — maps the token shape to attributed advisories
(alg-confusion, `alg:none`, jwk-injection CVE-2022-23529, ECDSA psychic
signatures CVE-2022-21449, PyJWT CVE-2022-29217, JWE RSA1_5 Bleichenbacher,
zip-bomb CVE-2023-48238, …) across jsonwebtoken / jose / PyJWT / golang-jwt /
Nimbus, plus a heuristic library fingerprint.
- **analyze JWE** — encrypted tokens (5 parts): weak key-management (`RSA1_5`),
CBC auth-tag caveats, `zip:DEF` decompression bombs, PBES2 `p2c` DoS, nested-JWT.
- **detect header manipulation** — `none` in any casing, RS↔HS confusion surface,
`kid` path-traversal vs SQLi (distinct fixes), unsupported `crit`.
- **grade the secret** — for a cracked HS secret: entropy, charset, patterns and an
**offline crack-time estimate** (hashcat HS256 economics), plus **breach
attribution** — is the secret a known framework default / jwt.io sample / leaked
placeholder (it was never private)?
- **audit non-JWT formats** — **PASETO** (v1–v4), **Branca**, and framework-signed
**session cookies**: Flask/itsdangerous, Django, Rails, Express. For the
HMAC-keyed cookies it **cracks the app `SECRET_KEY`** against the same corpus and
proves the session is forgeable (automated flask-unsign-style attack).
- **analyze SAML** — XML Signature Wrapping (multi-assertion / partial signing),
the comment-injection auth bypass, unsigned assertions, **XXE** (`DOCTYPE`),
weak SHA-1/MD5 signature algorithms, missing replay window.
- **live revocation (OCSP/CRL)** — for an `x5c`/`x5u` chain it parses the
certificate's AIA/CDP extensions and checks the cert is **not revoked** against
the live responder — a forensic step an LLM cannot perform.
- **mobile driving licence (mDL / ISO 18013-5)** — decodes and audits ISO mDL /
mdoc COSE structures, surfacing the trust and integrity issues specific to
verifiable mobile credentials.
- **COSE / CWT** — CBOR-Object-Signing tokens: structure, algorithm, and signature
posture for the IoT / WebAuthn token family.
- **batch** — audit up to **50 tokens in one paid call**; flags every
provably-forgeable token across a dump.
- **cross-request fleet anomalies** — up to **200 tokens** from one issuer: detects
attacks that only exist BETWEEN tokens — replayed `jti`, signing-key
rotation/injection mid-stream, non-monotonic `iat` (forged/replayed batch),
**burst issuance** (credential stuffing), and the **same weak HMAC secret signing
for multiple services** (forge-once, use-everywhere lateral movement).
- **hardening scorecard** — every deep audit returns an **A–F** token-security
maturity grade across signing / key-management / claims / lifetime /
sender-constraint, plus the **top-3 prioritised fixes**.
- **proof-of-possession** — verifies **DPoP** (RFC 9449) and **mTLS** (RFC 8705)
end-to-end: recomputes the DPoP proof JWK thumbprint vs `cnf.jkt`, and (BYO client
cert) recomputes the cert SHA-256 thumbprint vs `cnf.x5t#S256`.
- **verifiable credentials / SD-JWT** — recomputes every selective-disclosure
**digest** under `_sd_alg`, flags forged/tampered claims, verifies the holder
**Key-Binding JWT** signature against `cnf`, and checks `aud`/`nonce`/freshness.
- **WebAuthn / passkey attestation** — CBOR-decodes the `attestationObject`, parses
`authenticatorData`, classifies the format, and cryptographically verifies the
packed attestation signature against the x5c leaf.
- **OAuth 2.1 / JAR / RAR / PKCE** — audits a signed authorization **request object**
(JAR, RFC 9101): unsigned/HS-from-public-client, request-object substitution,
PKCE absent/`plain`, RAR wildcards, insecure `redirect_uri`, implicit grant.
- **remediation in 9 ecosystems** — every fix ships copy-paste snippets for Node
(jsonwebtoken/jose), Python, Go, **Java (Nimbus + jjwt), .NET, Ruby, PHP, Rust**.
## Tiers
| | Free | Deep (paid) |
|---|---|---|
| decode header/claims, `alg:none`, expiry, missing-claim hygiene | ✅ | ✅ |
| HMAC secret crack (45k corpus) | — | ✅ |
| live JWKS signature verification + SSRF/spoof flags | — | ✅ |
| `kid` rotation / not-in-JWKS detection | — | ✅ |
| real CVE fingerprinting + library guess | — | ✅ |
| JWE deep analysis (RSA1_5 / CBC / zip-bomb / p2c) | headline only | ✅ |
| secret strength grading + breach attribution | — | ✅ |
| PASETO / Branca / signed-cookie audit + cookie-secret crack | — | ✅ |
| SAML XSW / comment-injection / XXE analysis | — | ✅ |
| live OCSP/CRL revocation, mDL/ISO 18013-5, COSE/CWT | — | ✅ |
| batch audit (up to 50 tokens/call) | — | ✅ |
| cross-request fleet anomaly detection (up to 200 tokens) | — | ✅ |
| A–F hardening scorecard + top-3 fixes | — | ✅ |
| DPoP / mTLS proof-of-possession verification | — | ✅ |
| VC-JWT / SD-JWT, WebAuthn attestation, OAuth 2.1 / JAR / RAR | — | ✅ |
| remediation snippets in 9 ecosystems | — | ✅ |
Both tiers run **server-side** on the hosted service. The **free** tier is
rate-limited; the **deep** tier (the crack corpus, the network calls, and the CVE
data) runs behind payment and never ships to the client.
## Install (MCP)
```json
{
"mcpServers": {
"jwt-doctor": {
"command": "npx",
"args": ["-y", "jwt-doctor-mcp"],
"env": { "JWT_DOCTOR_KEY": "<your-deep-tier-key, optional>" }
}
}
}
```
Tools: **`check_jwt`** — `{ target: string, deep?: boolean, … }` (one token; deep
accepts OIDC/PASETO/DPoP/`client_cert_pem` companions), **`check_jwt_batch`** —
`{ tokens: string[] }` (up to 50, deep), and **`analyze_token_fleet`** —
`{ tokens: string[] }` (up to 200, cross-request anomaly detection). Without a key,
the deep tools return instructions to unlock; the free verdict needs no key.
### Example
```
check_jwt { "target": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjMifQ.dozjg..." }
→ verdict: WEAK — HS256, no exp, missing aud/iss. (free)
check_jwt { "target": "<same token>", "deep": true }
→ verdict: DANGEROUS — secret "secret" cracked from corpus (forgeable in <1s),
matches CVE pattern, A–F grade: F, top-3 fixes attached. (paid)
```
## Pay for the deep tier (two lanes, pick one)
- **🪙 x402** (AI agents with a wallet): `GET /pro/run?target=<t>&deep=true` — pay
**per call in USDC on Base**; any x402-aware client satisfies the 402 challenge
transparently. No signup, no key.
- **💳 Stripe** (humans/teams): buy a prepaid key at
https://jwt-doctor.vercel.app/pro/checkout, then set `JWT_DOCTOR_KEY` in the MCP
env above.
## Hosted HTTP surface
- `GET /run?target=<t>` — free, rate-limited.
- `GET /pro/run?target=<t>&deep=true` — deep tier (x402 or prepaid key).
- `POST /pro/batch` — deep batch, body `{ tokens: string[] }` (≤50).
- `POST /pro/analyze-batch` — cross-request fleet anomalies, body `{ tokens }` (≤200).
- `POST /mcp` — MCP-over-HTTP (streamable-http).
## Honesty
JWT Doctor analyzes structure, claims, declared algorithms, and the **live
signature** (when a key is reachable). It **does not decrypt** JWEs (no key) and
**never logs** the token. The secret-crack never asserts "forged" without a real
HMAC match; live verification reports network failures as such, never as a false
"safe".
## License
MIT — see [LICENSE](./LICENSE).
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessSyncing