← All fixes

Fix it

Hardcoded JWT or session secret — how to fix it

High severityCWE-798 (Use of Hard-coded Credentials)
We scanned nearly 2,000 AI-built apps and 1 in 8 shipped a high-severity flaw. Is this one in yours?Scan free →

The secret that signs your JWTs or sessions is the key to every user's identity. If it is hardcoded in source, or falls back to a default when the environment variable is missing, anyone who knows it can forge a valid token for any user, including an admin. Read it from the environment with no fallback, and fail loudly if it is not set.

Why it's a problem

Your server trusts a token because it can verify the signature with this secret. If an attacker has the secret, they can mint a token with any claims they want, a different user id, an admin flag, and your server will accept it as genuine. A fallback like process.env.JWT_SECRET || 'dev-secret' is the same as hardcoding, because the moment the variable is unset in production the default is used.

The pattern

const token = jwt.sign(
  payload,
  process.env.JWT_SECRET || "dev-secret"
);

The fix

const secret = process.env.JWT_SECRET;
if (!secret) throw new Error("JWT_SECRET not set");
const token = jwt.sign(payload, secret);

Why AI tools write this

The fallback pattern is a common training-data idiom because it makes the code run in development without setup. It works locally, so it survives to production, where a missing environment variable silently activates the public default value.

The quick fix

  • Read the signing secret from an environment variable with no fallback default.
  • Throw or refuse to start if the secret is not set, rather than using a default.
  • Use a long, random secret, and rotate it if it was ever hardcoded (this invalidates existing sessions).

Want to know if this pattern is already in something you shipped? Scan your live app or a public repo free, no account needed.

Scan my app →

Related: what a JWT is

Hardcoded JWT / Session Secret — Why It's Dangerous and the Fix: Prbl