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
| Auswirkung | Details |
|---|---|
| Sonstiges | Bereich: Sonstiges Reduzierte Wartbarkeit -- Unzureichende Fehlerbehandlungsdokumentation beeinträchtigt die Codewartbarkeit und erschwert die Implementierung konsistenter Fehlerbehandlung. |
| Sonstiges | Bereich: 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
- MITRE Corporation. "CWE-1118: Insufficient Documentation of Error Handling Techniques." https://cwe.mitre.org/data/definitions/1118.html
- Error Handling Best Practices in API Design
- Microsoft - Error Handling Documentation Guidelines