
Reprodutor executável em Spring Boot e Quarkus para a CVE-2026-85248, uma condição de corrida de Signature concorrente no camel-pqc que causa bypass na verificação de assinatura ML-DSA, com builds afetados e corrigidos.
Signature (bypass de verificação de assinatura)Reprodutor de prova de conceito executável para a vulnerabilidade do Apache Camel em que o produtor PQC mantinha uma única
instância de java.security.Signature e a utilizava para cada exchange sem sincronização. Signature é stateful
e não é thread-safe: update() acumula os dados a serem assinados ou verificados, e verify()/sign() consomem esse
estado acumulado. Com exchanges concorrentes compartilhando uma única instância, as chamadas de update e verify de mensagens diferentes
se intercalam, de modo que uma verificação pode ser concluída sobre dados que pertencem a outra exchange, ou sobre um buffer
parcialmente acumulado. O resultado é não determinístico e inclui uma verificação reportando sucesso para uma mensagem
cuja assinatura nunca foi realmente verificada, o que anula a garantia que o componente existe para fornecer. Alcançá-la
requer apenas tráfego concorrente através do mesmo endpoint — a condição ordinária para uma rota Camel sob carga.
| Runtime | Diretório | Stack |
|---|---|---|
| Camel Spring Boot | camel-spring-boot/ | Spring Boot 3.5.13 + camel-pqc 4.22.0 (afetado; corrigido 4.22.1) |
| Camel Quarkus | camel-quarkus/ | Quarkus 3.39.0 + camel-quarkus-pqc (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.
Uma rota assina cada mensagem com uma chave pós-quântica ML-DSA e então verifica imediatamente a assinatura que acabou de
produzir, de modo que toda mensagem legitimamente assinada deve verificar true. O driver executa 1024 desses round-trips
sign→verify concorrentemente (16 threads) através dos produtores pqc: compartilhados.
true — algumas retornam false, algumas lançam
erros do motor de assinatura — porque a única Signature stateful compartilhada entre exchanges concorrentes é corrompida pelo
intercalamento. Um veredito não corresponde mais à mensagem para a qual foi calculado. (A mesma corrida, na direção
perigosa, permite que um verify() tenha sucesso para dados que ele nunca cobriu.)Signature.# Camel Spring Boot
cd camel-spring-boot
mvn clean package
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack # affected: many of 1024 broken; >>> PROVEN
docker compose down
# Patched control
mvn clean package -Dcamel.version=4.22.1
java -jar target/cve-2026-85248-pqc-signature-race-0.0.1-SNAPSHOT.jar &
curl -s http://localhost:8080/exploit/attack # fixed: 0 broken; >>> 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): many broken
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: 0 broken
A corrida é, por natureza, dependente de timing; o reprodutor gera concorrência suficiente (1024 round-trips) para que se manifeste de forma confiável na build afetada. Se uma execução afetada alguma vez mostrar 0 quebrados, execute-a novamente.
| Propriedade | Valor |
|---|---|
| Componente | camel-pqc (assinatura/verificação do PQCProducer) |
| CWE | CWE-362 (Execução Concorrente usando Recurso Compartilhado com Sincronização Imprópria) |
| Severidade | MÉDIA |
| Vetor de ataque | Tráfego concorrente através do mesmo endpoint pqc: compartilhando um java.security.Signature com estado |
| Impacto | Verificação de assinatura não determinística; uma verificação pode reportar sucesso para uma mensagem cuja assinatura nunca foi verificada |
| Versões Afetadas | Da 4.12.0 antes da 4.18.5, da 4.19.0 antes da 4.22.1 |
| Versões Corrigidas | 4.18.5, 4.22.1, 4.23.0 |
| JIRA | CAMEL-24445 |
| Crédito | Claude Security Scan Tool |
Advisory: https://camel.apache.org/security/CVE-2026-85248.html
O PQCProducer já não compartilha a Signature entre exchanges
concorrentes. Quando o producer criava a instância ele próprio, agora cria uma nova por exchange
(signerForExchange()); quando o utilizador configurou uma instância (JVM-wide public static final), o acesso à mesma é
synchronized. De qualquer forma, duas exchanges nunca intercalam as suas sequências de init/update/verify numa única instância.
Restrinja a rota afetada a um único consumidor concorrente para que duas exchanges nunca utilizem a instância Signature ao
mesmo tempo.
Este repositório é publicado para fins educativos e defensivos: para ajudar os utilizadores do Apache Camel a compreender a vulnerabilidade, verificar se são afetados e confirmar que a atualização a resolve. As mensagens e chaves são fixtures locais inertes. Não utilize este material contra sistemas que não possui ou opera.