
Reprodutor de prova de conceito executável para CVE-2026-78163 no Apache Camel camel-docling, demonstrando SSRF e divulgação de arquivos locais por meio de entrada de corpo String não validada, com controle de build corrigido.
Reprodutor de prova de conceito executável para a vulnerabilidade do Apache Camel em que o DoclingProducer decidia o que significava um corpo de mensagem String inspecionando o seu prefixo:
http:// ou https:// era entregue ao Docling como um URL remoto a obter (SSRF), e/ (ou contendo uma barra invertida) era lido do sistema de ficheiros local (divulgação de ficheiros).O modo era escolhido implicitamente, sem qualquer opção de endpoint para fixar uma única interpretação e — ao contrário do namespace de cabeçalhos do Camel — o corpo da mensagem nunca é filtrado por um HeaderFilterStrategy. Assim, uma rota que significa "converter o texto que chegar no corpo" tornava-se silenciosamente num obtentor de recursos remotos ou num leitor de ficheiros locais sempre que o texto controlado pelo atacante começasse por um desses prefixos.
| Runtime | Diretório | Stack | Demonstra |
|---|---|---|---|
| Camel Spring Boot | camel-spring-boot/ | Spring Boot 3.5.13 + camel-docling 4.22.0 (afetado; corrigido em 4.22.1) | SSRF e divulgação de ficheiros, mais o controlo com a build corrigida |
| Camel Quarkus | camel-quarkus/ | Quarkus 3.29.0 + camel-quarkus-docling 3.29.0 (Camel 4.15.0, afetado) | apenas divulgação de ficheiros (ver nota) |
Cobertura de versões. O sink de divulgação de ficheiros locais existe desde que o camel-docling foi introduzido na 4.15.0; o sink de URL remoto foi adicionado na 4.16.0 com o suporte a docling-serve. O Camel Quarkus mais recente (3.29.0) inclui o Camel 4.15.0, pelo que o seu módulo demonstra apenas a divulgação de ficheiros. 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) como a build corrigida (4.22.1), pelo que também demonstra o comportamento corrigido. Nenhuma versão lançada do Camel Quarkus inclui ainda um Camel corrigido.
Nenhum dos reprodutores precisa de uma instalação real do Docling: um pequeno CLI docling falso (fake-docling/docling) substitui
o binário e torna visível o que o real faria com a entrada fornecida pelo producer — obter um URL ou ler um
ficheiro. É benigno: apenas ecoa o que lhe foi dito para processar e registra a sua própria invocação. O ponto da CVE é
que um corpo fornecido pelo atacante chega a esse argumento, sem qualquer opt-in.
A aplicação Spring Boot também executa um endpoint HTTP apenas interno em 127.0.0.1:9099 (apenas a porta 8080 é publicada,
pelo que um cliente externo não consegue alcançar a 9099 diretamente) e um ficheiro secreto local. O atacante envia apenas texto:
http://127.0.0.1:9099/internal-secret → a invocação do docling do lado do servidor obtém o
endpoint interno e o seu segredo é devolvido ao chamador./tmp/cve-2026-78163-secret.txt → o ficheiro local é lido e devolvido.Na build afetada ambos têm sucesso; na build corrigida ambos são rejeitados com uma IllegalArgumentException
que nomeia a opção (allowUrlSource / allowFilePathSource) que seria necessária para os ativar, e o docling
nunca é invocado.
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 do Spring Boot afetada:
[1] SSRF — sending body = http://127.0.0.1:9099/internal-secret
>>> PROVEN SSRF: the server-side docling invocation fetched the attacker-controlled internal URL.
>>> internal victim saw: [GET /internal-secret]
>>> content returned to the caller:
| INTERNAL-SECRET-DATA (only reachable from inside the deployment)
[2] File disclosure — sending body = /tmp/cve-2026-78163-secret.txt
>>> PROVEN file disclosure: the attacker-named local file was read and returned.
| TOP-SECRET-FILE-CONTENT (local file an attacker should not be able to read)
| Propriedade | Valor |
|---|---|
| Componente | camel-docling (camel-docling-starter / camel-quarkus-docling) |
| CWE | CWE-918 (SSRF), CWE-22 (Path Traversal), CWE-200 (Exposição de Informações) |
| Severidade | MÉDIA |
| Vetor de ataque | Um corpo de mensagem String encaminhado para um endpoint docling, cujo prefixo seleciona um sink de busca de URL ou leitura de arquivo; o corpo não está sujeito ao HeaderFilterStrategy |
| Impacto | Busca no lado do servidor de URLs escolhidas pelo atacante (serviços internos) e divulgação de arquivos locais |
| Versões Afetadas | De 4.15.0 antes de 4.18.5, de 4.19.0 antes de 4.22.1 (divulgação de arquivos desde 4.15.0; sink de URL desde 4.16.0) |
| Versões Corrigidas | 4.18.5, 4.22.1, 4.23.0 |
| JIRA | CAMEL-24422 |
| Crédito | Li Zhiyao (BUPT) |
Aviso: https://camel.apache.org/security/CVE-2026-78163.html
Um corpo String agora é tratado como o próprio documento por padrão. As duas leituras de localização tornaram-se opcionais através
das novas opções de endpoint allowUrlSource e allowFilePathSource (ambas com padrão false); um corpo que se pareça com uma URL
ou caminho é, caso contrário, rejeitado com uma IllegalArgumentException nomeando a opção que o habilitaria. Uma opção adicional
inputBaseDirectory restringe os caminhos de entrada locais a um diretório configurado. Corpos tipados (File, byte[],
InputStream) e o cabeçalho CamelDoclingInputFilePath já declaram seu significado e não são restringidos (mas permanecem
sujeitos ao inputBaseDirectory).
Não encaminhe corpos de mensagens de origem externa para um endpoint docling; passe o documento através de um corpo tipado
(File, byte[], InputStream) ou do cabeçalho CamelDoclingInputFilePath para que o corpo nunca esteja sujeito à interpretação
de prefixo.
Este repositório é publicado para fins educacionais e defensivos: para ajudar os usuários do Apache Camel a entender a
vulnerabilidade, verificar se são afetados e confirmar que a atualização a resolve. A CLI docling falsa e
os "segredos" são fixtures locais inertes. Não use este material contra sistemas que você não possui ou opera.