← Home ← Codex ← DEBT ← Engine
Browse by Category
+ added · updated 7d
← Back to glossary

CSPRNG

Security PHP 7.0+ Intermediate
debt(d5/e1/b1/t7)
d5 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'specialist tool catches' (d5). The term's detection_hints list semgrep, psalm, and phpstan as tools that can detect insecure random function usage (rand(), mt_rand(), uniqid(), array_rand(), shuffle()). These are specialist static analysis tools, not default linters that run automatically in most PHP setups.

e1 Effort Remediation debt — work required to fix once spotted

Closest to 'one-line patch' (e1). The quick_fix states to simply replace rand()/mt_rand() calls with random_bytes(n) or random_int(min, max). This is a direct single-call swap requiring no architectural changes.

b1 Burden Structural debt — long-term weight of choosing wrong

Closest to 'minimal commitment' (b1). Using CSPRNG functions like random_bytes() and random_int() is a localized choice at the call site. It doesn't impose ongoing maintenance burden or shape future development — it's just picking the right function for security-sensitive randomness.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap' (t7). The misconception explicitly states developers believe 'rand() and mt_rand() are random enough for security tokens.' This contradicts how 'random' functions work in security contexts elsewhere — most developers assume anything called 'random' is unpredictable. The functions look safe, produce output that appears random, but are entirely predictable given seed observation. This matches how similar concepts mislead developers from other ecosystems.

About DEBT scoring →

Also Known As

CSPRNG cryptographically secure random secure RNG

TL;DR

Cryptographically Secure Pseudo-Random Number Generator — produces unpredictable values suitable for security tokens.

Explanation

A CSPRNG is a random number generator that satisfies cryptographic security requirements: its output must be statistically indistinguishable from truly random data, and knowing past output must not allow predicting future output. PHP's random_bytes() and random_int() use the OS CSPRNG (/dev/urandom on Linux, CryptGenRandom on Windows). Regular rand(), mt_rand(), and uniqid() are NOT CSPRNGs and must not be used for security-sensitive values.

Common Misconception

rand() and mt_rand() are random enough for security tokens. Both are seeded PRNGs whose output is predictable given enough observed values. Use random_bytes() which pulls entropy from the OS kernel.

Why It Matters

Cryptographically secure pseudo-random number generators are unpredictable even knowing all previous outputs — non-CSPRNG functions like rand() are seeded by time and easily predicted.

Common Mistakes

  • Using rand(), mt_rand(), or array_rand() for security tokens, session IDs, or CSRF tokens.
  • Using uniqid() which is based on microtime and guessable.
  • Seeding mt_srand() with a predictable value like time() and using the output for secrets.
  • Not using random_bytes() or random_int() which are PHP's CSPRNG wrappers since PHP 7.

Code Examples

✗ Vulnerable
// Predictable token — seeded by time:
$token = md5(uniqid(mt_rand(), true)); // WRONG

// Correct:
$token = bin2hex(random_bytes(32));
✓ Fixed
// PHP 7+ — CSPRNG built in, no configuration needed
$bytes  = random_bytes(32);              // 32 random bytes from OS CSPRNG
$int    = random_int(1, 100);            // secure random int in range
$token  = bin2hex(random_bytes(32));     // 64-char hex token
$b64    = base64_encode(random_bytes(32)); // base64 encoded

// URL-safe base64 (no +/= chars)
$urlSafe = rtrim(strtr(base64_encode(random_bytes(32)), '+/', '-_'), '=');

// For OTPs
$otp = str_pad((string) random_int(0, 999999), 6, '0', STR_PAD_LEFT);

// NEVER use: rand(), mt_rand(), uniqid(), microtime() for security purposes
// They are NOT cryptographically secure

Added 15 Mar 2026
Edited 22 Mar 2026
Views 134
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings W 0 pings T 0 pings F 0 pings S 1 ping S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 2 pings S 1 ping M 2 pings T 0 pings W 0 pings T 0 pings F 1 ping S 1 ping S 1 ping M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T
No pings yet today
No pings yesterday
Amazonbot 14 Scrapy 14 Ahrefs 10 PetalBot 10 Perplexity 9 SEMrush 7 Google 5 Brave Search 5 Unknown AI 2 Applebot 2 Bing 2 Meta AI 1 Twitter/X 1
crawler 81 crawler_json 1
DEV INTEL Tools & Severity
🟠 High ⚙ Fix effort: Low
⚡ Quick Fix
Use random_bytes(n) for raw bytes, random_int(min, max) for integers — both use the OS CSPRNG (CryptGenRandom on Windows, getrandom() on Linux)
📦 Applies To
PHP 7.0+ web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
rand() mt_rand() uniqid() array_rand() shuffle() used for security tokens passwords salts
Auto-detectable: ✓ Yes semgrep psalm phpstan
⚠ Related Problems
🤖 AI Agent
Confidence: High False Positives: Low ✓ Auto-fixable Fix: Low Context: Line
CWE-330 CWE-338


✓ schema.org compliant