Division durch Null

Beschreibung

Division durch Null ist eine Schwachstelle, die auftritt, wenn ein Produkt einen Wert durch Null dividiert, was undefiniertes Verhalten, Abstürze oder Exceptions verursacht. Diese Schwäche tritt typischerweise auf, wenn ein unerwarteter Wert dem Produkt bereitgestellt wird, wenn Eingabevalidierung unzureichend ist, oder wenn eine Fehlerbedingung unentdeckt bleibt. Sie erscheint häufig in Berechnungen mit physikalischen Dimensionen wie Größe, Länge, Breite und Höhe sowie in Zeitberechnungen, Verhältnissen und Durchschnitten. In den meisten Programmiersprachen und Prozessoren verursacht Division durch Null eine Laufzeit-Exception oder Hardware-Fault, die das Programm beendet, wenn sie nicht abgefangen wird.

Risiko

Division durch Null kann Denial-of-Service durch Anwendungsabstürze verursachen. In Serveranwendungen kann ein Absturz den Dienst für alle Benutzer unterbrechen. In eingebetteten Systemen oder kritischen Anwendungen kann eine unbehandelte Division-durch-Null System-Resets oder undefiniertes Verhalten verursachen. Einige sicherheitskritische Operationen können umgangen werden, wenn die Anwendung abstürzt, bevor sie abgeschlossen sind. Während es primär ein Verfügbarkeitsproblem ist, kann Division durch Null manchmal mit anderen Schwachstellen verkettet werden - zum Beispiel wenn der Absturz Daten in einem inkonsistenten Zustand hinterlässt oder wenn die Ausnahmebehandlung sensible Informationen offenlegt.

Lösung

Validieren Sie immer, dass Divisorwerte nicht Null sind, bevor Sie eine Division durchführen. Implementieren Sie ordnungsgemäße Eingabevalidierung für alle Werte, die als Divisoren verwendet werden können. Prüfen Sie explizit auf Null und behandeln Sie es angemessen - entweder einen Fehler zurückgeben, einen Standardwert verwenden oder die Berechnung überspringen. Verwenden Sie sichere Mathematikbibliotheken, die Randfälle behandeln. Überlegen Sie, ob der Nullwert eine Fehlerbedingung anzeigt, die anders behandelt werden sollte. In Sprachen, die Exceptions werfen, umschließen Sie Divisionsoperationen mit try-catch-Blöcken, wenn der Divisor Null sein kann.

Häufige Auswirkungen

AuswirkungDetails
VerfügbarkeitUmfang: Verfügbarkeit

Eine Division durch Null führt zu einem Absturz, der die Anwendung unerwartet beendet oder neustartet, was zu Denial-of-Service führt.

Beispielcode

Anfälliger Code

// Anfällig: Keine Prüfung auf Null-Divisor
int vulnerable_calculate_average(int *values, int count) {
    int sum = 0;
    for (int i = 0; i < count; i++) {
        sum += values[i];
    }
    // Anfällig: count kann Null sein
    return sum / count;
}

// Anfällig: Null-Dimension bei Bildverarbeitung
void vulnerable_resize_image(Image *img, int new_width, int new_height) {
    // Anfällig: Dimensionen können Null sein
    int x_ratio = img->width / new_width;
    int y_ratio = img->height / new_height;
    // ... Größenänderungslogik
}
# Anfällig: Null-Divisor aus Benutzereingabe
def vulnerable_calculate_rate(total, time_seconds):
    # Anfällig: time_seconds kann Null sein
    return total / time_seconds

# Anfällig: Liste mit Nulllange
def vulnerable_average(values):
    # Anfällig: len(values) kann Null sein
    return sum(values) / len(values)
// Anfällig: Division ohne Validierung
public class VulnerableDivision {

    public double vulnerablePercentage(int part, int total) {
        // Anfällig: total kann Null sein
        return (part * 100.0) / total;
    }

    public int vulnerableItemsPerPage(int totalItems, int itemsPerPage) {
        // Anfällig: itemsPerPage kann Null sein
        return totalItems / itemsPerPage;
    }
}

Korrigierter Code

// Korrigiert: Auf Null-Divisor prüfen
int secure_calculate_average(int *values, int count) {
    if (count <= 0) {
        return 0;  // Oder Fehlercode zurückgeben
    }

    int sum = 0;
    for (int i = 0; i < count; i++) {
        sum += values[i];
    }
    return sum / count;
}

// Korrigiert: Dimensionen validieren
int secure_resize_image(Image *img, int new_width, int new_height) {
    if (new_width <= 0 || new_height <= 0) {
        return -1;  // Fehler: ungültige Dimensionen
    }

    int x_ratio = img->width / new_width;
    int y_ratio = img->height / new_height;
    // ... Größenänderungslogik
    return 0;
}
# Korrigiert: Divisor validieren
def secure_calculate_rate(total, time_seconds):
    if time_seconds <= 0:
        raise ValueError("Zeit muss positiv sein")
    return total / time_seconds

# Korrigiert: Auf leere Liste prüfen
def secure_average(values):
    if not values:
        raise ValueError("Kann Durchschnitt einer leeren Liste nicht berechnen")
    return sum(values) / len(values)

# Alternative: None für ungültige Eingabe zurückgeben
def secure_average_optional(values):
    if not values:
        return None
    return sum(values) / len(values)
// Korrigiert: Vor Division validieren
public class SecureDivision {

    public double securePercentage(int part, int total) {
        if (total == 0) {
            throw new IllegalArgumentException("Total darf nicht Null sein");
        }
        return (part * 100.0) / total;
    }

    public int secureItemsPerPage(int totalItems, int itemsPerPage) {
        if (itemsPerPage <= 0) {
            throw new IllegalArgumentException("Elemente pro Seite muss positiv sein");
        }
        return totalItems / itemsPerPage;
    }

    // Alternative: Optionaler Rückgabetyp
    public OptionalDouble safePercentage(int part, int total) {
        if (total == 0) {
            return OptionalDouble.empty();
        }
        return OptionalDouble.of((part * 100.0) / total);
    }
}

CVE-Beispiele

  • CVE-2007-3268 — Ungültiger Größenwert führte zu Division-durch-Null.
  • CVE-2007-2723 — Leerer Inhalt löste Division-durch-Null aus.
  • CVE-2007-2237 — Null-Höhenwert verursachte Division-durch-Null.

Referenzen

  1. MITRE Corporation. "CWE-369: Divide By Zero." https://cwe.mitre.org/data/definitions/369.html