FlawOpen

flawopen.com/AI Security/berriai-litellm-ghsa-7hp6-salt-key-session-token-privilege-escalation

● FlawOpen-Zuordnung: CWE-345 · CVSS 9.9 · Kritisch
Sicherheitsforschung · FlawOpen

LiteLLM: Rechteausweitung durch Salt-Key-Wiederverwendung (GHSA-7hp6)

LiteLLM verwendete denselben Verschlüsselungspfad für gespeicherte Geheimnisse und UI-/CLI-Sitzungstoken. Ein angemeldeter internal_user konnte kontrollierte Identitätsdaten durch diesen Pfad einschleusen und proxy_admin erreichen; diese Rolle konnte MCP-stdio-Befehlsausführung aufrufen. Der Patch bindet Sitzungstoken an ein eigenes Präfix und authentifizierten AES-GCM-Kontext. Ein CVE oder bestätigte Ausnutzung in freier Wildbahn ist nicht bekannt.[1], [2]

💡 Einfache Erklärung (ELI5)

Ein Gebäude nutzt dasselbe Siegel für einen Lagerumschlag und einen Administrationsausweis. Ein Besucher kann den Inhalt des Umschlags beeinflussen; später hält ein Wachmann ihn für einen echten Ausweis. LiteLLM versieht Sitzungsausweise nun mit einem eigenen Kennzeichen und bindet es kryptografisch an das Siegel.[1], [2]

Kernkonzepte & Begriffe

Salt Key
In LiteLLM konfiguriertes Schlüsselmaterial für Verschlüsselungshelfer. Die Schwachstelle verwendete denselben Pfad, ohne den Chiffretext an seinen Zweck zu binden.[1], [2]
Authentifizierte Zusatzdaten (AAD)
Daten wie ein Tokenpräfix, die AES-GCM zusammen mit dem Chiffretext authentifiziert. Änderung oder Weglassen führt zum Fehlschlag der Authentifizierung.[2]
internal_user und proxy_admin
LiteLLM-Rollen. Laut Advisory konnte ein angemeldeter internal_user zu proxy_admin, der Administrationsrolle, aufsteigen.[1]
MCP stdio
Ein Model-Context-Protocol-Transport, der einen lokalen Prozess startet und über Standardein- und -ausgabe kommuniziert. Laut Advisory konnte proxy_admin darüber Befehlsausführung erreichen.[1]
CWE-345
Unzureichende Prüfung der Datenherkunft. Dies ist FlawOpens primäre redaktionelle Zuordnung; das Advisory nennt außerdem CWE-269 und CWE-441.[1], [5], [6], [7]

Framework-Zuordnungen

  • Konzeptionelle Zuordnung von FlawOpen zu MITRE CWE; weder ein Anbieter noch ein CVE-Datensatz hat diese Schwachstellen-ID dieser Forschungsdemonstration zugewiesen. CWE-345

Schritt-für-Schritt Angriffsablauf

Schritt 1

Ein Konto mit wenigen Rechten erreicht die Schlüsselverwaltung

Ausgangspunkt laut Advisory ist ein angemeldeter internal_user. Anonymer Zugriff ist nicht nötig, aber diese Rolle muss bereits bestehen.[1]

Schritt 2

Metadaten-Chiffretext entsteht über den gemeinsamen Pfad

Laut Advisory konnten kontrollierte Identitätsdaten in Schlüsselmetadaten verschlüsselt und zurückgegeben werden. Der Fehler war, diesen Chiffretext später als anderen Tokentyp zu akzeptieren.[1], [2]

Schritt 3

Die Sitzungsprüfung akzeptiert Chiffretext mit anderem Zweck

Vor dem Fix teilten Wertverschlüsselung und Sitzungsprüfung Helfer und Schlüsselpfad, ohne den Tokenzweck authentisch zu binden. Die Identität konnte als proxy_admin interpretiert werden.[1], [2]

Schritt 4

Administrativer Zugriff erreicht MCP stdio

Mit proxy_admin konnte der Akteur laut Advisory Befehle über den MCP-stdio-Endpunkt ausführen. Das ist Prozessfähigkeit auf dem Host, keine vom Modell ausgeführte Anweisung.[1]

Schritt 5

Zweckbindung weist die Wiederverwendung zurück

Der Fix verwendet litellm_login_ als AES-GCM-AAD und einen eigenen Decoder. Auf eine behobene Version aktualisieren; das Abschalten von EXPERIMENTAL_UI_LOGIN ist nur eine befristete Abhilfe.[1], [2], [3], [4]

