
PoC riproducibile ed eseguibile per CVE-2026-78165, che dimostra la deserializzazione JDK non filtrata dei payload Redis PUBLISH in Apache Camel camel-spring-redis.
Reproduttore proof-of-concept eseguibile per la vulnerabilità di Apache Camel in cui camel-spring-redis, quando nessuna
opzione serializer è configurata, costruiva un JdkSerializationRedisSerializer nudo senza java.io.ObjectInputFilter
e lo utilizzava per ogni lettura. RedisConsumer.setBody lo applicava ai byte grezzi di ogni messaggio pubblicato sui
canali sottoscritti, prima che l'Exchange fosse costruito — quindi un attore in grado di emettere PUBLISH su un canale
sottoscritto raggiungeva direttamente il sink di deserializzazione e poteva eseguire il readObject di un grafo di oggetti
serializzati arbitrario (esecuzione di codice remoto, CWE-502). Lo stesso serializer predefinito era alla base dei comandi
di lettura del producer (GET/HGET/HGETALL/HVALS) e di SpringRedisIdempotentRepository.
| Runtime | Directory | Stack |
|---|---|---|
| Camel Spring Boot | camel-spring-boot/ | Spring Boot 3.5.13 + camel-spring-redis 4.22.0 (affetto; corretto in 4.22.1) |
| Camel Quarkus | camel-quarkus/ | Quarkus 3.29.0 + camel-quarkus-spring-redis 3.29.0 (Camel 4.15.0, affetto) |
Il difetto risale all'introduzione del componente nella 2.11.0, quindi ogni release affetta e il Camel 4.15.0 presente nell'ultima Camel Quarkus sono vulnerabili. La correzione è inclusa in Camel 4.18.5 / 4.22.1 / 4.23.0; il modulo Spring Boot esegue sia la build affetta (4.22.0) sia la build corretta (4.22.1). Nessuna release di Camel Quarkus include ancora un Camel corretto.
L'app esegue una route Camel che effettua SUBSCRIBE su cve-channel senza opzione serializer (quindi viene usato il
JdkSerializationRedisSerializer predefinito). L'attaccante è un semplice client Redis che può solo effettuare PUBLISH su quel
canale — non ha accesso al processo Camel. Pubblica i byte serializzati grezzi di un com.example.PwnMarker deliberatamente
benigno, il cui readObject si limita a invertire un flag globale della JVM (nessun gadget, nessun comando). Sulla build
affetta il consumer lo deserializza e readObject viene eseguito; sulla build corretta la allow-list predefinita (tipi
standard java./javax. e org.apache.camel.) rifiuta com.example.PwnMarker con
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
Output previsto sulla build interessata:
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.
| Proprietà | Valore |
|---|---|
| Componente | camel-spring-redis (camel-spring-redis-starter / camel-quarkus-spring-redis) |
| CWE | CWE-502 (Deserializzazione di dati non attendibili) |
| Gravità | ALTA |
| Vettore di attacco | PUBLISH verso un canale a cui è iscritto un consumer Camel spring-redis (oppure controllo di una chiave Redis letta dal producer); il serializer predefinito deserializza il payload senza alcun filtro |
| Impatto | Esecuzione di codice remoto all'interno del processo Camel tramite una classe gadget, prima che venga eseguita qualsiasi logica di route |
| Versioni interessate | Dalla 2.11.0 precedente alla 4.18.5, dalla 4.19.0 precedente alla 4.22.1 |
| Versioni corrette | 4.18.5, 4.22.1, 4.23.0 |
| JIRA | CAMEL-24421 |
| Credito | Leon Zlobecki |
Advisory: https://camel.apache.org/security/CVE-2026-78165.html
Una nuova opzione dell'endpoint deserializationFilter controlla il filtro applicato mentre il serializer predefinito legge
i payload. Quando non è impostata, viene rispettato il jdk.serialFilter a livello di JVM se presente, altrimenti viene applicata una allow-list
conservativa (tipi standard Java e Apache Camel; java.net negato), e su 4.23.0/4.22.1 vengono inoltre applicati i limiti
sulla forma del grafo di JEP-290. Il serializer viene costruito tramite il suo costruttore basato su Converter con un
converter di deserializzazione che imposta il filtro sullo stream prima che il grafo venga letto. Impostare serializer su un
RedisSerializer personalizzato aggira comunque il filtro, poiché Camel non controlla più come viene letto il payload.
Impostare il -Djdk.serialFilter=... a livello di JVM (il percorso interessato lo rispetta), oppure impostare l'opzione dell'endpoint serializer su
un serializer non Java come StringRedisSerializer (come opzione serializer, non solo su un
redisTemplate personalizzato). Richiedere l'autenticazione su Redis e limitare chi può pubblicare sui canali sottoscritti.
Questo repository è pubblicato per scopi educativi e difensivi: per aiutare gli utenti di Apache Camel a comprendere la vulnerabilità, verificare se sono interessati e confermare che l'aggiornamento la risolve. Il payload è un marker benigno che non esegue alcun codice. Non utilizzare questo materiale contro sistemi di cui non si è proprietari o gestori.