CWE-330: Use of Insufficiently Random Values
Overview
Insufficient Randomness occurs when applications use predictable or weak random number generators for security-sensitive operations, allowing attackers to guess or influence outcomes.
OWASP Classification
A04:2025 - Cryptographic Failures
Risk
High: Attackers can predict session tokens, passwords, cryptographic keys, or other sensitive values, leading to account compromise, privilege escalation, or data breaches.
Remediation Steps
Core principle: Security tokens and secrets must come from a CSPRNG; never use predictable values.
Locate the insecure random value generation in your code
- Review the flaw details to identify the specific file, line number, and code pattern
- Identify which random number generator is in use (e.g.,
random,Math.random, predictable seed) - Trace the data flow to understand what the random value is used for (session tokens, passwords, keys, salts, nonces)
- Determine the security requirements: randomness strength, length, unpredictability needed
Use cryptographically secure random generators (Primary Defense)
- Replace weak PRNGs: Use secure APIs instead of standard random functions
- Python: Use
secretsmodule oros.urandom()instead ofrandom - Java: Use
java.security.SecureRandominstead ofjava.util.Random - JavaScript/Node.js: Use
crypto.randomBytes()orcrypto.getRandomValues()instead ofMath.random() - .NET: Use
System.Security.Cryptography.RandomNumberGeneratorinstead ofSystem.Random - PHP: Use
random_bytes()orrandom_int()instead ofrand()ormt_rand()
- Python: Use
- Avoid standard PRNGs for security:
random,Math.random(),rand()are NOT cryptographically secure
Seed random generators securely and validate randomness requirements
- Use OS-provided entropy: Let the operating system provide entropy - do not use predictable seeds (time, PID, counter)
- No manual seeding needed: Cryptographically secure RNGs (SecureRandom, secrets) handle seeding automatically
- Validate length requirements: Ensure random values meet minimum length (128 bits for session tokens, 256 bits for cryptographic keys)
- Validate unpredictability: Random values should be statistically unpredictable and uniformly distributed
Apply additional randomness protections
- Use appropriate randomness for each use case: Session tokens need 128+ bits, cryptographic keys need 256+ bits, salts need 128+ bits
- Avoid mixing weak and strong sources: Don't combine
randomwithsecrets- use only secure sources - Generate fresh random values: Don't reuse random values across sessions or users
- Encode random values properly: Use base64url or hex encoding for tokens to avoid character set issues
Monitor and audit random value usage
- Review code for insecure random number generation (grep for
random(,Math.random,rand(,mt_rand) - Log random value generation for security-critical operations (session token creation, password reset tokens)
- Alert on failures or suspicious patterns (repeated values, sequential patterns)
- Track random value collisions in production (should be extremely rare with proper RNG)
Test the randomness fix thoroughly
- Verify the specific weak RNG is no longer used for security purposes
- Test with multiple generated values to ensure uniqueness and unpredictability
- Verify session tokens, passwords, keys use proper length and encoding
- Statistical testing: chi-square test, runs test to verify randomness quality
- Re-scan with security scanner to confirm the issue is resolved
Common Vulnerable Patterns
- Using
randomorMath.randomfor session tokens or passwords - Seeding PRNGs with predictable values (e.g., time, PID)
- Using insufficient entropy for security-critical operations
- Mixing weak and strong random sources
Language-Specific Guidance
For detailed implementation examples in specific programming languages:
- Python: See python/INDEX.md - secrets module, os.urandom(), avoiding random module for security
- JavaScript/Node.js: See javascript/INDEX.md - crypto.randomBytes(), crypto.getRandomValues(), avoiding Math.random() for security
- PHP: See php/INDEX.md - random_bytes(), random_int(), avoiding rand() and mt_rand() for security