Selbstgenerierte Fehlermeldung mit sensiblen Informationen

Beschreibung

Selbstgenerierte Fehlermeldung mit sensiblen Informationen ist eine Schwachstelle, die auftritt, wenn ein Produkt eine Fehlerbedingung identifiziert und eigene Diagnose- oder Fehlermeldungen erstellt, die sensible Informationen enthalten. Im Gegensatz zu Fehlermeldungen, die von externen Komponenten wie Interpretern oder Datenbanken generiert werden, werden diese Meldungen explizit vom eigenen Code der Anwendung konstruiert. Die sensiblen Informationen können Dateisystempfade, interne Variablenwerte, Konfigurationsdetails, Datenbankverbindungsstrings, Benutzeranmeldedaten oder Stack-Traces umfassen. Diese Schwäche entsteht typischerweise, wenn Entwickler detaillierte Debugging-Informationen in Fehlerhandlern einschließen, ohne zu berücksichtigen, dass diese Meldungen in Produktionsumgebungen für unbefugte Benutzer sichtbar sein können.

Risiko

Selbstgenerierte Fehlermeldungen mit sensiblen Informationen erzeugen erhebliche Sicherheitsrisiken durch Offenlegung interner Systemdetails an potenzielle Angreifer. Detaillierte Fehlermeldungen, die Dateipfade enthüllen, ermöglichen Path-Traversal-Angriffe und helfen Angreifern, die Verzeichnisstruktur der Anwendung zu verstehen. Stack-Traces und Variable-Dumps legen Code-Logik, Funktionsnamen und potenziell sensible Datenwerte offen. Konfigurationsdetails in Fehlermeldungen können Datenbank-Anmeldedaten, API-Schlüssel oder interne Netzwerkadressen enthüllen. Diese Informationsoffenlegung transformiert blinde Angriffe in gezielte, da Angreifer die enthüllten Details nutzen können, um spezifische Exploits für die identifizierten Softwareversionen, Konfigurationen oder Dateistrukturen zu erstellen. In Multi-Tenant-Umgebungen können Fehlermeldungen versehentlich Informationen über andere Benutzer oder Mandanten preisgeben.

Lösung

Implementieren Sie einen zentralisierten Fehlerbehandlungsmechanismus, der internes Diagnose-Logging von benutzerseitigen Fehlermeldungen trennt. Erstellen Sie generische, benutzerfreundliche Fehlermeldungen, die Anleitung bieten, ohne Systeminterna preiszugeben. Loggen Sie detaillierte Fehlerinformationen einschließlich Stack-Traces und Variablenwerten in sichere serverseitige Logs, die nur für Administratoren und Entwickler zugänglich sind. Konfigurieren Sie Produktionsumgebungen, um minimale Fehlerinformationen anzuzeigen, während Entwicklungsumgebungen vollständige Details zeigen können. Überprüfen Sie allen Fehlerbehandlungscode, um sicherzustellen, dass sensible Informationen niemals in Meldungen enthalten sind, die an Clients gesendet werden. Implementieren Sie Fehlermeldungsvorlagen, die automatisch potenziell sensible Inhalte entfernen. Testen Sie Fehlerbehandlungspfade mit Sicherheits-Scanning-Tools, um Informationslecks vor dem Deployment zu identifizieren.

Häufige Auswirkungen

AuswirkungDetails
VertraulichkeitBereich: Vertraulichkeit

Angreifer können sensible Anwendungsdaten durch detaillierte Fehlermeldungen lesen. Dateipfade, interne Zustände, Konfigurationswerte und andere Systemdetails können offengelegt werden und weitere Angriffe ermöglichen.

Beispielcode

Anfälliger Code (Python)

Der folgende Code demonstriert einen anfälligen Fehlerhandler, der sensible Systeminformationen offenlegt:

import traceback
import os
from flask import Flask, jsonify

app = Flask(__name__)

