
Reproducer per CVE-2026-40047: iniezione di argomenti CLI / attraversamento di percorso in Apache Camel camel-docling
Questo progetto dimostra una vulnerabilità di iniezione di argomenti CLI e path traversal nel componente camel-docling di Apache Camel, tracciata come CVE-2026-40047. DoclingProducer costruisce l'invocazione dello strumento a riga di comando esterno docling a partire dagli header del messaggio; gli argomenti personalizzati forniti tramite l'header CamelDoclingCustomArguments venivano aggiunti con una validazione insufficiente (una denylist più un controllo letterale di ../), quindi un attaccante che può influenzare questi header può iniettare flag CLI arbitrari di docling e valori di percorso con traversal nel sottoprocesso.
Avviso: https://camel.apache.org/security/CVE-2026-40047.html
DoclingProducer assembla l'invocazione di docling e la esegue tramite java.lang.ProcessBuilder (forma a lista — nessuna shell). Gli argomenti CLI personalizzati provenienti dall'header CamelDoclingCustomArguments vengono aggiunti al comando:
// DoclingProducer.addCustomArguments(...) - affected version
List<String> customArgs = exchange.getIn().getHeader(DoclingHeaders.CUSTOM_ARGUMENTS, List.class);
if (customArgs != null && !customArgs.isEmpty()) {
validateCustomArguments(customArgs); // denylist + literal "../" check (weak)
command.addAll(customArgs);
}
Nelle versioni interessate validateCustomArguments si basava su una denylist di flag non consentiti e rifiutava solo i valori di percorso contenenti un ../ letterale. Di conseguenza:
docling.../ letterale (percorsi assoluti o sequenze normalizzate) non vengono rilevati.Poiché Camel costruisce l'invocazione di docling, il componente è responsabile di vincolare questi valori. La correzione (CAMEL-23212) sostituisce la denylist con una rigorosa allowlist di flag riconosciuti, rifiuta i flag gestiti dal producer (--output/-o) e i metacaratteri della shell (difesa in profondità) e normalizza i valori simili a percorsi con Path.normalize() prima della validazione.
L'invocazione usa la forma a lista di
ProcessBuilder, quindi una shell non interpreta i valori — l'iniezione di comandi del sistema operativo tramite metacaratteri della shell non è possibile; il rifiuto dei metacaratteri nella correzione è una misura di difesa in profondità.
from("direct:convert")
.to("docling:convert?operation=CONVERT_TO_MARKDOWN&contentInBody=true");
docling è uno strumento esterno. Questo reproducer include uno stub di docling (nel PATH all'interno del container) che registra l'argv ricevuto e riscrive un file markdown, così gli argomenti iniettati sono visibili nella risposta HTTP e in /tmp/docling-invocations.log. Tutto viene eseguito all'interno di un'immagine Docker (app + stub), quindi non è necessaria un'installazione reale di docling.
docling)mvn clean package -DskipTests
docker compose up -d --build
curl http://localhost:8080/exploit/normal
# stub docling receives: docling --to md --ocr-lang en --output <tmp> /tmp/input.txt
curl "http://localhost:8080/exploit/attack"
# injects CamelDoclingCustomArguments = [--injected-by-attacker, arbitrary-value]
# -> stub docling receives:
# docling --injected-by-attacker arbitrary-value --to md --ocr-lang en --output <tmp> /tmp/input.txt
# a path value with no literal "../" (absolute path) also passes:
curl "http://localhost:8080/exploit/attack?flag=--artifacts-path&value=/etc/attacker-controlled"
Su una versione interessata (questo reproducer fissa la 4.18.2) la route riesce e gli argomenti iniettati raggiungono il sottoprocesso. Su una versione corretta (4.18.3 / 4.19.0) l'allowlist rifiuta --injected-by-attacker con un'IllegalArgumentException e la route fallisce.
docker compose down
CamelDoclingCustomArguments (o negli header che contengono percorsi) di un producer docling:.Aggiornare a 4.18.3 / 4.19.0. La correzione usa una rigorosa allowlist dei flag docling riconosciuti, rifiuta i flag gestiti dal producer e i metacaratteri della shell e normalizza i valori dei percorsi con Path.normalize() prima di validarli.
In attesa dell'aggiornamento:
CamelDoclingCustomArguments o negli header che contengono percorsi.removeHeaders("Camel*")) dai messaggi provenienti da producer non attendibili prima del producer docling:.CVE-2026-40047/
├── pom.xml
├── Dockerfile # app + stub 'docling' on PATH
├── docker-compose.yml
├── docling-stub.sh # stub 'docling' (logs argv, writes markdown)
├── README.md
└── src/main/
├── java/com/example/
│ ├── Application.java
│ ├── DoclingRoute.java # from(direct:convert).to(docling:convert)
│ └── ExploitController.java # injects CamelDoclingCustomArguments
└── resources/
└── application.properties
Questo reproducer è fornito solo per ricerca sulla sicurezza e test autorizzati, per una vulnerabilità divulgata pubblicamente e corretta. Non utilizzarlo contro sistemi senza autorizzazione esplicita.
| Proprietà | Valore |
|---|
| Componente | camel-docling |
| Classe interessata | org.apache.camel.component.docling.DoclingProducer (addCustomArguments / validateCustomArguments) |
| Causa principale | CamelDoclingCustomArguments (un List<String>) aggiunto agli argomenti CLI di docling con una denylist debole + controllo letterale di ../ |
| CWE | CWE-88 (Iniezione di argomenti) / CWE-22 (Path Traversal) |
| Impatto | Iniezione di flag CLI di docling arbitrari o non previsti e valori di percorso al di fuori della directory nello strumento esterno. NON è iniezione di comandi del sistema operativo (ProcessBuilder basato su lista, nessuna shell). |
| Versioni interessate | Dalla 4.15.0 a prima della 4.18.3 |
| Versioni corrette | 4.18.3, 4.19.0 |
| JIRA | CAMEL-23212 |
| Segnalato da | Andrea Cosentino (Apache Software Foundation) |