
Runnable proof-of-concept reproducer for CVE-2026-78165, demonstrating unfiltered JDK deserialization of Redis PUBLISH payloads in Apache Camel camel-spring-redis.
Runnable proof-of-concept reproducer for the Apache Camel vulnerability where camel-spring-redis, when no
serializer option is configured, built a bare JdkSerializationRedisSerializer with no java.io.ObjectInputFilter
and used it for every read. RedisConsumer.setBody applied it to the raw bytes of every message published to the
subscribed channels, before the Exchange was constructed — so an actor able to issue PUBLISH on a subscribed
channel reached the deserialization sink directly and could execute an arbitrary serialized object graph's
readObject (remote code execution, CWE-502). The same default serializer backed the producer read commands
(GET/HGET/HGETALL/HVALS) and SpringRedisIdempotentRepository.
| Runtime | Directory | Stack |
|---|---|---|
| Camel Spring Boot | camel-spring-boot/ | Spring Boot 3.5.13 + camel-spring-redis 4.22.0 (affected; fixed 4.22.1) |
| Camel Quarkus | camel-quarkus/ | Quarkus 3.29.0 + camel-quarkus-spring-redis 3.29.0 (Camel 4.15.0, affected) |
The defect dates back to the component's introduction in 2.11.0, so every affected release and the Camel 4.15.0 in the latest Camel Quarkus are vulnerable. The fix ships in Camel 4.18.5 / 4.22.1 / 4.23.0; the Spring Boot module runs both the affected build (4.22.0) and the fixed build (4.22.1). No released Camel Quarkus yet bundles a fixed Camel.
The app runs a Camel route that SUBSCRIBEs to cve-channel with no serializer option (so the default
JdkSerializationRedisSerializer is used). The attacker is a plain Redis client that can only PUBLISH to that
channel — it has no access to the Camel process. It publishes the raw serialized bytes of a deliberately benign
com.example.PwnMarker, whose readObject only flips a JVM-global flag (no gadget, no command). On the affected
build the consumer deserializes it and readObject runs; on the fixed build the default allow-list (standard
java./javax. and org.apache.camel. types) rejects com.example.PwnMarker with
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
Expected output on the affected build:
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.
| Property | Value |
|---|---|
| Component | camel-spring-redis (camel-spring-redis-starter / camel-quarkus-spring-redis) |
| CWE | CWE-502 (Deserialization of Untrusted Data) |
| Severity | HIGH |
| Attack vector | PUBLISH to a channel a Camel spring-redis consumer subscribes to (or control of a Redis key the producer reads); the default serializer deserializes the payload with no filter |
| Impact | Remote code execution inside the Camel process via a gadget class, before any route logic runs |
| Affected Versions | From 2.11.0 before 4.18.5, from 4.19.0 before 4.22.1 |
| Fixed Versions | 4.18.5, 4.22.1, 4.23.0 |
| JIRA | CAMEL-24421 |
| Credit | Leon Zlobecki |
Advisory: https://camel.apache.org/security/CVE-2026-78165.html
A new deserializationFilter endpoint option controls the filter applied while the default serializer reads
payloads. When unset, the JVM-wide jdk.serialFilter is honoured if present, otherwise a conservative allow-list
(standard Java and Apache Camel types; java.net denied) is applied, and on 4.23.0/4.22.1 the JEP-290 graph-shape
limits are additionally enforced. The serializer is constructed through its Converter-based constructor with a
deserializing converter that sets the filter on the stream before the graph is read. Setting serializer to a
custom RedisSerializer still bypasses the filter, since Camel then no longer controls how the payload is read.
Set the JVM-wide -Djdk.serialFilter=... (the affected path honours it), or set the serializer endpoint option to
a non-Java serializer such as StringRedisSerializer (as the serializer option, not only on a custom
redisTemplate). Require authentication on Redis and restrict who may publish to the subscribed channels.
This repository is published for educational and defensive purposes: to help Apache Camel users understand the vulnerability, verify whether they are affected, and confirm that upgrading resolves it. The payload is a benign marker that executes no code. Do not use this material against systems you do not own or operate.