# Sensible Konfiguration
DATABASE_URL = "postgresql://admin:[email protected]:5432/production"
API_KEY = "sk-live-abc123secretkey456"

def load_user_config(user_id):
    config_path = f"/etc/myapp/users/{user_id}/config.json"
    with open(config_path, 'r') as f:
        return f.read()

@app.route('/api/user/<user_id>/config')
def get_user_config(user_id):
    try:
        config = load_user_config(user_id)
        return jsonify({"config": config})
    except FileNotFoundError as e:
        # Anfällig: Legt vollständigen Dateipfad offen
        return jsonify({
            "error": "Konfigurationsdatei nicht gefunden",
            "details": f"Kann Datei nicht öffnen: {e.filename}",
            "path": f"/etc/myapp/users/{user_id}/config.json"
        }), 404
    except Exception as e:
        # Anfällig: Legt Stack-Trace und interne Details offen
        return jsonify({
            "error": "Interner Serverfehler",
            "exception_type": type(e).__name__,
            "message": str(e),
            "stack_trace": traceback.format_exc(),
            "database_url": DATABASE_URL,  # Kritische Offenlegung!
            "working_directory": os.getcwd(),
            "python_path": os.environ.get('PYTHONPATH', '')
        }), 500

@app.route('/api/connect')
def connect_database():
    try:
        # Datenbankverbindungsversuch
        raise ConnectionError("Verbindung abgelehnt")
    except Exception as e:
        # Anfällig: Legt Anmeldedaten in Fehler offen
        return jsonify({
            "error": f"Verbindung zu {DATABASE_URL} fehlgeschlagen",
            "api_key_status": f"Schlüssel {API_KEY[:10]}... ist gültig"
        }), 500

Der Code legt Dateipfade, Datenbank-Anmeldedaten, API-Schlüssel, Stack-Traces und Umgebungsvariablen in Fehlerantworten offen.

Korrigierter Code (Python)

import traceback
import logging
import uuid
from flask import Flask, jsonify

app = Flask(__name__)

# Sicheres Logging konfigurieren
logging.basicConfig(
    filename='/var/log/myapp/errors.log',
    level=logging.ERROR,
    format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)

# Generische Fehlermeldungen für Benutzer
ERROR_MESSAGES = {
    'not_found': "Die angeforderte Ressource könnte nicht gefunden werden.",
    'internal': "Ein interner Fehler ist aufgetreten. Bitte versuchen Sie es später erneut.",
    'unauthorized': "Sie sind nicht berechtigt, auf diese Ressource zuzugreifen.",
    'invalid_input': "Die bereitgestellte Eingabe ist ungültig."
}

def generate_error_id():
    """Generiert eindeutige Fehler-ID für Support-Referenz"""
    return str(uuid.uuid4())[:8]

def load_user_config(user_id):
    config_path = f"/etc/myapp/users/{user_id}/config.json"
    with open(config_path, 'r') as f:
        return f.read()

@app.route('/api/user/<user_id>/config')
def get_user_config(user_id):
    try:
        config = load_user_config(user_id)
        return jsonify({"config": config})

    except FileNotFoundError as e:
        error_id = generate_error_id()

        # Detaillierte Informationen intern loggen
        logger.error(
            f"Fehler-ID: {error_id} - Konfigurationsdatei nicht gefunden für Benutzer {user_id}. "
            f"Pfad: {e.filename}"
        )

        # Generische Nachricht an Benutzer zurückgeben
        return jsonify({
            "error": ERROR_MESSAGES['not_found'],
            "error_id": error_id,
            "support_message": "Wenn dieses Problem fortbesteht, kontaktieren Sie den Support mit der Fehler-ID."
        }), 404

    except Exception as e:
        error_id = generate_error_id()

        # Vollständige Details intern loggen (niemals Benutzern offenlegen)
        logger.error(
            f"Fehler-ID: {error_id} - Unbehandelte Ausnahme in get_user_config\n"
            f"Benutzer-ID: {user_id}\n"
            f"Ausnahme: {type(e).__name__}: {str(e)}\n"
            f"Stack-Trace:\n{traceback.format_exc()}"
        )

        # Generische Nachricht an Benutzer zurückgeben
        return jsonify({
            "error": ERROR_MESSAGES['internal'],
            "error_id": error_id
        }), 500

