RSTR-CRY-005 — Math.random() used for security

Summary

Math.random() is not a cryptographically secure RNG. Its output is fully predictable from a small handful of observed samples. Using it to generate session tokens, password-reset codes, OAuth nonces, API keys, or any other security-sensitive value lets an attacker forge those values offline.

Severity

Medium. (We picked Medium over High because the rule fires at every Math.random() site and not all of them are security-relevant; when the value is in fact a token, it is unambiguously critical.)

Languages

JavaScript, TypeScript.

What rastray flags

Any Math.random() call:

const token = Math.random().toString(36).slice(2);   // ← flagged

What rastray deliberately does not flag

  • crypto.randomUUID(), crypto.getRandomValues(...), crypto.randomBytes(...).

How to fix it

Use the platform-provided CSPRNG:

// Browser
const arr = new Uint8Array(16);
crypto.getRandomValues(arr);
const token = Array.from(arr, b => b.toString(16).padStart(2, '0')).join('');

// or, even simpler:
const token = crypto.randomUUID();          // available in modern browsers and Node 19+
// Node
import { randomBytes, randomUUID } from 'crypto';

const token = randomBytes(16).toString('hex');
const id    = randomUUID();

For non-security uses — animation jitter, sampling, shuffles in a single-player game — Math.random() is fine. If a finding is in clearly non-security code, suppress it per-line with a comment.

References