Bereitstellung des falschen Handlers

Beschreibung

Bereitstellung des falschen Handlers ist eine Schwachstelle, bei der der falsche "Handler" zur Verarbeitung eines Objekts zugewiesen wird. Diese Schwäche tritt auf, wenn falsche Verarbeitungsmechanismen Objekte behandeln, was zu unerwartetem Verhalten oder Sicherheitsproblemen führt. Häufige Beispiele sind das Aufrufen eines Servlets, das JSP-Quellcode offenlegt anstatt ihn auszuführen, die automatische Bestimmung von Objekttypen trotz expliziter Typspezifikationen, die der Bestimmung widersprechen, oder das Verarbeiten hochgeladener Dateien mit Handlern, die nicht dem deklarierten Dateityp entsprechen.

Risiko

Falsche Handler-Bereitstellung kann zu schwerwiegenden Sicherheitskonsequenzen führen, einschließlich Quellcode-Offenlegung, Sicherheitsumgehung und beliebiger Codeausführung. Wenn eine Skriptdatei von einem statischen Datei-Handler anstelle der Skript-Engine verarbeitet wird, wird Quellcode offengelegt, der Anmeldedaten oder Logik enthält. Wenn Dateityp-Validierung durch nicht übereinstimmende Handler umgangen wird, können Angreifer beliebigen Code über hochgeladene Dateien ausführen. Content-Type-Fehlbehandlung kann Browser dazu veranlassen, bösartige Inhalte auszuführen. Das Risiko wird verstärkt, wenn die Handler-Auswahl auf leicht manipulierbaren Eingaben wie Dateierweiterungen oder vom Benutzer bereitgestellten Headern basiert.

Lösung

Führen Sie Typprüfungen durch, bevor Objekte interpretiert werden, um sicherzustellen, dass der Handler dem tatsächlichen Inhaltstyp entspricht. Lehnen Sie alle inkonsistenten Typen ab, wie eine Datei mit .GIF-Erweiterung, die PHP-Code zu enthalten scheint. Implementieren Sie Defense-in-Depth, indem Sie sowohl den deklarierten Typ als auch den tatsächlichen Inhalt validieren. Konfigurieren Sie Webserver so, dass strikte Handler-Zuordnungen erzwungen werden und ein Fallback auf Standard-Handler verhindert wird. Verwenden Sie Content-Sniffing-Präventions-Header (X-Content-Type-Options: nosniff). Validieren Sie hochgeladene Dateien gegen erwartete Inhaltssignaturen, nicht nur Erweiterungen.

Häufige Auswirkungen

AuswirkungDetails
IntegritätUmfang: Integrität, Sonstiges

Variiert je nach Kontext - Die Konsequenzen hängen vom Kontext ab, führen aber typischerweise zu unerwarteten Anwendungszuständen. Unerwarteter Zustand - Falscher Handler kann Inhalte auf unbeabsichtigte Weise verarbeiten, was zu Informationsoffenlegung oder Sicherheitsumgehung führt.

Beispielcode

Anfälliger Code

// Anfällig: Servlet-Container-Fehlkonfiguration
// web.xml die direkten Servlet-Aufruf erlaubt
<servlet-mapping>
    <servlet-name>JspServlet</servlet-name>
    <url-pattern>*.jsp</url-pattern>
</servlet-mapping>

// Fehlt: Kein Schutz gegen direkten Klassenaufruf
// Angreifer kann aufrufen: /servlet/com.example.InternalServlet
// Dies umgeht JSP-Verarbeitung und kann Quellcode oder interne Funktionalität offenlegen
<?php
// Anfällig: Erweiterungsbasierte Handler-Auswahl
function vulnerable_process_upload($filename, $content) {
    $extension = pathinfo($filename, PATHINFO_EXTENSION);

    // Anfällig: Vertraut Erweiterung ohne Inhaltsvalidierung
    switch (strtolower($extension)) {
        case 'jpg':
        case 'gif':
        case 'png':
            // Verarbeitet als Bild, aber Inhalt könnte PHP sein!
            move_uploaded_file($content, "/uploads/" . $filename);
            break;
        case 'txt':
            // Behandelt als Text
            file_put_contents("/uploads/" . $filename, $content);
            break;
    }
}

// Angreifer lädt "malicious.php.jpg" oder "image.gif" mit PHP-Code hoch
// Wenn Webserver .gif-Dateien als PHP ausführt, läuft der Code
?>
# Anfällig: Content-Type-basierte Handler-Auswahl ohne Validierung
from flask import Flask, request, send_file

app = Flask(__name__)

@app.route('/process', methods=['POST'])
def vulnerable_process():
    content_type = request.content_type

    # Anfällig: Vertraut Content-Type-Header
    if 'image' in content_type:
        # Verarbeitet als Bild
        return process_image(request.data)
    elif 'text' in content_type:
        # Verarbeitet als Text
        return process_text(request.data)
    elif 'application/json' in content_type:
        # Verarbeitet als JSON
        return process_json(request.data)

    # Anfällig: Angreifer sendet PHP mit Content-Type: image/jpeg
# Anfällig: Apache-Konfiguration mit falschem Handler
# Handler-Mismatch kann Quellcode offenlegen

# Fehlende AddHandler-Direktive erlaubt falsche Verarbeitung
<Directory /var/www/cgi-bin>
    # Anfällig: Kein expliziter Handler - kann als statische Dateien serviert werden
    Options ExecCGI
</Directory>

# Anfällig: Erweiterungs-Kollision
AddHandler application/x-httpd-php .php
AddHandler text/html .phps  # Sollte für Quellcode-Ansicht sein, leicht verwechselbar

