← All fixes

Fix it

Math.random() for tokens — why it's insecure and what to use instead

Medium severityCWE-330 (Use of Insufficiently Random Values)

Math.random() is a fast pseudo-random generator built for things like animations, not security. Its output can be predicted from prior values, so using it to mint a token, session id, password-reset code, or OAuth state parameter lets an attacker guess valid ones. The fix is a single call to a cryptographic random source.

Why it's a problem

Anything that protects access needs to be unguessable. Because Math.random() is seeded and sequential under the hood, an attacker who observes a few outputs can narrow down or reproduce the sequence, then forge a reset code or a session token that the server accepts as legitimate. The value looks random to a human and is trivially reproducible to a machine.

The pattern

// predictable — do not use for anything security-sensitive
const token = Math.random().toString(36).slice(2);
const resetCode = String(Math.floor(Math.random() * 1000000));

The fix

import { randomUUID, randomInt, randomBytes } from "node:crypto";

const token = randomBytes(32).toString("hex");   // 256-bit token
const sessionId = randomUUID();                   // unguessable id
const resetCode = String(randomInt(100000, 1000000)); // 6-digit, secure

Why AI tools write this

Math.random() is the first random function most models reach for because it is the one that appears most often in training data, in overwhelmingly non-security contexts. When the surrounding task is 'generate a token,' the assistant still pattern-matches to the familiar call, producing code that runs and looks correct but is not safe for the job.

The quick fix

  • Replace Math.random() with crypto.randomBytes, crypto.randomUUID, or crypto.randomInt for any security-sensitive value.
  • In the browser, use crypto.getRandomValues() instead.
  • Audit tokens, session ids, reset codes, and OAuth state parameters specifically.

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

Scan a repo →

Related: a full scan walkthrough

Math.random() Is Not Secure for Tokens — The Fix: Prbl