hakluke@~
~$ ./jwt-hacking --token <paste>

JWT Hacking Toolkit

This page does two things. It teaches you how JWT attacks work — step by step, on a live token, nothing to install — and it's a fast editor for crafting JWTs once you know how: decode a token, edit either side, re-sign it, and fire off one-click forgeries like alg:none, algorithm confusion and kid injection.

A JSON Web Token (JWT) is the eyJ... string an app hands you after login to remember who you are. If that sentence is new, you're in the right place — start with the walkthrough.

Never seen a JWT before? The walkthrough teaches you one step at a time, and drives the real editor as it goes. Learn mode adds that walkthrough, the explanation on every panel, and a glossary of what each claim means. Turn it off for the bare tool.

Everything runs in your browser. No token, key or secret ever leaves this page — there is no backend here. Only test tokens you are authorised to test.

what is a JWT?

A JWT is three chunks of base64url text joined by dots. Base64 is encoding, not encryption — anyone holding the token can read every part of it, including you, right now.

1 — header
{"alg":"HS256","typ":"JWT"}
Which algorithm signed the token. The server reads this to decide how to check the signature — and you control it, which is where a lot of the trouble starts.
2 — payload
{"sub":"1337","role":"user","exp":1798675200}
The claims: who you are, what you're allowed to do, when the token dies. This is what the app trusts about you, so it's what an attacker wants to change.
3 — signature
sir4Z6YFHRlNI80opm9Upk...
Proof that the server — and only the server — produced parts 1 and 2. It is the single thing stopping you from editing the payload and becoming an admin.

When a token comes back, the server recomputes the signature over header.payload using its key, and compares. Match means untampered. Every attack on this page is a way of making that comparison pass when it shouldn't — or making the server skip it entirely.

how this page works
  1. 1The token box below holds one JWT. A sample is already loaded, or paste your own over it.
  2. 2The panels under it show that token decoded. Edit either side and the other updates instantly — that is the whole tool.
  3. 3The attack buttons rewrite the token for you, then write to the log what they changed and what server bug it tests.

1 · paste your JWT

Paste any JWT here, or use the sample. Green is the header, blue the payload, amber the signature. Type in this box and the decoded JSON below follows; edit the JSON and this box follows.

alg signature expiry

walkthrough

1/12  · 

2 · decode & edit the JWT

The same token, decoded. Everything here is editable, and every edit rewrites the box above.

header

alg tells the server how to verify. kid, if present, tells it which key to fetch. Both arrive from the client, so both are attacker-controlled input.

payload

Edit any claim and the token above rebuilds instantly. With auto re-sign on it is signed with whatever key material you've supplied; with it off you get a tampered token carrying its original, now-wrong signature — which is exactly what you send when you want to know whether the server checks at all.

signature & keys

HS* algorithms sign and verify with the same shared secret — know it and you can mint any token you like. RS/PS/ES sign with a private key and verify with a public one, so forging needs the private half — unless the server can be tricked into using the wrong key, which is what half the attacks below are about.

