Apache Camel: Camel Message Header Injection through request parameters
Description
Bypass/Injection vulnerability in Apache Camel.
This issue affects Apache Camel: from 4.10.0 before 4.10.2, from 4.8.0 before 4.8.5, from 3.10.0 before 3.22.4.
Users are recommended to upgrade to version 4.10.2 for 4.10.x LTS, 4.8.5 for 4.8.x LTS and 3.22.4 for 3.x releases.
This vulnerability is present in Camel's default incoming header filter, that allows an attacker to include Camel specific headers that for some Camel components can alter the behaviours such as the camel-bean component, or the camel-exec component.
If you have Camel applications that are directly connected to the internet via HTTP, then an attacker could include parameters in the HTTP requests that are sent to the Camel application that get translated into headers.
The headers could be both provided as request parameters for an HTTP methods invocation or as part of the payload of the HTTP methods invocation.
All the known Camel HTTP component such as camel-servlet, camel-jetty, camel-undertow, camel-platform-http, and camel-netty-http would be vulnerable out of the box.
This CVE is related to the CVE-2025-27636: while they have the same root cause and are fixed with the same fix, CVE-2025-27636 was assumed to only be exploitable if an attacker could add malicious HTTP headers, while we have now determined that it is also exploitable via HTTP parameters. Like in CVE-2025-27636, exploitation is only possible if the Camel route uses particular vulnerable components.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Apache Camel's default header filter allows injection via HTTP parameters, leading to potential manipulation of route behavior in vulnerable components.
CVE-2025-29891 is a bypass/injection vulnerability in Apache Camel's default incoming HTTP header filter (DefaultHeaderFilterStrategy). The filter fails to properly sanitize Camel-specific headers when they are provided as HTTP parameters, not just as regular headers. This allows an attacker to inject Camel headers such as those affecting the camel-bean or camel-exec components [1].
Exploitation requires the Camel application to be reachable via HTTP, with any of the standard Camel HTTP components (camel-servlet, camel-jetty, camel-undertow, camel-platform-http, camel-netty-http) being vulnerable out of the box. The attacker can include malicious Camel headers either as request parameters or within the payload of an HTTP request [1].
By injecting a crafted Camel header, an attacker can alter the behavior of Camel routes that use vulnerable components like camel-bean, potentially leading to arbitrary method invocation or command execution. This CVE expands on CVE-2025-27636, which was previously thought to only be exploitable via HTTP headers, but is now known to also be exploitable via HTTP parameters [1].
Apache has fixed the issue in DefaultHeaderFilterStrategy via commit 23a833e [2] and users are advised to upgrade to Apache Camel 4.10.2, 4.8.5, or 3.22.4, depending on their version line [1].
AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.apache.camel:camel-supportMaven | >= 3.10.0, < 3.22.4 | 3.22.4 |
org.apache.camel:camel-supportMaven | >= 4.9.0, < 4.10.2 | 4.10.2 |
org.apache.camel:camel-supportMaven | >= 4.0.0-M1, < 4.8.5 | 4.8.5 |
Affected products
3- Range: 4.10.0
Patches
245a6b74f7f8aCAMEL-21828: Fix DefaultHeaderFilterStrategy when filtering in lower-case mode (#17362)
3 files changed · +97 −0
components/camel-platform-http/src/test/java/org/apache/camel/component/platform/http/PlatformHttpCamelHeadersTest.java+60 −0 added@@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.platform.http; + +import org.apache.camel.Exchange; +import org.apache.camel.builder.RouteBuilder; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import static io.restassured.RestAssured.given; + +public class PlatformHttpCamelHeadersTest extends AbstractPlatformHttpTest { + + @Test + void testFilterCamelHeaders() { + given() + .header("Accept", "application/json") + .header("User-Agent", "User-Agent-Camel") + .header("caMElHttpResponseCode", "503") + .port(port) + .expect() + .statusCode(200) + .header("Accept", (String) null) + .header("User-Agent", (String) null) + .header("CamelHttpResponseCode", (String) null) + .when() + .get("/get"); + } + + @Override + protected RouteBuilder routes() { + return new RouteBuilder() { + @Override + public void configure() { + from("platform-http:/get") + .process(e -> { + Assertions.assertEquals("application/json", e.getMessage().getHeader("Accept")); + Assertions.assertEquals("User-Agent-Camel", e.getMessage().getHeader("User-Agent")); + Assertions.assertNull(e.getMessage().getHeader(Exchange.HTTP_RESPONSE_CODE)); + }) + .setBody().constant(""); + } + }; + } + +}
core/camel-core/src/test/java/org/apache/camel/impl/DefaultHeaderFilterStrategyTest.java+23 −0 modified@@ -25,6 +25,7 @@ import org.apache.camel.support.DefaultHeaderFilterStrategy; import org.junit.jupiter.api.Test; +import static org.apache.camel.support.DefaultHeaderFilterStrategy.CAMEL_FILTER_PATTERN; import static org.apache.camel.support.DefaultHeaderFilterStrategy.CAMEL_FILTER_STARTS_WITH; import static org.junit.jupiter.api.Assertions.*; @@ -175,4 +176,26 @@ public void testInStartsWith() { assertTrue(comp.applyFilterToExternalHeaders("org.apache.camel.component.jetty.session", "true", exchange)); } + @Test + public void testInStartsWithLowerCase() { + DefaultHeaderFilterStrategy comp = new DefaultHeaderFilterStrategy(); + comp.setLowerCase(true); + + comp.setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH); + + Exchange exchange = new DefaultExchange(context); + exchange.getIn().setHeader("bar", 123); + exchange.getIn().setHeader("foo", "cheese"); + exchange.getIn().setHeader("caMElVersion", "3.7"); + exchange.getIn().setHeader("org.apache.CAMEL.component.jetty.session", "true"); + + assertTrue(comp.applyFilterToExternalHeaders("caMElVersion", 123, exchange)); + assertTrue(comp.applyFilterToExternalHeaders("cAmelResponseCode", 503, exchange)); + + assertFalse(comp.applyFilterToExternalHeaders("bar", 123, exchange)); + assertFalse(comp.applyFilterToExternalHeaders("foo", "cheese", exchange)); + assertTrue(comp.applyFilterToExternalHeaders("CamelVersion", "3.7", exchange)); + assertTrue(comp.applyFilterToExternalHeaders("org.apache.camel.component.jetty.session", "true", exchange)); + } + }
core/camel-support/src/main/java/org/apache/camel/support/DefaultHeaderFilterStrategy.java+14 −0 modified@@ -314,6 +314,13 @@ private boolean doFiltering(Direction direction, String headerName, Object heade if (match) { return filterOnMatch; } + if (isLowerCase()) { + String lower = headerName.toLowerCase(Locale.ENGLISH); + match = lower.startsWith(s); + if (match) { + return filterOnMatch; + } + } } } @@ -325,6 +332,13 @@ private boolean doFiltering(Direction direction, String headerName, Object heade if (match) { return filterOnMatch; } + if (isLowerCase()) { + String lower = headerName.toLowerCase(Locale.ENGLISH); + match = lower.startsWith("camel") || lower.startsWith("org.apache.camel."); + if (match) { + return true; + } + } } else if (pattern.matcher(headerName).matches()) { return filterOnMatch; }
23a833eec613CAMEL-21828: Fix DefaultHeaderFilterStrategy when filtering in lower-case mode. (#17351)
3 files changed · +107 −7
components/camel-platform-http/src/test/java/org/apache/camel/component/platform/http/PlatformHttpCamelHeadersTest.java+60 −0 added@@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.platform.http; + +import org.apache.camel.Exchange; +import org.apache.camel.builder.RouteBuilder; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import static io.restassured.RestAssured.given; + +public class PlatformHttpCamelHeadersTest extends AbstractPlatformHttpTest { + + @Test + void testFilterCamelHeaders() { + given() + .header("Accept", "application/json") + .header("User-Agent", "User-Agent-Camel") + .header("caMElHttpResponseCode", "503") + .port(port) + .expect() + .statusCode(200) + .header("Accept", (String) null) + .header("User-Agent", (String) null) + .header("CamelHttpResponseCode", (String) null) + .when() + .get("/get"); + } + + @Override + protected RouteBuilder routes() { + return new RouteBuilder() { + @Override + public void configure() { + from("platform-http:/get") + .process(e -> { + Assertions.assertEquals("application/json", e.getMessage().getHeader("Accept")); + Assertions.assertEquals("User-Agent-Camel", e.getMessage().getHeader("User-Agent")); + Assertions.assertNull(e.getMessage().getHeader(Exchange.HTTP_RESPONSE_CODE)); + }) + .setBody().constant(""); + } + }; + } + +}
core/camel-core/src/test/java/org/apache/camel/impl/DefaultHeaderFilterStrategyTest.java+22 −0 modified@@ -175,4 +175,26 @@ public void testInStartsWith() { assertTrue(comp.applyFilterToExternalHeaders("org.apache.camel.component.jetty.session", "true", exchange)); } + @Test + public void testInStartsWithLowerCase() { + DefaultHeaderFilterStrategy comp = new DefaultHeaderFilterStrategy(); + comp.setLowerCase(true); + + comp.setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH); + + Exchange exchange = new DefaultExchange(context); + exchange.getIn().setHeader("bar", 123); + exchange.getIn().setHeader("foo", "cheese"); + exchange.getIn().setHeader("caMElVersion", "3.7"); + exchange.getIn().setHeader("org.apache.CAMEL.component.jetty.session", "true"); + + assertTrue(comp.applyFilterToExternalHeaders("caMElVersion", 123, exchange)); + assertTrue(comp.applyFilterToExternalHeaders("cAmelResponseCode", 503, exchange)); + + assertFalse(comp.applyFilterToExternalHeaders("bar", 123, exchange)); + assertFalse(comp.applyFilterToExternalHeaders("foo", "cheese", exchange)); + assertTrue(comp.applyFilterToExternalHeaders("CamelVersion", "3.7", exchange)); + assertTrue(comp.applyFilterToExternalHeaders("org.apache.camel.component.jetty.session", "true", exchange)); + } + }
core/camel-support/src/main/java/org/apache/camel/support/DefaultHeaderFilterStrategy.java+25 −7 modified@@ -17,7 +17,6 @@ package org.apache.camel.support; import java.util.HashSet; -import java.util.Locale; import java.util.Set; import java.util.regex.Pattern; @@ -344,35 +343,52 @@ private boolean doFiltering(Direction direction, String headerName, Object heade startsWith = inFilterStartsWith; } + String lower = null; + if (startsWith != null) { if (tryHeaderMatch(headerName, startsWith)) { return filterOnMatch; } + if (lowerCase) { + lower = headerName.toLowerCase(); + if (tryHeaderMatch(lower, startsWith)) { + return filterOnMatch; + } + } } if (pattern != null) { - if (tryPattern(headerName, pattern)) { + if (tryPattern(headerName, lower, pattern)) { return filterOnMatch; } } if (filter != null) { - if (evalFilterMatch(headerName, filter)) { + if (evalFilterMatch(headerName, lower, filter)) { return filterOnMatch; } } return extendedFilter(direction, headerName, headerValue, exchange); } - private boolean tryPattern(String headerName, Pattern pattern) { + private boolean tryPattern(String headerName, String lower, Pattern pattern) { // optimize if its the default pattern as we know the pattern is to check for keys starting with Camel if (pattern == CAMEL_FILTER_PATTERN) { boolean match = headerName.startsWith("Camel") || headerName.startsWith("camel") || headerName.startsWith("org.apache.camel."); if (match) { return true; } + if (lowerCase) { + if (lower == null) { + lower = headerName.toLowerCase(); + } + match = lower.startsWith("camel") || lower.startsWith("org.apache.camel."); + if (match) { + return true; + } + } } else if (pattern.matcher(headerName).matches()) { return true; } @@ -389,15 +405,17 @@ private boolean tryHeaderMatch(String headerName, String[] startsWith) { return false; } - private boolean evalFilterMatch(String headerName, Set<String> filter) { + private boolean evalFilterMatch(String headerName, String lower, Set<String> filter) { if (isCaseInsensitive()) { for (String filterString : filter) { if (filterString.equalsIgnoreCase(headerName)) { return true; } } - } else if (isLowerCase()) { - String lower = headerName.toLowerCase(Locale.ENGLISH); + } else if (lowerCase) { + if (lower == null) { + lower = headerName.toLowerCase(); + } if (filter.contains(lower)) { return true; }
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
7- camel.apache.org/security/CVE-2025-29891.htmlghsavendor-advisoryWEB
- github.com/advisories/GHSA-96v5-c2h5-56hmghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-29891ghsaADVISORY
- camel.apache.org/security/CVE-2025-27636.htmlghsarelatedWEB
- github.com/apache/camel/commit/23a833eec6131a3cdce6e4b1b40b3ac2035b6adfghsaWEB
- github.com/apache/camel/commit/45a6b74f7f8af8fd58f197566938a9534392a624ghsaWEB
- issues.apache.org/jira/browse/CAMEL-21828ghsaWEB
News mentions
0No linked articles in our index yet.