Ungeprüfter Fehlerzustand

Beschreibung

Ungeprüfter Fehlerzustand ist eine Schwachstelle, die auftritt, wenn Programmierer Ausnahmen und Fehlerbedingungen nicht ordnungsgemäß prüfen oder behandeln. Diese Schwäche entsteht aus fehlerhaften Annahmen: entweder, dass eine Operation nicht fehlschlagen kann, oder dass Fehlschläge keine Rolle spielen. Wenn Ausnahmen ignoriert oder Fehlerbedingungen nicht geprüft werden, können Angreifer unerwartetes Verhalten hervorrufen, das unbemerkt bleibt. Das Programm setzt die Ausführung in einem potenziell ungültigen Zustand fort, ohne zu wissen, dass eine kritische Operation fehlgeschlagen ist.

Risiko

Das Ignorieren von Ausnahmen und Fehlerbedingungen ermöglicht es Angreifern, die Lücke zwischen erwartetem und tatsächlichem Systemzustand auszunutzen. Speicherzuweisungsfehler, Dateioperationen, Netzwerkkommunikation und Authentifizierungsprüfungen, die stillschweigend fehlschlagen, lassen Anwendungen verwundbar. Sicherheitskontrollen, die aufgrund ungeprüfter Fehler umgangen werden, können unautorisierten Zugang gewähren. Datenbeschädigung kann auftreten, wenn Operationen zur Hälfte fehlschlagen, ohne ordnungsgemäß behandelt zu werden. Die stillschweigende Natur dieser Fehler macht sie besonders gefährlich, da es keine protokollierten Beweise für das Problem gibt, was die Erkennung und forensische Analyse behindert.

Lösung

Wählen Sie Programmiersprachen, die Ausnahmebehandlung zur Kompilierzeit erzwingen, um diese Probleme während der Entwicklung zu erkennen. Fangen Sie alle relevanten Ausnahmen ab und stellen Sie sicher, dass alle Ausnahmen so behandelt werden, dass ein vorhersagbarer Systemzustand aufrechterhalten wird. Lassen Sie Catch-Blöcke niemals leer -- protokollieren Sie mindestens den Fehler für Debugging-Zwecke. Etablieren Sie Kodierungsstandards, die explizite Fehlerbehandlung erfordern. Verwenden Sie statische Analyse-Tools zur Erkennung ungeprüfter Fehlerbedingungen. Dokumentieren Sie, welche Ausnahmen jede Funktion werfen kann, und verlangen Sie, dass Aufrufer sie behandeln. Erwägen Sie die Verwendung von Sprachen mit geprüften Ausnahmen oder Lintern, die vor ignorierten Fehlern warnen.

Häufige Auswirkungen

AuswirkungDetails
IntegritätBereich: Integrität, Ändere

Variiert je nach Kontext -- Unerwarteter Zustand, veränderte Ausführungslogik. Das System kann in einen ungültigen Zustand eintreten, der zu unbeabsichtigtem Verhalten führt.

Beispielcode und Lösung

Verwundbarer Code

// Verwundbar: Ausnahme gefangen aber komplett ignoriert
public class VulnerableExchange {

    public void performExchange() {
        try {
            doExchange();
        } catch (RareException e) {
            // Verwundbar: "Das kann nie passieren"
            // Wenn es doch passiert, wird es niemand je erfahren
        }

        // Fährt fort als ob der Austausch erfolgreich war
        confirmExchange();
    }

    public void processFile(String path) {
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(path);
            processData(fis);
        } catch (FileNotFoundException e) {
            // Verwundbar: Stillschweigend ignoriert
        } catch (IOException e) {
            // Verwundbar: Ebenfalls ignoriert
        }
        // Hat möglicherweise überhaupt keine Daten verarbeitet
    }
}
// Verwundbar: Rückgabewert nicht geprüft
void vulnerable_operation() {
    char *data = malloc(1024);
    // Verwundbar: malloc kann NULL zurückgeben

    strcpy(data, get_user_input());  // Absturz bei NULL

    FILE *f = fopen("/tmp/data", "w");
    // Verwundbar: fopen kann NULL zurückgeben

    fwrite(data, 1, strlen(data), f);  // Absturz bei NULL
    fclose(f);
}

