All vulnerabilities
HighA07:2021CWE-347Authentication Failures

JWT Security Issues

Insecure JWT implementations — weak secrets, algorithm confusion, missing validation — let attackers forge tokens and impersonate any user including admins.

What Are JWT Security Issues?

JSON Web Tokens (JWTs) are widely used for authentication in vibe-coded apps. But several common mistakes in JWT implementation allow attackers to forge valid tokens and authenticate as any user — including administrators.

Common Vulnerabilities

1. Weak or Default Secret

# Vulnerable — default or short secret is brute-forceable
SECRET = "secret"
SECRET = "your-secret-key"
SECRET = "changeme"

Tools like hashcat can crack weak JWT secrets offline in seconds using the token alone.

2. Algorithm Confusion (alg: none)

# Vulnerable — trusting the algorithm specified in the token header
import jwt
 
def verify_token(token: str):
    header = jwt.get_unverified_header(token)
    alg = header["alg"]  # Attacker sets this to "none"
    return jwt.decode(token, key="", algorithms=[alg])  # Accepts unsigned token!

An attacker modifies the header to {"alg": "none"}, removes the signature, and the server accepts the forged token.

3. RS256 → HS256 Confusion

The server uses RS256 (asymmetric). The attacker changes alg to HS256 and signs the token with the server's public key — which is, by definition, public. The server verifies the HS256 signature using its public key as the HMAC secret and accepts it.

4. Missing Claims Validation

# Vulnerable — not checking exp, iss, aud
payload = jwt.decode(token, SECRET, algorithms=["HS256"])
# Token never expires, works on any service

How to Fix

Use a strong, random secret (≥256 bits):

import secrets
SECRET = secrets.token_hex(32)  # Generate once, store securely in env vars

Always specify the exact algorithm explicitly:

import jwt
 
# Never allow the token to dictate its own algorithm
payload = jwt.decode(
    token,
    SECRET,
    algorithms=["HS256"],  # Hardcoded — not from the token header
)

Validate all claims:

payload = jwt.decode(
    token,
    SECRET,
    algorithms=["HS256"],
    options={"require": ["exp", "iat", "sub"]},
    audience="vibewshield-api",
    issuer="vibewshield.com",
)

Use a battle-tested auth library (NextAuth, Lucia, Clerk) rather than hand-rolling JWT logic.

What VibeWShield Detects

VibeWShield checks for JWT tokens in responses, tests algorithm confusion (alg: none, RS256→HS256), checks for common weak secrets via a dictionary attack, and verifies that expired tokens are properly rejected.

#jwt#authentication#token#auth

Free security scan

Test your app for JWT Security Issues

VibeWShield automatically checks for JWT Security Issues and 40+ other vulnerabilities using 63 scanners — in under 3 minutes, no signup required.

Scan your app free