SoftwareTestPilot
Free tool · 100% in-browser · no signup

JWT Debugger for QA & API Testers

Decode any JWT, verify HS256 / RS256 / ES256 signatures, and run a vulnerability audit (alg=none, weak secrets, jku/kid abuse, sensitive claims). One-click export to Postman, Playwright, Rest Assured, cURL. Your tokens never leave the browser.

OWASP JWT auditHS + RS + ES verifyExpiry countdownPostman + Playwright exportSample attack tokens100% local
Sample tokens (safe + attack)
Header · algorithm & token type
{
  "alg": "HS256",
  "typ": "JWT"
}
Payload · claims
{
  "sub": "1234567890",
  "name": "QA Tester",
  "admin": true,
  "iat": 1516239022,
  "exp": 9999999999
}
Signature
tPZTgH0YlrbShvXqxr_DjZNGgcVh3jNxwCxdo3f7ChM
Timestamps
iat2018-01-18T01:30:22.000Z · 3103d agonbfexp2286-11-20T17:46:39.000Z · in 95089dVALID

Header alg=HS256 — paste the shared secret below.

Secret is 19 bytes — for HS256 use ≥ 32 bytes (256 bits) or it's brute-forceable.

Checks OWASP JWT Cheat Sheet + RFC 8725 anti-patterns. Findings map to real CVE classes.

Long-lived bearer tokenmedium

Token TTL is ~98192 days (8483760977s). Bearer tokens should be short-lived.

Fix: Drop access-token TTL to ≤15 minutes and rely on refresh tokens for continuity.

Missing iss claimmedium

iss identifies your auth server. Without it you can't safely verify a token came from the expected issuer.

Fix: Require iss and validate it against a fixed allow-list in the verifier.

Missing aud claimmedium

aud binds the token to a specific API. Without it, a token minted for Service A works for Service B.

Fix: Require aud and validate the API-specific value on every request.

Symmetric HS algorithm in useinfo

Header uses HS256. Anyone with the secret can mint tokens. Fine for internal service-to-service; risky for public APIs.

Fix: For public APIs use RS256 or ES256 so only the auth server holds the private key.

// Postman → Pre-request Script
// Auto-refreshes the JWT if within 60s of expiry.
const token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IlFBIFRlc3RlciIsImFkbWluIjp0cnVlLCJpYXQiOjE1MTYyMzkwMjIsImV4cCI6OTk5OTk5OTk5OX0.tPZTgH0YlrbShvXqxr_DjZNGgcVh3jNxwCxdo3f7ChM";
const [, payloadB64] = token.split(".");
const pad = "=".repeat((4 - (payloadB64.length % 4)) % 4);
const payload = JSON.parse(
  Buffer.from((payloadB64 + pad).replace(/-/g, "+").replace(/_/g, "/"), "base64").toString()
);
const nowSec = Math.floor(Date.now() / 1000);
if (!payload.exp || payload.exp - nowSec < 60) {
  // TODO: call your /refresh endpoint here
  console.warn("JWT expiring soon — implement refresh");
}
pm.request.headers.upsert({ key: "Authorization", value: "Bearer " + token });

Why this JWT debugger beats jwt.io for QA teams

Vulnerability audit (15 checks)

alg=none, weak HS secret, missing exp, long-lived TTL, jku/x5u/jwk header abuse, kid path traversal, sensitive claims — with the exact remediation for your framework.

Live expiry countdown

iat / nbf / exp shown as ISO plus 'in 12m' / '4d ago'. VALID / EXPIRED badge updates every second so you never chase a stale token bug.

HS + RS + ES verify locally

WebCrypto verifies HS256/384/512 with a secret and RS256/384/512 + ES256 with a JWK. No round trip to a server.

Postman & Playwright export

Pre-request script that auto-refreshes near exp, Playwright request context, Rest Assured spec, cURL, Axios, Fetch — copy-paste ready.

Sample attack tokens

alg=none, expired, 10-year TTL, jku SSRF, kid path-traversal. Load one, run the audit, rehearse the fix before it ships.

100% local — safe for prod tokens

Zero network calls. Security teams that block jwt.io internally allow this tool because your bearer tokens and HS secrets never leave the tab.

How QA engineers use this JWT debugger

Auth negative-path tests
  1. Load the 'alg=none' sample.
  2. Send it to your protected endpoint via Postman/Playwright.
  3. Assert 401. If you get 200 — file a P0.
  4. Repeat with 'expired', 'jku', and 'kid path traversal'.
Postman collection setup
  1. Paste your JWT and open Export → Postman.
  2. Copy the pre-request script into your collection's Auth folder.
  3. Set token in a collection variable.
  4. Refresh logic runs automatically when exp is 60s away.
Playwright API auth
  1. Paste id_token from your login.
  2. Export → Playwright request context.
  3. Drop into fixtures.ts as an authenticated api fixture.
  4. Reuse across every API spec.
Rest Assured / Java
  1. Paste bearer token.
  2. Export → Rest Assured.
  3. Wrap in a RequestSpecBuilder singleton.
  4. Add negative-path test asserting 401 with tampered payload.

JWT claims & algorithms cheat sheet

Registered claims

ississuer
subsubject / user id
audaudience / API
expexpiry (unix seconds)
nbfnot before
iatissued at
jtiunique token id

Header fields

algsigning algorithm
typusually JWT
kidkey id (for JWKS)
jkuAVOID — SSRF risk
x5uAVOID — SSRF risk
jwkAVOID — trust attack
ctycontent type

Algorithms

