Apache Camel inbound header-to-Exchange mapping and deserialization wave¶
Date reviewed: 2026-08-27
Advisories: the July 6 Camel CVE wave plus the JMS ObjectMessage deserialization advisory
Severity: Critical and High (multiple CVSS 9.x)
Boundary class: inbound transport headers → Exchange property mapping without HeaderFilterStrategy; unsafe Java/ObjectInputStream deserialization in several Camel components
What is durable here¶
This is a multi-component Camel wave with one recurring trust-boundary pattern that is worth generalizing for any Camel route audit:
Inbound transport headers are mapped into the Exchange without a HeaderFilterStrategy. When a Camel endpoint receives untrusted inbound messages (HTTP, JMS, AMQP, SNS, CometD/Bayeux, Vertx-HTTP, Netty-HTTP, Elasticsearch-REST), the transport's native headers are copied into Exchange properties. If the route (or a default filter that is absent) does not strip headers outside the Camel- namespace, an attacker who controls inbound headers can:
- inject
Camel-*headers that downstream components treat as routing/instruction material (SSRF viaCamelHttpUri, header-based endpoint reselection, expression injection), - reach components that deserialize Exchange property values with
java.io.ObjectInputStream(JMSObjectMessage, Vertx-HTTP / Netty-HTTP response bodies, Hazelcast managed instances, PQC AWS Secrets Manager key metadata), - bypass the default
ObjectInputFilterwhere the default pattern is permissive enough to admitjava.net.**(enables DNS-based disclosure / OOB exfiltration even where full gadget chains are not available).
The individual advisories in this wave:
| Advisory | Component | Boundary |
|---|---|---|
| GHSA-r9cc-j7wr-p329 / CVE-2026-46454 | camel-cometd | Inbound Bayeux message headers mapped into the Exchange without a HeaderFilterStrategy |
| GHSA-m5vh-3fw5-5wgh / CVE-2026-40860 | camel-jms / sjms / sjms2 / amqp | Unsafe deserialization of JMS ObjectMessage |
| GHSA-rp9m-hfv5-pfvr / CVE-2026-46453 | camel-elasticsearch-rest-client | Exchange header constants without the Camel prefix bypass inbound HTTP header filtering |
| GHSA-f755-xp6r-8q84 / CVE-2026-40860, CVE-2026-43866 | camel-jms | JMS deserialization filter bypass |
| GHSA-xww8-mxqw-m84w / CVE-2026-43865 | camel-hazelcast | Unsafe Java deserialization in default-configured managed Hazelcast instances |
| GHSA-6qw3-4796-5984 / CVE-2026-40859 | camel-vertx-http / camel-netty-http | Unsafe Java deserialization of HTTP response bodies via raw ObjectInputStream |
| GHSA-w2v8-8q6c-3rhr / CVE-2026-46456, CVE-2026-56140 | camel-aws2-sns | Inbound Camel-namespace filter added to Sns2HeaderFilterStrategy (prior versions did not strip) |
| GHSA-7cmx-qjh8-7v3v / CVE-2026-40048, CVE-2026-43867, CVE-2026-46590 | camel-pqc | AWS Secrets Manager key-lifecycle manager deserializes persisted key metadata with java.io.ObjectInputStream |
| GHSA-rpv3-6645-2vqc / CVE-2026-40047 | camel-docling | Insufficient validation of custom CLI arguments enables argument injection and path traversal |
| GHSA-8h6p-jvhf-9hcr / CVE-2026-42527 | camel (core) | Permissive default ObjectInputFilter pattern admits java.net.** (DNS-based disclosure) |
Recon: enumerate Camel endpoints and header flows¶
- Find the Camel version. The July 6 wave is the most recent CVE publication batch; the JMS
ObjectMessagedeserialization advisory (GHSA-m5vh-3fw5-5wgh) was published earlier. Checkcamel-core, the transport components in use (camel-vertx-http,camel-netty-http,camel-jms,camel-amqp,camel-cometd,camel-hazelcast,camel-aws2-sns,camel-docling,camel-elasticsearch-rest-client), andcamel-pqc. - Map inbound endpoints. For each
from()that accepts untrusted inbound messages, note which transport is used and whether aHeaderFilterStrategy(orCamelHttpUri-style filtering) is registered on that endpoint or globally. - Check the default
ObjectInputFilter. If the Camel version predates the filter fix, the default pattern admitsjava.net.**. Even without a full deserialization gadget chain, an attacker who can control an Exchange property value that reaches aObjectInputStreamcan trigger DNS lookouts (OOB disclosure / exfiltration of the serialized payload's reachable state). - Identify the
ObjectMessagepath. If the route usescamel-jms/camel-amqpwithObjectMessagesupport and the deserialization filter is absent or bypassable (the JMS filter bypass advisory), a JMS broker that accepts attacker-controlledObjectMessagepayloads is a direct RCE primitive.
Validation workflow (authorized lab / customer-approved)¶
Header-injection proof (no code execution)¶
- Identify an inbound HTTP endpoint that maps to a Camel route with no
HeaderFilterStrategy. - Send a request with a benign
Camel-namespaced header, e.g.Camel-Test-Trace: skillz-canary. If the header appears in the Exchange (visible in route logs, a downstream HTTP request'sCamel-Test-Traceheader, or a route that echoes Exchange properties), the mapping is unfiltered. - Record the route and the specific header that crossed. Do not use
CamelHttpUrior other instruction headers that would cause SSRF / endpoint reselection during the proof.
Deserialization-boundary proof (no code execution)¶
- Confirm the component is present and the deserialization path is reachable (e.g. a JMS
ObjectMessageconsumer, a Vertx-HTTP response-body deserialization, a Hazelcast managed instance). - Do not send a gadget-chain payload. The proof is that the deserialization sink is reachable with attacker-controlled bytes. Record the component, the Exchange property that carries the bytes, and the route.
- If a permissive
ObjectInputFilteris present, a DNS-lookup canary (a serializedjava.net.InetAddress-adjacent object that triggers an outbound DNS query to an owned domain) is acceptable OOB evidence. Do not use it to exfiltrate data.
Negative evidence¶
- A
400/403on the inbound endpoint, or the absence of the attacker header in the Exchange, is negative evidence. - If the
HeaderFilterStrategyis present but the route still deserializes, the finding moves from "header injection" to "deserialization boundary" and the proof changes accordingly.
Reporting heuristic¶
- Lead with the specific transport and route that maps untrusted headers into the Exchange without filtering. The generic "Camel header injection" framing is not useful; the value is the route map.
- State the Camel version and the components in use. The advisory range is component-specific.
- Separate "header injection" (routing / instruction) from "deserialization boundary" (RCE primitive). They are different findings with different proofs.
- Do not publish gadget-chain payloads. The proof is the reachable sink + the unfiltered header mapping.
Safety constraints¶
- Do not execute arbitrary code on the target.
- Do not use
CamelHttpUrior similar instruction headers to redirect traffic during the proof. - Use owned DNS callback domains only for OOB disclosure.
- Do not test against production JMS brokers or Hazelcast instances with live data.
August 29 follow-up: Camel header-filter bypass wave (30 GHSAs)¶
The Aug 29 GitHub updated-feed wave adds 30 more Apache Camel advisories in the same bug class: inbound message/transport headers mapped into the Exchange without a HeaderFilterStrategy, or component-specific Exchange-header constants whose names do not carry the Camel- prefix that the default HTTP header filter strips. Same operator pattern, more sink sites.
Sub-patterns in the wave¶
- Non-Camel-prefixed component header constants bypass the HTTP filter. A large group of components define Exchange-header constants with un-prefixed names (
kafka.OVERRIDE_TOPIC,irc.sendTo,QUERY/RETURN_LUCENE_DOCS,SolrParam.*/SolrField.*,operationName/operationNamespace,mail.smtp.*, Salesforce/JIRA/Neo4j property names). An HTTP client that can reach the consumer endpoint can inject these directly. - Critical — Solr (GHSA-4h4f-v54q-7pq8 / CVE-2026-48203): injected
SolrParam.*headers are server-side request forgery into Solr query parameters;SolrField.*injects document fields. - Critical — AWS2-SQS (GHSA-cmc3-hr79-8mmv / CVE-2026-46456): inbound SQS message attributes map into the Exchange unfiltered — a message sender can inject Camel control headers.
- Critical — Keycloak (GHSA-mqwc-6qwc-v9gq / CVE-2026-46455): the access-token validity window is not verified because the
IS_ACTIVEcheck is missing from theTokenVerifier— expired tokens are accepted. - Critical — Undertow / Atmosphere-Websocket (GHSA-v7h8-xhh6-gfj4 / CVE-2026-78329, GHSA-m5r8-w65q-8wjf / CVE-2026-71300): the endpoint discards the component-specific header filter entirely; websocket dispatch headers are injected.
- High: Lucene full-text query injection (GHSA-566h-v38h-3xp3 / CVE-2026-46585), Neo4j Cypher injection via
CamelNeo4jMatchPropertiesproperty names — incomplete remediation of CVE-2025-66169 (GHSA-q86m-qjpm-vqcw / CVE-2026-46591), CXF SOAP operation-redirect (GHSA-mrrp-9gjm-749v / CVE-2026-46592), Couchbase/CouchDB operation override (GHSA-46jf-c9vx-hh79 / CVE-2026-46587, GHSA-5g68-f6xg-vf2r / CVE-2026-46588), Langchain4j tool-argument headers not filtered against declared parameters (GHSA-hh8r-75r6-qrg9 / CVE-2026-49042), NATS/Iggy/Vertx-Websocket/Atmosphere-Websocket inbound mapping without any filter strategy (GHSA-7v55-q9x3-83cj / CVE-2026-46457, GHSA-pw9q-pq7c-rfqw / CVE-2026-55994, GHSA-hgg5-gp4c-gpcg / CVE-2026-46726, GHSA-rcvm-6r79-cf4r / CVE-2026-55993). - Medium: Kafka topic override (GHSA-mm84-qvjh-hcj7 / CVE-2026-49098), IRC
irc.sendTo(GHSA-463m-2hr2-q2j7 / CVE-2026-49097), Salesforce (GHSA-gcc7-c8mp-34qx / CVE-2026-49099), JIRA constants (GHSA-64gv-6cq2-45jr / CVE-2026-48206), Dapr Pub/Sub CloudEvent name/topic copied into producer routing headers (GHSA-583r-f84w-33g7 / CVE-2026-49086), Knative CloudEvent extension fields mapped without filter (GHSA-vvwm-3j43-7pfm / CVE-2026-63621). - Inbound header/attribute mapping without any
HeaderFilterStrategyat the transport boundary — the same header-injection primitive as the original wave, now documented for NATS, Iggy, SQS, Atmosphere, and Vertx-Websocket consumers. - File-download path construction from remote object names.
Google-Storageappends the remote object name to the local download path without sanitization (GHSA-f78g-9385-qxqj / CVE-2026-66907);Azure-Storage-BlobdownloadBlobToFilebuilds the local path from the blob name (GHSA-2x37-89hj-2j95 / CVE-2026-66906, critical);Azure-Storage-DataLakedownloadToFilethe same (GHSA-7jwc-q3fj-c9pq / CVE-2026-60093). Same class as the original wave's filename-to-local-path entries: remote metadata → local filesystem write path. muteExceptiondefaulting to false leaks full stack traces in Netty-HTTP (GHSA-42q5-xw42-xf9g / CVE-2026-49365) and Undertow (GHSA-hjg2-f45w-c566 / CVE-2026-56139) consumers. Availability/low-value on its own; pair with header-injection findings when the same route is in scope.- Mail
mail.smtp.*header injection — the mail producer applies attacker-suppliedmail.smtp.*/mail.smtps.*headers as JavaMail session properties (GHSA-29vj-9mgp-mwp2 / CVE-2026-46584); the MimeMultipart data format copies MIME headers onto the Camel message whenheadersInlineis enabled (GHSA-cx47-qxp5-mmh2 / CVE-2026-59230). - PQC key-lifecycle manager (GHSA-857v-xvh8-7hjc / CVE-2026-46590): HashiCorp Vault and AWS Secrets Manager key-lifecycle management headers cross into key operations — treat as a key-management authority boundary, not generic header injection.
Durable pattern (unchanged from the original wave)¶
For any Camel route that consumes an inbound message:
- enumerate the component's Exchange-header constants and check whether each is
Camel--prefixed; - check whether a
HeaderFilterStrategyis configured and whether the endpoint's own filter is applied (two Camel endpoints in this wave discarded the component-specific filter entirely); - for file-download components, test remote object names with path-separator and traversal markers (stop at denied/normalized-path evidence on a disposable root).
Validation deltas from the original workflow¶
- Solr SSRF: send a canary
SolrParam.*header that steers the query to an owned Solr/HTTP endpoint; evidence is the query parameter landing in the outbound request, not document mutation. - Neo4j Cypher injection: property-name canary that reaches the
WHEREclause; capture the rendered Cypher in a read-only lab Neo4j, noCALL/write procedures. - Keycloak token expiry: mint a synthetic access token, let it expire, present it through a Camel route with Camel-Keycloak auth; positive = route accepts the expired token (
IS_ACTIVEcheck missing). Lab realm only. - CloudEvent routing (Dapr/Knative): inject a canary pub/sub name or extension field and observe producer-direction routing header propagation; stop at header-propagation evidence.
Sources¶
- Aug 29 follow-up: the 30 GHSAs listed inline above, each linked in the GitHub Advisory Database.
- Original wave context: the July 6 Apache Camel CVE wave and the JMS
ObjectMessagedeserialization advisory covered by this page's header.