Fictos
JWT Analyzer & Tester
Decode tokens and review security findings
Python / PyJWT
Web Crypto API
Pen-Test Ready
Paste JWT
Try a sample
CRITICAL
alg:none bypass
Signature check skipped
CRITICAL
Weak HS256 secret
Common signing secret
CRITICAL
Sensitive payload
Plaintext private data
CRITICAL
kid injection
Unsafe key ID value
WARNING
Expired token
Expired with missing claims
GOOD
Valid RS256
Asymmetric signing example

Token Structure
Paste a token above…

Decoded Claims
πŸ”
Paste a JWT to decode its header, payload, and signature

Verify Signature (HMAC)
Security Findings
πŸ›‘οΈ
Run security analysis to see findings,
score, timestamps, and Python fix
Header Claims
Payload Claims

Sign With (HMAC)

Quick Presets
Generated Token
Token appears here after generation…

Preview
βš—οΈ
Generate a token to preview it
Known JWT Attack Vectors
CRITICAL alg:none Signature Bypass
Set alg:"none" β€” vulnerable libraries skip verification entirely. Attacker can forge any payload including privilege escalation. CVE pattern: jwt.decode(token, options={"verify_signature":False})
CRITICAL Algorithm Confusion (RS256β†’HS256)
If a server accepts both RS256 and HS256, attacker uses the public key (which is public!) as the HMAC secret. Server verifies with public key β€” it matches. Fix: never list both in one algorithms=[] allowlist.
CRITICAL kid Header Injection
kid: "../../dev/null" β†’ empty key β†’ trivial sign
kid: "x' UNION SELECT 'secret'--" β†’ SQL injection
Validate kid strictly: re.match(r'^[a-zA-Z0-9\-_]{1,64}$', kid)
WARNING Weak Secret Brute-Force
Anyone with a JWT can run offline brute-force. hashcat tests billions/sec. Common secrets crack in milliseconds. The demo token uses "secret" β€” send to Analyzer to crack it instantly.
WARNING Replay Attack (no jti / no exp)
Without jti + server denylist, stolen tokens are valid until expiry. Even after logout. Fix: jti on every token + Redis denylist on logout.
WARNING Privilege Escalation via Payload Tampering
If signature verification is skipped or misconfigured, Base64-decode payload, change role:"user"β†’role:"admin", re-encode and submit. Never trust payload claims without verifying the signature.
Attack Demo Output
πŸ’€
Click "Demo β†’" to generate an attack token

Python Defence Template
🐍 Secure PyJWT Validation
import jwt, re from jwt.exceptions import DecodeError, ExpiredSignatureError # NEVER disable verification: # jwt.decode(token, options={"verify_signature": False}) ← BAD def safe_decode(token: str) -> dict: return jwt.decode( token, public_key_or_secret, algorithms=["RS256"], # exact list β€” never wildcard audience="myapp-api", issuer="https://auth.myapp.com", options={ "require": ["exp","iss","aud","jti","sub"], "verify_exp": True, } ) # Sanitize kid BEFORE using it to look up keys: def safe_kid(kid: str) -> str: if not re.match(r'^[a-zA-Z0-9\-_]{1,64}$', kid): raise ValueError("Invalid kid") return kid # Denylist check (run after decode): def check_revoked(payload: dict): if redis.exists(f"revoked:{payload['jti']}"): raise PermissionError("Token revoked")
Analyzed Token History
πŸ“œ
Tokens you analyze appear here.
Click any entry to reload it.