HMAC secret (HS256/384/512)
Public key (PEM SPKI — verify, alg confusion)
Private key (PEM PKCS#8 — sign RS/PS/ES)

crack HMAC secret

Tries a built-in list of common JWT secrets against the current HS* token. Add your own below, one per line. For anything serious use hashcat -m 16500.

3 · JWT attacks

Each button rewrites the current token in place and logs what it did. Use undo to step back.

None of these break cryptography — they exploit servers that trust the token to describe how it should be checked. Click one, read the log entry it writes underneath, then send the token at your target and watch whether it is accepted. Acceptance is the finding; the tool can't tell you that part.

signature bypass

Make the signature check pass without the key — or skip it altogether. These are the ones that turn into full authentication bypass, so try them first.

alg case variants (signature stripped):

The same attack as alg:none in different cases. Blocklists that reject the exact string “none” often still match case-insensitively when choosing the verifier.

key confusion & injection

The header can name, carry, or link to the key used to verify it. Point any of those at a key you own and the maths still checks out — for the wrong key. Each of these generates a real keypair and signs with it.

attacker URL

Where you'll host the key file. Any host the target can reach works — a VPS, an S3 bucket, a gist, an ngrok tunnel.

kid header injection

kid is a string from the token that the server feeds into a key lookup — a file path, a database query, sometimes a shell command. Ordinary injection, sitting in an authentication header.

claim tampering

Where the impact comes from. These need a token the server already accepts — solve the signature first, then come back and decide who you want to be.

target user

weak secret re-sign

Re-signs the token with HS256 using a known-weak secret. If the app accepts the result, its signing key is guessable and you can mint any token you like.

Faster than cracking when you only want a yes/no: pick the secret the developer probably used and see if the server agrees. The cracker in section 2 tries a longer list.

claim injection payloads

Drops a classic injection payload into the claim you name, then re-signs.

Claims don't stay in the token — they end up in SQL queries, templates, log lines and lookups. A signed token is a trusted-looking delivery vehicle for all of it.

into claim

4 · what just happened

what just happened

No attacks run yet.

5 · token analysis

claims

Every claim in the current payload, with timestamps decoded. Standard claims are explained inline; anything else is the application's own invention — and those are usually the ones that decide what you're allowed to do.

findings

Automatic observations about the token as it stands. [!] is a broken token, [~] is worth attacking, [i] is context.

    JWT hacking FAQ

    What is a JWT?

    A JSON Web Token is three base64url-encoded chunks joined by dots: a header naming the algorithm that signed it, a payload of claims about you, and a signature proving a server produced the first two. The header and payload are encoded, not encrypted, so anyone holding the token can read them.

    Can you decode a JWT without the secret key?

    Yes. Decoding needs no key at all, because the header and payload are ordinary base64url-encoded JSON. A key is only needed to verify the signature, or to produce a token the server will accept.

    Is it safe to paste a JWT into an online decoder?

    Only if the decoder runs entirely in your browser. This page has no backend, so your token, keys and secrets never leave the tab. Treat any tool that sends tokens to a server as a credential leak, because a JWT usually is one.

    What is the alg:none attack?

    The alg field in the header tells the server which algorithm to verify with. Setting it to none and deleting the signature makes libraries that trust that field skip verification entirely, which lets you forge any claim you like. Case variants such as None and NONE are worth trying, because blocklists often miss them.

    What is JWT algorithm confusion (RS256 to HS256)?

    RS256 signs with a private key and verifies with a public one. If a server picks its verification function from the token's alg header but passes in the RSA public key it holds, you can sign a token with HS256 using that public key as the HMAC secret. Public keys are published on purpose, so this turns public data into a signing key.

    How do you crack a JWT secret?

    HS256, HS384 and HS512 tokens are signed with a shared secret, and cracking is entirely offline: you already hold the signing input and the signature, so candidates can be tested without touching the target. This page tries a built-in list of common secrets; for a real wordlist use hashcat with mode 16500.

    What is kid injection in a JWT?

    The kid header names which key the server should verify with, and servers feed that string into a file path, a SQL query or sometimes a shell command. That makes it injectable like any other untrusted input: point it at /dev/null and sign with an empty key, UNION-select a key you choose, or test it for command injection and SSRF.

    How do I protect my application from JWT attacks?

    Pin the algorithm server-side and reject anything else. Never read alg, jwk, jku or x5u from the token to decide how to verify it. Treat kid as an opaque lookup into a fixed key set, never as a path or a query fragment. Use a random secret of at least 32 bytes for HMAC, validate exp, nbf, aud and iss on every request, and keep token lifetimes short.

    who made this

    Luke Stephens (hakluke)

    Luke Stephens, better known as hakluke, is a hacker and entrepreneur, and the founder and CEO of Haksec Group — a group of cybersecurity companies. He built this toolkit.

    Haksec Group spans:

    • HackerContent — a cybersecurity marketing agency, writing technical content for security companies.
    • Ironbark Cyber — a cybersecurity consultancy, doing the offensive testing that finds bugs like the ones on this page.
    • TRIAGERS™ — an outsourced triage team for vulnerability disclosure and bug bounty programs.

    subscribe

    Get an email when I publish something new. No spam, ever.