Unzureichende Dokumentation von Fehlerbehandlungstechniken

Beschreibung

Unzureichende Dokumentation von Fehlerbehandlungstechniken tritt auf, wenn die Dokumentation eines Softwareprodukts die verwendeten Techniken für Fehlerbehandlung, Exception-Verarbeitung oder ähnliche Mechanismen nicht ausreichend beschreibt. Dies umfasst fehlende Dokumentation darüber, wie Fehler erkannt, gemeldet, protokolliert und behoben werden. Die Dokumentation muss möglicherweise die Fehlerbehandlung auf mehreren Ebenen abdecken, einschließlich Modul-, Programm-, kompilierbare Codeeinheit- oder aufrufbare Ebene. Ohne ordnungsgemäße Fehlerbehandlungsdokumentation können Entwickler und Betreiber Fehler nicht ordnungsgemäß behandeln, was zu Sicherheitsproblemen führen kann.

Risiko

Unzureichende Fehlerbehandlungsdokumentation hat indirekte Sicherheitsauswirkungen. Entwickler implementieren möglicherweise ohne Anleitung keine ordnungsgemäße Fehlerbehandlung. Betreiber wissen möglicherweise nicht, wie auf Fehlerbedingungen reagiert werden soll. Sicherheitsrelevante Fehler werden möglicherweise nicht ordnungsgemäß protokolliert oder überwacht. Fehlerwiederherstellungsverfahren werden möglicherweise nicht befolgt. Sensible Informationen können durch undokumentierte Fehlermeldungen durchsickern. Exception-Handling kann im gesamten Code inkonsistent sein. Fail-Open-Verhalten kann auftreten, wenn Fail-Secure beabsichtigt war. Incident Response wird ohne dokumentierte Fehlerszenarien behindert.

Lösung

Dokumentieren Sie alle Fehlertypen und ihre Bedeutung auf jeder Ebene. Spezifizieren Sie, wie Fehler gemeldet werden (Rückgabecodes, Exceptions, Callbacks). Dokumentieren Sie Protokollierungsanforderungen und was protokolliert wird. Beschreiben Sie Fehlerwiederherstellungsverfahren und Retry-Strategien. Spezifizieren Sie Fail-Safe- vs. Fail-Secure-Verhalten für jede Komponente. Dokumentieren Sie Fehlercodes und ihre Sicherheitsauswirkungen. Bieten Sie Anleitungen zum Umgang mit verschiedenen Fehlerkategorien. Dokumentieren Sie Exception-Hierarchien und wann jede geworfen wird. Fügen Sie Fehlerbehandlungsbeispiele in die API-Dokumentation ein. Halten Sie die Fehlerdokumentation mit der Implementierung synchron.

Häufige Auswirkungen

AuswirkungDetails
SonstigesBereich: Sonstiges

Reduzierte Wartbarkeit -- Unzureichende Fehlerbehandlungsdokumentation beeinträchtigt die Codewartbarkeit und erschwert die Implementierung konsistenter Fehlerbehandlung.
SonstigesBereich: Sonstiges

Erhöhte analytische Komplexität -- Sicherheitsprüfer können ordnungsgemäße Fehlerbehandlung ohne Dokumentation nicht verifizieren.

Beispielcode und Lösung

Verwundbarer Code

// Verwundbar: Keine Dokumentation der Fehlerbehandlung

// DATEI: api_client.py
// Fehlende Dokumentation für:
// - Welche Exceptions geworfen werden können
// - Welche Fehlercodes zurückgegeben werden
// - Wie verschiedene Fehlerbedingungen zu behandeln sind
// - Was bei Fehlern protokolliert wird
// - Retry-Strategien

class APIClient:
    def fetch(self, url):
        # Was passiert bei Netzwerkfehler?
        # Was passiert bei Timeout?
        # Was passiert bei ungültiger Antwort?
        # Was wird protokolliert?
        response = requests.get(url)
        return response.json()

    def send(self, url, data):
        # Was wenn die Anfrage teilweise erfolgreich ist?
        # Woher wissen wir ob Daten empfangen wurden?
        # Welche Fehler sind wiederholbar?
        response = requests.post(url, json=data)
        return response.status_code == 200


// DATEI: database.py
// Keine Dokumentation über:
// - Transaktions-Fehlerbehandlung
// - Verbindungsausfall-Wiederherstellung
// - Deadlock-Behandlung
// - Constraint-Verletzungsfehler

