About jwt-security-review
jwt-security-review is a skill for end-to-end reviews of JWT authentication, intended for developers and security reviewers examining authentication code. It covers algorithms, keys, claims, and token lifecycle, and calls for findings with affected code paths and remediation.
Key features
- 01Check algorithm pinning and key types
- 02Assess secret strength and rotation
- 03Validate claims and privilege fields
- 04Review refresh, revocation, and storage practices
- 05Provide attack tests and remediation guidance
Use cases
- 01Review server-side JWT verification
- 02Check whether token claims can be abused
- 03Assess refresh-token rotation and revocation
- 04Document affected code paths and fixes for findings
Install
Copy the command and run it in a terminal.
$
npx skills add https:/ / github.com/ securityskills/ skills --skill jwt-security-reviewAfter installing, type/jwt-security-reviewin Claude Code to confirm it loaded.
Details
From the project READMEJWT Security Review
Review JWT-based authentication end to end.
Review Areas
Algorithm Handling
- Pin the expected algorithm server-side; reject
alg: noneoutright - RS256→HS256 confusion: if the server verifies HMAC using the public key as the secret, an attacker can forge tokens. Confirm verification uses the correct key type per algorithm
- Watch for
jku/x5uheader injection where the server fetches keys from an attacker-controllable URL kidinjection: path traversal or SQL/Command injection in key lookup
Key and Secret Strength
- HS256 secrets: ≥32 bytes of entropy, not from wordlists (
jwt-toolscrack mode) - Keys rotated; old keys revoked rather than just unused
Claims Validation
expandnbfenforced, clock skew boundedissandaudvalidated against expected values- Reject tokens with unexpected/extra privileged claims (e.g.,
admin: true) — parse then validate allowlist - Don't trust client-controlled
role/uidclaims if a server-side lookup exists
Token Lifecycle
- Refresh tokens: rotation with reuse detection; stored hashed server-side
- Revocation path exists for logout/password change/admin force-logout
- Access tokens short-lived (≤15 min); no long-lived bearer tokens
- Tokens not persisted in localStorage if XSS surface exists; prefer httpOnly cookies with CSRF protection
subis stable and unambiguous (user ID, not email that can change)
Common Code Smells
jwt.decode(token) // decode ≠ verify: signature never checked
jwt.verify(token, key) // no algorithms option pinned
jwt.verify(token, key, { algorithms: ['*'] })
Test Cases
- Remove the signature; send
alg: nonetoken - Flip
algto HS256 signed with the public key - Expired/missing
exp, wrongiss/aud - Tampered claims with valid signature (e.g., escalate role)
- Replay a rotated refresh token — should invalidate the family
Output
Findings with token samples (redacted), affected code paths, and remediation per issue.
Comments
Markdown supported