Use of Insufficiently Random Values

Description

Use of Insufficiently Random Values occurs when a product uses insufficiently random numbers or values in a security context that depends on unpredictable numbers. Cryptographic operations, session identifiers, password reset tokens, CSRF tokens, and other security-critical values must be generated using cryptographically secure random number generators (CSPRNGs). When predictable or low-entropy random number generators are used, attackers can predict future values, guess current values, or brute-force the limited keyspace to compromise security mechanisms.

Risk

Predictable random values undermine the security of systems that rely on unpredictability. Session tokens generated with weak randomness can be predicted, enabling session hijacking. CVE-2025-13353 in Cloudflare's gokey utility reduced key entropy from 240 bytes to just 28 bytes due to flawed seed derivation, allowing attackers with access to seed files to recover all passwords without needing the master password. Password reset tokens with insufficient randomness can be guessed. CSRF tokens become ineffective when predictable. Statistical PRNGs like Python's random module or JavaScript's Math.random() can have their internal state reconstructed from output, making all future values predictable.

Solution

Always use cryptographically secure random number generators (CSPRNGs) for security-sensitive operations. In Python, use the secrets module or os.urandom(). In JavaScript, use crypto.getRandomValues() or crypto.randomBytes(). In Java, use SecureRandom. Ensure sufficient entropy—use at least 128 bits for tokens and 256 bits for cryptographic keys. Never seed CSPRNGs with predictable values. Verify that random number generation is properly initialized. Use well-vetted libraries and avoid implementing custom random generation.

Common Consequences

ImpactDetails
AuthenticationScope: Session Hijacking

Predictable session tokens allow attackers to guess valid sessions and impersonate users.
Access ControlScope: Token Prediction

Password reset tokens, CSRF tokens, and API keys can be predicted and exploited.
ConfidentialityScope: Cryptographic Weakness

Weak random keys compromise all encryption using those keys.

Example Code + Solution Code

Vulnerable Code

# VULNERABLE: Using random module for security tokens
import random
import string

def generate_password_reset_token():
    # random module is NOT cryptographically secure!
    # Internal state can be reconstructed from output
    chars = string.ascii_letters + string.digits
    return ''.join(random.choice(chars) for _ in range(32))

def generate_session_id():
    # Predictable - based on Mersenne Twister
    return str(random.randint(0, 999999999))

# VULNERABLE: Weak seeding
import time
random.seed(time.time())  # Predictable seed based on time
token = random.randint(0, 2**32)
// VULNERABLE: Using java.util.Random for security
import java.util.Random;

public class TokenGenerator {
    private Random random = new Random();  // Not cryptographically secure!

    public String generateToken() {
        // Predictable after observing a few outputs
        return String.valueOf(random.nextLong());
    }

    public String generateApiKey() {
        // Weak randomness for API key
        StringBuilder key = new StringBuilder();
        for (int i = 0; i < 32; i++) {
            key.append((char) ('a' + random.nextInt(26)));
        }
        return key.toString();
    }
}
// VULNERABLE: Math.random() for security purposes
function generateCSRFToken() {
    // Math.random() is NOT cryptographically secure!
    return Math.random().toString(36).substring(2);
}

function generateVerificationCode() {
    // Low entropy - only 6 digits
    return Math.floor(Math.random() * 1000000).toString().padStart(6, '0');
}

// VULNERABLE: Predictable UUID generation
function generateSessionId() {
    // Using timestamp and counter - easily predictable
    return Date.now().toString(16) + '-' + (++counter).toString(16);
}

Fixed Code

# SAFE: Using secrets module for cryptographic randomness
import secrets
import string

def generate_password_reset_token_safe():
    # secrets module uses OS entropy source
    return secrets.token_urlsafe(32)  # 256 bits of entropy

def generate_session_id_safe():
    # Cryptographically secure random bytes
    return secrets.token_hex(32)  # 256-bit session ID

def generate_verification_code_safe():
    # Even for short codes, use cryptographic randomness
    return ''.join(secrets.choice(string.digits) for _ in range(6))

def generate_api_key_safe():
    # Generate secure API key with sufficient entropy
    return secrets.token_urlsafe(32)  # 256 bits
// SAFE: Using SecureRandom for cryptographic randomness
import java.security.SecureRandom;
import java.util.Base64;

public class SecureTokenGenerator {
    private final SecureRandom secureRandom;

    public SecureTokenGenerator() {
        // Use strong instance for better entropy
        try {
            this.secureRandom = SecureRandom.getInstanceStrong();
        } catch (NoSuchAlgorithmException e) {
            this.secureRandom = new SecureRandom();
        }
    }

    public String generateToken() {
        byte[] bytes = new byte[32];  // 256 bits
        secureRandom.nextBytes(bytes);
        return Base64.getUrlEncoder().withoutPadding().encodeToString(bytes);
    }

    public String generateApiKey() {
        byte[] bytes = new byte[32];
        secureRandom.nextBytes(bytes);
        return bytesToHex(bytes);
    }

    public String generateSessionId() {
        byte[] bytes = new byte[32];
        secureRandom.nextBytes(bytes);
        return Base64.getUrlEncoder().withoutPadding().encodeToString(bytes);
    }

    private static String bytesToHex(byte[] bytes) {
        StringBuilder hex = new StringBuilder();
        for (byte b : bytes) {
            hex.append(String.format("%02x", b));
        }
        return hex.toString();
    }
}
// SAFE: Using crypto module for secure randomness
const crypto = require('crypto');

function generateCSRFTokenSafe() {
    // 256 bits of cryptographic randomness
    return crypto.randomBytes(32).toString('hex');
}

function generateVerificationCodeSafe() {
    // Cryptographically secure random digits
    const buffer = crypto.randomBytes(4);
    const number = buffer.readUInt32BE(0) % 1000000;
    return number.toString().padStart(6, '0');
}

function generateSessionIdSafe() {
    // Use crypto.randomUUID() or randomBytes
    return crypto.randomUUID();  // Node 14.17+
}

// Browser-safe version
function generateTokenBrowser() {
    const array = new Uint8Array(32);
    crypto.getRandomValues(array);
    return Array.from(array, b => b.toString(16).padStart(2, '0')).join('');
}

// SAFE: Secure password generation
function generateSecurePassword(length = 16) {
    const charset = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*';
    const randomBytes = crypto.randomBytes(length);
    let password = '';
    for (let i = 0; i < length; i++) {
        password += charset[randomBytes[i] % charset.length];
    }
    return password;
}

Exploited in the Wild

Cloudflare gokey Entropy Reduction (Cloudflare, 2025)

CVE-2025-13353 in Cloudflare's gokey utility (before 0.2.0) used flawed seed decryption that only derived passwords from the AES-GCM authentication tag and IV rather than full 240-byte seed entropy, reducing key strength to just 28 bytes and enabling password recovery without the master password.

PHP Session ID Prediction (PHP, Historical)

Historical PHP versions generated session IDs using weak randomness, enabling attackers to predict valid session IDs and hijack user sessions. This led to improvements in PHP's session management.

OAuth Token Prediction Attacks (Multiple, Ongoing)

Multiple OAuth implementations have been compromised through predictable token generation, allowing attackers to forge authorization codes and access tokens.


Tools to test/exploit


CVE Examples


References

  1. MITRE. "CWE-330: Use of Insufficiently Random Values." https://cwe.mitre.org/data/definitions/330.html

  2. OpenSSF. "Secure Coding Guide for Python - CWE-330." https://best.openssf.org/Secure-Coding-Guide-for-Python/CWE-693/CWE-330/