flawopen.com/Teardowns/cve-2026-105699-langflow-mcp-cross-project-file-disclosure
CVE-2026-105699: MCP-Dateizugriff in Langflow
Langflow authentifizierte die MCP-Verbindung, autorisierte aber nicht jede angeforderte Datei. Ein Benutzer konnte Flow-Dateien anderer Nutzer lesen; Version 1.9.1 behebt die Eigentümerprüfung.[1], [2], [5]
CVSS-Vektor
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:NStell dir ein Hotel vor, das deinen Schlüssel prüft und dir dann das Gepäck aus jedem Zimmer gibt, sobald du dessen Anhänger nennst. Der Schlüssel beweist, dass du ins Hotel darfst, nicht dass der Koffer eines anderen Gasts dir gehört. Langflows MCP-Lesezugriff muss Besitzer und Projekt prüfen, bevor die Datei geöffnet wird.[1]
Kernkonzepte & Begriffe
Model Context Protocol (MCP)- Protokoll, über das eine KI-Anwendung Werkzeuge und Ressourcen von einem Server anfordert. Der Server muss jedes angeforderte Objekt weiterhin autorisieren.[1]
Projektgebundener MCP-Endpunkt- Eine Langflow-MCP-Verbindung, die einem Projekt zugeordnet ist. Der Zugriff auf diesen Endpunkt erlaubt keinen Zugriff auf Dateien aller Projekte.[1]
resources/read- MCP-Operation, mit der der Server eine durch eine URI bezeichnete Ressource zurückgeben soll.[1]
Framework-Zuordnungen
- CWE-Referenz für die in diesem Leitfaden beschriebene Schwachstelle: CWE-639
Ursachenanalyse
In den betroffenen Langflow-Versionen 1.6.8 bis 1.9.0 authentifizierte der projektgebundene MCP-Transport den Zugriff auf die Projekt-ID in der Verbindungs-URL. Anschließend nahm der resources/read-Handler eine Ressourcen-URI entgegen, extrahierte Flow-ID und Dateinamen und übergab sie an storage_service.get_file(), ohne zu prüfen, ob der Flow dem angemeldeten Benutzer oder dem aktuellen Projekt gehörte. Der Speicher liest anhand von Namespace und Dateiname; Langflows Benutzer- und Projektberechtigungen kennt er nicht. Deshalb konnte ein angemeldeter Benutzer mit Zugriff auf den MCP-Endpunkt seines eigenen Projekts eine Datei im Flow-Namespace eines anderen Benutzers anfordern. Das separat dokumentierte globale Verhalten von resources/list und tools/list konnte Kennungen offenlegen und das Auffinden erleichtern, war für den Lesezugriff aber nicht erforderlich. Es handelt sich um eine authentifizierte Vertraulichkeitsverletzung zwischen Benutzern, nicht um anonymen Zugriff oder Codeausführung. Der CVE-Datensatz weist CVSS 4.0 mit 7,1 High und CWE-639 aus. Langflow 1.9.1 behebt den Pfad: handle_read_resource() ermittelt den angemeldeten Benutzer und sucht den Flow mit Flow.user_id == current_user.id sowie bei projektgebundenem Transport zusätzlich Flow.folder_id == project_id; nicht autorisierte Namespaces werden vor dem Speicherzugriff abgewiesen. Der Patch weist außerdem Trennzeichen und Traversal-Sequenzen zurück, prüft Pfadbegrenzungen bei Lesen/Schreiben/Löschen und beschränkt globale Listen auf den aktuellen Benutzer. Der Regressionstest des Maintainers verweigert das Lesen eines fremden Flows.[1], [2], [3], [5]
Schritt-für-Schritt Angriffsablauf
Ein Benutzer meldet sich an seinem eigenen Projekt-MCP-Endpunkt an
Der Angreifer benötigt ein Langflow-Konto und Zugriff auf mindestens eine projektgebundene MCP-Verbindung. Die Schwachstelle umgeht keine Anmeldung.[1]
Der Client fordert eine Ressourcen-URI an
Die MCP-Anfrage resources/read enthält eine URI, deren letzte Pfadbestandteile einen Flow-Namespace und eine Datei bezeichnen.[1]
Der Speicher liest anhand des Namespace
storage_service.get_file() gab die Datei des angegebenen Namespace zurück. Dem Speicher fehlte der Kontext zum Benutzerbesitz.[1]
Quellcode: Verwundbar vs. Sicher
Dies sind gezielte Python-Auszüge des dokumentierten Pfads, keine eigenständige Anwendung. Der anfällige Pfad behandelte den vom Client gelieferten Namespace als ausreichende Berechtigung. Die Korrektur in 1.9.1 löst zuerst den Flow im Bereich des angemeldeten Benutzers und bei projektgebundenem MCP-Transport zusätzlich im aktuellen Projekt auf; erst dann darf der Speicher lesen. Der Patch validiert auch Dateinamen und erzwingt Pfadbegrenzungen in der Speicherschicht, damit andere Lese-, Schreib- oder Löschpfade die Prüfung nicht umgehen. Die Autorisierung gehört in den Dienst, der Benutzer und Projekt kennt; ein Speicheradapter kann den Besitz nicht ableiten. Umfang des Ausschnitts: Der echte Handler erlaubt eine Datei aus dem Benutzerbereich außerdem nur dann, wenn der Namespace der ID des angemeldeten Benutzers entspricht und der Server nicht auf ein Projekt beschränkt ist. Dieser separate Zweig fehlt im Ausschnitt; daraus darf kein Zugriff auf beliebige Namespaces abgeleitet werden. Die Upstream-Regressionstestsuite enthält test_handle_read_resource_denies_other_users_flow und prüft damit die Ablehnung des benutzerübergreifenden Lesezugriffs.[1], [3], [4], [7]
Quelltextauszug: mcp_utils.py — gezielte Quellcodeauszüge
# Auszug aus dem betroffenen Leseweg: Geparste IDs wurden direkt an den Speicher übergeben.
content = await storage_service.get_file(
flow_id=flow_id,
file_name=filename,
)
# Quellnahe Reduktion der Autorisierungsgrenze aus Version 1.9.1.
current_user = current_user_ctx.get()
query = select(Flow).where(
Flow.id == namespace_id,
Flow.user_id == current_user.id,
)
if project_id is not None:
query = query.where(Flow.folder_id == project_id)
flow = (await session.exec(query)).first()
if flow is None:
raise ValueError("Resource not found or access denied")
content = await storage_service.get_file(
flow_id=namespace_id,
file_name=filename,
)
Checkliste für Engineering & Systemsicherheit
- ✓Aktualisiere Langflow auf 1.9.1 oder höher und prüfe das tatsächlich bereitgestellte Paket und Container-Image, nicht nur den Quellcode.[5]
- ✓Autorisiere jede
resources/read-URI anhand des angemeldeten Benutzers und des Projekts der MCP-Verbindung, bevor der Speicher aufgerufen wird.[1], [3] - ✓Löse die Kennung in ein Datenbankobjekt auf und verlange Benutzerbesitz sowie bei projektgebundenen Endpunkten die Projektzugehörigkeit.[1], [3]
- ✓Verwende möglichst undurchsichtige, serverseitig erzeugte Ressourcen-IDs statt beliebige Speicherpfade oder Download-URIs vom Client anzunehmen.[1], [3]
- ✓Prüfe Dateinamen nach dem Dekodieren, weise Trennzeichen und Traversal-Bestandteile zurück und erzwinge kanonische Pfadbegrenzung für jedes Lesen, Schreiben und Löschen.[1], [3]
- ✓Beschränke
resources/list- undtools/list-Abfragen auf den angemeldeten Benutzer; die Kennungsauflistung ist eine eigene Offenlegung, die Autorisierungsfehler verstärken kann.[7] - ✓Füge einen Regressionstest mit zwei Benutzern hinzu: Der Projekt-MCP-Endpunkt des einen muss Flow-Dateien des anderen und Flows anderer Projekte ablehnen.[1]
- ✓Prüfe Zugriffsprotokolle betroffener Installationen und bewerte eine mögliche Offenlegung; der Hinweis belegt die Schwachstelle, aber keine Ausnutzung in freier Wildbahn.[7], [3]
- ✓Behalten Sie den Upstream-Regressionstest
test_handle_read_resource_denies_other_users_flowbei und ergänzen Sie einen Projektbereichstest, der den Zugriff auf einen eigenen Flow außerhalb des aktuellen Projekts ablehnt.[7], [3]
Quellen
- Langflow maintainer advisory GHSA-4hmc-cfm3-w43c
- CVE Program record CVE-2026-105699
- Upstream fix commit b8fe970
- Upstream pull request #12818 and regression coverage
- Langflow 1.9.1 release
- MITRE CWE-639 — Authorization Bypass Through User-Controlled Key
- Langflow regression tests — MCP resource authorization