Generierung von Fehlermeldungen mit sensiblen Informationen

Beschreibung

Generierung von Fehlermeldungen mit sensiblen Informationen tritt auf, wenn eine Anwendung Fehlermeldungen erstellt, die für Angreifer hilfreiche Details enthalten, wie Datenbankstrukturen, Dateipfade, Softwareversionen, Konfigurationseinstellungen oder sogar Anmeldedaten. Diese Meldungen können selbstgeneriert (explizit im Quellcode konstruiert) oder extern generiert (von Frameworks, Interpretern oder Datenbanken produziert) sein. Während ausführliche Fehlermeldungen beim Debugging helfen, liefern sie Angreifern Aufklärungsdaten, die gezielte Angriffe erleichtern.

Risiko

Ausführliche Fehlermeldungen sind eine primäre Informationsquelle für Angreifer während der Aufklärung. Stack-Traces enthüllen Anwendungsstruktur, Bibliotheken und Ausführungsfluss. Datenbankfehler legen Tabellennamen, Spaltennamen und Abfragelogik offen – was SQL-Injection-Verfeinerung ermöglicht. Pfadoffenlegung ermöglicht Path-Traversal-Angriffe durch Enthüllung von Verzeichnisstrukturen. Versionsinformationen helfen Angreifern, bekannte Schwachstellen zu identifizieren. In Produktionsumgebungen ist solche Informationsoffenlegung eine erhebliche Sicherheitslücke. Diese Schwachstelle wird unter OWASPs Top 10 "Unsicheres Design"-Kategorie klassifiziert aufgrund des grundlegenden Design-Fehlers, interne Details offenzulegen.

Lösung

Implementieren Sie benutzerdefinierte Fehlerbehandlung, die Benutzern generische Meldungen liefert, während detaillierte Fehler sicher für Administratoren geloggt werden. Konfigurieren Sie Produktionsumgebungen, um Debug-Modus und ausführliche Fehlerberichterstattung zu deaktivieren. Erstellen Sie Fehlerseiten, die keine Stack-Traces, Datenbankabfragen oder Systempfade enthüllen. Zentralisieren Sie Ausnahmebehandlung, um konsistente Fehlerantworten sicherzustellen. Für Frameworks konfigurieren Sie Produktions-Fehlerhandler entsprechend (z.B. DEBUG=False in Django, benutzerdefinierte Fehlerseiten in ASP.NET). Überprüfen und bereinigen Sie alle Fehlerausgaben vor dem Deployment.

Häufige Auswirkungen

AuswirkungDetails
VertraulichkeitBereich: Informationsoffenlegung

Fehlermeldungen legen sensible Daten offen, einschließlich Anmeldedaten, interner Pfade, Datenbankschemata und Konfigurationsdetails.
ZugriffskontrolleBereich: Angriffserleichterung

Offengelegte Informationen ermöglichen Angreifern, gezielte Angriffe wie SQL-Injection, Path-Traversal oder Authentifizierungsumgehung zu erstellen.
SicherheitBereich: Aufklärung

Versionsinformationen und Stack-Traces enthüllen Software- und Bibliotheksversionen mit bekannten Schwachstellen.

Beispielcode + Lösungscode

Anfälliger Code

// ANFÄLLIG: Vollständiger Stack-Trace in Antwort
@RestController
public class DatabaseController {
    @GetMapping("/data")
    public ResponseEntity<?> getData(@RequestParam String query) {
        try {
            return ResponseEntity.ok(jdbcTemplate.queryForList(query));
        } catch (SQLException e) {
            // Legt Datenbankfehler, Abfragestruktur und Stack-Trace offen
            return ResponseEntity.status(500)
                .body("Datenbankfehler: " + e.getMessage() +
                      "\nAbfrage: " + query +
                      "\nStack Trace: " + Arrays.toString(e.getStackTrace()));
        }
    }
}
// ANFÄLLIG: PHP-Fehler legt Pfad und Konfiguration offen
<?php
// Fehler zeigt vollständigen Dateipfad und Zeilennummern
error_reporting(E_ALL);
ini_set('display_errors', 1);

function getUser($id) {
    $conn = new mysqli("localhost", "root", "password123", "users");
    // SQLException legt Datenbank-Anmeldedaten und -Struktur offen
    $result = $conn->query("SELECT * FROM users WHERE id = $id");
    return $result;
}
?>
# ANFÄLLIG: Django Debug-Modus in Produktion
# settings.py
DEBUG = True  # NIEMALS in Produktion!
ALLOWED_HOSTS = ['*']

