
Reprodutor de prova de conceito executável para CVE-2026-85312, demonstrando o sequestro de saga do Apache Camel por meio do cabeçalho Long-Running-Action no Spring Boot e no Quarkus.
Long-Running-ActionReprodutor de prova de conceito executável para a vulnerabilidade do Apache Camel em que o SagaProcessor do camel-core selecionava o
coordenador de saga a partir do cabeçalho de mensagem Long-Running-Action em cada exchange. Esse nome de cabeçalho não carrega o
prefixo Camel, portanto fica fora do namespace que os filtros de cabeçalho do consumidor removem — um remetente externo poderia fornecê-lo
em uma mensagem de entrada e, assim, nomear a saga à qual sua exchange se junta, anexando sua requisição a uma ação de longa duração
iniciada por outra pessoa (ou associando compensação a uma ação que não iniciou). A exposição é
limitada a implantações que executam sagas, mas onde se aplica o remetente controla a qual saga uma exchange pertence
(CWE-20).
| Runtime | Diretório | Stack |
|---|---|---|
| Camel Spring Boot | camel-spring-boot/ | Spring Boot 3.5.13 + camel-spring-boot 4.22.0 (afetado; corrigido 4.22.1) |
| Camel Quarkus | camel-quarkus/ | Quarkus 3.39.0 + camel-quarkus-saga (Camel 4.22.0, afetado; controle corrigido CQ 3.40.0 / Camel 4.22.1) |
Ambos os módulos demonstram o comportamento afetado e o corrigido contra o SagaProcessor real do camel-core.
O driver espelha o próprio teste de regressão da correção (SagaHeaderCannotSelectCoordinatorTest). Ele constrói uma rota de saga
from("direct:…").saga().propagation(MANDATORY) apoiada por um serviço de saga em memória que registra cada id cuja resolução
lhe é solicitada, e então envia uma exchange carregando o cabeçalho de entrada Long-Running-Action = a-saga-id-from-the-wire
— o id que um remetente externo colocaria no fio. O oráculo é simplesmente quais ids de saga chegam ao serviço:
a-saga-id-from-the-wire é consultado
— a mensagem escolheu o coordenador.Em ambas as builds a exchange MANDATORY acaba falhando (não há uma saga real à qual se juntar) — a vulnerabilidade não é a
falha, mas que um id escolhido pelo atacante foi usado para selecionar o coordenador, razão pela qual o oráculo observa a
consulta em vez do resultado.
# Camel Spring Boot
cd camel-spring-boot
mvn clean package
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack # affected: wire id looked up = true; >>> PROVEN
docker compose down
# Patched control
mvn clean package -Dcamel.version=4.22.1
java -jar target/cve-2026-85312-saga-header-hijack-0.0.1-SNAPSHOT.jar &
curl -s http://localhost:8080/exploit/attack # fixed: wire id looked up = false; >>> Not exploited
# Camel Quarkus
cd camel-quarkus
mvn clean package
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack # affected (Camel 4.22.0): wire id looked up = true
docker compose down
# Patched control: CQ 3.40.0 ships Camel 4.22.1
mvn clean package -Dcamel-quarkus.version=3.40.0 -Dquarkus.platform.version=3.40.0
java -jar target/quarkus-app/quarkus-run.jar &
curl -s http://localhost:8080/exploit/attack # fixed: wire id looked up = false
| Propriedade | Valor |
|---|---|
| Componente | camel-core (SagaProcessor.getCurrentSagaCoordinator) |
| CWE | CWE-20 (Validação de Entrada Imprópria) |
| Severidade | MÉDIA |
| Vetor de ataque | Um remetente externo fornece o cabeçalho Long-Running-Action sem prefixo em uma mensagem de entrada para uma rota que executa o EIP saga |
| Impacto | O remetente nomeia a saga à qual um exchange se junta — anexando-se à ação de longa duração de outra parte, ou associando incorretamente a compensação |
| Versões Afetadas | A partir de 4.0.0 antes de 4.18.5, a partir de 4.19.0 antes de 4.22.1 |
| Versões Corrigidas | 4.18.5, 4.22.1, 4.23.0 |
| JIRA | CAMEL-24449 |
| Crédito | Claude Security Scan Tool |
Aviso: https://camel.apache.org/security/CVE-2026-85312.html
O módulo afetado do Quarkus é construído sobre o CQ 3.39.0 (Camel 4.22.0). O controle corrigido é o CQ 3.40.0 (Camel 4.22.1).
SagaProcessor agora consulta o cabeçalho Long-Running-Action apenas quando
o serviço de saga anuncia que participa de tal protocolo, por meio do novo
CamelSagaService.isLongRunningActionHeaderSupported() (padrão false; o serviço LRA o substitui por true). O
estado interno do exchange — que sobrevive a removeHeaders("*") — permanece como o portador normal do id da saga, de modo que uma mensagem
não pode mais escolher o coordenador para um serviço que não executa nenhum coordenador externo.
Remova o cabeçalho na fronteira de confiança com removeHeaders("Long-Running-Action") em todo consumidor que aceita
mensagens de um remetente não confiável.
Este repositório é publicado para fins educacionais e defensivos: para ajudar os usuários do Apache Camel a entender a vulnerabilidade, verificar se são afetados e confirmar que a atualização a resolve. A demonstração executa uma rota saga em processo com um serviço de saga em memória; o id de saga do "atacante" é uma string de espaço reservado inofensiva. Não use este material contra sistemas que você não possui ou opera.