
Reproducer for CVE-2026-40047: Apache Camel camel-docling CLI argument injection / path traversal
Este projeto demonstra uma vulnerabilidade de injeção de argumentos CLI e path traversal no componente camel-docling do Apache Camel, rastreada como CVE-2026-40047. O DoclingProducer constrói a invocação da ferramenta de linha de comando externa docling a partir de cabeçalhos da mensagem; argumentos personalizados fornecidos através do cabeçalho CamelDoclingCustomArguments eram anexados com validação insuficiente (uma denylist mais uma verificação literal ../), de modo que um atacante que influencia esses cabeçalhos pode injetar flags arbitrárias do docling e valores de caminho com travessia no subprocesso.
Comunicado: https://camel.apache.org/security/CVE-2026-40047.html
O DoclingProducer monta a invocação do docling e a executa via java.lang.ProcessBuilder (formato lista — sem shell). Argumentos CLI personalizados do cabeçalho CamelDoclingCustomArguments são anexados ao comando:
// DoclingProducer.addCustomArguments(...) - versão afetada
List<String> customArgs = exchange.getIn().getHeader(DoclingHeaders.CUSTOM_ARGUMENTS, List.class);
if (customArgs != null && !customArgs.isEmpty()) {
validateCustomArguments(customArgs); // denylist + verificação literal "../" (fraca)
command.addAll(customArgs);
}
Nas versões afetadas, validateCustomArguments dependia de uma denylist de flags proibidas e apenas rejeitava valores de caminho contendo um ../ literal. Como resultado:
docling.../ literal (caminhos absolutos ou sequências normalizadas) não são capturados.Como o Camel constrói a invocação do docling, o componente é responsável por restringir esses valores. A correção (CAMEL-23212) substitui a denylist por uma allowlist estrita de flags reconhecidas, rejeita flags gerenciadas pelo produtor (--output/-o) e metacaracteres de shell (defesa em profundidade), e normaliza valores do tipo caminho com Path.normalize() antes de validar.
A invocação usa a forma de lista do
ProcessBuilder, portanto um shell não interpreta os valores — a injeção de comando do SO via metacaracteres de shell não é possível; a rejeição de metacaracteres na correção é defesa em profundidade.
from("direct:convert")
.to("docling:convert?operation=CONVERT_TO_MARKDOWN&contentInBody=true");
docling é uma ferramenta externa. Este reprodutor inclui um docling stub (no PATH dentro do contêiner) que registra os argv que recebe e escreve um arquivo markdown, de modo que os argumentos injetados ficam visíveis na resposta HTTP e em /tmp/docling-invocations.log. Tudo é executado dentro de uma imagem Docker (aplicativo + stub) — portanto, não é necessário instalar um docling real.
docling)mvn clean package -DskipTests
docker compose up -d --build
curl http://localhost:8080/exploit/normal
# stub docling recebe: docling --to md --ocr-lang en --output <tmp> /tmp/input.txt
curl "http://localhost:8080/exploit/attack"
# injeta CamelDoclingCustomArguments = [--injected-by-attacker, arbitrary-value]
# -> stub docling recebe:
# docling --injected-by-attacker arbitrary-value --to md --ocr-lang en --output <tmp> /tmp/input.txt
# um valor de caminho sem "../" literal (caminho absoluto) também passa:
curl "http://localhost:8080/exploit/attack?flag=--artifacts-path&value=/etc/attacker-controlled"
Em uma versão afetada (este reprodutor fixa a versão 4.18.2) a rota é bem-sucedida e os argumentos injetados alcançam o subprocesso. Em uma versão corrigida (4.18.3 / 4.19.0) a allowlist rejeita --injected-by-attacker com uma IllegalArgumentException e a rota falha.
docker compose down
CamelDoclingCustomArguments (ou os cabeçalhos de caminho) de um produtor docling:.Atualize para 4.18.3 / 4.19.0. A correção usa uma allowlist estrita de flags reconhecidas do docling, rejeita flags gerenciadas pelo produtor e metacaracteres de shell, e normaliza valores de caminho com Path.normalize() antes de validá-los.
Até atualizar:
CamelDoclingCustomArguments ou os cabeçalhos de caminho.removeHeaders("Camel*")) de mensagens vindas de produtores não confiáveis antes do produtor docling:.CVE-2026-40047/
├── pom.xml
├── Dockerfile # aplicativo + stub 'docling' no PATH
├── docker-compose.yml
├── docling-stub.sh # stub 'docling' (registra argv, escreve markdown)
├── README.md
└── src/main/
├── java/com/example/
│ ├── Application.java
│ ├── DoclingRoute.java # from(direct:convert).to(docling:convert)
│ └── ExploitController.java # injeta CamelDoclingCustomArguments
└── resources/
└── application.properties
Este reprodutor é fornecido apenas para pesquisa de segurança e testes autorizados, para uma vulnerabilidade divulgada publicamente e corrigida. Não o utilize contra sistemas sem permissão explícita.
| Propriedade | Valor |
|---|
| Componente | camel-docling |
| Classe Afetada | org.apache.camel.component.docling.DoclingProducer (addCustomArguments / validateCustomArguments) |
| Causa raiz | CamelDoclingCustomArguments (uma List<String>) anexado aos argumentos da CLI do docling com uma denylist fraca + verificação literal ../ |
| CWE | CWE-88 (Injeção de Argumento) / CWE-22 (Path Traversal) |
| Impacto | Injeção de flags docling arbitrárias/não intencionais e valores de caminho fora do diretório na ferramenta externa. NÃO é injeção de comando do SO (ProcessBuilder baseado em lista, sem shell). |
| Versões Afetadas | De 4.15.0 antes de 4.18.3 |
| Versões Corrigidas | 4.18.3, 4.19.0 |
| JIRA | CAMEL-23212 |
| Relator | Andrea Cosentino (Apache Software Foundation) |