# Legt vollständigen Traceback, lokale Variablen und SQL-Abfragen offen

Korrigierter Code

// SICHER: Generische Fehlerantwort mit sicherem Logging
@RestController
@ControllerAdvice
public class DatabaseController {
    private static final Logger logger = LoggerFactory.getLogger(DatabaseController.class);

    @GetMapping("/data")
    public ResponseEntity<?> getData(@RequestParam String id) {
        try {
            // Parametrisierte Abfragen verwenden
            return ResponseEntity.ok(dataService.findById(id));
        } catch (Exception e) {
            // Detaillierten Fehler intern loggen
            String errorId = UUID.randomUUID().toString();
            logger.error("Fehler-ID {}: Datenbankoperation fehlgeschlagen - {}",
                        errorId, e.getMessage(), e);

            // Generische Nachricht mit Referenz-ID zurückgeben
            return ResponseEntity.status(500)
                .body(Map.of(
                    "error", "Bei der Verarbeitung Ihrer Anfrage ist ein Fehler aufgetreten",
                    "reference", errorId
                ));
        }
    }

    @ExceptionHandler(Exception.class)
    public ResponseEntity<?> handleException(Exception e) {
        logger.error("Unbehandelte Ausnahme: {}", e.getMessage(), e);
        return ResponseEntity.status(500)
            .body(Map.of("error", "Interner Serverfehler"));
    }
}
// SICHER: Produktions-Fehlerbehandlung
<?php
// Fehleranzeige in Produktion deaktivieren
error_reporting(0);
ini_set('display_errors', 0);
ini_set('log_errors', 1);
ini_set('error_log', '/var/log/php/error.log');

function getUser($id) {
    try {
        $conn = new PDO($dsn, $user, $pass);
        $stmt = $conn->prepare("SELECT * FROM users WHERE id = ?");
        $stmt->execute([$id]);
        return $stmt->fetch();
    } catch (PDOException $e) {
        // Intern loggen
        error_log("Datenbankfehler: " . $e->getMessage());
        // Generische Nachricht zurückgeben
        throw new UserException("Benutzerinformationen könnten nicht abgerufen werden");
    }
}
?>
# SICHER: Django Produktionseinstellungen
# settings.py
DEBUG = False
ALLOWED_HOSTS = ['meineseite.de']

# Benutzerdefinierte Fehler-Views
handler404 = 'myapp.views.custom_404'
handler500 = 'myapp.views.custom_500'

LOGGING = {
    'handlers': {
        'file': {
            'class': 'logging.FileHandler',
            'filename': '/var/log/django/error.log',
        },
    },
    'loggers': {
        'django': {
            'handlers': ['file'],
            'level': 'ERROR',
        },
    },
}

Ausgenutzt in der Praxis

GitLab Informationsoffenlegung (GitLab, 2025)

Mehrere CWE-209-Schwachstellen in GitLab CE/EE legten sensible Informationen durch Fehlermeldungen offen und betrafen Enterprise-Quellcodeverwaltungssysteme.

Umbraco CMS Informationsoffenlegung (Umbraco, 2025)

Informationsoffenlegungs-Schwachstelle in Umbraco CMS ermöglichte Angreifern, Systeminformationen durch ausführliche Fehlermeldungen zu sammeln.

Nextcloud Kalender (Nextcloud, 2025)

Fehlermeldungs-Informationsoffenlegung in Nextcloud Kalender enthüllte interne Details an unbefugte Benutzer.


Tools zum Testen/Ausnutzen

  • Burp Suite — Anfragen manipulieren um Fehlerbedingungen auszulösen.

  • OWASP ZAP — Spider und Scan nach Informationsoffenlegung in Fehlern.

  • Nikto — Webserver-Scanner, der ausführliche Fehlerantworten identifiziert.


CVE-Beispiele

  • CVE-2024-21733 — Apache Tomcat Informationsoffenlegung durch Fehlermeldungen.

  • CVE-2023-44487 — HTTP/2-Implementierungsfehler, die Systeminformationen offenlegen.

  • CVE-2023-2868 — Barracuda ESG Fehlermeldungsoffenlegung.


Referenzen

  1. MITRE. "CWE-209: Generation of Error Message Containing Sensitive Information." https://cwe.mitre.org/data/definitions/209.html

  2. OWASP. "Error Handling." https://cheatsheetseries.owasp.org/cheatsheets/Error_Handling_Cheat_Sheet.html