
Reproducer for CVE-2026-43865 — Apache Camel camel-hazelcast default-configured instance unsafe Java deserialization (RCE)
Este projeto demonstra uma vulnerabilidade de desserialização Java no componente camel-hazelcast do Apache Camel, registrada como CVE-2026-43865. Quando o Camel monta o Config do Hazelcast por conta própria – ou seja, quando nenhuma HazelcastInstance, hazelcastConfigUri ou bean Config fornecido pelo usuário é passado – ele não aplica nenhum filtro de desserialização Java (nem o JavaSerializationFilterConfig do Hazelcast nem um ObjectInputFilter do lado do Camel). Objetos que chegam pelo protocolo do cluster Hazelcast são desserializados dentro da camada de serialização do Hazelcast (ObjectInputStream.readObject) sem restrições de classe. Um atacante que consiga ingressar ou alcançar o cluster pode publicar um objeto serializado malicioso que será desserializado em todos os nós Camel — execução remota de código, presente por padrão e que não requer configuração opcional de endpoint.
Comunicado: https://camel.apache.org/security/CVE-2026-43865.html
Isso é distinto dos comunicados da biblioteca Hazelcast CVE-2016-10750 / CVE-2022-36418 (que tratam do código próprio do Hazelcast). Aqui a falha é que o Camel não aplica a proteção de desserialização que o Hazelcast oferece.
Quando nenhuma instância/configuração é fornecida, HazelcastDefaultComponent monta a instância a partir da configuração padrão e não define nenhum filtro de serialização:
// HazelcastDefaultComponent - afetado 4.18.2
if (hazelcastInstance == null && config == null) {
config = new XmlConfigBuilder().build();
config.getProperties().setProperty("hazelcast.version.check.enabled", "false");
config.getProperties().setProperty("hazelcast.phone.home.enabled", "false");
hzInstance = Hazelcast.newHazelcastInstance(config); // sem JavaSerializationFilterConfig
}
A correção insere um filtro padrão (lista branca java./javax./org.apache.camel., lista negra java.net.) nas instâncias que o Camel cria por conta própria, deixando Config/HazelcastInstance fornecidas pelo usuário inalteradas:
// corrigido 4.18.3 / 4.21.0
config.getProperties().setProperty("hazelcast.phone.home.enabled", "false");
HazelcastSerializationFilterHelper.applyDefault(config); // <-- adicionado
hzInstance = Hazelcast.newHazelcastInstance(config);
Qualquer estrutura que entregue o objeto desserializado ao Camel o aciona. Este PoC usa um consumidor de fila no modo Poll, onde IQueue.poll() desserializa o elemento cabeça antes que o Camel o roteie:
// HazelcastQueueConsumer (modo Poll) - afetado
final Object body = queue.poll(config.getPollingTimeout(), TimeUnit.MILLISECONDS); // readObject, sem filtro
exchange.getIn().setBody(body);
from("hazelcast-queue:cve?queueConsumerMode=Poll") // Camel monta a instância padrão (sem filtro)
.log("Consumido: ${body.class.name}");
A vítima é o nó Camel (um membro Hazelcast). O atacante é qualquer parte que consiga alcançar o cluster. Este PoC autocontido executa um cliente Hazelcast (o atacante) que ingressa no mesmo cluster de membro único (dev em 127.0.0.1:5701) e oferece um gadget à fila que a vítima consome.
CVE-2026-43865/
├── pom.xml # camel-hazelcast 4.18.2 + commons-collections 3.2.1 (gadget)
├── Dockerfile # executa o app (--add-opens para construção do gadget; endereço loopback do cluster)
├── docker-compose.yml
├── README.md
└── src/main/
├── java/com/example/
│ ├── Application.java
│ ├── VictimRoute.java # vítima: consumidor hazelcast-queue (instância padrão)
│ ├── Gadget.java # gadget CommonsCollections6, dispara durante a desserialização do Hazelcast
│ └── ExploitController.java # atacante: cliente Hazelcast oferece o gadget à fila
└── resources/
└── application.properties
Em um ataque real os bytes serializados são produzidos pelo próprio cliente/membro Hazelcast do atacante; apenas a vítima precisa da cadeia de gadget no seu classpath. Este PoC constrói o gadget in-process, razão pela qual a JVM é executada com
--add-opens java.base/java.util=ALL-UNNAMED— um detalhe de construção do gadget, não relacionado à vulnerabilidade.
mvn clean package -DskipTests
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack
# -> Gadget oferecido à fila hazelcast 'cve' como cliente do cluster.
# O queue.poll() do nó Camel o desserializou via Hazelcast (sem filtro).
#
# >>> Prova de RCE — /tmp/pwned existe: true
docker exec cve-2026-43865 ls -la /tmp/pwned
docker compose down
Qualquer rota Camel que use um consumidor hazelcast (hazelcast-topic, hazelcast-queue, hazelcast-seda, hazelcast-map, hazelcast-multimap, hazelcast-replicatedmap, hazelcast-list, hazelcast-set), ou o HazelcastAggregationRepository / HazelcastIdempotentRepository, sempre que a instância gerenciada for criada a partir da configuração padrão do Camel e um atacante puder alcançar o cluster.
HazelcastInstance, hazelcastConfigUri ou bean Config fornecida pelo usuário).commons-collections:3.2.1).Atualize para 4.14.8 / 4.18.3 / 4.21.0 (CAMEL-23414), que aplica um JavaSerializationFilterConfig padrão do Hazelcast às instâncias que o Camel cria a partir de sua própria configuração padrão.
Até atualizar:
JavaSerializationFilterConfig, ou o JVM-wide -Djdk.serialFilter=!java.net.**;java.**;javax.**;org.apache.camel.**;!*).Este reprodutor é fornecido apenas para pesquisa de segurança e testes autorizados, para uma vulnerabilidade divulgada publicamente e corrigida. Não o use contra sistemas sem permissão explícita.
| Propriedade | Valor |
|---|
| Componente | camel-hazelcast (qualquer consumidor + HazelcastAggregationRepository / HazelcastIdempotentRepository) |
| Classe Afetada | org.apache.camel.component.hazelcast.HazelcastDefaultComponent (criação de instância com configuração padrão) |
| CWE | CWE-502: Desserialização de Dados Não Confiáveis |
| Impacto | Execução Remota de Código (RCE) em cada nó Camel do cluster |
| Gatilho | Um consumidor/repositório hazelcast cuja instância gerenciada é criada a partir da configuração padrão do Camel |
| Versões Afetadas | De 4.0.0 anterior a 4.14.8, de 4.15.0 anterior a 4.18.3, de 4.19.0 anterior a 4.21.0 |
| Versões Corrigidas | 4.14.8, 4.18.3, 4.21.0 |
| JIRA | CAMEL-23414 |
| Relator | gaorenyusi |