class DatabaseConnection:
    def execute(self, query, params):
        # Welche Exceptions kann dies werfen?
        # Wie werden Constraint-Verletzungen gemeldet?
        # Ist die Verbindung nach einem Fehler noch gültig?
        cursor = self.conn.cursor()
        cursor.execute(query, params)
        return cursor.fetchall()


// DATEI: payment_processor.py
// Kritisches System mit undokumentierter Fehlerbehandlung

class PaymentProcessor:
    def charge(self, card, amount):
        # Was passiert bei Ablehnung?
        # Was passiert bei Betrugserkennung?
        # Was passiert bei Netzwerk-Timeout?
        # Ist die Belastung atomar?
        # Wie prüfen wir ob die Belastung nach Timeout durchging?
        pass

    def refund(self, transaction_id, amount):
        # Was wenn die ursprüngliche Transaktion nicht gefunden wird?
        # Was wenn die Rückerstattung teilweise erfolgreich ist?
        # Welche Fehler werden protokolliert?
        pass

Sichere Lösung

// Behoben: Umfassende Fehlerbehandlungsdokumentation

/*
 * ============================================================================
 * FEHLERBEHANDLUNGSDOKUMENTATION
 * ============================================================================
 *
 * Dieses Dokument beschreibt die im gesamten System verwendeten
 * Fehlerbehandlungstechniken.
 *
 * 1. FEHLERKATEGORIEN
 * ===================
 *
 * Kategorie          | Aktion        | Retry? | Log-Level | Alarm?
 * -------------------|---------------|--------|-----------|--------
 * Netzwerk-Timeout   | Wiederholen   | Ja     | WARN      | Nach 3 Versuchen
 * Verbindung fehlg.  | Neuverbindung | Ja     | WARN      | Nach 5 Fehlern
 * Auth fehlgeschlagen | Fehler        | Nein   | ERROR     | Ja (möglicher Angriff)
 * Ungültige Eingabe  | Ablehnen      | Nein   | WARN      | Nach Schwellwert
 * Rate-limitiert     | Backoff       | Ja     | INFO      | Nein
 * Serverfehler       | Retry/Fehler  | Evtl.  | ERROR     | Ja
 * Datenkorruption    | Fehler+Alarm  | Nein   | CRITICAL  | Sofort
 *
 * 2. EXCEPTION-HIERARCHIE
 * =======================
 *
 * BaseError
 * ├── NetworkError
 * │   ├── TimeoutError (wiederholbar)
 * │   ├── ConnectionError (wiederholbar)
 * │   └── SSLError (nicht wiederholbar)
 * ├── AuthenticationError (nicht wiederholbar)
 * │   ├── InvalidCredentialsError
 * │   └── TokenExpiredError
 * ├── ValidationError (nicht wiederholbar)
 * │   ├── InvalidInputError
 * │   └── ConstraintViolationError
 * └── ServiceError
 *     ├── RateLimitError (wiederholbar mit Backoff)
 *     └── InternalError (möglicherweise wiederholbar)
 *
 * 3. RETRY-STRATEGIEN
 * ===================
 *
 * Wiederholbare Fehler verwenden exponentielles Backoff:
 * - Initiale Verzögerung: 100ms
 * - Maximale Verzögerung: 30 Sekunden
 * - Maximale Wiederholungen: 3 (konfigurierbar pro Operation)
 * - Backoff-Multiplikator: 2
 * - Jitter: ±10%
 *
 * Nicht wiederholbare Fehler scheitern sofort.
 *
 * 4. PROTOKOLLIERUNGSANFORDERUNGEN
 * ================================
 *
 * Alle Fehler werden protokolliert mit:
 * - Zeitstempel (ISO 8601 UTC)
 * - Fehlerkategorie und -code
 * - Korrelations-ID zur Nachverfolgung
 * - Benutzerkontext (ohne personenbezogene Daten)
 * - Stack-Trace (nur DEBUG-Level)
 *
 * NIE protokollieren:
 * - Passwörter oder Anmeldedaten
 * - Vollständige Kartennummern
 * - Persönliche Identifikationsnummern
 *
 */

// DATEI: api_client.py

