VYPR
Moderate severityNVD Advisory· Published Mar 12, 2025· Updated Mar 19, 2025

Apache Camel: Camel Message Header Injection through request parameters

CVE-2025-29891

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.

PackageAffected versionsPatched versions
org.apache.camel:camel-supportMaven
>= 3.10.0, < 3.22.43.22.4
org.apache.camel:camel-supportMaven
>= 4.9.0, < 4.10.24.10.2
org.apache.camel:camel-supportMaven
>= 4.0.0-M1, < 4.8.54.8.5

Affected products

3

Patches

2
45a6b74f7f8a

CAMEL-21828: Fix DefaultHeaderFilterStrategy when filtering in lower-case mode (#17362)

https://github.com/apache/camelClaus IbsenMar 5, 2025via ghsa
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;
                 }
    
23a833eec613

CAMEL-21828: Fix DefaultHeaderFilterStrategy when filtering in lower-case mode. (#17351)

https://github.com/apache/camelClaus IbsenMar 4, 2025via ghsa
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

News mentions

0

No linked articles in our index yet.