
Reproducteur pour CVE-2026-43865 — instance camel-hazelcast d'Apache Camel configurée par défaut, désérialisation Java non sécurisée (RCE)
Ce projet démontre une vulnérabilité de désérialisation Java dans le composant camel-hazelcast d'Apache Camel, suivie sous la référence CVE-2026-43865. Lorsque Camel construit lui-même la Config Hazelcast — c'est-à-dire lorsqu'aucun HazelcastInstance, hazelcastConfigUri ou bean Config fourni par l'utilisateur n'est présent — il n'applique aucun filtre de désérialisation Java (ni le JavaSerializationFilterConfig de Hazelcast ni un ObjectInputFilter côté Camel). Les objets arrivant via le protocole de cluster Hazelcast sont donc désérialisés dans la couche de sérialisation de Hazelcast (ObjectInputStream.readObject) sans restriction de classes. Un attaquant capable de rejoindre ou d'atteindre le cluster peut publier un objet sérialisé spécialement conçu qui est désérialisé sur chaque nœud Camel — exécution de code à distance, présente par défaut et ne nécessitant aucune configuration d'endpoint explicite.
Avis de sécurité : https://camel.apache.org/security/CVE-2026-43865.html
Cette vulnérabilité est distincte des avis de sécurité de la bibliothèque Hazelcast CVE-2016-10750 / CVE-2022-36418 (qui concernent le code de Hazelcast lui-même). Ici, le défaut est que Camel n'applique pas la protection de désérialisation fournie par Hazelcast.
Lorsqu'aucune instance/config n'est fournie, HazelcastDefaultComponent construit l'instance à partir de la configuration standard et ne définit aucun filtre de sérialisation :
// HazelcastDefaultComponent - affected 4.18.2
if (hazelcastInstance == null && config == null) {
config = new XmlConfigBuilder().build();
config.getProperties().setProperty("hazelcast.version.check.enabled", "false");
config.getProperties().setProperty("hazelcast.phone.home.enabled", "false");
hzInstance = Hazelcast.newHazelcastInstance(config); // no JavaSerializationFilterConfig
}
Le correctif insère un filtre par défaut (liste blanche java./javax./org.apache.camel., liste noire java.net.) sur les instances que Camel crée lui-même, sans toucher aux Config/HazelcastInstance fournis par l'utilisateur :
// fixed 4.18.3 / 4.21.0
config.getProperties().setProperty("hazelcast.phone.home.enabled", "false");
HazelcastSerializationFilterHelper.applyDefault(config); // <-- added
hzInstance = Hazelcast.newHazelcastInstance(config);
Toute structure qui transmet l'objet désérialisé à Camel déclenche la vulnérabilité. Cette PoC utilise un consommateur de file en mode Poll, où IQueue.poll() désérialise l'élément en tête avant que Camel ne l'achemine :
// HazelcastQueueConsumer (Poll mode) - affected
final Object body = queue.poll(config.getPollingTimeout(), TimeUnit.MILLISECONDS); // readObject, no filter
exchange.getIn().setBody(body);
from("hazelcast-queue:cve?queueConsumerMode=Poll") // Camel builds the default (unfiltered) instance
.log("Consumed: ${body.class.name}");
La victime est le nœud Camel (un membre Hazelcast). L'attaquant est toute entité capable d'atteindre le cluster. Cette PoC autonome exécute un client Hazelcast (l'attaquant) qui rejoint le même cluster à membre unique (dev sur 127.0.0.1:5701) et place un gadget dans la file consommée par la victime.
CVE-2026-43865/
├── pom.xml # camel-hazelcast 4.18.2 + commons-collections 3.2.1 (gadget)
├── Dockerfile # runs the app (--add-opens for gadget build; loopback cluster address)
├── docker-compose.yml
├── README.md
└── src/main/
├── java/com/example/
│ ├── Application.java
│ ├── VictimRoute.java # victim: hazelcast-queue consumer (default instance)
│ ├── Gadget.java # CommonsCollections6 gadget, fires during Hazelcast deserialization
│ └── ExploitController.java # attacker: Hazelcast client offers the gadget to the queue
└── resources/
└── application.properties
Dans une attaque réelle, les octets sérialisés sont produits par le client/membre Hazelcast de l'attaquant ; seule la victime doit avoir la chaîne de gadgets dans son classpath. Cette PoC construit le gadget dans le processus, c'est pourquoi la JVM est lancée avec
--add-opens java.base/java.util=ALL-UNNAMED— un détail de construction du gadget, sans rapport avec la vulnérvulnérabilité.
mvn clean package -DskipTests
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack
# -> Offered gadget to hazelcast queue 'cve' as a cluster client.
# The Camel node's queue.poll() deserialized it via Hazelcast (no filter).
#
# >>> RCE proof — /tmp/pwned exists: true
docker exec cve-2026-43865 ls -la /tmp/pwned
docker compose down
Toute route Camel utilisant un consommateur hazelcast (hazelcast-topic, hazelcast-queue, hazelcast-seda,
hazelcast-map, hazelcast-multimap, hazelcast-replicatedmap, hazelcast-list, hazelcast-set), ou les
HazelcastAggregationRepository / HazelcastIdempotentRepository, dès lors que l'instance gérée est créée
à partir de la configuration par défaut de Camel et qu'un attaquant peut atteindre le cluster.
HazelcastInstance / hazelcastConfigUri / Config fourni par l'utilisateur).commons-collections:3.2.1).Mettez à jour vers 4.14.8 / 4.18.3 / 4.21.0 (CAMEL-23414), qui applique un JavaSerializationFilterConfig Hazelcast par défaut aux instances que Camel crée à partir de sa propre configuration par défaut.
En attendant la mise à jour :
JavaSerializationFilterConfig, ou le -Djdk.serialFilter=!java.net.**;java.**;javax.**;org.apache.camel.**;!* à l'échelle de la JVM).Ce reproducteur est fourni uniquement pour la recherche en sécurité et les tests autorisés, pour une vulnérabilité publiquement divulguée et corrigée. Ne l'utilisez pas contre des systèmes sans autorisation explicite.
| Propriété | Valeur |
|---|
| Composant | camel-hazelcast (tout consommateur + HazelcastAggregationRepository / HazelcastIdempotentRepository) |
| Classe affectée | org.apache.camel.component.hazelcast.HazelcastDefaultComponent (création de l'instance avec la configuration par défaut) |
| CWE | CWE-502 : Désérialisation de données non fiables |
| Impact | Exécution de code à distance (RCE) sur chaque nœud Camel du cluster |
| Déclencheur | Un consommateur/référentiel hazelcast dont l'instance gérée est créée à partir de la configuration par défaut de Camel |
| Versions affectées | De 4.0.0 à 4.14.8 exclu, de 4.15.0 à 4.18.3 exclu, de 4.19.0 à 4.21.0 exclu |
| Versions corrigées | 4.14.8, 4.18.3, 4.21.0 |
| JIRA | CAMEL-23414 |
| Rapporteur | gaorenyusi |