Ursachenanalyse

Das BerriAI-Advisory GHSA-7hp6-4w63-5g45 beschreibt eine Verwechslung von Authentifizierungszwecken. LiteLLM nutzte denselben Wer­te-Verschlüsselungshelfer für gespeicherte Geheimnisse und UI-/CLI-Sitzungstoken; auch die Sitzungsprüfung entschlüsselte über denselben Schlüsselpfad. Ein angemeldeter internal_user konnte einen API-Schlüssel mit kontrollierten serialisierten Identitätsdaten in der Metadaten anfordern. Die Verwaltungsroute verschlüsselte und lieferte diesen Wert zurück. Als Bearer-Token vorgelegt, konnte der Chiffretext vom Sitzungspfad entschlüsselt und als gefälschte proxy_admin-Identität interpretiert werden; damit war Befehlsausführung über MCP stdio erreichbar. Der Upstream-Fix f7cd90f ändert Ausgabe und Prüfung: litellm_login_-Präfix, AES-GCM-AAD für dieses Präfix und eigener Decoder. Der Salt Key bleibt Schlüsselmaterial; getrennt wird der kryptografisch authentifizierte Tokenzweck samt Decoder. Chiffretext für gespeicherte Werte gilt damit nicht als Sitzungstoken. Das Advisory nennt CVSS 3.1 9.9 Critical; Versionen nach 1.91.0 sind standardmäßig betroffen, 1.87.0–1.90.x nur bei EXPERIMENTAL_UI_LOGIN=true. Genannte Fixes sind 1.100.4, 1.101.3, 1.102.2, 1.103.1 und 1.104.0rc2 in den jeweiligen Branches. EXPERIMENTAL_UI_LOGIN=false ist eine temporäre Abhilfe, deaktiviert aber auch CLI SSO und Claude-Code-Gateway-Login. Es ist kein CVE bekannt und keine Ausnutzung in freier Wildbahn bestätigt. Der Codevergleich zeigt den Upstream-Wechsel der Authentifizierungsdomäne, keinen Exploit und keine vollständige Authentifizierung.[1], [2], [3], [4]

Quellcode: Verwundbar vs. Sicher

Der Upstream-Patch ersetzt die allgemeinen Wert-Helfer beim Erstellen und Prüfen von Sitzungstoken. encrypt_bearer_token authentifiziert das Präfix als AES-GCM-AAD; decrypt_bearer_token verlangt dasselbe Präfix und dieselben Zusatzdaten. Chiffretext für gespeicherte Werte kann so nicht als Login-Token dienen. Dies ist ein gekürzter Ausschnitt des Commits, keine eigenständige Authentifizierung. Ein gemeinsam verwendeter Salt-Schlüssel belegt allein keinen eigenen Schlüssel je Verwendungszweck; die hier nachgewiesene Trennung entsteht durch den authentifizierten Tokentyp und den passenden Decoder.[2], [3]

Quelltextauszug: litellm/proxy/auth/auth_checks.py und litellm/proxy/common_utils/encrypt_decrypt_utils.py — gekürzte Ausschnitte aus dem Upstream-Commit f7cd90f

VERWUNDBARE IMPLEMENTIERUNG
# Vor dem Patch wurde Chiffretext gespeicherter Werte auch als Sitzungstoken ausgegeben.
return encrypt_value_helper(valid_token.model_dump_json(exclude_none=True))

# Die Sitzungsauthentifizierung entschlüsselte ihn mit dem allgemeinen Werte-Helper.
decrypted_token = decrypt_value_helper(hashed_token, key="ui_hash_key")
GEHÄRTETER SICHERHEITS-PATCH
# Nach dem Patch haben Sitzungstoken einen eigenen Typ und eigene AAD.
LITELLM_SESSION_TOKEN_PREFIX = "litellm_login_"
return encrypt_bearer_token(
    valid_token.model_dump_json(exclude_none=True),
    prefix=LITELLM_SESSION_TOKEN_PREFIX,
)

# Die Authentifizierung verwendet den passenden zweckgebundenen Decoder.
decrypted_token = decrypt_bearer_token(
    hashed_token, prefix=LITELLM_SESSION_TOKEN_PREFIX
)

Checkliste für Engineering & Systemsicherheit

Quellen

← AI Security Directory →