DEV Community

Rashid Salimov
Rashid Salimov

Posted on Originally published at vault-pro.rashid-salimov96.workers.dev

Stop Pasting Production JWTs into Random Websites: The Security Guide to JSON Web Tokens

How many times this week have you opened a random online "JWT Debugger", pasted an Authorization: Bearer eyJhbGci... token from your production network tab, and hit enter?

Most developers treat online JWT inspectors like formatters. But here is the uncomfortable truth: when you paste a token into a server-rendered online decoder, you are handing a third-party server your user IDs, tenant claims, role permissions, and potentially a live session that does not expire for days.

If their logging is sloppy, your production bearer token is now sitting in a centralized log aggregator or third-party analytics database.

Here is a breakdown of why JWTs are so frequently misunderstood, how the anatomy actually works under the hood, the top vulnerabilities to defend against, and how to inspect them 100% locally in your browser.


1. The #1 Misconception: JWT is Signed, NOT Encrypted

The single most common mistake junior developers make is assuming that because a token looks scrambled (eyJhbGci...), its payload is secret.

A standard JSON Web Token (RFC 7519) is a JWS (JSON Web Signature). It is Base64Url encoded, not encrypted. Anyone who intercepts the token can decode the claims in two lines of JavaScript:

// Never store API keys or passwords here!
const payload = JSON.parse(atob(token.split('.')[1]));
console.log(payload);
Enter fullscreen mode Exit fullscreen mode

If you need cryptographic confidentiality where only the recipient can read the contents, you must use JWE (JSON Web Encryption), which wraps the payload in an authenticated cipher like AES-GCM.


2. The 3-Part Anatomy of a JWT

A standard token consists of three distinct segments separated by periods:

  eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9   .   eyJzdWIiOiIxMjM0NTYiLCJyb2xlIjoiYWRtaW4ifQ   .   SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
 └─────────────────┬───────────────────┘     └──────────────────────┬──────────────────────┘     └─────────────────────┬────────────────────┘
             1. Header                                      2. Payload                                        3. Signature
         (Algorithm & Type)                             (Claims & Metadata)                               (Tamper Verification)
Enter fullscreen mode Exit fullscreen mode

Part 1: The Header

Defines the cryptographic algorithm (alg) and token type (typ):

{
  "alg": "HS256",
  "typ": "JWT"
}
Enter fullscreen mode Exit fullscreen mode

Part 2: The Payload (Claims)

Contains user identity and authorization metadata:

  • sub (Subject): Unique user or service ID.
  • iat (Issued At): Unix timestamp of token generation.
  • exp (Expiration): Unix timestamp when the token becomes invalid.
  • Custom claims: role: "admin", org_id: "acme-corp".

Part 3: The Cryptographic Signature

Ensures data integrity. Computed by hashing the header and payload with a secret key:

$$\text{Signature} = \text{HMAC-SHA256}(\text{Base64Url}(\text{Header}) + "." + \text{Base64Url}(\text{Payload}), \text{secret})$$

If an attacker alters a single character in the payload (e.g. changing "role": "user" to "role": "admin"), the server's verification recalculation fails immediately.


3. The 3 Critical JWT Vulnerabilities to Avoid

1. The Infamous alg: "none" Attack

The JWT specification originally allowed an algorithm named none for testing environments without signatures. Attackers discovered they could modify the header to {"alg": "none"}, strip the signature segment, and bypass signature verification entirely on poorly written backend libraries.

Defense: Always enforce a whitelist of accepted algorithms on your server (e.g., algorithms: ['RS256']) and reject unsigned tokens unconditionally.

2. Symmetric vs Asymmetric Confusion (HMAC vs RSA)

When a server expects an asymmetric key (RS256 with public/private keys), an attacker might obtain the public key (which is publicly visible) and sign a forged token using symmetric HS256, feeding the public key as the secret.

Defense: Never let the token header dictate which key verification function is used. Pin your verification logic to asymmetric verification (jwt.verify(token, pubKey, { algorithms: ['RS256'] })).

3. Expiration Ignorance

Stateless JWTs cannot be revoked without a centralized denylist (like Redis). If your access tokens have a lifetime of 30 days and an engineer's laptop is compromised, that token remains valid for 30 days.

Defense: Keep access token lifetimes short (5 to 15 minutes) and rely on rotating refresh tokens stored in HttpOnly, Secure, SameSite=Strict cookies.


4. How to Inspect Tokens Safely 100% In-Browser

You do not need to send your tokens to a remote server just to format JSON claims or verify an expiration timestamp.

If you need a fast, private way to debug tokens without risking your company's credentials, we built a client-side JWT Decoder on Digital Vault PRO.

It runs entirely in your local browser sandbox:

  • Zero Server Uploads: The token string never leaves your device (verify it in the DevTools Network tab — zero HTTP requests).
  • Expiration Visualizer: Instantly shows whether the token is active, expired, or not yet valid based on exp and nbf claims.
  • Header & Payload Formatter: Formats claims, humanizes Unix timestamps, and inspects token metadata locally.

Next time you need to debug a 401 Unauthorized header, keep your production credentials off third-party servers!

Top comments (0)