DEV Community

Neural Download
Neural Download

Posted on • Originally published at neuraldownload.com

JWT Is Not Encrypted (And That's By Design)

https://www.youtube.com/watch?v=2UIT8w0YvIg

Every time you log into a website, the server hands you a token. A long, ugly string of characters. You carry it with you on every single request. "Here's my token. Let me in."

But most developers never actually look inside that token. Let's fix that.

What's Inside a JWT

Take a real JWT. It looks like random noise — three chunks of gibberish separated by dots. But base64 decode the first chunk and it's just JSON. Plain text. It says algorithm: HS256, type: JWT. That's the header. It tells you how this token was signed.

Decode the second chunk. More JSON. This time it's your identity — your user ID, your name, your role, when this token expires. All of it sitting right there. Not encrypted. Not hidden. Just encoded.

Anyone with your token can read everything about you. Right now. In their browser console. That's not a bug — that's how JWT was designed.

Header, Payload, Signature

A JWT has three parts: header dot payload dot signature.

The header tells the server which algorithm to use. The payload carries your claims — your identity, your permissions. And the signature is a mathematical proof that nobody tampered with the other two parts.

Think of the signature like a wax seal on a letter. The letter itself isn't secret. Anyone can read it. But if someone changes even one character, the seal breaks.

Here's the critical insight: the server never needs to store your session. No database lookup, no Redis cache, no session table. It just checks the signature. Valid? The payload is trustworthy. Invalid? Rejected.

That's why JWT became so popular. Stateless authentication. The token carries everything the server needs.

How HMAC Signing Works

The server has a secret key — a long random string that only it knows.

  1. Base64 encode the header
  2. Base64 encode the payload
  3. Concatenate them with a dot
  4. Feed that string plus the secret key into a hashing algorithm

What comes out is a fixed-length hash — a fingerprint. Change one letter in the payload, even a space, and the hash is completely different. That's your signature.

When a token comes back, the server repeats the process: recompute the signature using its secret key, and compare. Match? Authentic. Different? Someone modified it. Rejected.

This is why the secret key matters so much. If an attacker gets your key, they can forge any token they want — any user, any role, any permission. The whole system crumbles with one leaked secret.

The alg: none Attack

Remember the header has an alg field that tells the server which algorithm to use? In 2015, researchers discovered that multiple JWT libraries honored alg: "none" — meaning no algorithm, no signature needed.

An attacker could set their role to admin, remove the signature completely, and walk right in. The libraries trusted the token to tell them how to verify itself. The fox guarding the henhouse.

The fix: never let the token dictate how it gets verified. The server should already know which algorithm it expects. Anything else gets rejected immediately.

Modern libraries have patched this. But it's a perfect example of how a convenient design can hide a catastrophic flaw.

Common JWT Mistakes

Weak secrets. If your signing key is "password123", an attacker can brute force it offline. They have the header and payload in plain text — they just need to guess the key until the signature matches. Use at least 256 bits of randomness.

No expiration. If a token never expires, a stolen token works forever. Always set the exp claim. Short-lived tokens (15 minutes to an hour) limit the blast radius.

Sensitive data in the payload. Remember, anyone can decode it. Don't put passwords, credit card numbers, or internal system details in there. The payload is public — treat it that way.

No revocation strategy. JWT is stateless, which means you can't traditionally invalidate a single token. If a user logs out or gets compromised, their token still works until it expires. Solutions exist (token blocklists, short expiration plus refresh tokens) but they add complexity back. The stateless dream has limits.

JWT is a powerful tool. But like any powerful tool, it assumes you know where the sharp edges are.

Neural Download — visual mental models for the systems you use but don't fully understand.

Top comments (0)