"""
API-Client mit dokumentierter Fehlerbehandlung.

Fehlerbehandlungs-Zusammenfassung:
    - Netzwerkfehler: Automatische Wiederholung mit exponentiellem Backoff
    - Auth-Fehler: Sofortiges Scheitern, keine Wiederholung
    - Rate-Limits: Automatisches Backoff und Wiederholung
    - Ungültige Antworten: Protokolliert und als ValidationError ausgelöst

Exceptions:
    NetworkError: Verbindungsprobleme (Timeout, Verbindung verweigert)
    AuthenticationError: Ungültige oder abgelaufene Anmeldedaten
    RateLimitError: Zu viele Anfragen (automatische Wiederholung mit Backoff)
    ValidationError: Ungültige Antwort vom Server
    ServiceError: Server hat 5xx-Fehler zurückgegeben

Protokollierung:
    - Alle Anfragen auf DEBUG-Level protokolliert (ohne Auth-Header)
    - Fehler auf WARN- oder ERROR-Level protokolliert
    - Erfolgreiche Antworten auf DEBUG-Level protokolliert
"""

class APIClient:
    """
    HTTP-API-Client mit automatischer Wiederholung und Fehlerbehandlung.

    Attribute:
        base_url: API-Basis-URL
        timeout: Anfrage-Timeout in Sekunden (Standard: 30)
        max_retries: Maximale Wiederholungsversuche für wiederholbare Fehler (Standard: 3)

    Fehlerbehandlung:
        Wiederholbare Fehler (NetworkError, RateLimitError, 5xx-Antworten):
            - Automatische Wiederholung mit exponentiellem Backoff
            - Nach max_retries wird die zugrundeliegende Exception ausgelöst

        Nicht wiederholbare Fehler (AuthenticationError, ValidationError, 4xx-Antworten):
            - Sofortiges Scheitern, keine Wiederholung
            - Exception wird mit vollständigen Fehlerdetails ausgelöst

    Beispiel:
        client = APIClient("https://api.example.com")
        try:
            data = client.fetch("/users/123")
        except AuthenticationError:
            # Auth-Fehler behandeln - Token erneuern oder erneut authentifizieren
            pass
        except RateLimitError as e:
            # Rate-Limit behandeln - e.retry_after enthält Wartezeit
            pass
        except NetworkError as e:
            # Netzwerkfehler nach erschöpften Wiederholungen behandeln
            pass
    """

    def fetch(self, url: str) -> dict:
        """
        Daten von URL mit automatischer Wiederholung abrufen.

        Args:
            url: URL-Pfad (wird an base_url angehängt)

        Returns:
            Geparste JSON-Antwort als Dictionary

        Raises:
            NetworkError: Verbindung nach allen Wiederholungen fehlgeschlagen
                - TimeoutError: Anfrage hat Timeout überschritten
                - ConnectionError: Server nicht erreichbar
            AuthenticationError: Ungültige oder abgelaufene Anmeldedaten (keine Wiederholung)
            RateLimitError: Zu viele Anfragen (automatisch wiederholt, ausgelöst
                           wenn nach Backoff immer noch fehlschlagend)
            ValidationError: Antwort ist kein gültiges JSON
            ServiceError: Server hat nach allen Wiederholungen 5xx zurückgegeben

        Seiteneffekte:
            - Protokolliert Anfrage/Antwort auf DEBUG-Level
            - Protokolliert Fehler auf WARN/ERROR-Level
            - Aktualisiert Rate-Limit-Tracking

        Beispiel:
            try:
                user = client.fetch("/users/123")
            except NetworkError:
                logger.error("Netzwerk nicht verfügbar, verwende gecachte Daten")
                user = cache.get("user_123")
        """
        pass
# Behoben: Python-Modul mit dokumentierter Fehlerbehandlung

"""
Datenbankverbindungsmodul.

Fehlerbehandlungs-Übersicht
============================

Dieses Modul verwendet einen geschichteten Fehlerbehandlungsansatz:

1. Verbindungsfehler
   - Automatische Neuverbindung bei Verbindungsverlust
   - Verbindungspool verwaltet Retry-Logik
   - Nach 5 Fehlern wird DatabaseConnectionError ausgelöst

2. Transaktionsfehler
   - Deadlocks: Automatische Wiederholung bis zu 3 Mal
   - Constraint-Verletzungen: Als IntegrityError ausgelöst
   - Andere Fehler: Transaktion wird automatisch zurückgesetzt

3. Abfragefehler
   - Syntaxfehler: Sofort ausgelöst
   - Timeout: Konfigurierbar, löst QueryTimeoutError aus
   - Ergebnis zu groß: Löst ResultSetTooLargeError aus

Exception-Hierarchie
====================

DatabaseError (Basis)
├── ConnectionError (wiederholbar)
│   ├── ConnectionTimeoutError
│   └── ConnectionRefusedError
├── TransactionError
│   ├── DeadlockError (automatische Wiederholung)
│   └── IntegrityError (nicht wiederholbar)
├── QueryError
│   ├── SyntaxError
│   ├── QueryTimeoutError
│   └── ResultSetTooLargeError
└── PoolExhaustedError (warten oder scheitern)

Protokollierung
===============

Alle Abfragen auf DEBUG-Level protokolliert (parametrisiert, nicht mit Werten).
Fehler auf ERROR-Level mit Abfrage-Hash zur Korrelation protokolliert.
Verbindungsereignisse auf INFO-Level protokolliert.

Sicherheitshinweise
===================

- Abfrageparameter nur als Platzhalter protokolliert, nie tatsächliche Werte
- Verbindungszeichenfolgen in Logs geschwärzt
- Stack-Traces im Produktionsmodus begrenzt
"""

