
Reproducteur de preuve de concept exécutable pour CVE-2026-85312, démontrant le détournement de saga Apache Camel via l'en-tête Long-Running-Action dans Spring Boot et Quarkus.
Long-Running-ActionReproducteur de preuve de concept exécutable pour la vulnérabilité Apache Camel où le SagaProcessor de camel-core sélectionnait le
coordinateur de saga à partir de l'en-tête de message Long-Running-Action sur chaque échange. Ce nom d'en-tête ne porte aucun
préfixe Camel, il se situe donc en dehors de l'espace de noms que les filtres d'en-têtes des consommateurs suppriment — un expéditeur externe pouvait le fournir
sur un message entrant et ainsi nommer la saga que son échange rejoint, rattachant sa requête à une action de longue durée
démarrée par quelqu'un d'autre (ou associant une compensation à une action qu'il n'a pas initiée). L'exposition est
limitée aux déploiements exécutant des sagas, mais là où elle s'applique, l'expéditeur contrôle à quelle saga un échange appartient
(CWE-20).
| Runtime | Répertoire | Pile |
|---|---|---|
| Camel Spring Boot | camel-spring-boot/ | Spring Boot 3.5.13 + camel-spring-boot 4.22.0 (affecté ; corrigé en 4.22.1) |
| Camel Quarkus | camel-quarkus/ | Quarkus 3.39.0 + camel-quarkus-saga (Camel 4.22.0, affecté ; témoin corrigé CQ 3.40.0 / Camel 4.22.1) |
Les deux modules démontrent le comportement affecté et le comportement corrigé face au véritable SagaProcessor de camel-core.
Le pilote reproduit le propre test de régression du correctif (SagaHeaderCannotSelectCoordinatorTest). Il construit une route de saga
from("direct:…").saga().propagation(MANDATORY) adossée à un service de saga en mémoire qui enregistre chaque id dont la résolution lui est demandée,
puis envoie un échange portant l'en-tête entrant Long-Running-Action = a-saga-id-from-the-wire
— l'id qu'un expéditeur externe placerait sur le réseau. L'oracle est simplement quels ids de saga atteignent le service :
a-saga-id-from-the-wire est recherché
— le message a choisi le coordinateur.Dans les deux versions, l'échange MANDATORY finit par échouer (il n'y a pas de véritable saga à rejoindre) — la vulnérabilité n'est pas
l'échec mais le fait qu'un id choisi par l'attaquant ait été utilisé pour sélectionner le coordinateur, ce qui explique pourquoi l'oracle surveille la
recherche plutôt que le résultat.
# 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
| Propriété | Valeur |
|---|---|
| Composant | camel-core (SagaProcessor.getCurrentSagaCoordinator) |
| CWE | CWE-20 (Validation d'entrée incorrecte) |
| Gravité | MOYENNE |
| Vecteur d'attaque | Un expéditeur externe fournit l'en-tête Long-Running-Action sans préfixe sur un message entrant vers une route exécutant l'EIP saga |
| Impact | L'expéditeur nomme la saga à laquelle un échange se joint — en s'attachant à l'action de longue durée d'un tiers, ou en associant à tort une compensation |
| Versions affectées | À partir de 4.0.0 avant 4.18.5, à partir de 4.19.0 avant 4.22.1 |
| Versions corrigées | 4.18.5, 4.22.1, 4.23.0 |
| JIRA | CAMEL-24449 |
| Crédit | Claude Security Scan Tool |
Avis : https://camel.apache.org/security/CVE-2026-85312.html
Le module Quarkus affecté est construit sur CQ 3.39.0 (Camel 4.22.0). Le correctif de contrôle est CQ 3.40.0 (Camel 4.22.1).
SagaProcessor ne consulte désormais l'en-tête Long-Running-Action que lorsque
le service saga déclare qu'il participe à un tel protocole, via la nouvelle
méthode CamelSagaService.isLongRunningActionHeaderSupported() (par défaut false ; le service LRA la redéfinit à true). L'état
interne de l'échange — qui survit à removeHeaders("*") — reste le porteur normal de l'identifiant de saga, de sorte qu'un message
ne peut plus choisir le coordinateur pour un service qui n'exécute aucun coordinateur externe.
Supprimez l'en-tête à la frontière de confiance avec removeHeaders("Long-Running-Action") sur chaque consommateur qui accepte
des messages provenant d'un expéditeur non fiable.
Ce dépôt est publié à des fins éducatives et défensives : pour aider les utilisateurs d'Apache Camel à comprendre la vulnérabilité, à vérifier s'ils sont affectés, et à confirmer que la mise à jour la résout. La démonstration exécute une route saga en processus avec un service saga en mémoire ; l'identifiant de saga de l'« attaquant » est une chaîne de remplacement bénigne. N'utilisez pas ce matériel contre des systèmes que vous ne possédez pas ou n'exploitez pas.