This is an automated email from the ASF dual-hosted git repository.

gnodet pushed a commit to branch camel-4.18.x
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/camel-4.18.x by this push:
     new 6fbaa6bb67cc CAMEL-24655: camel-coap - guard case-insensitive header 
filtering, backport to camel-4.18.x (#26217)
6fbaa6bb67cc is described below

commit 6fbaa6bb67ccd2cc78afb983a570d34387dda870
Author: Claus Ibsen <[email protected]>
AuthorDate: Tue Sep 8 21:55:28 2026 +0200

    CAMEL-24655: camel-coap - guard case-insensitive header filtering, backport 
to camel-4.18.x (#26217)
    
    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.18.x.
    
    One adaptation was needed: CoAPTestSupport.PORT is a plain int on this
    branch, not an AvailablePortFinder.Port, so the route uses PORT rather
    than PORT.getPort(). Nothing else differs from the original.
    
    
    (cherry picked from commit e6e5621639a1e39540feb57d5f1b3687069ce565)
    
    Signed-off-by: Claus Ibsen <[email protected]>
    Co-authored-by: Andrea Cosentino <[email protected]>
    Co-authored-by: Claude Opus 5 <[email protected]>
---
 .../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..ec00df2fa1f4
--- /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)
+                        .to("mock:result")
+                        .setBody(constant("ok"));
+            }
+        };
+    }
+}

Reply via email to