class DatabaseConnection:
    """
    Datenbankverbindung mit dokumentierter Fehlerbehandlung.

    Verbindungsmanagement:
        - Verbindungen vor Verwendung validiert (ping/select 1)
        - Automatische Neuverbindung bei Verbindungsverlust
        - Verbindungspooling mit konfigurierbaren Grenzen

    Transaktionsbehandlung:
        - Standard-Auto-Commit deaktiviert
        - Explizites Commit/Rollback erforderlich
        - Automatisches Rollback bei Exception

    Fehlerwiederherstellung:
        - Deadlocks: Automatische Wiederholung mit Backoff
        - Verbindungsverlust: Automatische Neuverbindung
        - Timeout: Transaktion zurückgesetzt, Verbindung an Pool zurückgegeben
    """

    def execute(
        self,
        query: str,
        params: tuple = None,
        timeout: float = 30.0
    ) -> list:
        """
        Führt eine SQL-Abfrage mit Parametern aus.

        Args:
            query: SQL-Abfrage mit Parameter-Platzhaltern
            params: Abfrageparameter (ordnungsgemäß escaped)
            timeout: Abfrage-Timeout in Sekunden

        Returns:
            Liste von Ergebniszeilen als Dictionaries

        Raises:
            ConnectionError: Datenbankverbindung fehlgeschlagen
                Verbindung wird automatisch wiederhergestellt; Aufrufer kann wiederholen.

            SyntaxError: SQL-Syntaxfehler in der Abfrage
                Abfrage ist ungültig; Abfrage vor Wiederholung korrigieren.

            IntegrityError: Constraint-Verletzung (unique, foreign key usw.)
                Transaktion wird zurückgesetzt. Aufrufer sollte Konflikt behandeln.

            DeadlockError: Deadlock erkannt
                Automatisch 3 Mal wiederholt. Ausgelöst wenn immer noch blockiert.
                Aufrufer sollte Transaktionsreihenfolge überdenken.

            QueryTimeoutError: Abfrage hat Timeout überschritten
                Transaktion wird zurückgesetzt. Abfrageoptimierung in Betracht ziehen.

        Seiteneffekte:
            - Abfrage auf DEBUG protokolliert (nur parametrisierte Form)
            - Fehler auf ERROR mit Abfrage-Hash protokolliert
            - Metriken aktualisiert (Abfragezähler, Latenz, Fehler)

        Thread-Sicherheit:
            Diese Methode ist NICHT thread-sicher. Jeder Thread sollte seine
            eigene Verbindung verwenden oder ConnectionPool nutzen.

        Beispiel:
            try:
                users = db.execute(
                    "SELECT * FROM users WHERE status = ?",
                    ("active",)
                )
            except IntegrityError:
                logger.warning("Constraint-Verletzung, prüfe Duplikate")
            except QueryTimeoutError:
                logger.error("Abfrage-Timeout, verwende gecachte Ergebnisse")
        """
        pass

CVE-Beispiele

Diese CWE ist als VERBOTEN für direkte CVE-Zuordnung markiert, da sie ein Dokumentationsqualitätsproblem darstellt und keine direkte Sicherheitslücke.


Verwandte CWEs

  • CWE-1059: Unzureichende technische Dokumentation (Eltern)
  • CWE-1225: Dokumentationsprobleme (Kategoriemitglied)
  • CWE-1110: Unvollständige Design-Dokumentation (verwandt)
  • CWE-755: Unsachgemäße Behandlung außergewöhnlicher Bedingungen (verwandte Konsequenz)

Referenzen

  1. MITRE Corporation. "CWE-1118: Insufficient Documentation of Error Handling Techniques." https://cwe.mitre.org/data/definitions/1118.html
  2. Error Handling Best Practices in API Design
  3. Microsoft - Error Handling Documentation Guidelines