CWE-330 in APIs
- CWE ID
- CWE-330
- Category
- Encryption
- Severity
- HIGH
- Short Name
- Weak Randomness
What is CWE-330?
CWE-330, or Use of Insufficiently Random Values, is a critical weakness where software uses predictable or low-entropy values in security contexts where randomness is required. This vulnerability occurs when developers rely on inadequate random number generators (RNGs), static values, or predictable sequences for security-critical operations.
The weakness manifests when systems require randomness for:
- Session tokens or authentication cookies
- Cryptographic keys or initialization vectors
- Nonce values in cryptographic protocols
- Challenge-response mechanisms
- Password reset tokens
- API rate limiting tokens
When insufficient randomness is used, attackers can predict, reproduce, or brute-force these values, leading to authentication bypasses, session hijacking, or cryptographic attacks.
CWE-330 in API Contexts
APIs are particularly vulnerable to CWE-330 because they handle authentication, session management, and cryptographic operations at scale. Common API-specific manifestations include:
- Predictable API keys: Using sequential or timestamp-based identifiers instead of cryptographically secure random values
- Weak session tokens: JWTs or session IDs generated with insufficient entropy
- Nonces in OAuth flows: Predictable values in authorization code exchanges
- CSRF tokens: Static or easily guessable anti-CSRF values
- Rate limiting tokens: Sequential identifiers that allow bypassing rate limits
- Database IDs in URLs: Predictable primary keys that enable enumeration attacks
Consider this vulnerable API endpoint:
GET /api/v1/users/123
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIxMjMifQ.xxxxxIf the JWT is signed with a weak key or uses predictable user IDs, an attacker can easily enumerate users by incrementing the ID.
Detection
Detecting CWE-330 requires both static analysis and dynamic testing. Here's how to identify insufficient randomness:
Static Analysis
Review source code for:
- Use of
Math.random()in JavaScript or similar weak RNGs - Timestamp-based identifiers without additional entropy
- Sequential counters for security tokens
- Hardcoded or static values in security contexts
Dynamic Testing
Security scanners like middleBrick can detect CWE-330 by:
- Analyzing token entropy and predictability patterns
- Testing for token reuse across sessions
- Checking if tokens can be predicted or brute-forced
- Verifying cryptographic implementations use secure random sources
middleBrick specifically tests for:
$ middlebrick scan https://api.example.com
Authentication: F (Predictable session tokens detected)
Input Validation: B (No obvious injection points)
Rate Limiting: C (Sequential rate limit tokens found)The scanner identifies weak randomness in tokens, keys, and nonces, providing severity ratings and remediation guidance.
Remediation
Fixing CWE-330 requires using cryptographically secure random number generators and proper entropy sources. Here are code-level fixes:
JavaScript/Node.js
Instead of Math.random():
// VULNERABLE - DO NOT USE
const token = Math.random().toString(36).substring(2);Use crypto module:
// SECURE
const crypto = require('crypto');
const token = crypto.randomBytes(32).toString('hex');
const jwt = require('jsonwebtoken');
const secureToken = jwt.sign({ userId: 123 }, crypto.randomBytes(64), { expiresIn: '1h' });Python
Instead of random module:
# VULNERABLE - DO NOT USE
import random
token = ''.join(random.choices('abcdefghijklmnopqrstuvwxyz', k=32))Use secrets module:
# SECURE
import secrets
token = secrets.token_hex(32)
import secrets
import string
token = ''.join(secrets.choice(string.ascii_letters + string.digits) for i in range(32))Java
Instead of java.util.Random:
// VULNERABLE - DO NOT USE
import java.util.Random;
Random rand = new Random();
String token = String.valueOf(rand.nextLong());Use SecureRandom:
// SECURE
import java.security.SecureRandom;
SecureRandom random = new SecureRandom();
byte[] bytes = new byte[32];
random.nextBytes(bytes);
String token = bytesToHex(bytes); // Implement bytesToHex helperPHP
Instead of rand() or mt_rand():
// VULNERABLE - DO NOT USE
function generateToken() {
return bin2hex(random_bytes(16)); // Actually this is secure
// The real vulnerability is using non-cryptographic functions:
function vulnerableToken() {
return uniqid(); // Predictable based on timestamp
Best Practices
Always use:
- Cryptographically secure RNGs (
crypto.randomBytes,secrets,SecureRandom) - Minimum 128 bits of entropy for tokens
- Proper key lengths (256+ bits for symmetric keys)
- Random salts for password hashing
- Unique nonces for each cryptographic operation
Never use:
Math.random(),random,rand()for security- Timestamps alone for tokens
- Sequential or predictable identifiers
- Static values in security contexts