Instantly decode JWT (JSON Web Tokens) to inspect Header and Payload claims. Professional-grade JWT analyzer with expiration tracking, security assessment, and 100% privacy.
JSON Web Tokens (JWT) have become the de facto standard for securing modern stateless applications. Defined in RFC 7519, a JWT provides a compact, URL-safe means of representing claims to be transferred between two parties. The claims in a JWT are encoded as a JSON object that is used as the payload of a JSON Web Signature (JWS) structure or as the plaintext of a JSON Web Encryption (JWE) structure, enabling the claims to be digitally signed or integrity protected with a Message Authentication Code (MAC) and/or encrypted. This guide provides a deep, technical breakdown of JWT architecture, encoding mechanisms, cryptographic strategies, and common security pitfalls.
A JWT in its compact form consists of three distinct parts separated by dots (`.`). These parts are the Header, the Payload (or Claims), and the Signature. Consequently, a typical JWT looks like this: `xxxxx.yyyyy.zzzzz`.
The header typically consists of two parts: the type of the token, which is `JWT`, and the signing algorithm being used, such as HMAC SHA256 or RSA. It serves as the metadata describing how the rest of the token should be processed.
{
"alg": "HS256",
"typ": "JWT"
}The second part of the token is the payload, which contains the claims. Claims are statements about an entity (typically, the user) and additional data. There are three types of claims: registered, public, and private claims.
{
"sub": "1234567890",
"name": "John Doe",
"admin": true,
"iat": 1516239022
}To create the signature part you have to take the encoded header, the encoded payload, a secret, the algorithm specified in the header, and sign that. For example, if you want to use the HMAC SHA256 algorithm, the signature will be created in the following way:
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret )
The signature is used to verify the message wasn't changed along the way, and, in the case of tokens signed with a private key, it can also verify that the sender of the JWT is who it says it is.
When you inspect a raw JWT string, you aren't looking at encrypted data; you are looking at Base64Url encoded data. This is a crucial distinction. Base64 is a binary-to-text encoding scheme that represents binary data in an ASCII string format by translating it into a radix-64 representation.
However, standard Base64 uses the characters `+`, `/`, and `=` (for padding). These characters have special semantic meaning in URLs and HTTP headers, which can lead to parsing errors when tokens are transmitted in standard web requests (like the `Authorization: Bearer <token>` header or as query string parameters).
To solve this, JWT relies on Base64Url encoding (defined in RFC 4648). Base64Url makes three critical modifications to standard Base64:
Because the Header and Payload are merely encoded (not encrypted), anyone who intercepts a JWT can decode it and read its contents. Never put secrets, passwords, or highly sensitive PII in the payload of a standard JWT. If you must transmit sensitive data securely within a token, you should use JSON Web Encryption (JWE) instead.
The most critical component of a JWT is its signature. The signature guarantees the token's integrity. If any single character in the header or payload is modified, the computed signature will change drastically, and validation will fail. There are two primary paradigms for signing JWTs: Symmetric (HMAC) and Asymmetric (RSA/ECDSA).
HMAC (Hash-based Message Authentication Code), such as HS256 (HMAC using SHA-256), is a symmetric algorithm. This means the same secret key is used both to sign the token when it is created and to verify the token when it is received.
Asymmetric algorithms use a public/private key pair. The Authorization Server signs tokens with its private key. Any consumer (API Gateway, microservice, third party) verifies tokens using only the corresponding public key. RS256 uses RSASSA-PKCS1-v1_5 with SHA-256 and a minimum 2048-bit RSA key. ES256 uses ECDSA with the NIST P-256 curve — producing ~4× smaller signatures than RS256 with equivalent or better security. PS256 (RSA-PSS) is the modern, provably secure RSA variant and should be preferred over RS256 in new systems. Public keys are typically distributed via a JSON Web Key Set (JWKS) endpoint — a standard JSON document at a well-known URI containing the public keys in JWK format.
Production systems using RS256 or ES256 should expose a /.well-known/jwks.json endpoint. Each key in the set has a kid field matching the kid in issued token headers. During key rotation, the old public key remains in the JWKS set until all tokens signed with it have expired. Consumers cache JWKS responses (respecting Cache-Control headers) and re-fetch only when they encounter an unknown kid, enabling zero-downtime key rotation without coordinated deployments.
alg: none FlawWhile JWT is a robust standard, historically poor implementations in popular libraries have led to catastrophic, zero-effort authentication bypasses. The most infamous of these is the alg: none vulnerability, first reported in 2015 and affecting libraries in Node.js, Python, Ruby, PHP, and Java ecosystems simultaneously.
RFC 7519 defines none as a valid algorithm value for use cases where the JWT is delivered over a channel that already provides integrity protection (e.g., mutual TLS). A none-algorithm token has a valid header and payload but an empty signature segment — the token ends with a trailing dot: header.payload.
The exploit in detail: Vulnerable library implementations resolved the verification path by reading the alg field from the token header itself rather than from a server-side trusted configuration. An attacker intercepts or constructs a JWT, modifies the payload (e.g., elevates "admin": false to "admin": true), changes the header algorithm to none, removes the signature, and replays the forged token. The server calls verify(token, secret), the library sees alg: none, concludes no cryptographic verification is needed, and returns the payload as fully trusted — without performing any signature check.
Step 1 — Legitimate HS256-signed token (admin: false):
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOmZhbHNlfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5cStep 2 — Attacker-forged token (alg: none, admin: true, empty signature):
eyJhbGciOiJub25lIn0.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.Decoded forged header: { "alg": "none" }
Decoded forged payload: { "sub": "1234567890", "name": "John Doe", "admin": true }
Signature: (empty — trailing dot only)
If the server blindly dispatched verification based on the header's algorithm field, it skipped all cryptographic checks and treated the forged payload as fully authentic. The attacker achieved privilege escalation with zero knowledge of any secret or private key.
verify(token, secret, { algorithms: ['HS256'] }). The library should then reject any token whose header declares a different algorithm.none as a valid algorithm unless you have a deeply considered, extremely narrow use case — and even then, handle it in a separate code path entirely isolated from your production verification logic.A closely related and equally devastating attack exploits the confusion between symmetric and asymmetric algorithm families. Consider a server configured to verify tokens using RS256. The server holds an RSA public key (often published at a JWKS endpoint) and uses it to verify incoming token signatures. An attacker retrieves this public key — which is public by design and freely downloadable.
The attacker then crafts a malicious token, sets the header algorithm to HS256, modifies the payload as desired, and signs the entire token using HMAC-SHA256 — but uses the server's RSA public key as the HMAC secret. When this forged token is sent to the server, a vulnerable library reads the header's alg: HS256 and switches to its HMAC verification path. That path calls HMAC-SHA256(token, serverPublicKey) — which is exactly what the attacker computed. The signatures match perfectly. Authentication is bypassed.
This vulnerability stems from the library treating the verification key and the algorithm selector as separate, independently trusted inputs rather than as an inseparable unit determined at configuration time.
Mitigations for Key Confusion
KeyObject in Node.js 18+) so the runtime distinguishes an RSA public key from an HMAC symmetric key at the type level — making it physically impossible to pass an RSA public key as an HMAC secret.jose, python-jose, nimbus-jose-jwt).Always validate exp and nbf claims on every request. Allow a small clock-skew tolerance (typically 30–60 seconds) to account for distributed system time drift, but no more. Issue short-lived tokens (5–15 minutes for access tokens) and use refresh token rotation to limit the blast radius of a stolen token.
aud) ValidationA JWT issued by your Auth Server for Service A must not be accepted by Service B. Always validate the aud claim against the resource server's own identifier. Missing audience validation is a horizontal privilege escalation vector in microservice architectures sharing an Auth Server.
jti)A stolen but unexpired JWT is fully valid. Protect sensitive operations by issuing single-use tokens with a unique jti claim, storing used JTIs in a fast deny-list (Redis with TTL matching token exp), and rejecting tokens whose JTI is already in the deny-list. This prevents replay attacks even within the token's validity window.
For HS256, a weak shared secret can be brute-forced offline — an attacker who intercepts a JWT can run it through Hashcat with a wordlist and recover the secret without any network interaction. Always use a cryptographically random secret of at least 256 bits (32 bytes), generated by a CSPRNG. Tools like openssl rand -base64 32 produce suitable secrets.
This JWT Decoder tool operates strictly within your browser. When you paste a token, the Base64Url decoding and JSON parsing happen entirely in local memory using native Web Crypto APIs. Tokens are never transmitted across the network, stored in logs, or saved to any database. We provide this utility as a secure, privacy-first diagnostic tool for developers working with sensitive authentication flows.
Technical standards, security compliance, and advanced debugging — everything a developer needs to understand what happens under the hood.
Every tool in the Dev Hub operates against a formal specification. Below is a comparison of the underlying standards, processing models, and privacy guarantees.
| Parameter | CSS Minifier | JS Minifier | SQL Formatter | JWT Decoder | YAML Validator |
|---|---|---|---|---|---|
| Processing Location | Browser (V8 JIT) | Browser (V8 JIT) | Browser (WASM) | Browser (atob/JSON.parse) | Browser (js-yaml) |
| Primary Standard | W3C CSS Level 4 | ECMAScript 2024 | ISO/IEC 9075 | RFC 7519 / RFC 8725 | YAML 1.2 Spec |
| Server Data Sent | ❌ Zero | ❌ Zero | ❌ Zero | ❌ Zero | ❌ Zero |
| AST Parsing | ✅ Yes | ✅ Yes (terser) | ✅ Yes (node-sql-parser) | ❌ No (base64 only) | ✅ Yes |
| Offline Support | ✅ Service Worker | ✅ Service Worker | ✅ Service Worker | ✅ Service Worker | ✅ Service Worker |
| Output Format | Minified stylesheet | Minified bundle | Indented SQL | Decoded JSON claims | Validated manifest |
CSS and JS minification uses Abstract Syntax Tree parsing — not simple regex. This ensures structural integrity is preserved even after whitespace removal, comment stripping, and shorthand optimization. The tree is fully rebuilt before serialization, preventing invalid output.
All code transformations are executed in-process within the browser's V8 JavaScript engine. Web Workers handle CPU-intensive tasks like large file minification, preventing main-thread blocking. No code — not even telemetry — is transmitted to any external server.
This node has been audited for mathematical precision and memory isolation by the MyUtilityBox engineering team. All logic executes locally in browser V8 to ensure zero data leakage. Last Verified: April 2026.
Input any JWT above to begin local analysis