oscerd/CVE-2026-40047

GitHub: oscerd/CVE-2026-40047

Apache Camel camel-docling 组件 CLI 参数注入与路径穿越漏洞(CVE-2026-40047)的概念验证与复现工具。

Stars: 2 | Forks: 0

# camel-docling CLI Argument Injection / Path Traversal 复现器 (CVE-2026-40047) 本项目演示了 Apache Camel 的 `camel-docling` 组件中的一个 **CLI argument injection 和 path traversal** 漏洞,追踪编号为 **CVE-2026-40047**。`DoclingProducer` 根据 message header 构建对外部 `docling` 命令行工具的调用;通过 `CamelDoclingCustomArguments` header 传入的 custom arguments 在被追加时缺乏充分的验证(仅使用 denylist 和字面量 `../` 检查),因此能够影响这些 header 的攻击者可以向子进程注入任意的 `docling` CLI flag 和包含 traversal 的 path 值。 Advisory: https://camel.apache.org/security/CVE-2026-40047.html ## 漏洞概述 | Property | Value | |----------|-------| | **Component** | `camel-docling` | | **Affected Class** | `org.apache.camel.component.docling.DoclingProducer` (`addCustomArguments` / `validateCustomArguments`) | | **Root cause** | `CamelDoclingCustomArguments` (一个 `List`) 被追加到 `docling` CLI args 时,仅使用了较弱的 denylist + 字面量 `../` 检查 | | **CWE** | CWE-88 (Argument Injection) / CWE-22 (Path Traversal) | | **Impact** | 向外部工具注入任意/非预期的 `docling` CLI flag 和目录外的 path 值。这不是 OS command injection(基于 list 的 ProcessBuilder,没有 shell)。 | | **Affected Versions** | 从 4.15.0 到 4.18.3 之前的版本 | | **Fixed Versions** | 4.18.3, 4.19.0 | | **JIRA** | CAMEL-23212 | | **Reporter** | Andrea Cosentino (Apache Software Foundation) | ## 技术细节 `DoclingProducer` 组装 `docling` 调用并通过 `java.lang.ProcessBuilder`(list 形式——无 shell)运行它。来自 `CamelDoclingCustomArguments` header 的 custom CLI arguments 会被追加到 命令中: ``` // DoclingProducer.addCustomArguments(...) - affected version List customArgs = exchange.getIn().getHeader(DoclingHeaders.CUSTOM_ARGUMENTS, List.class); if (customArgs != null && !customArgs.isEmpty()) { validateCustomArguments(customArgs); // denylist + literal "../" check (weak) command.addAll(customArgs); } ``` 在受影响的版本中,`validateCustomArguments` 依赖于一个不允许 flag 的 **denylist**,并且只 拒绝包含字面量 `../` 的 path 值。因此: - **无法识别的 flag**(不在 denylist 中)被直接传递给 `docling`。 - **类似 path 的值**,如果不包含字面量 `../`(绝对路径或规范化序列)就不会被拦截。 因为 Camel 构建了 `docling` 的调用,所以该组件负责约束这些 值。修复方案 (CAMEL-23212) 将 denylist 替换为已识别 flag 的严格 **allowlist**, 拒绝 producer 管理的 flag(`--output`/`-o`)和 shell 元字符(纵深防御),并在验证前使用 `Path.normalize()` 规范化类似 path 的值。 ## 路由 ``` from("direct:convert") .to("docling:convert?operation=CONVERT_TO_MARKDOWN&contentInBody=true"); ``` ## 本复现程序如何观察注入 `docling` 是一个外部工具。本复现程序附带了一个 **stub `docling`**(位于容器内的 `PATH` 中),它会记录接收到的 argv 并写回一个 markdown 文件,因此被注入的参数 将在 HTTP 响应和 `/tmp/docling-invocations.log` 中可见。所有这些都运行在一个 Docker 镜像中(app + stub)——因此不需要安装真正的 `docling`。 ## 前置条件 - Java 17+ 和 Maven 3.8+(用于构建 jar) - Docker(运行 app + stub `docling`) ## 复现步骤 ### 步骤 1:构建 jar 和镜像 ``` mvn clean package -DskipTests docker compose up -d --build ``` ### 步骤 2:良性转换 ``` curl http://localhost:8080/exploit/normal # stub docling 接收:docling --to md --ocr-lang en --output /tmp/input.txt ``` ### 步骤 3:注入任意 CLI arguments ``` curl "http://localhost:8080/exploit/attack" # 注入 CamelDoclingCustomArguments = [--injected-by-attacker, arbitrary-value] # -> stub docling 接收: # docling --injected-by-attacker arbitrary-value --to md --ocr-lang en --output /tmp/input.txt # 不包含字面量 "../" 的 path 值(绝对路径)同样可以通过: curl "http://localhost:8080/exploit/attack?flag=--artifacts-path&value=/etc/attacker-controlled" ``` 在受影响的版本上(本复现程序锁定为 **4.18.2**),路由会**成功**执行,并且被注入的 参数会到达子进程。在已修复的版本(4.18.3 / 4.19.0)上,allowlist 会以 `IllegalArgumentException` 拒绝 `--injected-by-attacker`,从而导致路由失败。 ### 清理 ``` docker compose down ``` ## 漏洞利用条件 1. 一个 Camel 路由将受外部影响的数据转发到 `docling:` producer 的 `CamelDoclingCustomArguments`(或 包含路径的 header)中。 2. 没有对来自不受信任的 producer 的 message 剥离 Camel 内部的 header。 ## 推荐修复 升级到 4.18.3 / 4.19.0。该修复使用已识别 `docling` flag 的严格 allowlist,拒绝 producer 管理的 flag 和 shell 元字符,并在验证它们 之前使用 `Path.normalize()` 规范化 path 值。 ## 缓解措施 在升级之前: 1. **不要将不受信任的内容**映射到 `CamelDoclingCustomArguments` 或包含路径的 header 中。 2. **剥离 Camel 内部的 header**(`removeHeaders("Camel*")`),针对来自不受信任的 producer 的 message,在到达 `docling:` producer 之前进行处理。 ## 文件 ``` 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 ``` ## 免责声明 本复现程序仅供**安全研究和授权测试使用**,针对的是一个**已公开 披露且已修复**的漏洞。未经明确许可,请勿将其用于任何系统。
标签:Apache Camel, JS文件枚举, Maven, 参数注入, 域名枚举, 漏洞复现, 漏洞验证, 版权保护, 请求拦截, 路径穿越