HIGH CWE-338 Authentication & Session Management

CWE-338 in APIs

CWE ID
CWE-338
Category
Encryption
Severity
MEDIUM
Short Name
Weak PRNG

What is CWE-338?

CWE-338 refers to the use of a predictable seed in a pseudorandom number generator (PRNG). This weakness occurs when an application initializes a random number generator with a seed value that is easily guessable or derived from a limited set of possibilities. The Common Weakness Enumeration (CWE) describes this as a situation where the seed used to initialize a random number generator can be predicted, allowing attackers to reproduce the sequence of random numbers generated by the algorithm.

Random number generators are fundamental to many security mechanisms, including session token generation, cryptographic operations, and API key creation. When these generators are initialized with predictable seeds, the entire sequence of "random" numbers becomes deterministic and vulnerable to prediction. An attacker who can guess or determine the seed can then calculate all subsequent values produced by the PRNG, effectively breaking any security mechanism that relies on these values.

CWE-338 in API Contexts

In API development, CWE-338 manifests in several critical ways that directly impact security. One of the most common scenarios involves session token generation. Many APIs generate session identifiers or JWT tokens using PRNGs initialized with predictable values like the current timestamp, process ID, or system uptime. When an attacker can predict these seeds, they can potentially generate valid session tokens for other users.

API key generation represents another significant vulnerability point. Some APIs create temporary API keys or one-time passwords using predictable seeds, making it possible for attackers to regenerate valid keys. This is particularly dangerous in scenarios where API keys are used for authentication or to access sensitive data.

Rate limiting mechanisms can also be compromised when they rely on predictable random values. Some APIs use random numbers to implement token bucket algorithms or to generate rate limit identifiers. If these values are predictable, attackers can bypass rate limiting by generating valid tokens or identifiers.

Database record identifiers and pagination tokens frequently suffer from this weakness. APIs that expose sequential or predictable identifiers allow attackers to enumerate records through simple iteration, potentially exposing sensitive data through IDOR (Insecure Direct Object Reference) vulnerabilities.

Detection

Detecting CWE-338 requires both static code analysis and dynamic testing approaches. Static analysis tools can identify code patterns where random number generators are initialized with predictable values like timestamps, process IDs, or hardcoded constants. Code review should focus on finding instances where Math.random(), rand(), or similar functions are called without proper seeding or with predictable seeds.

Dynamic testing involves analyzing the output patterns of random number generators. If an API consistently produces predictable sequences or shows patterns in token generation, this indicates potential CWE-338 vulnerabilities. Tools like middleBrick can automatically detect these patterns by analyzing API responses for predictable token structures and identifying weak random number generation practices.

middleBrick specifically scans for CWE-338 by examining API endpoints that generate tokens, keys, or identifiers. The scanner analyzes the entropy and predictability of these values, checking for patterns that suggest predictable seeding. It also tests whether tokens can be reproduced or predicted based on known input values.

Network traffic analysis can reveal CWE-338 vulnerabilities by showing whether tokens or identifiers follow predictable patterns. If an attacker can observe multiple token generations and identify the seeding mechanism, they can potentially predict future values.

Timing analysis provides another detection vector. APIs that use timestamps as seeds may show correlations between request timing and token generation, allowing attackers to narrow down the possible seed space.

Remediation

Fixing CWE-338 requires implementing cryptographically secure random number generation with truly unpredictable seeds. The fundamental principle is to use a cryptographically secure pseudorandom number generator (CSPRNG) and to seed it with high-entropy values from reliable sources.

Here are code examples for proper implementation:

// Node.js - Secure token generation
const crypto = require('crypto');

function generateSecureToken(length = 32) {
    return crypto.randomBytes(length).toString('hex');
}

// Usage
const sessionToken = generateSecureToken();
const apiKey = generateSecureToken(64);
# Python - Secure random generation
import secrets
import uuid

def generate_secure_token(length=32):
    return secrets.token_hex(length)

def generate_api_key():
    return secrets.token_urlsafe(32)

def generate_session_id():
    return uuid.uuid4().hex
// Java - Secure random generation
import java.security.SecureRandom;
import java.util.Base64;

public class SecureTokenGenerator {
    private static final SecureRandom random = new SecureRandom();
    
    public static String generateToken(int byteLength) {
        byte[] bytes = new byte[byteLength];
        random.nextBytes(bytes);
        return Base64.getUrlEncoder().withoutPadding().encodeToString(bytes);
    }
    
    public static String generateAPIKey() {
        return generateToken(32);
    }
}

Key principles for remediation:

  • Always use CSPRNGs (cryptographically secure pseudorandom number generators) instead of standard PRNGs
  • Never use timestamps, process IDs, or other predictable values as seeds
  • Let the operating system provide entropy through system calls
  • Ensure sufficient token length (at least 128 bits of entropy for session tokens)
  • Implement proper key rotation and expiration policies
  • Avoid custom random number generation algorithms

For existing APIs, conduct a thorough audit of all random number usage. Replace any instances of Math.random(), rand(), or similar functions with secure alternatives. Pay special attention to token generation, key creation, and any security-critical randomization.

Testing the effectiveness of remediation involves attempting to predict generated values and measuring the entropy of token distributions. Tools like dieharder or TestU01 can analyze random number generator quality, while custom scripts can test token predictability.

Frequently Asked Questions

How can I test if my API is vulnerable to CWE-338?
Test by analyzing the entropy and predictability of your API's generated tokens and identifiers. Use tools like middleBrick to scan your endpoints for predictable patterns in session tokens, API keys, and other random values. Manually examine your code for uses of Math.random(), rand(), or similar functions without cryptographically secure seeding. Try to reproduce tokens given known inputs or timestamps to verify if they're predictable.
What's the difference between a regular PRNG and a CSPRNG?
A regular PRNG (pseudorandom number generator) produces deterministic sequences that appear random but are predictable if you know the seed. A CSPRNG (cryptographically secure PRNG) is designed so that it's computationally infeasible to predict future outputs even if you know previous outputs and the algorithm. CSPRNGs use entropy from the operating system and are suitable for security-sensitive operations like token generation, while regular PRNGs are only appropriate for simulations or games where predictability isn't a concern.