| name | insufficient-randomness-anti-pattern |
| description | Security anti-pattern for insufficient randomness vulnerabilities (CWE-330). Use when generating or reviewing code that creates security tokens, session IDs, encryption keys, nonces, or any security-critical random values. Detects use of Math.random() or predictable seeds. |
Insufficient Randomness Anti-Pattern
Severity: High
Summary
Insufficient randomness occurs when security-sensitive values (session tokens, password reset codes, encryption keys) are generated using predictable non-cryptographic PRNGs. AI models frequently suggest Math.random() or Python's random module for simplicity. These generators enable attackers to predict outputs after observing a few values, allowing token forgery, session hijacking, and cryptographic compromise.
The Anti-Pattern
Never use predictable, non-cryptographic random number generators for security-sensitive values.
BAD Code Example
function generateSessionToken() {
let token = '';
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
for (let i = 0; i < 32; i++) {
token += chars.charAt(Math.floor(Math.random() * chars.length));
}
return token;
}
GOOD Code Example
const crypto = require('crypto');
function generateSessionToken() {
const buffer = crypto.randomBytes(32);
return buffer.toString('hex');
}
Language-Specific Examples
Python:
import random
import string
def generate_reset_token():
chars = string.ascii_letters + string.digits
return ''.join(random.choice(chars) for _ in range(32))
import secrets
def generate_reset_token():
return secrets.token_urlsafe(32)
import os
import base64
def generate_session_id():
return base64.urlsafe_b64encode(os.urandom(32)).decode('utf-8')
Java:
import java.util.Random;
public String generateSessionToken() {
Random random = new Random();
byte[] bytes = new byte[32];
random.nextBytes(bytes);
return Base64.getEncoder().encodeToString(bytes);
}
import java.security.SecureRandom;
import java.util.Base64;
public String generateSessionToken() {
SecureRandom secureRandom = new SecureRandom();
byte[] bytes = new byte[32];
secureRandom.nextBytes(bytes);
return Base64.getEncoder().encodeToString(bytes);
}
C#:
using System;
public string GenerateApiKey()
{
var random = new Random();
var bytes = new byte[32];
random.NextBytes(bytes);
return Convert.ToBase64String(bytes);
}
using System;
using System.Security.Cryptography;
public string GenerateApiKey()
{
using (var rng = RandomNumberGenerator.Create())
{
var bytes = new byte[32];
rng.GetBytes(bytes);
return Convert.ToBase64String(bytes);
}
}
Detection
- Search for weak PRNGs in security contexts: Grep for non-cryptographic random functions:
rg 'Math\.random\(\)' --type js (JavaScript)
rg 'import random[^_]|from random import' --type py (Python random module)
rg 'new Random\(\)|Random\.next' --type java (Java util.Random)
rg '\brand\(|mt_rand\(' --type php (PHP rand/mt_rand)
- Identify manual seeding: Find predictable seeds:
rg 'random\.seed|Random\(time|srand\(time'
- CSPRNGs should never be manually seeded
- Audit token generation: Find session/token creation logic:
rg 'session.*token|reset.*token|api.*key' -A 10
- Verify CSPRNG usage for all security tokens
Prevention
Related Security Patterns & Anti-Patterns
References