JWT Attacker

JWT Attacker

Inspect a JSON Web Token for known attack surfaces and forge a new token in your browser.

Preset library:

No findings yet — paste a JWT above to begin.

Forge playground

kid playground

Rendered server-side path (never fetched)
keys/.pem

About JWT Attacker

JWT Attacker is a browser-based tool for security engineers, pentesters, CTF players, and code reviewers. Where the sibling JWT Decoder assumes the token is well-formed and the JWT Creator assumes the user is on the defending side, JWT Attacker assumes nothing: paste any three-segment JWT and instantly see, in one findings panel, every well-known attack surface the token is exposed to.

The five attack classes the tool detects

  • alg: none bypass — including any case variant (None, NONE, NoNe) and any leading / trailing whitespace. A token with alg: none declares that no signature is required; a vulnerable verifier will accept it as-is.
  • HS256 ↔ RS256 key-confusion — when the token's alg is in the RSA family and a public key is supplied, the tool mints an HS256 token whose secret is the public key bytes and reports whether the signature would be accepted by a vulnerable verifier (via the in-page key-confusion forge, gated behind a two-click disclosure).
  • kid injection markers — path-traversal (../, ..%2f, %2e%2e%2f), SQL injection (', --, union select, or 1=1), and XSS markers (<script>, javascript:, on*=) in the kid header value. Each match is its own finding row with the marker named.
  • Header injection — the presence of jku, jwk, x5u, or x5c in the header, with a one-line SSRF / key-substitution / trust-store-injection risk note and the URL or key blob rendered next to the title.
  • Claim-based replay / replacement hints — missing exp, missing nbf, iat in the future, exp in the past, and exp - iat longer than 30 days. Reuses the JWT Decoder's interpretTimeClaims for the time math; the new code lives in a thin wrapper that turns each state into a finding row.

What the kid playground is for

The kid playground lets you type any custom kid value and see the rendered server-side path it would resolve to, using a template you control (default: keys/<kid>.pem). It is purely client-side string assembly — no network request is ever made to the rendered path. The purpose is to demonstrate kid-injection attacks (path traversal, SQLi, XSS-via-kid) without ever touching a real server. For example, type ../../etc/passwd and the playground renders keys/../../etc/passwd.pem — exactly the file path a vulnerable verifier would read. The "Swap kid" action writes the playground's kid into the forge playground's header so you can immediately sign a variant with the new kid and study the resulting token.

The "Forge with current key" playground

Below the findings panel, the forge playground supports all nine JWS algorithms (HS256, HS384, HS512, RS256, RS384, RS512, ES256, ES384, ES512) and reuses signJwt / verifyJwt from the JWT Decoder's jwt.js — no new crypto code. Pick an algorithm, edit the header and payload as JSON, supply a key (the label and placeholder auto-switch between "shared secret" and "PEM private key" based on the algorithm family, mirroring the JWT Creator's pattern), click Sign to produce a three-segment token, click Copy to put it on the clipboard, and click Verify to run signature verification with the currently-supplied key.

Two-click gating for the alg: none forge

The "Generate alg: none variant" button is gated behind a small Show me the alg: none variant disclosure on the alg finding row, so a casual visitor who pastes a token does not accidentally produce an alg: none token on their clipboard. The button is rendered conditionally on the disclosure's expanded state — it is NOT in the DOM (not just hidden) until the user clicks the disclosure. The expert audience is willing to click twice; the footgun is not worth the saved click.

Common use cases

  • CTF challenges — the "five preset" library ships with one canonical known-bad token per attack class (alg-none bypass, kid with ../, jku header injection, RS256 + public key for key-confusion, clean token) so demos and writeups are one click away.
  • Code review — paste a token from a pull request and see, in one glance, whether the verifier is exposed to the alg-none bypass, key-confusion, kid-injection, or claim-audit classes.
  • Pentest writeups — the in-page alg-none forge and key-confusion forge let you mint the bypass variant and copy it to the clipboard without leaving the page; the resulting token round-trips through the sibling JWT Decoder for verification.
  • Teaching — the per-finding explanation block (with the relevant RFC or PortSwigger Academy reference) and the kid playground are designed to be read alongside a security textbook.

Privacy invariant

All analysis, all five detectors, both forges, and the kid playground run entirely in your browser. No token, no key, no signed output, and no kid-derived URL is ever sent in a network request. This is verified at runtime by a Playwright page.on('request') listener in the end-to-end test suite (the same pattern the JWT Decoder and Email Header Analyzer tools use). The site is served from HTTPS in production, so the browser's SubtleCrypto API (used by the key-confusion forge) is available; the rare non-secure-context case disables the key-confusion forge button with a clear explanation, and the rest of the tool still works.

Comments

Please accept the "Functionality" cookie category to view and post comments.