Skip to content
Free lab

JWT Attack & Defense Lab

Almost every JWT break has the same root cause: the verifier trusts something the attacker controls — the header's alg, the kid key hint — or a signing secret weak enough to guess. This lab runs the real thing — HS256, RS256 and ES256 via your browser's Web Crypto API, no server, no mocks. Forge an alg:none token, dictionary-crack a weak HMAC secret and mint an admin token, substitute HS256 for RS256 by signing with the public key, then — for each attack — name the exploit and pick the server-side fix.

The real job. More noise, a tighter clock.

0sPro

JWT workbench

real HS256 (HMAC-SHA256), in your browser

Build and sign a JWT with a shared secret, then decode and verify it. Edit the received token by one character — or the secret — and watch the signature stop verifying. Header and payload are only base64url, never encrypted.

Signed token
sign a payload to see the token
Verify received token against the secret

—

Attack the tokens, then defend them

4 graded challenges that run real JWT cryptography in your browser via the Web Crypto API. For each one you carry out the attack for real — strip a signature, dictionary-crack an HMAC secret, substitute an algorithm, waved a bad claim past a lax verifier — then identify the exploit and pick the correct server-side hardening. Score on correct exploit identification + correct hardening choices + pulling off the live attack. Clear 80% to pass; finish under par for a speed bonus and a better grade.

alg:none
weak HMAC secret
HS/RS confusion
claim hygiene
TL;DR

What this lab is

  • A free, browser-based JWT lab that builds and breaks JSON Web Tokens with REAL Web Crypto — HS256 is HMAC-SHA256, RS256 is RSASSA-PKCS1-v1_5, ES256 is ECDSA P-256.
  • A live workbench signs a JWT with a shared secret, decodes it, and shows the signature failing the moment you tamper with the token or the key.
  • Graded attacks you actually perform: forge an alg:none token a lax server trusts, dictionary-crack a weak HMAC secret and mint an admin token, and pull off HS/RS key confusion by signing with the public key.
  • Each round grades you twice — correctly identify the exploit, then pick the correct server-side hardening (pin the algorithm, use a strong random secret, validate claims, allow-list kid).
  • Difficulty tiers add subtler cases: longer secret wordlists, kid-header injection, and nbf/exp not-before and expiry edge cases.

Frequently asked questions

What is the JWT Attack & Defense Lab?

A free, in-browser exercise that teaches JSON Web Token security by having you attack real tokens and then fix the verifier. A workbench signs and verifies HS256 tokens with the Web Crypto API, and a graded run walks through the classic JWT breaks — the alg:none trick, a brute-forceable HMAC secret, HS/RS algorithm-substitution (key confusion), missing claim validation, and kid-header injection — each demonstrated with genuine crypto, then matched to the correct server-side hardening. No account, upload or install.

Is this real cryptography or a simulation?

Real. HS256 signatures and verifications use crypto.subtle HMAC over SHA-256; the key-confusion round generates an actual RSA keypair and verifies RS256 with it, plus an ECDSA P-256 keypair for ES256; the dictionary attack recomputes a real HMAC for every candidate secret. Token headers and payloads are base64url-encoded exactly as the JWT spec requires. Nothing is faked or precomputed on a server — it all runs locally in your browser.

What is the alg:none attack and how do you stop it?

A verifier that reads the algorithm from the token header can be handed a token with header {"alg":"none"} and an empty signature. If it treats "none" as "already trusted", it accepts a token anyone can mint. The fix is to decide the expected algorithm on the server (for example HS256) and reject any token whose alg differs — never honour "none". The header alg is attacker-controlled input, not an instruction.

What is HS/RS key confusion?

When a library lets the token header choose between symmetric (HS256) and asymmetric (RS256) verification with the same configured key, an attacker switches the alg to HS256 and signs the forged token using the RSA public key as the HMAC secret — a value they legitimately have, because it is public. The server HMAC-verifies with that same public key and is fooled. The defence is to pin the algorithm per key out of band: an RSA verification key must only ever verify RS256.

Why validate claims if the signature is valid?

A signature proves integrity and origin; it says nothing about whether the token is still valid, meant for your service, or from an issuer you trust. A verifier must independently check exp and nbf against the clock, confirm aud matches this API, and confirm iss is a trusted authority. Skipping those turns one leaked or misissued token into a standing bypass, which is what the claim-hygiene round demonstrates.

🎉 New here? Use code WELCOME10 for 10% off any plan at checkout
JWT Attack & Defense Lab — Free Web Crypto Trainer · PlayCISO