Servergenerierte Fehlermeldung mit sensiblen Informationen
Beschreibung
Servergenerierte Fehlermeldung mit sensiblen Informationen ist eine Schwachstelle, bei der Fehlermeldungen, die von Webservern, Anwendungsservern oder Backend-Systemen erzeugt werden, sensible Daten für Benutzer oder Angreifer offenlegen. Während Fehlermeldungen einen legitimen Zweck erfüllen, werden sie zu Sicherheitsschwachstellen, wenn sie Informationen preisgeben, die Angreifer für Aufklärung oder Ausnutzung verwenden können. Dies umfasst Server-Versionen, interne Pfade, Datenbankdetails, Konfigurationseinstellungen, Stack-Traces und andere technische Informationen.
Risiko
Servergenerierte Fehlermeldungen bergen erhebliche Aufklärungsrisiken. HTTP-Fehlerseiten können Webserver-Software und Versionsnummern offenlegen, was gezielte Exploits ermöglicht. Datenbankfehler können Abfragestrukturen, Tabellennamen und Datenwerte preisgeben. Anwendungsfehler können vollständige Dateipfade anzeigen. Stack-Traces legen Klassennamen, Methodensignaturen und Zeilennummern offen. Angreifer lösen systematisch Fehler aus, um die Backend-Infrastruktur zu kartieren.
Lösung
Implementieren Sie konsistente Fehlerbehandlung, die legitimen Benutzern aussagekräftiges Feedback bietet, während angreifernutzbare Informationen eingeschränkt werden. Konfigurieren Sie Webserver für benutzerdefinierte Fehlerseiten. Fangen Sie alle Ausnahmen ab und geben Sie generische Fehlermeldungen zurück. Protokollieren Sie detaillierte Fehlerinformationen serverseitig. Deaktivieren Sie Debug-Modi in der Produktion.
Häufige Auswirkungen
| Auswirkung | Details |
|---|---|
| Vertraulichkeit | Bereich: Vertraulichkeit Anwendungsdaten lesen - Angreifer können sensible Systeminformationen aus Fehlermeldungen extrahieren, einschließlich Server-Versionen, Pfade und Datenbankdetails. |
Beispielcode
Verwundbarer Code
// Verwundbar: Rohe Ausnahme an Client
public class VerwundbaresServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
Connection conn = DriverManager.getConnection(
"jdbc:mysql://db.internal:3306/app", "admin", "password");
} catch (SQLException e) {
// Verwundbar: Details werden exponiert
response.sendError(500, "Datenbankfehler: " + e.getMessage());
// Ausgabe enthält Hostnamen und Port!
}
}
}
<?php
// Verwundbar: display_errors aktiviert
// php.ini: display_errors = On
function getUserData($userId) {
$conn = mysqli_connect("localhost", "root", "password", "users");
$result = mysqli_query($conn, "SELECT * FROM users WHERE id = '$userId'");
if (!$result) {
// Verwundbar: SQL-Fehler mit Abfragedetails
die("Datenbankfehler: " . mysqli_error($conn));
}
}
?>
# Verwundbar: Flask mit Debug-Modus
from flask import Flask
import traceback
app = Flask(__name__)
app.debug = True # Verwundbar!
@app.route('/api/user/<user_id>')
def get_user(user_id):
try:
user = database.get_user(user_id)
return jsonify(user)
except Exception as e:
# Verwundbar: Vollständiger Traceback
return f"Fehler: {traceback.format_exc()}", 500
Lösungscode
// Behoben: Sichere Fehlerbehandlung
public class SicheresServlet extends HttpServlet {
private static final Logger logger = LoggerFactory.getLogger(SicheresServlet.class);
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
Connection conn = getConnection();
// ...
} catch (SQLException e) {
String errorId = UUID.randomUUID().toString().substring(0, 8);
// Behoben: Details nur im Log
logger.error("Datenbankfehler [{}]: {}", errorId, e.getMessage(), e);
// Behoben: Generische Nachricht an Client
response.sendError(500, "Ein Fehler ist aufgetreten. Referenz: " + errorId);
}
}
}
<?php
// Behoben: Sichere Fehlerbehandlung
// php.ini: display_errors = Off, log_errors = On
set_exception_handler(function($e) {
$errorId = bin2hex(random_bytes(4));
error_log("Fehler [$errorId]: " . $e->getMessage());
http_response_code(500);
echo json_encode(['error' => 'Ein Fehler ist aufgetreten', 'reference' => $errorId]);
});
function getUserData($userId) {
try {
$conn = getSecureConnection();
$stmt = $conn->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$userId]);
return $stmt->fetch();
} catch (PDOException $e) {
throw new RuntimeException("Benutzerdaten nicht abrufbar");
}
}
?>
# Behoben: Flask ohne Debug-Modus
from flask import Flask, jsonify
import logging
import uuid
app = Flask(__name__)
app.debug = False # Behoben
logging.basicConfig(filename='/var/log/app/error.log', level=logging.ERROR)
logger = logging.getLogger(__name__)
@app.route('/api/user/<user_id>')
def get_user(user_id):
try:
user = database.get_user(user_id)
return jsonify(user)
except Exception as e:
error_id = str(uuid.uuid4())[:8]
logger.error(f"Fehler [{error_id}]", exc_info=True)
return jsonify({'error': 'Ein Fehler ist aufgetreten', 'reference': error_id}), 500
@app.errorhandler(Exception)
def handle_exception(e):
error_id = str(uuid.uuid4())[:8]
logger.error(f"Unbehandelt [{error_id}]", exc_info=True)
return jsonify({'error': 'Interner Fehler', 'reference': error_id}), 500
CVE-Beispiele
Keine spezifischen CVEs, aber servergenerierte Fehler-Informationsoffenlegung ist häufig bei fehlkonfigurierten Webanwendungen und Entwicklungseinstellungen in der Produktion.
Referenzen
- MITRE Corporation. "CWE-550: Server-generated Error Message Containing Sensitive Information." https://cwe.mitre.org/data/definitions/550.html
- OWASP. "Error Handling Cheat Sheet."
- OWASP. "OWASP Top Ten 2021 - A05:2021 Security Misconfiguration."