
Reproducteur de preuve de concept exécutable pour CVE-2026-78165, démontrant une désérialisation JDK non filtrée des charges utiles Redis PUBLISH dans Apache Camel camel-spring-redis.
Reproducteur de preuve de concept exécutable pour la vulnérabilité Apache Camel où camel-spring-redis, lorsqu'aucune
option serializer n'est configurée, construisait un JdkSerializationRedisSerializer brut sans java.io.ObjectInputFilter
et l'utilisait pour chaque lecture. RedisConsumer.setBody l'appliquait aux octets bruts de chaque message publié sur les
canaux souscrits, avant la construction de l'Exchange — ainsi un acteur capable d'émettre PUBLISH sur un canal souscrit
atteignait directement le point de désérialisation et pouvait exécuter le readObject d'un graphe d'objets sérialisés
arbitraire (exécution de code à distance, CWE-502). Le même sérialiseur par défaut sous-tendait les commandes de lecture du producteur
(GET/HGET/HGETALL/HVALS) et SpringRedisIdempotentRepository.
| Runtime | Répertoire | Pile |
|---|---|---|
| Camel Spring Boot | camel-spring-boot/ | Spring Boot 3.5.13 + camel-spring-redis 4.22.0 (affecté ; corrigé en 4.22.1) |
| Camel Quarkus | camel-quarkus/ | Quarkus 3.29.0 + camel-quarkus-spring-redis 3.29.0 (Camel 4.15.0, affecté) |
Le défaut remonte à l'introduction du composant en 2.11.0, donc chaque version affectée et le Camel 4.15.0 du dernier Camel Quarkus sont vulnérables. Le correctif est livré dans Camel 4.18.5 / 4.22.1 / 4.23.0 ; le module Spring Boot exécute à la fois la version affectée (4.22.0) et la version corrigée (4.22.1). Aucun Camel Quarkus publié n'embarque encore un Camel corrigé.
L'application exécute une route Camel qui s'SUBSCRIBE à cve-channel sans option serializer (le
JdkSerializationRedisSerializer par défaut est donc utilisé). L'attaquant est un simple client Redis qui ne peut que PUBLISH vers ce
canal — il n'a aucun accès au processus Camel. Il publie les octets sérialisés bruts d'un com.example.PwnMarker
délibérément bénin, dont le readObject ne fait que basculer un indicateur global de la JVM (aucun gadget, aucune commande). Sur la version affectée
le consommateur le désérialise et readObject s'exécute ; sur la version corrigée la liste d'autorisation par défaut (types standard
java./javax. et org.apache.camel.) rejette com.example.PwnMarker avec
InvalidClassException: filter status: REJECTED.
cd camel-spring-boot
mvn clean package
docker compose up -d --build # starts Redis + the reproducer
curl -s http://localhost:8080/exploit/attack
docker compose down
Sortie attendue sur le build affecté :
Attacker connects to Redis redis:6379 and PUBLISHes a serialized com.example.PwnMarker to channel 'cve-channel'.
PUBLISH delivered to 1 subscriber(s).
Result:
>>> PROVEN: the Redis consumer deserialized the attacker-published, non-allow-listed class
>>> (com.example.PwnMarker) with no ObjectInputFilter — its readObject executed.
| Propriété | Valeur |
|---|---|
| Composant | camel-spring-redis (camel-spring-redis-starter / camel-quarkus-spring-redis) |
| CWE | CWE-502 (Désérialisation de données non fiables) |
| Gravité | ÉLEVÉE |
| Vecteur d'attaque | PUBLISH vers un canal auquel un consommateur Camel spring-redis est abonné (ou contrôle d'une clé Redis lue par le producteur) ; le sérialiseur par défaut désérialise la charge utile sans aucun filtre |
| Impact | Exécution de code à distance au sein du processus Camel via une classe gadget, avant l'exécution de toute logique de route |
| Versions affectées | À partir de 2.11.0 avant 4.18.5, à partir de 4.19.0 avant 4.22.1 |
| Versions corrigées | 4.18.5, 4.22.1, 4.23.0 |
| JIRA | CAMEL-24421 |
| Crédit | Leon Zlobecki |
Avis de sécurité : https://camel.apache.org/security/CVE-2026-78165.html
Une nouvelle option de point de terminaison deserializationFilter contrôle le filtre appliqué pendant que le sérialiseur par défaut lit les charges utiles. Lorsqu'elle n'est pas définie, le jdk.serialFilter à l'échelle de la JVM est respecté s'il est présent, sinon une liste d'autorisation conservatrice (types Java standard et Apache Camel ; java.net refusé) est appliquée, et sur 4.23.0/4.22.1 les limites de forme de graphe de la JEP-290 sont en outre imposées. Le sérialiseur est construit via son constructeur basé sur Converter avec un convertisseur de désérialisation qui définit le filtre sur le flux avant la lecture du graphe. Définir serializer sur un RedisSerializer personnalisé contourne toujours le filtre, puisque Camel ne contrôle alors plus la manière dont la charge utile est lue.
Définissez le -Djdk.serialFilter=... à l'échelle de la JVM (le chemin affecté le respecte), ou définissez l'option de point de terminaison serializer sur un sérialiseur non-Java tel que StringRedisSerializer (en tant qu'option serializer, et pas seulement sur un redisTemplate personnalisé). Exigez l'authentification sur Redis et restreignez qui peut publier vers les canaux auxquels un abonnement est effectué.
Ce dépôt est publié à des fins éducatives et défensives : pour aider les utilisateurs d'Apache Camel à comprendre la vulnérabilité, à vérifier s'ils sont affectés et à confirmer que la mise à jour la résout. La charge utile est un marqueur bénin qui n'exécute aucun code. N'utilisez pas ce matériel contre des systèmes que vous ne possédez pas ou n'exploitez pas.