Verwendung unzureichend zufälliger Werte

Beschreibung

Verwendung unzureichend zufälliger Werte tritt auf, wenn ein Produkt unzureichend zufällige Zahlen oder Werte in einem Sicherheitskontext verwendet, der von unvorhersagbaren Zahlen abhängt. Kryptografische Operationen, Session-Identifikatoren, Passwort-Reset-Tokens, CSRF-Tokens und andere sicherheitskritische Werte müssen mit kryptografisch sicheren Zufallszahlengeneratoren (CSPRNGs) generiert werden. Wenn vorhersagbare oder Zufallszahlengeneratoren mit niedriger Entropie verwendet werden, können Angreifer zukünftige Werte vorhersagen, aktuelle Werte erraten oder den begrenzten Schlüsselraum per Brute-Force durchsuchen, um Sicherheitsmechanismen zu kompromittieren.

Risiko

Vorhersagbare Zufallswerte untergraben die Sicherheit von Systemen, die auf Unvorhersagbarkeit angewiesen sind. Session-Tokens, die mit schwacher Zufälligkeit generiert werden, können vorhergesagt werden, was Session-Hijacking ermöglicht. CVE-2025-13353 in Cloudflares gokey-Utility reduzierte die Schlüsselentropie von 240 Bytes auf nur 28 Bytes aufgrund fehlerhafter Seed-Ableitung, wodurch Angreifer mit Zugriff auf Seed-Dateien alle Passwörter ohne Master-Passwort wiederherstellen könnten. Passwort-Reset-Tokens mit unzureichender Zufälligkeit können erraten werden. CSRF-Tokens werden unwirksam, wenn sie vorhersagbar sind. Statistische PRNGs wie Pythons random-Modul oder JavaScripts Math.random() können ihren internen Zustand aus der Ausgabe rekonstruieren lassen, was alle zukünftigen Werte vorhersagbar macht.

Lösung

Verwenden Sie immer kryptografisch sichere Zufallszahlengeneratoren (CSPRNGs) für sicherheitsrelevante Operationen. In Python verwenden Sie das secrets-Modul oder os.urandom(). In JavaScript verwenden Sie crypto.getRandomValues() oder crypto.randomBytes(). In Java verwenden Sie SecureRandom. Stellen Sie ausreichende Entropie sicher - verwenden Sie mindestens 128 Bits für Tokens und 256 Bits für kryptografische Schlüssel. Initialisieren Sie CSPRNGs niemals mit vorhersagbaren Werten. Verifizieren Sie, dass die Zufallszahlengenerierung ordnungsgemäß initialisiert ist. Verwenden Sie gut geprüfte Bibliotheken und vermeiden Sie die Implementierung benutzerdefinierter Zufallsgenerierung.

Häufige Auswirkungen

AuswirkungDetails
AuthentifizierungUmfang: Session-Hijacking

Vorhersagbare Session-Tokens ermöglichen Angreifern, gültige Sessions zu erraten und Benutzer zu imitieren.
ZugriffskontrolleUmfang: Token-Vorhersage

Passwort-Reset-Tokens, CSRF-Tokens und API-Schlüssel können vorhergesagt und ausgenutzt werden.
VertraulichkeitUmfang: Kryptografische Schwäche

Schwache zufällige Schlüssel kompromittieren alle Verschlüsselung, die diese Schlüssel verwendet.

Beispielcode + Korrigierter Code

Anfälliger Code

# ANFÄLLIG: Verwendung des random-Moduls für Sicherheitstokens
import random
import string

def generate_password_reset_token():
    # random-Modul ist NICHT kryptografisch sicher!
    # Interner Zustand kann aus Ausgabe rekonstruiert werden
    chars = string.ascii_letters + string.digits
    return ''.join(random.choice(chars) for _ in range(32))

def generate_session_id():
    # Vorhersagbar - basiert auf Mersenne Twister
    return str(random.randint(0, 999999999))

# ANFÄLLIG: Schwaches Seeding
import time
random.seed(time.time())  # Vorhersagbarer Seed basiert auf Zeit
token = random.randint(0, 2**32)
// ANFÄLLIG: Verwendung von java.util.Random für Sicherheit
import java.util.Random;

