
Prova de conceito executável que reproduz a CVE-2026-79983, uma path traversal nos consumidores camel-ftp do Apache Camel, com fixtures de servidor FTP malicioso e builds afetados versus corrigidos.
Reprodutor de prova de conceito executável para a vulnerabilidade do Apache Camel em que os consumidores de arquivos remotos consultam um
diretório em um servidor remoto e constroem o caminho remoto absoluto de cada arquivo concatenando o diretório
configurado com o nome do arquivo informado na listagem de diretório do servidor, sem normalização lexical e sem
verificação de que o resultado permanece dentro do diretório consultado. Esse caminho então se torna o operando para recuperação (sempre),
e para exclusão ou renomeação quando delete=true, move, preMove, moveFailed ou readLock=rename estão configurados.
Um nome de listagem não é dado controlado pela rota — ele é fornecido pelo servidor remoto, e o canal de controle FTP
não possui proteção de integridade, portanto um atacante no caminho pode reescrever uma resposta LIST, e um servidor comprometido ou multi-inquilino
pode emitir tal nome diretamente. A opção documentada e ativada por padrão jailStartingDirectory não restringia
esse operando remoto.
| Runtime | Diretório | Stack |
|---|---|---|
| Camel Spring Boot | camel-spring-boot/ | Spring Boot 3.5.13 + camel-ftp 4.22.0 (afetado; corrigido em 4.22.1) |
| Camel Quarkus | camel-quarkus/ | Quarkus 3.29.0 + camel-quarkus-ftp 3.29.0 (Camel 4.15.0, afetado) |
A correção é distribuída no Camel 4.18.5 / 4.22.1 / 4.23.0; o módulo Spring Boot executa tanto a build afetada (4.22.0) quanto a build corrigida (4.22.1). Nenhum Camel Quarkus lançado ainda inclui um Camel corrigido.
A aplicação incorpora um servidor FTP malicioso deliberado (Apache MINA FtpServer com um VFS em memória) que lista, no
diretório consultado /upload:
normal.txt — um arquivo legítimo dentro do diretório, ed/../../outside.txt — uma entrada forjada cujo nome não é um único segmento de caminho. Ele não começa com um ponto
(portanto a regra de arquivo oculto do Camel não o captura), e /upload + d/../../outside.txt resolve para /outside.txt,
um nível acima do diretório consultado.Um consumidor FTP simples do Camel consulta /upload. Na build afetada, ele recupera ambas as entradas — incluindo
/outside.txt, um arquivo que nunca deveria alcançar. Na build corrigida, ele mantém normal.txt e ignora a entrada de escape,
registrando Skipping file as it resolves outside the starting directory: upload/d/../../outside.txt.
cd camel-spring-boot
mvn clean package
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack
docker compose down
Saída esperada na build afetada:
What the Camel consumer retrieved:
name=[normal.txt] (inside)
name=[d/../../outside.txt] <<< FILE FROM OUTSIDE THE POLLED DIRECTORY
content: OUTSIDE-SECRET (/outside.txt, a file the consumer should never reach)
Paths the server was asked to read:
upload/normal.txt -> /upload/normal.txt
upload/d/../../outside.txt -> /outside.txt
| Propriedade | Valor |
|---|---|
| Componente | camel-ftp (esquemas ftp, ftps, sftp) |
| CWE | CWE-22 (Limitação Imprópria de um Nome de Caminho a um Diretório Restrito) |
| Severidade | ALTA |
| Vetor de ataque | Uma entrada LIST (fornecida pelo servidor, reescrevível num canal de controlo FTP não autenticado) que não é um único segmento de caminho |
| Impacto | Leitura — e, com delete/move/readLock=rename, eliminação ou renomeação — de ficheiros fora do diretório consultado, usando as credenciais do endpoint |
| Versões Afetadas | Desde 4.0.0 antes de 4.18.5, desde 4.19.0 antes de 4.22.1 |
| Versões Corrigidas | 4.18.5, 4.22.1, 4.23.0 |
| JIRA | CAMEL-24487 |
| Crédito | Dilrevx da NSSL, SJTU |
Advisory: https://camel.apache.org/security/CVE-2026-79983.html
Uma sobrecarga de GenericFileHelper.isWithinDirectory sensível ao separador e uma estratégia
GenericFileConsumer.isWithinStartingDirectory (consultada a partir de isValidFile quando jailStartingDirectory
está ativado) compactam o caminho resolvido e verificam, nos limites dos segmentos do caminho, que este ainda
resolve dentro do diretório consultado. Um ficheiro que resolva fora é ignorado com um aviso (para que outras
entradas legítimas na mesma listagem continuem a ser processadas). RemoteFileConsumer e SmbConsumer substituem
a verificação; a implementação base local é uma no-op, uma vez que os nomes das listagens locais são sempre
segmentos únicos.
Prefira sftp/ftps em vez de ftp para que a listagem não possa ser reescrita em trânsito, e verifique a chave
do host/certificado. Restrinja o consumidor com filter, antInclude ou include para aceitar apenas nomes de
segmento único, e evite delete=true/move/preMove/moveFailed/readLock=rename contra servidores cujas
listagens não sejam totalmente fidedignas. Sempre que possível, confine a conta do servidor ao diretório consultado.
Este repositório é publicado para fins educativos e defensivos: para ajudar os utilizadores do Apache Camel a compreender a vulnerabilidade, verificar se são afetados e confirmar que a atualização a resolve. O servidor malicioso e o "segredo" são fixtures locais inertes. Não utilize este material contra sistemas que não possui ou opera.