JWT Signing Secret Hardcoded in Application Source
What Is This Vulnerability?
The secret key used to sign and verify JSON Web Tokens (JWTs) is written directly into the source code. An attacker who obtains this secret can forge valid tokens, impersonate any user, escalate privileges to admin, and bypass all authentication and authorization controls in the application.
Why It Happens
JWT libraries require a secret or key for signing, and tutorials often show inline string examples. Developers copy these patterns and never refactor them to use environment variables. In some cases, the same secret string (like 'secret' or 'jwt-secret') is used across all environments.
Example Code
import jwt from "jsonwebtoken";
const JWT_SECRET = "my-super-secret-jwt-key-2024";
export function generateToken(userId: string, role: string) {
return jwt.sign({ userId, role }, JWT_SECRET, { expiresIn: "24h" });
}
export function verifyToken(token: string) {
return jwt.verify(token, JWT_SECRET);
}import jwt from "jsonwebtoken";
const JWT_SECRET = process.env.JWT_SECRET;
export function generateToken(userId: string, role: string) {
if (!JWT_SECRET) {
throw new Error("JWT_SECRET environment variable must be set");
}
return jwt.sign({ userId, role }, JWT_SECRET, { expiresIn: "24h" });
}
export function verifyToken(token: string) {
if (!JWT_SECRET) {
throw new Error("JWT_SECRET environment variable must be set");
}
return jwt.verify(token, JWT_SECRET);
}How Hackers Exploit It
With the JWT secret, an attacker can craft tokens with arbitrary claims, such as setting their role to admin or impersonating another user. They can also modify the expiration time to create tokens that never expire. Since the server trusts any token signed with the correct secret, forged tokens are indistinguishable from legitimate ones.
How to Fix It
Move the JWT secret to an environment variable and ensure it is a long, randomly generated string (at least 256 bits of entropy). Consider using asymmetric signing (RS256) with a private key stored in a secrets manager and a public key for verification. Rotate the secret periodically and implement token revocation for compromised sessions.