Weak Random Function
Also Known As
rand()
mt_rand()
insecure random
PRNG
TL;DR
Using rand(), mt_rand(), or array_rand() for security-sensitive values — these are predictable pseudo-random generators not suitable for tokens, keys, or passwords.
Explanation
PHP's rand() and mt_rand() are Mersenne Twister-based PRNGs — fast and deterministic, suitable for simulations and games, but predictable given enough outputs. For security: tokens, session IDs, password reset links, CSRF tokens, and API keys must use cryptographically secure randomness. PHP 7+ provides random_bytes() and random_int() which use the OS CSPRNG (/dev/urandom on Linux). Never use weak PRNGs for anything an attacker must not be able to predict.
Common Misconception
✗ mt_rand() is secure because it uses Mersenne Twister — Mersenne Twister's state can be fully reconstructed from 624 outputs, making all future values predictable.
Why It Matters
A password reset token generated with mt_rand() can be predicted by an attacker who has observed previous random outputs — enabling account takeover without knowing the password.
Common Mistakes
- rand() or mt_rand() for password reset tokens, CSRF tokens, or session IDs.
- uniqid() for security tokens — uses microtime(), highly predictable.
- base64_encode(mt_rand()) — encoding does not add entropy.
- str_shuffle() for token generation — relies on mt_rand() internally.
Avoid When
- Never use rand(), mt_rand(), or uniqid() for security tokens — they are predictable.
- Do not use microtime() or time() as a seed for token generation — trivially guessable.
When To Use
- Use random_bytes() for any security-sensitive random value — tokens, nonces, CSRF values, API keys.
- Use random_int() for cryptographically secure random integers within a range.
Code Examples
✗ Vulnerable
// Predictable — never use for security:
$token = md5(uniqid(mt_rand(), true)); // Both predictable
$resetToken = rand(100000, 999999); // 900000 possibilities — brute-forceable
$apiKey = base64_encode(mt_rand()); // Predictable state
✓ Fixed
// Cryptographically secure:
$token = bin2hex(random_bytes(32)); // 256 bits of entropy
$resetUrl = bin2hex(random_bytes(16)); // 128 bits — URL-safe
$pin = random_int(100000, 999999); // Secure integer range
$apiKey = base64_encode(random_bytes(32)); // Secure API key
Tags
🤝 Adopt this term
£79/year · your link shown here
Added
16 Mar 2026
Edited
31 Mar 2026
Views
26
🤖 AI Guestbook educational data only
|
|
Last 30 days
Agents 0
No pings yet today
Amazonbot 7
Perplexity 2
Unknown AI 2
Ahrefs 2
ChatGPT 2
Google 1
SEMrush 1
Also referenced
How they use it
crawler 16
crawler_json 1
Related categories
⚡
DEV INTEL
Tools & Severity
🔴 Critical
⚙ Fix effort: Low
⚡ Quick Fix
Replace every security use of mt_rand(), rand(), array_rand(), and shuffle() with random_bytes() or random_int() — the old functions are seeded deterministically and are predictable
📦 Applies To
PHP 7.0+
web
cli
queue-worker
🔗 Prerequisites
🔍 Detection Hints
mt_rand() for token generation; rand() for password reset codes; shuffle() for security shuffling; uniqid() for session tokens
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