HS256/384/512HMAC — shared secret
RS256/384/512RSA + SHA — public/private
ES256/384ECDSA — public/private
PS256/384RSA-PSS
EdDSAEd25519
noneNEVER — always reject

Common CVEs

alg=none bypassCVE-2015-9235 class
RS→HS confusionCVE-2016-10555
kid path traversalauth bypass
jku SSRFOWASP JWT §6
weak HS secrethashcat 16500

Recommended TTLs

Access token15 min
Refresh token7-30 days
Password reset15 min
Email verify24 h
Service token1 h max

Providers

Auth0/.well-known/jwks.json
AWS Cognito/.well-known/jwks.json
Okta/oauth2/default/v1/keys
Firebasesecuretoken jwks
Keycloak/realms/{r}/protocol/openid-connect/certs

Pair this with

JWT debugger — frequently asked questions

1.Is this JWT debugger safe to paste production tokens into?
Yes. Decoding, signature verification, encoding, and the vulnerability audit run 100% inside your browser using the native WebCrypto API. There is no fetch, no analytics event, and no server round-trip — open DevTools → Network while pasting a token and you'll see zero outbound requests. This is the main reason security teams block jwt.io internally and allow this tool: your bearer tokens, refresh tokens, and HS256 secrets never leave the tab.
2.How is this different from jwt.io?
Six differences that matter for QA and security engineers: (1) an automatic vulnerability audit that flags alg=none, weak HS secrets, missing/oversized exp, expired or not-yet-valid tokens, jku/x5u/jwk header abuse, kid injection payloads, and sensitive claims in the payload; (2) live expiry countdown and human-readable iat/nbf/exp; (3) one-click export to Postman pre-request scripts, Playwright request context, cURL Authorization headers, Axios interceptors, and Rest Assured; (4) HS256/HS384/HS512 signing and verification with WebCrypto; (5) RS256/384/512 and ES256 verification with a pasted JWK; (6) sample library with real attack tokens so you can rehearse fixes before they hit staging.
3.Which algorithms are supported?
Decoding is universal — any JWT (or JWS) with a base64url header, payload, and signature. Signing supports HS256, HS384, and HS512. Verification supports HS256/384/512 with a shared secret and RS256/384/512 and ES256 with a JWK (paste the JSON Web Key from your OIDC /.well-known/jwks.json). The unsafe alg=none is decoded and flagged as a CRITICAL vulnerability but never emitted.
4.What does the vulnerability audit check?
Fifteen checks aligned with OWASP JWT Cheat Sheet and RFC 8725 (JWT BCP): alg=none, HS with a secret shorter than the algorithm digest, missing exp, exp more than 24 hours after iat (long-lived bearer), token already expired, nbf in the future, missing iss / aud / sub for user tokens, jku or x5u header (SSRF risk), embedded jwk header (self-provided key attack), kid values containing path traversal or SQL characters, typ missing or non-standard, cty=JWT (nested JWT confusion), sensitive keys in payload (password, ssn, credit_card, api_key), and confusable RS→HS algorithm downgrade patterns. Each finding shows the exact remediation for your framework.
5.Can I verify a token signed by Auth0, Cognito, Okta, Firebase, or Keycloak?
Yes. Copy the matching JWK from your provider's JWKS endpoint (Auth0: /.well-known/jwks.json; Cognito: /.well-known/jwks.json under the user pool; Okta: /oauth2/default/v1/keys; Firebase: securetoken.google.com/{project}/well-known/jwks; Keycloak: /realms/{realm}/protocol/openid-connect/certs), paste it into the JWK panel, and the tool imports it via crypto.subtle.importKey and verifies the RS256 / ES256 signature locally.
6.How do I use the tool with Postman, Playwright, or Rest Assured?
Paste your JWT, click Export, and pick your target. Postman gets a pre-request script that decodes the token, checks expiry, and refreshes if within 60 seconds of exp. Playwright gets a request.newContext({ extraHTTPHeaders: { Authorization: `Bearer ${token}` } }) snippet. Rest Assured gets a RequestSpecBuilder that adds the header and asserts the response is not 401. cURL, Axios, and Fetch snippets are also available.
7.Can I sign a new JWT for testing?
Yes. Switch to the Encode tab, fill in your header (alg, typ, kid), payload (claims + iat/exp), and shared secret. The tool signs it with WebCrypto and emits a valid HS256/384/512 token you can drop into your integration tests as a fixture, or use to reproduce a specific claim shape a bug reporter sent you. RS/ES signing is intentionally not supported — private keys should never be pasted into browser tools.
8.Does the tool store my tokens or secrets?
The current token stays in a React useState — cleared on refresh. There is no localStorage, no IndexedDB, no cookies, and no telemetry. If you want a shareable link you must build it yourself; the tool intentionally does not expose one so you can't accidentally paste a live JWT into Slack via a URL.
9.Is the JWT debugger free? Do I need to sign up?
Yes, 100% free with no login, no watermark, no ads, and no rate limits — same as every other tool at /tools. Bookmark and share it internally to replace jwt.io for teams that block third-party token debuggers.
10.Which JWT vulnerabilities can this tool actually catch in a QA workflow?
Every audit check maps to a real CVE class or OWASP finding: alg=none (CVE-2015-9235 style bypass), algorithm confusion (CVE-2016-10555, RS→HS with the public key as secret), embedded jwk (RFC 7515 §4.1.3 abuse), jku SSRF, kid path traversal (auth bypass via /dev/null or SQL), missing exp (persistent session hijack), overly long TTL, weak HS secret (brute-forceable in seconds with hashcat mode 16500). Add the JWT debugger to your API test suite's negative-path checklist.