
Reproducer per CVE-2026-43865 — istanza Apache Camel camel-hazelcast configurata di default con deserializzazione Java non sicura (RCE)
Questo progetto dimostra una vulnerabilità di deserializzazione Java nel componente camel-hazelcast di Apache Camel, tracciata come CVE-2026-43865. Quando Camel costruisce la Config di Hazelcast stessa — cioè quando non viene fornita alcuna HazelcastInstance fornita dall'utente, hazelcastConfigUri o bean Config referenziato — non applica alcun filtro di deserializzazione Java (né il JavaSerializationFilterConfig di Hazelcast né un ObjectInputFilter lato Camel). Gli oggetti che arrivano tramite il protocollo del cluster Hazelcast vengono quindi deserializzati all'interno del layer di serializzazione di Hazelcast (ObjectInputStream.readObject) senza restrizioni sulle classi. Un attaccante che può unirsi o comunque raggiungere il cluster può pubblicare un oggetto serializzato appositamente creato che viene deserializzato su ogni nodo Camel — esecuzione remota di codice, presente per impostazione predefinita e che non richiede alcuna configurazione endpoint opzionale.
Avviso: https://camel.apache.org/security/CVE-2026-43865.html
Questo è diverso dagli advisory della libreria Hazelcast CVE-2016-10750 / CVE-2022-36418 (che riguardano il codice di Hazelcast stesso). Qui il difetto è che Camel non applica la protezione di deserializzazione fornita da Hazelcast.
Quando non viene fornita alcuna istanza/configurazione, HazelcastDefaultComponent costruisce l'istanza dalla configurazione standard e non imposta alcun filtro di serializzazione:
// 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
}
Il fix inserisce un filtro predefinito (whitelist java./javax./org.apache.camel., blacklist java.net.) sulle istanze che Camel crea autonomamente, lasciando invariate la Config/HazelcastInstance fornite dall'utente:
// fixed 4.18.3 / 4.21.0
config.getProperties().setProperty("hazelcast.phone.home.enabled", "false");
HazelcastSerializationFilterHelper.applyDefault(config); // <-- added
hzInstance = Hazelcast.newHazelcastInstance(config);
Qualsiasi struttura che passa l'oggetto deserializzato a Camel attiva la vulnerabilità. Questa PoC usa un consumatore queue in modalità Poll, dove IQueue.poll() deserializza l'elemento in testa prima che Camel lo instradi:
// 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 vittima è il nodo Camel (un membro Hazelcast). L'attaccante è qualsiasi soggetto in grado di raggiungere il cluster. Questa PoC autonoma esegue un client Hazelcast (l'attaccante) che si unisce allo stesso cluster a membro singolo (dev su 127.0.0.1:5701) e offre un gadget alla coda consumata dalla vittima.
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
In un attacco reale i byte serializzati sono prodotti dal client/membro Hazelcast dell'attaccante; solo la vittima ha bisogno della catena di gadget nel proprio classpath. Questa PoC costruisce il gadget in-process, motivo per cui la JVM viene eseguita con
--add-opens java.base/java.util=ALL-UNNAMED— un dettaglio di costruzione del gadget, non correlato alla vulnerabilità.
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
Qualsiasi route Camel che utilizza un consumatore hazelcast (hazelcast-topic, hazelcast-queue, hazelcast-seda, hazelcast-map, hazelcast-multimap, hazelcast-replicatedmap, hazelcast-list, hazelcast-set), o HazelcastAggregationRepository / HazelcastIdempotentRepository, ogni volta che l'istanza gestita viene creata dalla configurazione predefinita di Camel e un attaccante può raggiungere il cluster.
HazelcastInstance / hazelcastConfigUri / Config fornito dall'utente).commons-collections:3.2.1).Effettuare l'upgrade a 4.14.8 / 4.18.3 / 4.21.0 (CAMEL-23414), che applica un JavaSerializationFilterConfig Hazelcast predefinito alle istanze che Camel crea dalla propria configurazione predefinita.
Fino all'aggiornamento:
JavaSerializationFilterConfig, oppure il -Djdk.serialFilter=!java.net.**;java.**;javax.**;org.apache.camel.**;!* a livello di JVM).Questo riproduttore è fornito solo per ricerca sulla sicurezza e test autorizzati, per una vulnerabilità divulgata pubblicamente e corretta. Non usarlo contro sistemi senza permesso esplicito.
| Property | Value |
|---|
| Componente | camel-hazelcast (qualsiasi consumatore + HazelcastAggregationRepository / HazelcastIdempotentRepository) |
| Classe interessata | org.apache.camel.component.hazelcast.HazelcastDefaultComponent (creazione dell'istanza con configurazione predefinita) |
| CWE | CWE-502: Deserializzazione di dati non attendibili |
| Impatto | Esecuzione remota di codice (RCE) su ogni nodo Camel del cluster |
| Attivazione | Un consumatore/repository hazelcast la cui istanza gestita è creata dalla configurazione predefinita di Camel |
| Versioni interessate | Dalla 4.0.0 prima della 4.14.8, dalla 4.15.0 prima della 4.18.3, dalla 4.19.0 prima della 4.21.0 |
| Versioni corrette | 4.14.8, 4.18.3, 4.21.0 |
| JIRA | CAMEL-23414 |
| Segnalatore | gaorenyusi |