Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-43866 — Reproducer for CVE-2026-43866 — Apache Camel camel-jms forged DefaultExchangeHolder bypass of the CVE-2026-40860 deserialization filter (Exchange-state injection) | Kitploit
Tools/GitHubGitHub/oscerd/cve-2026-43866
Vulnerability AnalysisCode AnalysisExploitationWeb Application ExploitationPenetration TestingLearning & Education
GitHuboscerd/cve-2026-43866

CVE-2026-43866

Reproducer for CVE-2026-43866 — Apache Camel camel-jms forged DefaultExchangeHolder bypass of the CVE-2026-40860 deserialization filter (Exchange-state injection)

View Repository
1 month agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

camel-jms Forged DefaultExchangeHolder Filter-Bypass Reproducer (CVE-2026-43866)

This project demonstrates CVE-2026-43866, a bypass of the CVE-2026-40860 fix in Apache Camel's camel-jms (and camel-sjms / JMS-family) components. CVE-2026-40860 added a post-deserialization class allow-list (java.**;javax.**;org.apache.camel.**;!*) to incoming JMS ObjectMessage payloads. But org.apache.camel.support.DefaultExchangeHolder lives in the allow-listed org.apache.camel.** namespace, so an ObjectMessage whose top-level object is a DefaultExchangeHolder passes the check. The receiving side then calls DefaultExchangeHolder.unmarshal() on it without requiring transferExchange — writing every non-null field of the holder into the routed Exchange (body, IN/OUT headers, exchange properties, variables, exchange id, exception). An attacker who can publish an ObjectMessage can thus inject arbitrary Exchange state using only universally-trusted java.* types — no deserialization gadget chain required — to manipulate routing, headers, properties and error handling.

Advisory: https://camel.apache.org/security/CVE-2026-43866.html

Vulnerability Summary

Technical Details

root@kitploit:~
// 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;
    }
}

The asymmetry: the sending side gates ObjectMessage/transferExchange creation, but the receiving side unmarshals any DefaultExchangeHolder it deserializes. The fix (4.14.8 / 4.18.3 / 4.21.0) adds a new objectMessageEnabled option (security = "insecure:serialization", default false) — an incoming ObjectMessage is no longer deserialized at all unless explicitly enabled, so a forged holder can never reach unmarshal(). (This is a breaking change for routes that rely on ObjectMessage / transferExchange.)

A JMS-provider allow-list does not help. This PoC configures the ActiveMQ client with a realistic, locked-down trustedPackages = [java, javax, org.apache.camel] — the org.apache.camel entry is exactly what a deployment using legitimate transferExchange must trust. The forged holder still passes, because it is itself a DefaultExchangeHolder whose fields are all trusted java.* types, indistinguishable from a legitimate one.

The victim route

root@kitploit:~
from("jms:queue:cve")                 // mapJmsMessage defaults to true; transferExchange NOT set
    .process(exchange -> { /* observes the injected body / headers / properties */ });

Repository layout — attacker vs. victim

The victim is the Camel JMS consumer. The attacker is any producer that can publish to the queue. Both talk to a real Apache ActiveMQ Artemis broker in Docker.

root@kitploit:~
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

Prerequisites

  • Java 17+ and Maven 3.8+
  • Docker (runs the broker and the app)

Reproduction Steps

Step 1: Build and start everything

root@kitploit:~
mvn clean package -DskipTests
docker compose up -d --build

Step 2: Trigger the bypass

root@kitploit:~
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

The route ran with a body, header and property it never set — all supplied by the attacker's forged holder.

Cleanup

root@kitploit:~
docker compose down

Attack Vectors

Any Camel JMS consumer (camel-jms, camel-sjms, camel-sjms2, camel-amqp, camel-activemq, camel-activemq6) with mapJmsMessage=true (the default), reading from a destination an attacker can publish to. transferExchange does not need to be enabled on the consumer.

Exploit Conditions

  1. A Camel JMS consumer with mapJmsMessage=true (default), on an affected version.
  2. The attacker can enqueue an ObjectMessage whose payload is a DefaultExchangeHolder.
  3. The JMS provider deserializes the payload — which, for any deployment using transferExchange, means the provider already trusts org.apache.camel. No gadget library is required.

Recommended Fix

Upgrade to 4.14.8 / 4.18.3 / 4.21.0 (CAMEL-23373 / CAMEL-23409). JMS ObjectMessage handling is disabled by default via the new objectMessageEnabled option; only enable it against destinations fed exclusively by trusted producers.

Mitigation

Until upgrading:

  1. Restrict publish access to Camel-consumed queues/topics to trusted producers via JMS broker authorization.
  2. Do not expose JMS consumers that map ObjectMessage bodies to untrusted networks.
  3. Note: a JMS-provider deserialization allow-list does not mitigate this specific bypass (the payload uses only universally-trusted classes plus DefaultExchangeHolder).

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.

Download Tool
PropertyValue
Componentscamel-jms (+ camel-sjms, camel-sjms2, camel-amqp, camel-activemq, camel-activemq6)
Affected Classorg.apache.camel.component.jms.JmsBinding#extractBodyFromJms → DefaultExchangeHolder.unmarshal
CWECWE-502 (Deserialization of Untrusted Data) + CWE-20 (Improper Input Validation)
ImpactExchange-state injection: attacker-controlled body, headers, properties, variables, exception
NatureBypass of the CVE-2026-40860 class-filter fix (not a flaw in it)
Affected VersionsFrom 3.0.0 before 4.14.8, from 4.15.0 before 4.18.3, from 4.19.0 before 4.21.0
Fixed Versions4.14.8, 4.18.3, 4.21.0
JIRACAMEL-23373 (jms), CAMEL-23409 (sjms)
Reportergaorenyusi