
Reproducer per CVE-2026-46454 — Apache Camel camel-cometd iniezione di header Bayeux in ingresso (iniezione di control-header Camel non autenticata → reindirizzamento del producer a valle / RCE)
Questo progetto dimostra un'iniezione di header di messaggio nel componente camel-cometd di Apache Camel, tracciata come
CVE-2026-46454. Il componente mappa gli header dei messaggi Bayeux (CometD) in ingresso nello scambio Camel senza
una HeaderFilterStrategy. CometdBinding.createCamelMessage copia l'intera mappa ext.CamelHeaders fornita
dal client CometD direttamente sul messaggio Camel (message.setHeaders(...)), quindi qualsiasi nome di header — inclusi
gli header di controllo interni di Camel come CamelHttpUri, CamelFileName, CamelJmsDestinationName (o, come in questo caso,
gli header di controllo camel-exec) — viene accettato senza modifiche. Poiché un CometdComponent non installa nessuna
SecurityPolicy Bayeux per impostazione predefinita, qualsiasi client che riesca a completare l'handshake Bayeux può pubblicare
un tale messaggio senza autenticazione e pilotare i produttori a valle nella route.
Advisory: https://camel.apache.org/security/CVE-2026-46454.html
Stessa famiglia di iniezioni di header di CVE-2025-27636, CVE-2025-29891, CVE-2025-30177, CVE-2026-40453 e CVE-2026-47323 — componenti che mappano header in ingresso nello scambio senza filtrare il namespace
Camel.
// CometdBinding.createCamelMessage(...) - 4.18.2 interessata
Message message = new DefaultMessage(camelContext);
message.setBody(data);
Map<String, Object> headers = getHeadersFromMessage(cometdMessage); // legge ext.CamelHeaders forniti dal client
if (headers != null) {
message.setHeaders(headers); // <-- nessuna HeaderFilterStrategy
}
Il client controlla ext.CamelHeaders, quindi può impostare qualsiasi header di controllo Camel sullo scambio. La
correzione (4.14.8 / 4.18.3 / 4.21.0) implementa una HeaderFilterStrategy (un TODO di lunga data nel codice) che
filtra il namespace Camel* / camel* senza distinzione tra maiuscole e minuscole nella mappatura in ingresso.
from("cometd://0.0.0.0:8088/service/inject")
.to("exec:echo?args=hello"); // l'autore della route intende solo eseguire: echo hello
Un attaccante pubblica su /service/inject con ext.CamelHeaders = { CamelExecCommandExecutable: "/usr/bin/touch", CamelExecCommandArgs: "/tmp/pwned" }; il binding li mappa sullo scambio e il produttore
exec esegue il comando dell'attaccante invece di quello previsto.
Autocontenuto: il consumer camel-cometd esegue un server Bayeux incorporato (porta 8088) all'interno dell'app, e
l'endpoint /exploit/attack funge da client CometD non autenticato.
CVE-2026-46454/
├── pom.xml # camel-cometd + camel-exec 4.18.2; client cometd 9.0.0; Jetty fissato alla 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 # BayeuxClient dell'attaccante: handshake + publish con ext.CamelHeaders
└── resources/
└── application.properties
mvn clean package -DskipTests
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack
# -> Handshaked (non autenticato) e pubblicato su /service/inject con ext.CamelHeaders = {...}.
# Il consumer camel-cometd li ha mappati sullo scambio; il produttore exec ha eseguito il comando.
#
# >>> Prova di RCE — /tmp/pwned esiste: true
docker exec cve-2026-46454 ls -la /tmp/pwned
docker compose down
Qualsiasi route con un consumer camel-cometd che alimenta un produttore a valle il cui comportamento è controllato dagli
header Camel — un produttore HTTP (CamelHttpUri), un produttore file (CamelFileName), un produttore JMS
(CamelJmsDestinationName), un produttore exec (CamelExecCommand*), ecc. Qualsiasi client che riesca a completare l'handshake
contro l'endpoint Bayeux può iniettarli; non è richiesta autenticazione per impostazione predefinita. Gli header iniettati
persistono attraverso i salti interni direct, seda e vm.
SecurityPolicy Bayeux sul CometdComponent (il comportamento predefinito), quindi qualsiasi client può pubblicare.Aggiornare alla 4.14.8 / 4.18.3 / 4.21.0 (CAMEL-23507), che aggiunge una HeaderFilterStrategy al binding cometd
che blocca gli header Camel* / camel* forniti dal client nella mappatura in ingresso.
Fino all'aggiornamento:
.removeHeaders("Camel*") e .removeHeaders("camel*").SecurityPolicy Bayeux esplicita sul CometdComponent in modo che solo i client autenticati possano
pubblicare.Questo riproduttore è fornito esclusivamente per ricerca sulla sicurezza e test autorizzati, per una vulnerabilità divulgata pubblicamente e corretta. Non utilizzarlo contro sistemi senza esplicita autorizzazione.
| Proprietà | Valore |
|---|
| Componente | camel-cometd |
| Classe interessata | org.apache.camel.component.cometd.CometdBinding#createCamelMessage (message.setHeaders(...)) |
| CWE | CWE-20: Convalida impropria dell'input |
| Impatto | Iniezione non autenticata di header di controllo Camel → pilotaggio dei produttori a valle (RCE tramite exec in questo caso) |
| Versioni interessate | Dalla 4.0.0 precedente alla 4.14.8, dalla 4.15.0 precedente alla 4.18.3, dalla 4.19.0 precedente alla 4.21.0 |
| Versioni corrette | 4.14.8, 4.18.3, 4.21.0 |
| JIRA | CAMEL-23507 |
| Segnalatore | Yu Bao (PayPal) |