Fehlende Initialisierung von Ressourcen

Beschreibung

Fehlende Initialisierung von Ressourcen ist eine Schwachstelle, bei der Software versäumt, eine kritische Ressource vor ihrer Verwendung ordnungsgemäß zu initialisieren. Viele Ressourcen erfordern eine explizite Initialisierung, um korrekt zu funktionieren - ohne sie können sie unvorhersehbare Daten aus vorherigen Operationen, ungültige Standardwerte oder Müll-Daten enthalten. Diese Schwachstelle unterscheidet sich von CWE-908 (Verwendung nicht initialisierter Ressourcen) dadurch, dass sie sich auf das Versäumnis konzentriert, die Initialisierung durchzuführen, während CWE-908 sich auf die anschließende Verwendung der nicht initialisierten Ressource konzentriert.

Risiko

Ressourcen, die nicht ordnungsgemäß initialisiert werden, können zu schwerwiegenden Sicherheitsproblemen führen. Nicht initialisierter Speicher kann sensible Daten aus vorherigen Operationen enthalten, was zu Informationsoffenlegung führt. Variablen mit fehlender Initialisierung können unvorhersehbare Werte haben, die die Programmlogik oder Sicherheitsentscheidungen beeinflussen. In Zugriffskontroll-Kontexten kann fehlende Initialisierung zu Standardwerten führen, die übermäßige Privilegien gewähren. Pufferoperationen auf nicht initialisiertem Speicher können Abstürze verursachen oder Ausnutzung ermöglichen. Die unvorhersehbare Natur nicht initialisierter Daten macht das Debugging schwierig und kann intermittierende, schwer reproduzierbare Sicherheitsprobleme verursachen.

Lösung

Stellen Sie sicher, dass alle Ressourcen vor der Verwendung ordnungsgemäß initialisiert werden. Definieren Sie Initialisierungsprozeduren für alle benutzerdefinierten Datentypen und Strukturen. Verwenden Sie Konstruktoren oder Initialisierungsfunktionen, die alle Felder auf bekannte sichere Werte setzen. In Sprachen ohne automatische Initialisierung verwenden Sie memset() oder calloc() für Speicherallokation. Implementieren Sie Codierungsstandards, die explizite Initialisierung erfordern. Aktivieren Sie Compiler-Warnungen für fehlende Initialisierung. Verwenden Sie statische Analysetools, um fehlende Initialisierung zu erkennen. Für sicherheitskritischen Code initialisieren Sie alle Variablen zum Deklarationszeitpunkt. Erwägen Sie die Verwendung von Sprachen mit obligatorischen Initialisierungsanforderungen.

Häufige Auswirkungen

AuswirkungDetails
VertraulichkeitBereich: Vertraulichkeit

Anwendungsdaten lesen - Nicht initialisierte Ressourcen können sensible Informationen offenlegen, wenn sie ohne Löschen des ursprünglichen Inhalts wiederverwendet werden.
VerfügbarkeitBereich: Verfügbarkeit

DoS: Absturz/Beenden/Neustart - Fehlende Initialisierung kann unerwarteten Programmfluss verursachen, der zu Abstürzen oder Denial-of-Service führt.
IntegritätBereich: Integrität

Ausführungslogik ändern - Nicht initialisierte Werte können die Programmlogik auf unvorhersehbare Weise beeinflussen.

Beispielcode + Lösungscode

Verwundbarer Code

// Verwundbar: Fehlende Initialisierung des Zeichenarrays
#include <stdio.h>
#include <string.h>

void vulnerable_build_path(char *filename) {
    char path[256];  // Fehlende Initialisierung

    // Verwundbar: strcat nimmt an, dass path ein leerer String ist
    // aber path enthält Müll, der sensible Daten enthalten kann
    strcat(path, "/home/user/");
    strcat(path, filename);

    printf("Pfad: %s\n", path);
}

// Angriff: Sensible Daten aus vorheriger Stack-Verwendung können leaken
// Verwundbar: Boolean auf falschen Wert initialisiert verhindert Setup
public class VulnerableConfig {

    private boolean initialized = true;  // Falsch! Sollte false sein
    private String connectionString;
    private int maxConnections;

    public void setupIfNeeded() {
        if (!initialized) {
            // Dieser Code wird nie ausgeführt, weil initialized == true
            connectionString = loadFromConfig("database.url");
            maxConnections = loadFromConfig("max.connections");
            initialized = true;
        }
    }

    public String getConnectionString() {
        setupIfNeeded();
        return connectionString;  // Gibt null zurück!
    }
}

Sicherer Code

// Behoben: Ordnungsgemäße Initialisierung des Zeichenarrays
#include <stdio.h>
#include <string.h>

void fixed_build_path(char *filename) {
    char path[256];

    // Behoben: Als leeren String initialisieren
    path[0] = '\0';
    // Oder: memset(path, 0, sizeof(path));

    // Jetzt funktioniert strcat korrekt
    strcat(path, "/home/user/");

    // Auch validieren, um Überlauf zu verhindern
    if (strlen(path) + strlen(filename) < sizeof(path)) {
        strcat(path, filename);
    }

    printf("Pfad: %s\n", path);
}
// Behoben: Korrektes Initialisierungs-Flag
public class FixedConfig {

    private boolean initialized = false;  // Behoben: Korrekter Anfangswert
    private String connectionString;
    private int maxConnections;

    public synchronized void setupIfNeeded() {
        if (!initialized) {
            connectionString = loadFromConfig("database.url");
            maxConnections = loadFromConfig("max.connections");

            // Geladene Werte validieren
            if (connectionString == null) {
                throw new ConfigurationException("Fehlende database.url");
            }

            initialized = true;
        }
    }

    public String getConnectionString() {
        setupIfNeeded();
        return connectionString;  // Jetzt ordnungsgemäß initialisiert
    }
}
// Behoben: Vollständige Struktur-Initialisierung
typedef struct {
    int user_id;
    int privilege_level;
    char username[64];
    int permissions[10];
} UserSession;

UserSession* fixed_create_session() {
    // Behoben: calloc für Null-Initialisierung verwenden
    UserSession *session = calloc(1, sizeof(UserSession));
    if (session == NULL) {
        return NULL;
    }

    // Spezifische Felder auf bekannte Werte setzen
    session->user_id = INVALID_USER_ID;
    session->privilege_level = PRIVILEGE_NONE;
    strcpy(session->username, "guest");

    // permissions-Array ist bereits null (keine Berechtigungen) von calloc

    return session;
}

CVE-Beispiele

  • CVE-2020-20739: Variable wurde nur unter bestimmten Bedingungen gesetzt, was zu Datenlecks führte, wenn die Bedingung fehlschlug.
  • CVE-2005-1036: Unsachgemäß initialisierte I/O-Berechtigungs-Bitmap erlaubte Umgehung von Zugriffsbeschränkungen.

Verwandte CWEs

  • CWE-665: Unsachgemäße Initialisierung (Eltern)
  • CWE-456: Fehlende Initialisierung einer Variablen (Kind)
  • CWE-908: Verwendung nicht initialisierter Ressourcen (kann folgen)
  • CWE-1271: Nicht initialisierter Wert bei Reset für Register (Kind - hardwarespezifisch)

Referenzen

  1. MITRE Corporation. "CWE-909: Missing Initialization of Resource." https://cwe.mitre.org/data/definitions/909.html
  2. CERT C Secure Coding Standard. "EXP33-C. Do not read uninitialized memory."
  3. CERT C Secure Coding Standard. "DCL30-C. Declare objects with appropriate storage durations."