
Reproducer for CVE-2026-43865 — Apache Camel camel-hazelcast default-configured instance unsafe Java deserialization (RCE)
Dieses Projekt demonstriert eine Java-Deserialisierungsschwachstelle in der camel-hazelcast-Komponente von Apache Camel, die als CVE-2026-43865 verfolgt wird. Wenn Camel die Hazelcast-Config selbst erstellt – d.h. wenn keine benutzerdefinierte HazelcastInstance, hazelcastConfigUri oder ein referenzierter Config-Bean bereitgestellt wird – wendet es keinen Java-Deserialisierungsfilter an (weder Hazelcasts JavaSerializationFilterConfig noch einen Camel-seitigen ObjectInputFilter). Objekte, die über das Hazelcast-Cluster-Protokoll ankommen, werden daher in Hazelcasts Serialisierungsebene (ObjectInputStream.readObject) ohne Klasseneinschränkungen deserialisiert. Ein Angreifer, der dem Cluster beitreten oder anderweitig darauf zugreifen kann, kann ein manipuliertes serialisiertes Objekt veröffentlichen, das auf jedem Camel-Knoten deserialisiert wird – Remote Code Execution, standardmäßig vorhanden und ohne erforderliche Endpunktkonfiguration.
Hinweis: https://camel.apache.org/security/CVE-2026-43865.html
Dies unterscheidet sich von den Hazelcast-Bibliothekshinweisen CVE-2016-10750 / CVE-2022-36418 (die Hazelcasts eigenen Code betreffen). Hier liegt der Fehler darin, dass Camel den von Hazelcast bereitgestellten Deserialisierungsschutz nicht anwendet.
Wenn keine Instanz/Konfiguration bereitgestellt wird, erstellt HazelcastDefaultComponent die Instanz aus der Standardkonfiguration und setzt keinen Serialisierungsfilter:
// HazelcastDefaultComponent - betroffen 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); // kein JavaSerializationFilterConfig
}
Der Fix fügt einen Standardfilter (Whitelist java./javax./org.apache.camel., Blacklist java.net.) auf Instanzen ein, die Camel selbst erstellt, und lässt benutzerdefinierte Config/HazelcastInstance unberührt:
// behoben 4.18.3 / 4.21.0
config.getProperties().setProperty("hazelcast.phone.home.enabled", "false");
HazelcastSerializationFilterHelper.applyDefault(config); // <-- hinzugefügt
hzInstance = Hazelcast.newHazelcastInstance(config);
Jede Struktur, die das deserialisierte Objekt an Camel übergibt, löst es aus. Dieser PoC verwendet einen Queue-Consumer im Poll-Modus, bei dem IQueue.poll() das Kopf-Element deserialisiert, bevor Camel es weiterleitet:
// HazelcastQueueConsumer (Poll-Modus) - betroffen
final Object body = queue.poll(config.getPollingTimeout(), TimeUnit.MILLISECONDS); // readObject, kein Filter
exchange.getIn().setBody(body);
from("hazelcast-queue:cve?queueConsumerMode=Poll") // Camel erstellt die Standardinstanz (ungefiltert)
.log("Consumed: ${body.class.name}");
Das Opfer ist der Camel-Knoten (ein Hazelcast-Mitglied). Der Angreifer ist jede Partei, die das Cluster erreichen kann. Dieser eigenständige PoC führt einen Hazelcast-Client (den Angreifer) aus, der demselben Ein-Mitglieder-Cluster (dev auf 127.0.0.1:5701) beitritt und ein Gadget in die Queue einstellt, die das Opfer konsumiert.
CVE-2026-43865/
├── pom.xml # camel-hazelcast 4.18.2 + commons-collections 3.2.1 (Gadget)
├── Dockerfile # führt die App aus (--add-opens für Gadget-Erstellung; Loopback-Cluster-Adresse)
├── docker-compose.yml
├── README.md
└── src/main/
├── java/com/example/
│ ├── Application.java
│ ├── VictimRoute.java # Opfer: hazelcast-queue Consumer (Standardinstanz)
│ ├── Gadget.java # CommonsCollections6 Gadget, wird während der Hazelcast-Deserialisierung ausgelöst
│ └── ExploitController.java # Angreifer: Hazelcast-Client stellt das Gadget in die Queue
└── resources/
└── application.properties
In einem echten Angriff werden die serialisierten Bytes vom eigenen Hazelcast-Client/-Mitglied des Angreifers erzeugt; nur das Opfer benötigt die Gadget-Kette auf seinem Classpath. Dieser PoC erstellt das Gadget prozessintern, weshalb die JVM mit
--add-opens java.base/java.util=ALL-UNNAMEDläuft – ein Detail der Gadget-Erstellung, nicht mit der Schwachstelle zusammenhängend.
mvn clean package -DskipTests
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack
# -> Gadget in Hazelcast-Queue 'cve' als Cluster-Client eingestellt.
# Der Queue.poll() des Camel-Knotens hat es über Hazelcast deserialisiert (kein Filter).
#
# >>> RCE-Beweis — /tmp/pwned existiert: true
docker exec cve-2026-43865 ls -la /tmp/pwned
docker compose down
Jede Camel-Route, die einen Hazelcast-Consumer verwendet (hazelcast-topic, hazelcast-queue, hazelcast-seda, hazelcast-map, hazelcast-multimap, hazelcast-replicatedmap, hazelcast-list, hazelcast-set) oder den HazelcastAggregationRepository / HazelcastIdempotentRepository, wenn die verwaltete Instanz aus Camels Standardkonfiguration erstellt wird und ein Angreifer das Cluster erreichen kann.
HazelcastInstance / hazelcastConfigUri / Config-Bean).commons-collections:3.2.1).Upgrade auf 4.14.8 / 4.18.3 / 4.21.0 (CAMEL-23414), das eine standardmäßige Hazelcast JavaSerializationFilterConfig auf Instanzen anwendet, die Camel aus seiner eigenen Standardkonfiguration erstellt.
Bis zum Upgrade:
JavaSerializationFilterConfig oder den JVM-weiten -Djdk.serialFilter=!java.net.**;java.**;javax.**;org.apache.camel.**;!*).Dieser Reproducer wird nur für Sicherheitsforschung und autorisierte Tests bereitgestellt, für eine öffentlich offengelegte und behobene Schwachstelle. Verwenden Sie ihn nicht gegen Systeme ohne ausdrückliche Genehmigung.
| Eigenschaft | Wert |
|---|
| Komponente | camel-hazelcast (jeder Consumer + HazelcastAggregationRepository / HazelcastIdempotentRepository) |
| Betroffene Klasse | org.apache.camel.component.hazelcast.HazelcastDefaultComponent (Standardkonfig-Instanzerstellung) |
| CWE | CWE-502: Deserialisierung nicht vertrauenswürdiger Daten |
| Auswirkung | Remote Code Execution (RCE) auf jedem Camel-Knoten im Cluster |
| Auslöser | Ein Hazelcast-Consumer/Repository, dessen verwaltete Instanz aus Camels Standardkonfiguration erstellt wird |
| Betroffene Versionen | Von 4.0.0 vor 4.14.8, von 4.15.0 vor 4.18.3, von 4.19.0 vor 4.21.0 |
| Behobene Versionen | 4.14.8, 4.18.3, 4.21.0 |
| JIRA | CAMEL-23414 |
| Melder | gaorenyusi |