Is Math.random() safe for password-reset tokens, invite codes or API keys?

No. Math.random() is built for speed, not secrecy: its output can be predicted from earlier values, so tokens made with it can be guessed. Use crypto.randomUUID() or crypto.getRandomValues() in the browser and Node, or crypto.randomBytes() on the server.

Why

Browsers and Node implement Math.random() with fast generators whose internal state can be worked out from a handful of outputs. Once someone knows the state, they can compute the next values, including the reset token or invite code your app is about to send someone else.

AI tools reach for Math.random().toString(36) because it's short and works everywhere. In our scan of about 1,460 public repos it was one of the few problems found in every builder: 22% of Bolt repos, 19% of Lovable, 14% of Replit, 12% of Cursor and 8% of v0.

It's fine for things nobody gains from guessing, like animation timing or picking a random tip. It's not fine for anything that grants access: session IDs, reset and magic-link tokens, invite codes, API keys, file names meant to be unguessable.

How to check

  1. Search your code for Math.random and look at what each result produces.
  2. Replace every one that makes a token, code, key or secret ID with the crypto version below.
  3. Shippable's code scan (npx shippable-dev scan in your project folder) flags Math.random() used for secrets.
JavaScript
// Instead of Math.random().toString(36).slice(2): const token = crypto.randomUUID(); // Or 32 random bytes as hex: const bytes = crypto.getRandomValues(new Uint8Array(32)); const key = Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");

Check your app

Your first app is free, and it is read-only. You prove the app is yours with a one-line tag first.

More questions