Korrigierter Code

// Korrigiert: Ordnungsgemäße Servlet-Sicherheitskonfiguration
// web.xml mit Handler-Einschränkungen
<web-app>
    <!-- Korrigiert: Direkten Servlet-Aufruf blockieren -->
    <security-constraint>
        <web-resource-collection>
            <web-resource-name>Servlets</web-resource-name>
            <url-pattern>/servlet/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <!-- Keine Rollen = kein Zugriff -->
        </auth-constraint>
    </security-constraint>

    <!-- Korrigiert: Nur explizite Handler-Zuordnung -->
    <servlet-mapping>
        <servlet-name>JspServlet</servlet-name>
        <url-pattern>*.jsp</url-pattern>
    </servlet-mapping>

    <!-- Korrigiert: Standard-Servlet für nicht zugeordnete Anfragen -->
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>
<?php
// Korrigiert: Inhalt entspricht deklariertem Typ validieren
function secure_process_upload($filename, $tmp_path) {
    $extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION));

    // Korrigiert: Tatsächlichen Inhaltstyp validieren
    $finfo = new finfo(FILEINFO_MIME_TYPE);
    $actual_mime = $finfo->file($tmp_path);

    // Korrigiert: Erlaubte Typen mit Inhaltsvalidierung definieren
    $allowed_types = [
        'jpg' => ['image/jpeg'],
        'gif' => ['image/gif'],
        'png' => ['image/png'],
        'txt' => ['text/plain'],
    ];

    if (!isset($allowed_types[$extension])) {
        throw new Exception("Nicht unterstützter Dateityp");
    }

    // Korrigiert: Inhalt entspricht Erweiterung verifizieren
    if (!in_array($actual_mime, $allowed_types[$extension])) {
        throw new Exception("Inhaltstyp-Mismatch: erwartet " .
            implode('/', $allowed_types[$extension]) . ", erhalten " . $actual_mime);
    }

    // Korrigiert: Sicheren Dateinamen generieren
    $safe_name = bin2hex(random_bytes(16)) . '.' . $extension;

    // Korrigiert: Außerhalb des Web-Roots speichern oder mit deaktivierter Ausführung
    move_uploaded_file($tmp_path, "/var/uploads/" . $safe_name);

    return $safe_name;
}
?>
# Korrigiert: Inhalt entspricht deklariertem Typ validieren
from flask import Flask, request
import magic

app = Flask(__name__)

ALLOWED_HANDLERS = {
    'image/jpeg': process_jpeg,
    'image/png': process_png,
    'image/gif': process_gif,
    'application/json': process_json,
    'text/plain': process_text,
}

@app.route('/process', methods=['POST'])
def secure_process():
    # Korrigiert: Magic Bytes verwenden um tatsächlichen Inhaltstyp zu erkennen
    actual_type = magic.from_buffer(request.data, mime=True)
    declared_type = request.content_type.split(';')[0].strip()

    # Korrigiert: Deklarierter Typ entspricht tatsächlichem Inhalt verifizieren
    if actual_type != declared_type:
        return {"error": f"Inhaltstyp-Mismatch: deklariert {declared_type}, tatsächlich {actual_type}"}, 400

    # Korrigiert: Nur bekannte Handler erlauben
    handler = ALLOWED_HANDLERS.get(actual_type)
    if handler is None:
        return {"error": f"Nicht unterstützter Inhaltstyp: {actual_type}"}, 415

    # Korrigiert: Validierten Handler verwenden
    return handler(request.data)

# Korrigiert: Content-Type-Header zu Antworten hinzufügen
@app.after_request
def add_security_headers(response):
    response.headers['X-Content-Type-Options'] = 'nosniff'
    return response
# Korrigiert: Explizite Handler-Konfiguration
<Directory /var/www/cgi-bin>
    # Korrigiert: Expliziten Handler erfordern
    Options -ExecCGI
    SetHandler none

    # Korrigiert: CGI nur für bestimmte Erweiterungen aktivieren
    <FilesMatch "\.cgi$">
        SetHandler cgi-script
        Options +ExecCGI
    </FilesMatch>
</Directory>

# Korrigiert: Strikte PHP-Behandlung
<FilesMatch "\.php$">
    SetHandler application/x-httpd-php
</FilesMatch>

# Korrigiert: Doppelte-Erweiterung-Angriffe verhindern
<FilesMatch "\.php\.">
    SetHandler none
    Require all denied
</FilesMatch>

# Korrigiert: Ausführung im Uploads-Verzeichnis deaktivieren
<Directory /var/www/uploads>
    SetHandler none
    php_flag engine off
    Options -ExecCGI
    <FilesMatch ".*">
        SetHandler default-handler
    </FilesMatch>
</Directory>

CVE-Beispiele

  • CVE-2001-0004 — Quellcode-Offenlegung durch manipulierte Dateierweiterung, die Parsing durch falsche DLL verursacht.
  • CVE-2002-0025 — Webbrowser-Fehlbehandlung von Content-Type-Headern, wodurch falsche Anwendung Inhalt verarbeitet.
  • CVE-2000-1052 — Quellcode-Offenlegung durch direkten Servlet-Aufruf.
  • CVE-2002-1742 — Beliebige Perl-Funktionen durch nicht-existente Funktions-Handler-Aktivierung geladen.

Referenzen

  1. MITRE Corporation. "CWE-430: Deployment of Wrong Handler." https://cwe.mitre.org/data/definitions/430.html
  2. CAPEC-11. "Cause Web Server Misclassification." https://capec.mitre.org/data/definitions/11.html