@app.errorhandler(500)
def handle_500(error):
    """Globaler Handler stellt sicher, dass keine sensiblen Daten durchsickern"""
    error_id = generate_error_id()
    logger.error(f"Fehler-ID: {error_id} - Unbehandelter 500-Fehler: {error}")
    return jsonify({
        "error": ERROR_MESSAGES['internal'],
        "error_id": error_id
    }), 500

Die Korrektur verwendet generische Fehlermeldungen für Benutzer, während detaillierte Diagnosen in sicheren serverseitigen Logs protokolliert werden. Fehler-IDs verknüpfen Benutzerberichte mit detaillierten internen Logs.


Ausgenutzt in der Praxis

ASP.NET Detaillierte Fehlerseiten (Mehrere Organisationen, 2000er-Heute)

ASP.NET-Anwendungen mit deaktiviertem customErrors in der Produktion legten detaillierte Stack-Traces und Konfigurationsinformationen durch selbstgenerierte Fehlerseiten offen. Diese Fehlermeldungen enthüllten Datenbankverbindungsstrings, Dateipfade und Code-Struktur. Angreifer nutzten diese Informationen, um anfällige Komponenten zu identifizieren und gezielte Angriffe zu planen. Microsoft änderte schließlich die Standardkonfigurationen, um diese Offenlegung zu verhindern.

Laravel Debug-Modus-Offenlegung (Mehrere Organisationen, 2021)

Tausende von Laravel-Anwendungen wurden entdeckt, die mit APP_DEBUG=true in der Produktion liefen, was das Framework veranlasste, detaillierte Fehlerseiten zu generieren, die Umgebungsvariablen, Datenbank-Anmeldedaten und API-Schlüssel enthielten. Sicherheitsforscher fanden offengelegte Geheimnisse einschließlich AWS-Anmeldedaten und Payment-Gateway-Schlüssel. Dies führte zu einer koordinierten Offenlegungsaktion und erhöhtem Bewusstsein für sichere Konfigurationsverwaltung.


Tools zum Testen/Ausnutzen

  • Burp Suite — Web-Sicherheitstest-Plattform, die Fehlerantworten auslösen und analysieren kann, um sensible Informationsoffenlegung zu identifizieren.

  • OWASP ZAP — Open-Source-Scanner mit aktiven Scan-Fähigkeiten zur Erkennung von Informationslecks in Fehlermeldungen.

  • Nikto — Webserver-Scanner, der auf Fehlerseiten-Informationsoffenlegung und Debug-Modus-Erkennung testet.


CVE-Beispiele

  • CVE-2005-1745 — Informationsleck enthüllte sensible Daten durch detaillierte Fehlermeldungen, die mit physischem Systemzugang zugänglich waren.

  • CVE-2018-1000129 — Jolokia legte sensible Systemeigenschaften und Umgebungsvariablen durch Fehlermeldungen offen.

  • CVE-2021-22986 — F5 BIG-IP legte interne Konfigurationsdetails durch selbstgenerierte Fehlerantworten offen.


Referenzen

  1. MITRE Corporation. "CWE-210: Self-generated Error Message Containing Sensitive Information." Common Weakness Enumeration. https://cwe.mitre.org/data/definitions/210.html

  2. OWASP Foundation. "Improper Error Handling." OWASP. https://owasp.org/www-community/Improper_Error_Handling

  3. OWASP Foundation. "Error Handling Cheat Sheet." OWASP Cheat Sheet Series. https://cheatsheetseries.owasp.org/cheatsheets/Error_Handling_Cheat_Sheet.html