v0.14 is out: a mobile auth pack for Swift/iOS and Android, catching insecure token storage, cleartext traffic, and OAuth in embedded WebViews. Read more →
HIGH AI PREVALENCE: HIGH auth.jwt.weak-secret

JWT signing or verification uses a hard-coded secret.

Why AI tools produce this: AI coding tools generate this anti-pattern by default, it appears in a large share of AI-written auth code.

Why this matters

Anyone who reads the source (including via leaked GitHub commits) can forge valid tokens.

Move the secret to an environment variable or secret manager, and ensure the value is at least 256 bits (32 ASCII characters) when using HMAC-based algorithms (HS256/HS384/HS512).

Real-world incident: 24,008 unique secrets were found in MCP config files and 3.2% of Claude Code commits leaked secrets in GitGuardian's 2026 report.

VULNERABLE
vulnerable.ts
import jwt from 'jsonwebtoken';

// ruleid: auth.jwt.weak-secret
export const token1 = jwt.sign({ uid: 1 }, 'secret');

// ruleid: auth.jwt.weak-secret
export const token2 = jwt.sign({ uid: 2 }, 'changeme');

// ruleid: auth.jwt.weak-secret
export function verifyBad(t: string) {
  return jwt.verify(t, 'mySecret');
}

import { sign } from 'jsonwebtoken';
// ruleid: auth.jwt.weak-secret -- destructured import
export const token3 = sign({ uid: 3 }, 'secret');
SAFE
safe.ts
import jwt from 'jsonwebtoken';

// ok: auth.jwt.weak-secret
export const token = jwt.sign({ uid: 1 }, process.env.JWT_SECRET!);

// ok: auth.jwt.weak-secret
export function verifyGood(t: string) {
  return jwt.verify(t, process.env.JWT_PUBLIC_KEY!, { algorithms: ['RS256'] });
}

Suppressing this rule

If a finding is a genuine false positive, scope the suppression to the exact line and leave a reason, never disable the rule project-wide. Disable directives are line-scoped by design.

// oauthlint-disable-next-line auth.jwt.weak-secret -- <reason>

References

https://datatracker.ietf.org/doc/html/rfc7518#section-3.2 ↗https://cwe.mitre.org/data/definitions/798.html ↗