You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2026/09/08 18:14:08 UTC
(camel) branch backport/26208-to-camel-4.22.x created (now c88203dd160f)
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a change to branch backport/26208-to-camel-4.22.x
in repository https://gitbox.apache.org/repos/asf/camel.git
at c88203dd160f CAMEL-24655: camel-coap - guard case-insensitive header filtering
This branch includes the following new commits:
new c88203dd160f CAMEL-24655: camel-coap - guard case-insensitive header filtering
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
(camel) 01/01: CAMEL-24655: camel-coap - guard case-insensitive header filtering
Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch backport/26208-to-camel-4.22.x
in repository https://gitbox.apache.org/repos/asf/camel.git
commit c88203dd160f9ec0f5d61d9cc1c698db35a60f8a
Author: Andrea Cosentino <an...@gmail.com>
AuthorDate: Tue Sep 8 20:11:24 2026 +0200
CAMEL-24655: camel-coap - guard case-insensitive header filtering
The CoAP consumer maps the URI query parameters of an incoming request
into Exchange headers, running each through the endpoint
HeaderFilterStrategy first. The default strategy filters names starting
with Camel/camel case-insensitively, so a remote peer cannot set Camel
internal headers that steer downstream processing. That behaviour was
correct but untested, so a refactoring of the consumer could silently
drop it - the exact regression the CVE-2025-27636 family was about.
Adds CoAPHeaderInjectionTest: sends requests carrying a Camel internal
header name as a URI query parameter in four casings and asserts it is
never mapped onto the Exchange, while an ordinary query parameter still
is. Verified to fail when the filter call in CamelCoapResource is
removed. Test-only; no production code is modified.
Backport of #26208 to camel-4.22.x.
Co-authored-by: Claude Opus 5 <no...@anthropic.com>
(cherry picked from commit e6e5621639a1e39540feb57d5f1b3687069ce565)
Signed-off-by: Claus Ibsen <cl...@gmail.com>
---
.../apache/camel/coap/CoAPHeaderInjectionTest.java | 83 ++++++++++++++++++++++
1 file changed, 83 insertions(+)
diff --git a/components/camel-coap/src/test/java/org/apache/camel/coap/CoAPHeaderInjectionTest.java b/components/camel-coap/src/test/java/org/apache/camel/coap/CoAPHeaderInjectionTest.java
new file mode 100644
index 000000000000..82a14c81ad15
--- /dev/null
+++ b/components/camel-coap/src/test/java/org/apache/camel/coap/CoAPHeaderInjectionTest.java
@@ -0,0 +1,83 @@
+/*
+ * 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.coap;
+
+import java.util.List;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.eclipse.californium.core.CoapClient;
+import org.eclipse.californium.core.coap.MediaTypeRegistry;
+import org.eclipse.californium.core.coap.Request;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+/**
+ * The CoAP consumer maps URI query parameters of an incoming request into Exchange headers. A remote peer must not be
+ * able to use that to set Camel internal headers, whatever casing it uses, as those steer downstream processing (bean
+ * method dispatch, file names, and so on).
+ */
+public class CoAPHeaderInjectionTest extends CoAPTestSupport {
+
+ private static final String[] CAMEL_HEADER_VARIANTS = {
+ "CamelBeanMethodName", "camelBeanMethodName", "caMELBeanMethodName", "CAMELBEANMETHODNAME" };
+
+ @Test
+ void camelHeadersInUriQueryAreFilteredRegardlessOfCase() throws Exception {
+ MockEndpoint mock = getMockEndpoint("mock:result");
+ mock.expectedMessageCount(CAMEL_HEADER_VARIANTS.length);
+
+ CoapClient client = createClient("/TestResource");
+ for (String variant : CAMEL_HEADER_VARIANTS) {
+ Request request = Request.newPost();
+ request.setURI(client.getURI() + "?" + variant + "=malicious&normalParam=value");
+ request.setPayload("test");
+ request.getOptions().setContentFormat(MediaTypeRegistry.TEXT_PLAIN);
+ assertNotNull(client.advanced(request), "no CoAP response received for variant " + variant);
+ }
+
+ MockEndpoint.assertIsSatisfied(context);
+
+ List<Exchange> received = mock.getReceivedExchanges();
+ for (int i = 0; i < CAMEL_HEADER_VARIANTS.length; i++) {
+ String variant = CAMEL_HEADER_VARIANTS[i];
+ Message in = received.get(i).getIn();
+ // the Camel header map is case-insensitive, so this lookup also catches the other spellings
+ assertNull(in.getHeader(variant),
+ "a Camel internal header must not be injectable through a CoAP URI query parameter: " + variant);
+ assertEquals("value", in.getHeader("normalParam", String.class),
+ "a non-Camel query parameter must still be mapped to a header");
+ }
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() {
+ return new RouteBuilder() {
+ @Override
+ public void configure() {
+ fromF("coap://localhost:%d/TestResource", PORT.getPort())
+ .to("mock:result")
+ .setBody(constant("ok"));
+ }
+ };
+ }
+}