public class TokenGenerator {
    private Random random = new Random();  // Nicht kryptografisch sicher!

    public String generateToken() {
        // Vorhersagbar nach Beobachtung einiger Ausgaben
        return String.valueOf(random.nextLong());
    }

    public String generateApiKey() {
        // Schwache Zufälligkeit für API-Schlüssel
        StringBuilder key = new StringBuilder();
        for (int i = 0; i < 32; i++) {
            key.append((char) ('a' + random.nextInt(26)));
        }
        return key.toString();
    }
}
// ANFÄLLIG: Math.random() für Sicherheitszwecke
function generateCSRFToken() {
    // Math.random() ist NICHT kryptografisch sicher!
    return Math.random().toString(36).substring(2);
}

function generateVerificationCode() {
    // Niedrige Entropie - nur 6 Ziffern
    return Math.floor(Math.random() * 1000000).toString().padStart(6, '0');
}

// ANFÄLLIG: Vorhersagbare UUID-Generierung
function generateSessionId() {
    // Verwendung von Zeitstempel und Zähler - leicht vorhersagbar
    return Date.now().toString(16) + '-' + (++counter).toString(16);
}

Korrigierter Code

# SICHER: Verwendung des secrets-Moduls für kryptografische Zufälligkeit
import secrets
import string

def generate_password_reset_token_safe():
    # secrets-Modul verwendet OS-Entropiequelle
    return secrets.token_urlsafe(32)  # 256 Bits Entropie

def generate_session_id_safe():
    # Kryptografisch sichere zufällige Bytes
    return secrets.token_hex(32)  # 256-Bit Session-ID

def generate_verification_code_safe():
    # Selbst für kurze Codes kryptografische Zufälligkeit verwenden
    return ''.join(secrets.choice(string.digits) for _ in range(6))

def generate_api_key_safe():
    # Sicheren API-Schlüssel mit ausreichender Entropie generieren
    return secrets.token_urlsafe(32)  # 256 Bits
// SICHER: Verwendung von SecureRandom für kryptografische Zufälligkeit
import java.security.SecureRandom;
import java.util.Base64;

public class SecureTokenGenerator {
    private final SecureRandom secureRandom;

    public SecureTokenGenerator() {
        // Starke Instanz für bessere Entropie verwenden
        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();
    }
}
// SICHER: Verwendung des crypto-Moduls für sichere Zufälligkeit
const crypto = require('crypto');

function generateCSRFTokenSafe() {
    // 256 Bits kryptografische Zufälligkeit
    return crypto.randomBytes(32).toString('hex');
}

function generateVerificationCodeSafe() {
    // Kryptografisch sichere zufällige Ziffern
    const buffer = crypto.randomBytes(4);
    const number = buffer.readUInt32BE(0) % 1000000;
    return number.toString().padStart(6, '0');
}

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

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

// SICHER: Sichere Passwortgenerierung
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;
}

Ausgenutzt in der Praxis

Cloudflare gokey Entropie-Reduktion (Cloudflare, 2025)

CVE-2025-13353 in Cloudflares gokey-Utility (vor 0.2.0) verwendete fehlerhafte Seed-Entschlüsselung, die Passwörter nur aus dem AES-GCM-Authentifizierungs-Tag und IV anstelle der vollen 240-Byte-Seed-Entropie ableitete, was die Schlüsselstärke auf nur 28 Bytes reduzierte und Passwortwiederherstellung ohne Master-Passwort ermöglichte.

PHP Session-ID-Vorhersage (PHP, Historisch)

Historische PHP-Versionen generierten Session-IDs mit schwacher Zufälligkeit, was Angreifern ermöglichte, gültige Session-IDs vorherzusagen und Benutzersitzungen zu kapern. Dies führte zu Verbesserungen in PHPs Session-Management.

OAuth-Token-Vorhersageangriffe (Mehrere, laufend)

Mehrere OAuth-Implementierungen wurden durch vorhersagbare Token-Generierung kompromittiert, wodurch Angreifer Autorisierungscodes und Zugriffstoken fälschen könnten.


Tools zum Testen/Ausnutzen


CVE-Beispiele


Referenzen

  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/