Rules Hub
Code Ruleset
Rule priority, scope & exceptions
Use this to align rules with the senior-level structure (P0/P1/P2, scope, exceptions/tradeoffs).
Generate security tokens with a CSPRNG, never Math.random
Use crypto.randomBytes/randomUUID/getRandomValues for tokens, IDs, salts, nonces — never Math.random or timestamps.
Bad example
| 1 | // Predictable: Math.random is a non-cryptographic PRNG. |
| 2 | export function makeResetToken(): string { |
| 3 | return Math.random().toString(36).slice(2) + Date.now().toString(36); |
| 4 | } |
| 5 |
|
| 6 | // Same problem for 'unique' ids used as security boundaries. |
| 7 | export function makeApiKey(): string { |
| 8 | let key = ''; |
| 9 | for (let i = 0; i < 32; i += 1) { |
| 10 | key += Math.floor(Math.random() * 16).toString(16); |
| 11 | } |
| 12 | return key; |
| 13 | } |
Explanation (EN)
Math.random or timestamps cannot supply an attacker-resistant secret.
Objašnjenje (HR)
Math.random i vremenske oznake ne daju tajnu otpornu na pogađanje napadača.
Good example
| 1 | import { randomBytes, randomUUID } from 'node:crypto'; |
| 2 |
|
| 3 | // 256 bits of CSPRNG entropy, URL-safe. |
| 4 | export function makeResetToken(): string { |
| 5 | return randomBytes(32).toString('base64url'); |
| 6 | } |
| 7 |
|
| 8 | export function makeApiKey(): string { |
| 9 | return `sk_${randomBytes(24).toString('hex')}`; |
| 10 | } |
| 11 |
|
| 12 | export function makeRequestId(): string { |
| 13 | return randomUUID(); // v4, CSPRNG-backed |
| 14 | } |
| 15 |
|
| 16 | // Browser/Edge runtime equivalent: |
| 17 | export function makeNonce(): string { |
| 18 | const bytes = new Uint8Array(16); |
| 19 | crypto.getRandomValues(bytes); |
| 20 | return btoa(String.fromCharCode(...bytes)); |
| 21 | } |
Explanation (EN)
crypto.randomBytes (Node) and crypto.getRandomValues (Web/Edge) draw from the OS CSPRNG and are unpredictable. randomUUID() is CSPRNG-backed v4. Use at least 128 bits of entropy for tokens (OWASP recommends >=128, prefer 256 for long-lived secrets) and encode as base64url/hex. This works the same way in Node, the browser, and Next.js Edge runtime.
Objašnjenje (HR)
crypto.randomBytes (Node) i crypto.getRandomValues (Web/Edge) crpe iz OS CSPRNG-a i nepredvidljivi su. randomUUID() je v4 utemeljen na CSPRNG-u. Koristi barem 128 bita entropije za tokene (OWASP preporuca >=128, radije 256 za dugotrajne tajne) i kodiraj kao base64url/hex. Radi jednako u Nodeu, pregledniku i Next.js Edge runtimeu.
Notes (EN)
Use a platform CSPRNG and the protocol-required entropy/encoding for credentials, unpredictable identifiers and cryptographic nonces.
Exceptions / Tradeoffs (EN)
Math.random is fine for non-security purposes: jitter/backoff, UI animation, sampling, test fixtures, picking a placeholder. The rule is about anything an attacker benefits from guessing. Random uniqueness is not authorization, and nonce uniqueness requirements differ by cryptographic protocol. Request/correlation IDs are not automatically credentials; preserve the existing domain contract.
Iznimke / Tradeoffi (HR)
Math.random je prikladan za nesigurnosne potrebe poput animacije, jittera ili testnih podataka. Pravilo se odnosi na vrijednosti koje napadaču koristi pogoditi. Slučajna jedinstvenost nije autorizacija, a zahtjevi za nonce ovise o protokolu. Request i correlation ID-jevi nisu automatski vjerodajnice.