
Reproductor de prueba de concepto ejecutable para CVE-2026-95628, una brecha de validación de rutas absolutas en Apache Camel camel-docling, con arneses de Spring Boot y Quarkus y verificación de la corrección.
validatePathSafety no rechazaba rutas absolutas (corrección incompleta de CVE-2026-40047)Reproductor de prueba de concepto ejecutable para la vulnerabilidad de Apache Camel en la que la comprobación de rutas de argumentos personalizados que introdujo la corrección de CVE-2026-40047 buscaba solo recorrido relativo. Rechazaba un valor que contenía ../ y un valor cuya forma normalizada aún conservaba un elemento .., pero nunca comprobaba si un valor era una ruta absoluta, y una ruta absoluta sin segmentos de recorrido no contiene ninguno de los dos.
| Runtime | Directorio | Stack |
|---|---|---|
| Camel Spring Boot | camel-spring-boot/ | Spring Boot 3.5.13 + camel-docling 4.22.1 |
| Camel Quarkus | camel-quarkus/ | Camel Quarkus 3.39.0 (Quarkus 3.39.0, Camel 4.22.0) |
cd camel-spring-boot # or: cd camel-quarkus
mvn clean package
docker compose up -d --build
until [ "$(curl -s http://localhost:8080/exploit/ready)" = "Started" ]; do sleep 1; done
curl -s http://localhost:8080/exploit/attack
docker compose down
En una compilación afectada (idéntico en ambos runtimes):
1) A relative traversal value, which the CVE-2026-40047 fix does reject
header CamelDoclingCustomArguments = [--artifacts-path, ../../../../etc]
REJECTED by Camel: IllegalArgumentException: Custom argument at index 1 contains a relative path traversal sequence
2) Traversal hidden behind redundant separators - also rejected (normalized first)
header CamelDoclingCustomArguments = [--artifacts-path, models/./../../../../etc]
REJECTED by Camel: IllegalArgumentException: Custom argument at index 1 contains a relative path traversal sequence
3) An ABSOLUTE path, which contains no traversal sequence at all
header CamelDoclingCustomArguments = [--artifacts-path, /etc]
argv docling received: --artifacts-path /etc --to md --ocr-lang en --output /tmp/docling-... /tmp/docling-.../docling-....tmp
4) The same, attached to the flag after an equals sign
header CamelDoclingCustomArguments = [--artifacts-path=/root/.ssh]
argv docling received: --artifacts-path=/root/.ssh --to md --ocr-lang en --output /tmp/docling-... /tmp/docling-.../docling-....tmp
>>> PROVEN: ...
Las sondas 1 y 2 muestran que la corrección de CVE-2026-40047 hace su trabajo. Las sondas 3 y 4 son el vacío: el flag está en la lista de permitidos de esa corrección (--artifacts-path indica a docling dónde encontrar sus artefactos de modelo), y el valor pasa de largo en ambas formas de argumento — un elemento de lista separado que sigue al flag, y adjunto después de un =. Una parte capaz de elegir los argumentos personalizados podría, por lo tanto, apuntar el proceso de docling a cualquier directorio al que el proceso de Camel pueda acceder, fuera del directorio de trabajo en el que la comprobación pretendía mantener los valores de ruta, que es exactamente el resultado que la corrección anterior se propuso evitar.
No se necesita una instalación de docling. El fallo está en la línea de comandos que Camel construye, por lo que la opción doclingCommand del endpoint apunta a un sustituto de grabación para la CLI que escribe el vector de argumentos que se le entregó en un archivo. Se ejecutan el DoclingProducer real, el validateCustomArguments() real y el validatePathSafety() real; solo se reemplaza la herramienta externa.
Solo el modo CLI, que es el predeterminado, pasa argumentos personalizados a docling.
CamelDoclingCustomArguments pertenece al espacio de nombres de cabeceras de Camel, que los consumidores que aplican el filtrado de cabeceras predeterminado de Camel — los consumidores JMS y Kafka, por ejemplo — eliminan de los mensajes entrantes. Por lo tanto, el problema se alcanza cuando una ruta reenvía valores influenciados externamente a la cabecera, o cuando un consumidor mapea cabeceras entrantes sin ese filtrado.
| Propiedad | Valor |
|---|---|
| Componente | camel-docling (DoclingProducer.validatePathSafety()) |
| CWE | CWE-22 (Limitación incorrecta de un nombre de ruta a un directorio restringido) |
| Severidad | Media |
| Vector de ataque | Una ruta absoluta como valor de un flag similar a una ruta incluido en la lista de permitidos en CamelDoclingCustomArguments |
| Impacto | Apuntar el proceso de docling a cualquier directorio al que el proceso de Camel pueda acceder |
| Versiones afectadas | Desde 4.15.0 antes de 4.18.5, desde 4.19.0 antes de 4.22.2 |
| Versiones corregidas | 4.18.5, 4.22.2, 4.23.0 |
| JIRA | CAMEL-24893 |
| Crédito | Zhixi "Jace" Sun, investigador de seguridad independiente |
Aviso: https://camel.apache.org/security/CVE-2026-95628.html
Relacionado: esta es una corrección incompleta de CVE-2026-40047, y la cabecera de ruta de salida del mismo componente es CVE-2026-95629.
validatePathSafety ahora también rechaza un valor de argumento personalizado similar a una ruta que sea una ruta absoluta, haciendo fallar el intercambio con una IllegalArgumentException que indica que el argumento no debe ser una ruta absoluta. Debido a que la comprobación se encuentra en el helper compartido que valida cada valor similar a una ruta, ambas formas de argumento quedan cubiertas.
Corregido en main en apache/camel#26738 (fd3bc8e7), retroportado a camel-4.22.x en #26743 (e9233c37) y a camel-4.18.x en #26744 (59d30af1).
Establezca camel.version en 4.22.2 y ejecútelo de nuevo. Verificado con 4.22.1 → 4.22.2:
3) An ABSOLUTE path, which contains no traversal sequence at all
REJECTED by Camel: IllegalArgumentException: Custom argument at index 1 must not be an absolute path
4) The same, attached to the flag after an equals sign
REJECTED by Camel: IllegalArgumentException: Custom argument at index 0 must not be an absolute path
>>> NOT reproduced: the absolute path was rejected too.
No construya CamelDoclingCustomArguments a partir de valores que se originen fuera del despliegue; elimine esa
cabecera de los mensajes que llegan desde el exterior antes de que alcancen un endpoint de docling; y asegúrese de que los consumidores
que mapean las cabeceras entrantes descarten el espacio de nombres de cabeceras de Camel, de modo que solo la ruta elija los argumentos personalizados.
Este repositorio se publica con fines educativos y defensivos: para ayudar a los usuarios de Apache Camel a comprender la vulnerabilidad, verificar si se ven afectados y confirmar que la actualización la resuelve. No utilice este material contra sistemas que no sean de su propiedad o que no opere.