// Verwundbar: Fehlercode ignoriert
void vulnerable_network() {
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    // Verwundbar: socket kann -1 zurückgeben

    connect(sock, (struct sockaddr*)&addr, sizeof(addr));
    // Verwundbar: connect kann fehlschlagen

    send(sock, buffer, len, 0);
    // Verwundbar: send kann teilweise oder vollständig fehlschlagen
}
# Verwundbar: Generisches except, das alle Fehler ignoriert
def vulnerable_database_operation():
    try:
        connection = database.connect()
        cursor = connection.cursor()
        cursor.execute("INSERT INTO audit_log VALUES (?)", (event,))
        connection.commit()
    except:
        # Verwundbar: Alle Ausnahmen stillschweigend verschluckt
        pass

    # Fährt fort als ob Logging erfolgreich war
    perform_sensitive_operation()

Sichere Lösung

// Behoben: Ordnungsgemäße Ausnahmebehandlung
public class SecureExchange {

    public void performExchange() throws ExchangeException {
        try {
            doExchange();
        } catch (RareException e) {
            // Behoben: Protokollieren und behandeln oder propagieren
            logger.error("Rare exception during exchange", e);
            throw new ExchangeException("Exchange failed", e);
        }

        confirmExchange();
    }

    public void processFile(String path) throws FileProcessingException {
        try (FileInputStream fis = new FileInputStream(path)) {
            processData(fis);
        } catch (FileNotFoundException e) {
            // Behoben: Angemessen behandeln
            logger.error("File not found: " + path, e);
            throw new FileProcessingException("File not found: " + path, e);
        } catch (IOException e) {
            // Behoben: I/O-Fehler behandeln
            logger.error("Error reading file: " + path, e);
            throw new FileProcessingException("Failed to read file", e);
        }
    }
}
// Behoben: Alle Rückgabewerte prüfen
int secure_operation() {
    char *data = malloc(1024);
    // Behoben: malloc-Rückgabe prüfen
    if (data == NULL) {
        perror("malloc failed");
        return -1;
    }

    const char *input = get_user_input();
    if (input == NULL) {
        free(data);
        return -1;
    }
    strncpy(data, input, 1023);
    data[1023] = '\0';

    FILE *f = fopen("/tmp/data", "w");
    // Behoben: fopen-Rückgabe prüfen
    if (f == NULL) {
        perror("fopen failed");
        free(data);
        return -1;
    }

    size_t written = fwrite(data, 1, strlen(data), f);
    // Behoben: Schreiberfolg prüfen
    if (written != strlen(data)) {
        perror("fwrite incomplete");
        fclose(f);
        free(data);
        return -1;
    }

    fclose(f);
    free(data);
    return 0;
}

// Behoben: Netzwerkoperationen prüfen
int secure_network() {
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    // Behoben: Socket-Erstellung prüfen
    if (sock < 0) {
        perror("socket failed");
        return -1;
    }

    // Behoben: Connect prüfen
    if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
        perror("connect failed");
        close(sock);
        return -1;
    }

    // Behoben: Send prüfen
    ssize_t sent = send(sock, buffer, len, 0);
    if (sent < 0) {
        perror("send failed");
        close(sock);
        return -1;
    }
    if (sent != len) {
        fprintf(stderr, "Partial send: %zd of %zu\n", sent, len);
    }

    close(sock);
    return 0;
}
# Behoben: Ordnungsgemäße Ausnahmebehandlung
def secure_database_operation():
    try:
        connection = database.connect()
        cursor = connection.cursor()
        cursor.execute("INSERT INTO audit_log VALUES (?)", (event,))
        connection.commit()
    except DatabaseError as e:
        # Behoben: Spezifischen Fehler protokollieren
        logger.error(f"Database operation failed: {e}")
        # Behoben: Nicht fortfahren wenn Audit-Logging fehlgeschlagen
        raise AuditFailureException("Audit logging required") from e
    finally:
        if connection:
            connection.close()

    # Nur fortfahren wenn Logging erfolgreich war
    perform_sensitive_operation()

CVE-Beispiele

Für diese CWE sind keine spezifischen CVEs aufgeführt. Das Schwachstellenmuster tritt auf in:

  • Anwendungen mit leeren Catch-Blöcken
  • C-Code, der Funktionsrückgabewerte ignoriert
  • Systemen, die nach fehlgeschlagenen sicherheitskritischen Operationen fortfahren

Referenzen

  1. MITRE Corporation. "CWE-391: Unchecked Error Condition." https://cwe.mitre.org/data/definitions/391.html