← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

Weak Random Function

security PHP 7.0+ Intermediate

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

Added 16 Mar 2026
Edited 31 Mar 2026
Views 26
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings F 0 pings S 0 pings S 1 ping M 0 pings T 0 pings W 0 pings T 1 ping F 0 pings S 0 pings S 0 pings M 0 pings T 1 ping W 2 pings T 1 ping F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 1 ping F 0 pings S 0 pings S 1 ping M 0 pings T 0 pings W 0 pings T 1 ping F 0 pings S
No pings yet today
Amazonbot 7 Perplexity 2 Unknown AI 2 Ahrefs 2 ChatGPT 2 Google 1 SEMrush 1
crawler 16 crawler_json 1
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

✓ schema.org compliant