VibeSecurity

Security check

JWT security: the mistakes that let attackers forge sessions

A JWT is signed, not encrypted. Anyone can read its contents, and its safety depends entirely on verifying the signature correctly on the server.

By the VibeSecurity team1 min read

Mistakes to look for

  • Using a decode function where a verify function is needed, so the signature is never checked.
  • Accepting the algorithm named inside the token instead of pinning the expected one.
  • Short, guessable or default signing secrets.
  • No exp claim, or very long lifetimes for tokens that cannot be revoked.
  • Secrets or personal data stored in the payload, which is only base64 encoded.
  • Trusting a role or admin flag read from the token without checking it against your database for sensitive actions.

Verify with a pinned algorithm

jsonwebtoken
import jwt from 'jsonwebtoken';

const payload = jwt.verify(token, process.env.JWT_SECRET!, {
  algorithms: ['HS256'],
  issuer: 'https://your-app.example',
});

Create a strong secret

Terminal
openssl rand -base64 48

Storage and lifetime

  • Prefer short-lived access tokens with a refresh flow.
  • Where you can, store tokens in HttpOnly, Secure cookies instead of localStorage.
  • Rotate the signing secret if it was ever committed or shared.

Frequently asked questions

Can users read what is inside a JWT?

Yes. The payload is base64url text. Never store anything in it that you would not show the user.

Are JWTs a bad idea?

No, but they are easy to misuse. Server-side sessions are a simpler choice when you do not need stateless tokens.

Sources

  1. 1.RFC 8725: JSON Web Token best current practices