diff --git a/components/camel-aws/camel-aws2-sns/src/main/java/org/apache/camel/component/aws2/sns/Sns2HeaderFilterStrategy.java b/components/camel-aws/camel-aws2-sns/src/main/java/org/apache/camel/component/aws2/sns/Sns2HeaderFilterStrategy.java index fe85840d9ae9c..4ca1c14db9a02 100644 --- a/components/camel-aws/camel-aws2-sns/src/main/java/org/apache/camel/component/aws2/sns/Sns2HeaderFilterStrategy.java +++ b/components/camel-aws/camel-aws2-sns/src/main/java/org/apache/camel/component/aws2/sns/Sns2HeaderFilterStrategy.java @@ -19,15 +19,12 @@ import org.apache.camel.support.DefaultHeaderFilterStrategy; public class Sns2HeaderFilterStrategy extends DefaultHeaderFilterStrategy { + public Sns2HeaderFilterStrategy() { initialize(); } protected void initialize() { - setLowerCase(true); - - // filter headers begin with "Camel" or "org.apache.camel" - setOutFilterPattern("(breadcrumbId|Camel|org\\.apache\\.camel)[\\.|a-z|A-z|0-9]*"); - setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH); + getOutFilter().add("breadcrumbId"); } } diff --git a/components/camel-aws/camel-aws2-sqs/src/main/java/org/apache/camel/component/aws2/sqs/Sqs2HeaderFilterStrategy.java b/components/camel-aws/camel-aws2-sqs/src/main/java/org/apache/camel/component/aws2/sqs/Sqs2HeaderFilterStrategy.java index d6b460c53ecee..9d829293f64a6 100644 --- a/components/camel-aws/camel-aws2-sqs/src/main/java/org/apache/camel/component/aws2/sqs/Sqs2HeaderFilterStrategy.java +++ b/components/camel-aws/camel-aws2-sqs/src/main/java/org/apache/camel/component/aws2/sqs/Sqs2HeaderFilterStrategy.java @@ -19,14 +19,12 @@ import org.apache.camel.support.DefaultHeaderFilterStrategy; public class Sqs2HeaderFilterStrategy extends DefaultHeaderFilterStrategy { + public Sqs2HeaderFilterStrategy() { initialize(); } protected void initialize() { - setLowerCase(true); - // filter headers begin with "Camel" or "org.apache.camel" - setOutFilterPattern("(breadcrumbId|Camel|org\\.apache\\.camel)[\\.|a-z|A-z|0-9]*"); - setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH); + getOutFilter().add("breadcrumbId"); } } diff --git a/components/camel-aws/camel-aws2-sqs/src/test/java/org/apache/camel/component/aws2/sqs/Sqs2HeaderFilterStrategyTest.java b/components/camel-aws/camel-aws2-sqs/src/test/java/org/apache/camel/component/aws2/sqs/Sqs2HeaderFilterStrategyTest.java index 1c21bd4698068..6f2dd922daa7a 100644 --- a/components/camel-aws/camel-aws2-sqs/src/test/java/org/apache/camel/component/aws2/sqs/Sqs2HeaderFilterStrategyTest.java +++ b/components/camel-aws/camel-aws2-sqs/src/test/java/org/apache/camel/component/aws2/sqs/Sqs2HeaderFilterStrategyTest.java @@ -43,7 +43,6 @@ void inboundAllowsNonCamelHeaders() { @Test void outboundFiltersCamelAndBreadcrumbHeaders() { assertTrue(strategy.applyFilterToCamelHeaders("CamelHttpUri", "value", null)); - assertTrue(strategy.applyFilterToCamelHeaders("org.apache.camel.internal", "value", null)); assertTrue(strategy.applyFilterToCamelHeaders("breadcrumbId", "value", null)); } diff --git a/components/camel-azure/camel-azure-servicebus/src/main/java/org/apache/camel/component/azure/servicebus/ServiceBusHeaderFilterStrategy.java b/components/camel-azure/camel-azure-servicebus/src/main/java/org/apache/camel/component/azure/servicebus/ServiceBusHeaderFilterStrategy.java index 709c2ed532c45..8c55063402879 100644 --- a/components/camel-azure/camel-azure-servicebus/src/main/java/org/apache/camel/component/azure/servicebus/ServiceBusHeaderFilterStrategy.java +++ b/components/camel-azure/camel-azure-servicebus/src/main/java/org/apache/camel/component/azure/servicebus/ServiceBusHeaderFilterStrategy.java @@ -37,13 +37,6 @@ public class ServiceBusHeaderFilterStrategy extends DefaultHeaderFilterStrategy Date.class, UUID.class); - public ServiceBusHeaderFilterStrategy() { - super(); - setLowerCase(true); - setOutFilterStartsWith(DefaultHeaderFilterStrategy.CAMEL_FILTER_STARTS_WITH); - setInFilterStartsWith(DefaultHeaderFilterStrategy.CAMEL_FILTER_STARTS_WITH); - } - @Override public boolean applyFilterToCamelHeaders(String headerName, Object headerValue, Exchange exchange) { return headerValue == null || !SUPPORTED_TYPES.contains(headerValue.getClass()) diff --git a/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPEndpoint.java b/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPEndpoint.java index ae5d8697682b3..74909335fad77 100644 --- a/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPEndpoint.java +++ b/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPEndpoint.java @@ -45,6 +45,7 @@ import org.apache.camel.spi.UriParam; import org.apache.camel.spi.UriPath; import org.apache.camel.support.DefaultEndpoint; +import org.apache.camel.support.DefaultHeaderFilterStrategy; import org.apache.camel.support.jsse.ClientAuthentication; import org.apache.camel.support.jsse.KeyManagersParameters; import org.apache.camel.support.jsse.SSLContextParameters; @@ -281,7 +282,7 @@ public void setClient(CoapClient client) { @Override public HeaderFilterStrategy getHeaderFilterStrategy() { if (headerFilterStrategy == null) { - headerFilterStrategy = new CoAPHeaderFilterStrategy(); + headerFilterStrategy = new DefaultHeaderFilterStrategy(); } return headerFilterStrategy; } diff --git a/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPHeaderFilterStrategy.java b/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPHeaderFilterStrategy.java deleted file mode 100644 index 827c14973796f..0000000000000 --- a/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPHeaderFilterStrategy.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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 org.apache.camel.support.DefaultHeaderFilterStrategy; - -/** - * Default header filter strategy for CoAP endpoints. - *

- * Filters out Camel internal headers (starting with "Camel" or "camel") in both directions to prevent external CoAP - * clients from injecting internal Camel headers via query parameters. - */ -public class CoAPHeaderFilterStrategy extends DefaultHeaderFilterStrategy { - - public CoAPHeaderFilterStrategy() { - setLowerCase(true); - setOutFilterStartsWith(CAMEL_FILTER_STARTS_WITH); - setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH); - } -} diff --git a/components/camel-coap/src/test/java/org/apache/camel/coap/CoAPHeaderFilterStrategyTest.java b/components/camel-coap/src/test/java/org/apache/camel/coap/CoAPHeaderFilterStrategyTest.java deleted file mode 100644 index c6460a2994e67..0000000000000 --- a/components/camel-coap/src/test/java/org/apache/camel/coap/CoAPHeaderFilterStrategyTest.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * 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 org.apache.camel.Exchange; -import org.apache.camel.RoutesBuilder; -import org.apache.camel.builder.RouteBuilder; -import org.apache.camel.component.mock.MockEndpoint; -import org.eclipse.californium.core.CoapClient; -import org.eclipse.californium.core.CoapResponse; -import org.eclipse.californium.core.coap.MediaTypeRegistry; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; - -/** - * Test that the default {@link CoAPHeaderFilterStrategy} prevents external CoAP clients from injecting internal Camel - * headers via query parameters. - */ -public class CoAPHeaderFilterStrategyTest extends CoAPTestSupport { - - @Test - void testCamelHeadersAreFilteredFromQueryParameters() throws Exception { - MockEndpoint mock = getMockEndpoint("mock:result"); - mock.expectedMessageCount(1); - - // Send a CoAP request with a Camel-prefixed query parameter that should be filtered - CoapClient client = createClient("/test?CamelHttpMethod=DELETE&safeParam=hello"); - CoapResponse response = client.post("body", MediaTypeRegistry.TEXT_PLAIN); - - mock.assertIsSatisfied(); - - Exchange exchange = mock.getReceivedExchanges().get(0); - // CamelHttpMethod should be filtered out by the header filter strategy - assertNull(exchange.getIn().getHeader("CamelHttpMethod"), - "Camel-prefixed header should be filtered from external CoAP query parameters"); - // Non-Camel headers should pass through - assertEquals("hello", exchange.getIn().getHeader("safeParam"), - "Non-Camel headers should be allowed through"); - } - - @Test - void testCamelLowercaseHeadersAreFiltered() throws Exception { - MockEndpoint mock = getMockEndpoint("mock:result"); - mock.expectedMessageCount(1); - - CoapClient client = createClient("/test?camelInternal=secret&allowed=value"); - CoapResponse response = client.post("body", MediaTypeRegistry.TEXT_PLAIN); - - mock.assertIsSatisfied(); - - Exchange exchange = mock.getReceivedExchanges().get(0); - assertNull(exchange.getIn().getHeader("camelInternal"), - "Lowercase camel-prefixed header should be filtered"); - assertEquals("value", exchange.getIn().getHeader("allowed"), - "Non-Camel headers should be allowed through"); - } - - @Override - protected RoutesBuilder createRouteBuilder() { - return new RouteBuilder() { - @Override - public void configure() { - fromF("coap://localhost:%d/test", PORT.getPort()) - .to("mock:result"); - } - }; - } -} diff --git a/components/camel-cometd/src/main/java/org/apache/camel/component/cometd/CometdBinding.java b/components/camel-cometd/src/main/java/org/apache/camel/component/cometd/CometdBinding.java index 7e104a212d1c1..814954d262539 100644 --- a/components/camel-cometd/src/main/java/org/apache/camel/component/cometd/CometdBinding.java +++ b/components/camel-cometd/src/main/java/org/apache/camel/component/cometd/CometdBinding.java @@ -26,6 +26,7 @@ import org.apache.camel.Message; import org.apache.camel.spi.HeaderFilterStrategy; import org.apache.camel.spi.Metadata; +import org.apache.camel.support.DefaultHeaderFilterStrategy; import org.apache.camel.support.DefaultMessage; import org.cometd.bayeux.server.ServerChannel; import org.cometd.bayeux.server.ServerMessage; @@ -57,7 +58,7 @@ public CometdBinding(BayeuxServerImpl bayeux) { } public CometdBinding(BayeuxServerImpl bayeux, boolean enableSessionHeader) { - this(bayeux, enableSessionHeader, new CometdHeaderFilterStrategy()); + this(bayeux, enableSessionHeader, new DefaultHeaderFilterStrategy()); } public CometdBinding(BayeuxServerImpl bayeux, boolean enableSessionHeader, HeaderFilterStrategy headerFilterStrategy) { diff --git a/components/camel-cometd/src/main/java/org/apache/camel/component/cometd/CometdHeaderFilterStrategy.java b/components/camel-cometd/src/main/java/org/apache/camel/component/cometd/CometdHeaderFilterStrategy.java deleted file mode 100644 index 3c6c6d89532bb..0000000000000 --- a/components/camel-cometd/src/main/java/org/apache/camel/component/cometd/CometdHeaderFilterStrategy.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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.cometd; - -import org.apache.camel.support.DefaultHeaderFilterStrategy; - -public class CometdHeaderFilterStrategy extends DefaultHeaderFilterStrategy { - - public CometdHeaderFilterStrategy() { - setLowerCase(true); - setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH); - setOutFilterStartsWith(CAMEL_FILTER_STARTS_WITH); - } -} diff --git a/components/camel-cxf/camel-cxf-rest/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsHeaderFilterStrategy.java b/components/camel-cxf/camel-cxf-rest/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsHeaderFilterStrategy.java index 422e1d3144bcc..d4ace48e77909 100644 --- a/components/camel-cxf/camel-cxf-rest/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsHeaderFilterStrategy.java +++ b/components/camel-cxf/camel-cxf-rest/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsHeaderFilterStrategy.java @@ -26,17 +26,8 @@ public CxfRsHeaderFilterStrategy() { } protected void initialize() { - getOutFilter().add(CxfConstants.OPERATION_NAME.toLowerCase()); getOutFilter().add("Content-Type".toLowerCase()); - // Support to filter the Content-Type case insensitive - setLowerCase(true); - - // filter headers begin with "Camel" or "org.apache.camel" - setOutFilterStartsWith(CAMEL_FILTER_STARTS_WITH); - setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH); - } - } diff --git a/components/camel-cxf/camel-cxf-transport/src/main/java/org/apache/camel/component/cxf/transport/header/CxfHeaderFilterStrategy.java b/components/camel-cxf/camel-cxf-transport/src/main/java/org/apache/camel/component/cxf/transport/header/CxfHeaderFilterStrategy.java index 921c45f94b5f0..c44f7bd182668 100644 --- a/components/camel-cxf/camel-cxf-transport/src/main/java/org/apache/camel/component/cxf/transport/header/CxfHeaderFilterStrategy.java +++ b/components/camel-cxf/camel-cxf-transport/src/main/java/org/apache/camel/component/cxf/transport/header/CxfHeaderFilterStrategy.java @@ -89,15 +89,9 @@ protected void initialize() { // is passed to the other endpoint getInFilter().add("content-length".toLowerCase()); - setLowerCase(true); - // initialize message header filter map with default SOAP filter messageHeaderFiltersMap = new HashMap<>(); addToMessageHeaderFilterMap(new SoapMessageHeaderFilter()); - - // filter headers begin with "Camel" or "org.apache.camel" - setOutFilterStartsWith(CAMEL_FILTER_STARTS_WITH); - setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH); } @SuppressWarnings("unchecked") diff --git a/components/camel-google/camel-google-pubsub/src/main/java/org/apache/camel/component/google/pubsub/GooglePubsubHeaderFilterStrategy.java b/components/camel-google/camel-google-pubsub/src/main/java/org/apache/camel/component/google/pubsub/GooglePubsubHeaderFilterStrategy.java index 8f75c1aa4fecb..b58bd91c0adbf 100644 --- a/components/camel-google/camel-google-pubsub/src/main/java/org/apache/camel/component/google/pubsub/GooglePubsubHeaderFilterStrategy.java +++ b/components/camel-google/camel-google-pubsub/src/main/java/org/apache/camel/component/google/pubsub/GooglePubsubHeaderFilterStrategy.java @@ -25,9 +25,6 @@ public GooglePubsubHeaderFilterStrategy() { } public GooglePubsubHeaderFilterStrategy(boolean includeAllGoogleProperties) { - setLowerCase(true); - setOutFilterStartsWith(DefaultHeaderFilterStrategy.CAMEL_FILTER_STARTS_WITH); - setInFilterStartsWith(DefaultHeaderFilterStrategy.CAMEL_FILTER_STARTS_WITH); // Filter authorization on both directions for security getOutFilter().add("authorization"); getInFilter().add("authorization"); diff --git a/components/camel-http-base/src/main/java/org/apache/camel/http/base/HttpHeaderFilterStrategy.java b/components/camel-http-base/src/main/java/org/apache/camel/http/base/HttpHeaderFilterStrategy.java index 9249a9fd32590..dde1d72570ed3 100644 --- a/components/camel-http-base/src/main/java/org/apache/camel/http/base/HttpHeaderFilterStrategy.java +++ b/components/camel-http-base/src/main/java/org/apache/camel/http/base/HttpHeaderFilterStrategy.java @@ -30,13 +30,6 @@ public HttpHeaderFilterStrategy() { protected void initialize() { final Set outFilter = getOutFilter(); HttpUtil.addCommonFilters(outFilter); - - setLowerCase(true); - - // filter headers begin with "Camel" or "org.apache.camel" - // must ignore case for Http based transports - setOutFilterStartsWith(CAMEL_FILTER_STARTS_WITH); - setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH); } } diff --git a/components/camel-http-base/src/main/java/org/apache/camel/http/base/HttpProtocolHeaderFilterStrategy.java b/components/camel-http-base/src/main/java/org/apache/camel/http/base/HttpProtocolHeaderFilterStrategy.java index d3a0db4f500d8..afb3c4f69b407 100644 --- a/components/camel-http-base/src/main/java/org/apache/camel/http/base/HttpProtocolHeaderFilterStrategy.java +++ b/components/camel-http-base/src/main/java/org/apache/camel/http/base/HttpProtocolHeaderFilterStrategy.java @@ -27,6 +27,9 @@ public HttpProtocolHeaderFilterStrategy() { // Just add the http headers here protected void initialize() { + // This strategy filters HTTP protocol headers only; Camel-prefixed headers must not be blocked + // so that they survive the request-to-response copy in HttpProducer.copyHeaders. + setInFilterStartsWith((String[]) null); getInFilter().add("content-encoding"); getInFilter().add("content-language"); @@ -68,7 +71,5 @@ protected void initialize() { getInFilter().add("www-authenticate"); HttpUtil.addCommonFilters(getInFilter()); - - setLowerCase(true); } } diff --git a/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpHeaderFilterStrategy.java b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpHeaderFilterStrategy.java index 2ca35f1d64db3..d5c852822421e 100644 --- a/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpHeaderFilterStrategy.java +++ b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpHeaderFilterStrategy.java @@ -33,13 +33,6 @@ public HttpHeaderFilterStrategy() { protected void initialize() { final Set outFilter = getOutFilter(); HttpUtil.addCommonFilters(outFilter); - - setLowerCase(true); - - // filter headers begin with "Camel" or "org.apache.camel" - // must ignore case for Http based transports - setOutFilterStartsWith(CAMEL_FILTER_STARTS_WITH); - setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH); } } diff --git a/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpProtocolHeaderFilterStrategy.java b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpProtocolHeaderFilterStrategy.java index 54f8f95c3e3ea..44c1e0c5575f7 100644 --- a/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpProtocolHeaderFilterStrategy.java +++ b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpProtocolHeaderFilterStrategy.java @@ -16,5 +16,9 @@ */ package org.apache.camel.http.common; +/** + * @deprecated use {@link org.apache.camel.http.base.HttpProtocolHeaderFilterStrategy} directly + */ +@Deprecated(since = "4.21") public class HttpProtocolHeaderFilterStrategy extends org.apache.camel.http.base.HttpProtocolHeaderFilterStrategy { } diff --git a/components/camel-http/src/main/java/org/apache/camel/component/http/HttpProducer.java b/components/camel-http/src/main/java/org/apache/camel/component/http/HttpProducer.java index 8931a5607fa3b..2c0641844ab4f 100644 --- a/components/camel-http/src/main/java/org/apache/camel/component/http/HttpProducer.java +++ b/components/camel-http/src/main/java/org/apache/camel/component/http/HttpProducer.java @@ -45,9 +45,9 @@ import org.apache.camel.WrappedFile; import org.apache.camel.component.http.helper.HttpMethodHelper; import org.apache.camel.http.base.HttpOperationFailedException; +import org.apache.camel.http.base.HttpProtocolHeaderFilterStrategy; import org.apache.camel.http.base.cookie.CookieHandler; import org.apache.camel.http.common.HttpHelper; -import org.apache.camel.http.common.HttpProtocolHeaderFilterStrategy; import org.apache.camel.spi.HeaderFilterStrategy; import org.apache.camel.support.DefaultProducer; import org.apache.camel.support.ExchangeHelper; diff --git a/components/camel-iggy/src/main/java/org/apache/camel/component/iggy/IggyEndpoint.java b/components/camel-iggy/src/main/java/org/apache/camel/component/iggy/IggyEndpoint.java index a37d8c957423a..90f8e8885c262 100644 --- a/components/camel-iggy/src/main/java/org/apache/camel/component/iggy/IggyEndpoint.java +++ b/components/camel-iggy/src/main/java/org/apache/camel/component/iggy/IggyEndpoint.java @@ -32,6 +32,7 @@ import org.apache.camel.spi.UriParam; import org.apache.camel.spi.UriPath; import org.apache.camel.support.DefaultEndpoint; +import org.apache.camel.support.DefaultHeaderFilterStrategy; import org.apache.iggy.client.blocking.IggyBaseClient; import org.apache.iggy.consumergroup.ConsumerGroupDetails; import org.apache.iggy.identifier.ConsumerId; @@ -170,7 +171,7 @@ public ExecutorService createExecutor() { @Override public HeaderFilterStrategy getHeaderFilterStrategy() { if (headerFilterStrategy == null) { - headerFilterStrategy = new IggyHeaderFilterStrategy(); + headerFilterStrategy = new DefaultHeaderFilterStrategy(); } return headerFilterStrategy; } diff --git a/components/camel-iggy/src/main/java/org/apache/camel/component/iggy/IggyHeaderFilterStrategy.java b/components/camel-iggy/src/main/java/org/apache/camel/component/iggy/IggyHeaderFilterStrategy.java deleted file mode 100644 index 58bb0f746b7e8..0000000000000 --- a/components/camel-iggy/src/main/java/org/apache/camel/component/iggy/IggyHeaderFilterStrategy.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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.iggy; - -import org.apache.camel.support.DefaultHeaderFilterStrategy; - -/** - * Default header filter strategy for Iggy endpoints. - *

- * Filters out Camel internal headers (starting with "Camel" or "camel") in both directions to prevent external Iggy - * message producers from injecting internal Camel headers via message user-headers. - */ -public class IggyHeaderFilterStrategy extends DefaultHeaderFilterStrategy { - - public IggyHeaderFilterStrategy() { - setLowerCase(true); - setOutFilterStartsWith(CAMEL_FILTER_STARTS_WITH); - setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH); - } -} diff --git a/components/camel-iggy/src/test/java/org/apache/camel/component/iggy/IggyHeaderFilterStrategyTest.java b/components/camel-iggy/src/test/java/org/apache/camel/component/iggy/IggyHeaderFilterStrategyTest.java deleted file mode 100644 index 59a3a2d7303ee..0000000000000 --- a/components/camel-iggy/src/test/java/org/apache/camel/component/iggy/IggyHeaderFilterStrategyTest.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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.iggy; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -public class IggyHeaderFilterStrategyTest { - - private final IggyHeaderFilterStrategy strategy = new IggyHeaderFilterStrategy(); - - @Test - void inboundCamelHeadersAreFiltered() { - assertTrue(strategy.applyFilterToExternalHeaders("CamelHttpUri", "http://evil.example", null)); - assertTrue(strategy.applyFilterToExternalHeaders("CamelFileName", "../../etc/passwd", null)); - assertTrue(strategy.applyFilterToExternalHeaders("CamelBeanMethodName", "evilMethod", null)); - } - - @Test - void inboundLowercaseCamelHeadersAreFiltered() { - assertTrue(strategy.applyFilterToExternalHeaders("camelHttpUri", "http://evil.example", null)); - assertTrue(strategy.applyFilterToExternalHeaders("camelfilename", "../../etc/passwd", null)); - } - - @Test - void outboundCamelHeadersAreFiltered() { - assertTrue(strategy.applyFilterToCamelHeaders("CamelHttpUri", "value", null)); - assertTrue(strategy.applyFilterToCamelHeaders("camelHttpUri", "value", null)); - } - - @Test - void nonCamelHeadersPassThrough() { - assertFalse(strategy.applyFilterToExternalHeaders("Content-Type", "application/json", null)); - assertFalse(strategy.applyFilterToExternalHeaders("X-Request-Id", "abc-123", null)); - assertFalse(strategy.applyFilterToCamelHeaders("Content-Type", "application/json", null)); - } -} diff --git a/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpBridgeMultipartRouteTest.java b/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpBridgeMultipartRouteTest.java index eb62bf3a8a79a..1d2491a26ef82 100644 --- a/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpBridgeMultipartRouteTest.java +++ b/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpBridgeMultipartRouteTest.java @@ -44,9 +44,7 @@ private static class MultipartHeaderFilterStrategy extends DefaultHeaderFilterSt } protected void initialize() { - setLowerCase(true); getOutFilter().add("content-length"); - setOutFilterStartsWith(CAMEL_FILTER_STARTS_WITH); } } diff --git a/components/camel-jms/src/main/java/org/apache/camel/component/jms/ClassicJmsHeaderFilterStrategy.java b/components/camel-jms/src/main/java/org/apache/camel/component/jms/ClassicJmsHeaderFilterStrategy.java index 36d862a75a013..fb2594711a02f 100644 --- a/components/camel-jms/src/main/java/org/apache/camel/component/jms/ClassicJmsHeaderFilterStrategy.java +++ b/components/camel-jms/src/main/java/org/apache/camel/component/jms/ClassicJmsHeaderFilterStrategy.java @@ -29,7 +29,8 @@ public ClassicJmsHeaderFilterStrategy() { } public ClassicJmsHeaderFilterStrategy(boolean includeAllJMSXProperties) { - setLowerCase(true); + setInFilterStartsWith((String[]) null); // opt out: pass Camel headers inbound (legacy mode) + setOutFilterStartsWith((String[]) null); // opt out: pass Camel headers outbound (legacy mode) if (!includeAllJMSXProperties) { initialize(); } diff --git a/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsHeaderFilterStrategy.java b/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsHeaderFilterStrategy.java index 6a290839767a0..dd6ee5787eee0 100644 --- a/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsHeaderFilterStrategy.java +++ b/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsHeaderFilterStrategy.java @@ -25,9 +25,6 @@ public JmsHeaderFilterStrategy() { } public JmsHeaderFilterStrategy(boolean includeAllJMSXProperties) { - setLowerCase(true); - setOutFilterStartsWith(DefaultHeaderFilterStrategy.CAMEL_FILTER_STARTS_WITH); - setInFilterStartsWith(DefaultHeaderFilterStrategy.CAMEL_FILTER_STARTS_WITH); if (!includeAllJMSXProperties) { initialize(); } diff --git a/components/camel-jms/src/test/java/org/apache/camel/component/jms/ClassicJmsHeaderFilterStrategyTest.java b/components/camel-jms/src/test/java/org/apache/camel/component/jms/ClassicJmsHeaderFilterStrategyTest.java new file mode 100644 index 0000000000000..1aa6ff24f76b5 --- /dev/null +++ b/components/camel-jms/src/test/java/org/apache/camel/component/jms/ClassicJmsHeaderFilterStrategyTest.java @@ -0,0 +1,70 @@ +/* + * 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.jms; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Verifies that {@link ClassicJmsHeaderFilterStrategy} opts out of the default Camel header filtering so that + * Camel-internal headers propagate across the JMS wire (legacy behaviour). + */ +public class ClassicJmsHeaderFilterStrategyTest { + + private final ClassicJmsHeaderFilterStrategy strategy = new ClassicJmsHeaderFilterStrategy(); + + @Test + void camelHeadersPassThroughInboundDirection() { + // In classic mode, Camel headers must NOT be blocked when arriving from JMS + assertFalse(strategy.applyFilterToExternalHeaders("CamelJmsDestination", "queue://foo", null), + "CamelJmsDestination must pass through inbound in classic mode"); + assertFalse(strategy.applyFilterToExternalHeaders("CamelFileName", "report.txt", null), + "CamelFileName must pass through inbound in classic mode"); + assertFalse(strategy.applyFilterToExternalHeaders("camelCorrelationId", "abc", null), + "camelCorrelationId must pass through inbound in classic mode"); + assertFalse(strategy.applyFilterToExternalHeaders("org.apache.camel.foo", "bar", null), + "org.apache.camel.foo must pass through inbound in classic mode"); + } + + @Test + void camelHeadersPassThroughOutboundDirection() { + // In classic mode, Camel headers must NOT be blocked when sent to JMS + assertFalse(strategy.applyFilterToCamelHeaders("CamelJmsDestination", "queue://foo", null), + "CamelJmsDestination must pass through outbound in classic mode"); + assertFalse(strategy.applyFilterToCamelHeaders("CamelFileName", "report.txt", null), + "CamelFileName must pass through outbound in classic mode"); + assertFalse(strategy.applyFilterToCamelHeaders("camelCorrelationId", "abc", null), + "camelCorrelationId must pass through outbound in classic mode"); + assertFalse(strategy.applyFilterToCamelHeaders("org.apache.camel.foo", "bar", null), + "org.apache.camel.foo must pass through outbound in classic mode"); + } + + @Test + void jmsProviderHeadersStillFiltered() { + // JMSXDeliveryCount and peers are filtered in both directions (provider-set, not user headers) + assertTrue(strategy.applyFilterToCamelHeaders("JMSXDeliveryCount", "1", null), + "JMSXDeliveryCount must be blocked outbound"); + } + + @Test + void nonCamelHeadersPassThrough() { + assertFalse(strategy.applyFilterToExternalHeaders("myApp-correlationId", "123", null)); + assertFalse(strategy.applyFilterToCamelHeaders("myApp-correlationId", "123", null)); + } +} diff --git a/components/camel-kafka/src/main/java/org/apache/camel/component/kafka/KafkaHeaderFilterStrategy.java b/components/camel-kafka/src/main/java/org/apache/camel/component/kafka/KafkaHeaderFilterStrategy.java index d2b1fb49a8f9d..e0a4044eea4a2 100644 --- a/components/camel-kafka/src/main/java/org/apache/camel/component/kafka/KafkaHeaderFilterStrategy.java +++ b/components/camel-kafka/src/main/java/org/apache/camel/component/kafka/KafkaHeaderFilterStrategy.java @@ -16,6 +16,8 @@ */ package org.apache.camel.component.kafka; +import java.util.Arrays; + import org.apache.camel.support.DefaultHeaderFilterStrategy; public class KafkaHeaderFilterStrategy extends DefaultHeaderFilterStrategy { @@ -28,10 +30,10 @@ protected void initialize() { // filter out kafka record metadata getInFilter().add("org.apache.kafka.clients.producer.RecordMetadata"); - setLowerCase(true); - - // filter headers beginning with "Camel" or "org.apache.camel" or "kafka." - setOutFilterStartsWith("Camel", "camel", "org.apache.camel.", "kafka."); - setInFilterStartsWith("Camel", "camel", "org.apache.camel.", "kafka."); + // filter headers beginning with Camel-internal prefixes and "kafka." + String[] kafkaFilterStartsWith = Arrays.copyOf(CAMEL_FILTER_STARTS_WITH, CAMEL_FILTER_STARTS_WITH.length + 1); + kafkaFilterStartsWith[CAMEL_FILTER_STARTS_WITH.length] = "kafka."; + setOutFilterStartsWith(kafkaFilterStartsWith); + setInFilterStartsWith(kafkaFilterStartsWith); } } diff --git a/components/camel-knative/camel-knative-http/src/main/java/org/apache/camel/component/knative/http/KnativeHttpHeaderFilterStrategy.java b/components/camel-knative/camel-knative-http/src/main/java/org/apache/camel/component/knative/http/KnativeHttpHeaderFilterStrategy.java index 2e54bd56b435e..e39c808b25793 100644 --- a/components/camel-knative/camel-knative-http/src/main/java/org/apache/camel/component/knative/http/KnativeHttpHeaderFilterStrategy.java +++ b/components/camel-knative/camel-knative-http/src/main/java/org/apache/camel/component/knative/http/KnativeHttpHeaderFilterStrategy.java @@ -26,12 +26,5 @@ public KnativeHttpHeaderFilterStrategy() { protected final void initialize() { HttpUtil.addCommonFilters(getOutFilter()); - - setLowerCase(true); - - // filter headers begin with "Camel" or "org.apache.camel" - // must ignore case for Http based transports - setOutFilterPattern("(?i)(Camel|org\\.apache\\.camel)[\\.|a-z|A-z|0-9]*"); - setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH); } } diff --git a/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailHeaderFilterStrategy.java b/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailHeaderFilterStrategy.java index c92548a6ac5e4..d368cbdd6aa1e 100644 --- a/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailHeaderFilterStrategy.java +++ b/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailHeaderFilterStrategy.java @@ -27,9 +27,6 @@ public MailHeaderFilterStrategy() { } protected void initialize() { - setLowerCase(true); - // filter headers begin with "Camel" or "org.apache.camel" - setOutFilterStartsWith(CAMEL_FILTER_STARTS_WITH); // on the inbound path also filter the Camel-internal mail.smtp.* / mail.smtps.* namespace so an // external mail message cannot inject JavaMail session properties (CAMEL-23522) String[] inFilter = Arrays.copyOf(CAMEL_FILTER_STARTS_WITH, CAMEL_FILTER_STARTS_WITH.length + 2); diff --git a/components/camel-nats/src/main/java/org/apache/camel/component/nats/NatsConfiguration.java b/components/camel-nats/src/main/java/org/apache/camel/component/nats/NatsConfiguration.java index 4db1cdef3ba31..00b489098c7bf 100644 --- a/components/camel-nats/src/main/java/org/apache/camel/component/nats/NatsConfiguration.java +++ b/components/camel-nats/src/main/java/org/apache/camel/component/nats/NatsConfiguration.java @@ -29,6 +29,7 @@ import org.apache.camel.spi.UriParam; import org.apache.camel.spi.UriParams; import org.apache.camel.spi.UriPath; +import org.apache.camel.support.DefaultHeaderFilterStrategy; import org.apache.camel.support.jsse.SSLContextParameters; import org.apache.camel.util.ObjectHelper; @@ -115,7 +116,7 @@ public class NatsConfiguration implements Cloneable { @UriParam(label = "advanced") private boolean traceConnection; @UriParam(label = "advanced") - private HeaderFilterStrategy headerFilterStrategy = new NatsHeaderFilterStrategy(); + private HeaderFilterStrategy headerFilterStrategy = new DefaultHeaderFilterStrategy(); public NatsConfiguration copy() { try { diff --git a/components/camel-nats/src/main/java/org/apache/camel/component/nats/NatsHeaderFilterStrategy.java b/components/camel-nats/src/main/java/org/apache/camel/component/nats/NatsHeaderFilterStrategy.java deleted file mode 100644 index 9997b3a666237..0000000000000 --- a/components/camel-nats/src/main/java/org/apache/camel/component/nats/NatsHeaderFilterStrategy.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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.nats; - -import org.apache.camel.support.DefaultHeaderFilterStrategy; - -public class NatsHeaderFilterStrategy extends DefaultHeaderFilterStrategy { - - public NatsHeaderFilterStrategy() { - initialize(); - } - - protected void initialize() { - setLowerCase(true); - // filter headers begin with "Camel" or "org.apache.camel" - setOutFilterStartsWith(CAMEL_FILTER_STARTS_WITH); - setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH); - } - -} diff --git a/components/camel-nats/src/test/java/org/apache/camel/component/nats/NatsHeaderFilterStrategyTest.java b/components/camel-nats/src/test/java/org/apache/camel/component/nats/NatsHeaderFilterStrategyTest.java deleted file mode 100644 index 96083045a0db8..0000000000000 --- a/components/camel-nats/src/test/java/org/apache/camel/component/nats/NatsHeaderFilterStrategyTest.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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.nats; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -public class NatsHeaderFilterStrategyTest { - - private final NatsHeaderFilterStrategy strategy = new NatsHeaderFilterStrategy(); - - @Test - void inboundCamelHeadersAreFiltered() { - assertTrue(strategy.applyFilterToExternalHeaders("CamelHttpUri", "http://evil.example", null)); - assertTrue(strategy.applyFilterToExternalHeaders("CamelFileName", "../../etc/passwd", null)); - assertTrue(strategy.applyFilterToExternalHeaders("CamelBeanMethodName", "evilMethod", null)); - } - - @Test - void inboundLowercaseCamelHeadersAreFiltered() { - assertTrue(strategy.applyFilterToExternalHeaders("camelHttpUri", "http://evil.example", null)); - assertTrue(strategy.applyFilterToExternalHeaders("camelfilename", "../../etc/passwd", null)); - } - - @Test - void outboundCamelHeadersAreFiltered() { - assertTrue(strategy.applyFilterToCamelHeaders("CamelHttpUri", "value", null)); - assertTrue(strategy.applyFilterToCamelHeaders("camelHttpUri", "value", null)); - } - - @Test - void nonCamelHeadersPassThrough() { - assertFalse(strategy.applyFilterToExternalHeaders("Content-Type", "application/json", null)); - assertFalse(strategy.applyFilterToExternalHeaders("X-Request-Id", "abc-123", null)); - assertFalse(strategy.applyFilterToCamelHeaders("Content-Type", "application/json", null)); - } -} diff --git a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpHeaderFilterStrategy.java b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpHeaderFilterStrategy.java index 12b81b0b19910..239d5e846869a 100644 --- a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpHeaderFilterStrategy.java +++ b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpHeaderFilterStrategy.java @@ -33,12 +33,5 @@ public NettyHttpHeaderFilterStrategy() { protected void initialize() { HttpUtil.addCommonFilters(getOutFilter()); - - setLowerCase(true); - - // filter headers begin with "Camel" or "org.apache.camel" - // must ignore case for Http based transports - setOutFilterStartsWith(CAMEL_FILTER_STARTS_WITH); - setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH); } } diff --git a/components/camel-sjms/src/main/java/org/apache/camel/component/sjms/SjmsHeaderFilterStrategy.java b/components/camel-sjms/src/main/java/org/apache/camel/component/sjms/SjmsHeaderFilterStrategy.java index 56d89d009a813..4a9169ed3add7 100644 --- a/components/camel-sjms/src/main/java/org/apache/camel/component/sjms/SjmsHeaderFilterStrategy.java +++ b/components/camel-sjms/src/main/java/org/apache/camel/component/sjms/SjmsHeaderFilterStrategy.java @@ -25,9 +25,6 @@ public SjmsHeaderFilterStrategy() { } public SjmsHeaderFilterStrategy(boolean includeAllJMSXProperties) { - setLowerCase(true); - setOutFilterStartsWith(DefaultHeaderFilterStrategy.CAMEL_FILTER_STARTS_WITH); - setInFilterStartsWith(DefaultHeaderFilterStrategy.CAMEL_FILTER_STARTS_WITH); if (!includeAllJMSXProperties) { initialize(); } diff --git a/components/camel-spring-parent/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/SpringRabbitMQHeaderFilterStrategy.java b/components/camel-spring-parent/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/SpringRabbitMQHeaderFilterStrategy.java index 41bd5bcebc6ff..baa359cb8f5b0 100644 --- a/components/camel-spring-parent/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/SpringRabbitMQHeaderFilterStrategy.java +++ b/components/camel-spring-parent/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/SpringRabbitMQHeaderFilterStrategy.java @@ -28,9 +28,6 @@ protected void initialize() { this.getOutFilter().add("content-encoding"); this.getOutFilter().add("content-length"); this.getOutFilter().add("content-type"); - this.setLowerCase(true); - this.setOutFilterStartsWith(CAMEL_FILTER_STARTS_WITH); - this.setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH); } } diff --git a/components/camel-vertx/camel-vertx-http/src/main/java/org/apache/camel/component/vertx/http/VertxHttpHeaderFilterStrategy.java b/components/camel-vertx/camel-vertx-http/src/main/java/org/apache/camel/component/vertx/http/VertxHttpHeaderFilterStrategy.java index 734eeea1ff036..7ea588ef42abf 100644 --- a/components/camel-vertx/camel-vertx-http/src/main/java/org/apache/camel/component/vertx/http/VertxHttpHeaderFilterStrategy.java +++ b/components/camel-vertx/camel-vertx-http/src/main/java/org/apache/camel/component/vertx/http/VertxHttpHeaderFilterStrategy.java @@ -30,13 +30,6 @@ public VertxHttpHeaderFilterStrategy() { protected void initialize() { final Set outFilter = getOutFilter(); HttpUtil.addCommonFilters(outFilter); - - setLowerCase(true); - - // filter headers begin with "Camel" or "org.apache.camel" - // must ignore case for Http based transports - setOutFilterStartsWith(CAMEL_FILTER_STARTS_WITH); - setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH); } } diff --git a/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketEndpoint.java b/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketEndpoint.java index 46439641d075d..7d6e1a383fdeb 100644 --- a/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketEndpoint.java +++ b/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketEndpoint.java @@ -41,6 +41,7 @@ import org.apache.camel.spi.UriEndpoint; import org.apache.camel.spi.UriParam; import org.apache.camel.support.DefaultEndpoint; +import org.apache.camel.support.DefaultHeaderFilterStrategy; import org.apache.camel.support.jsse.SSLContextParameters; import org.apache.camel.util.ObjectHelper; import org.apache.camel.util.URISupport; @@ -132,7 +133,7 @@ public VertxWebsocketConfiguration getConfiguration() { @Override public HeaderFilterStrategy getHeaderFilterStrategy() { if (headerFilterStrategy == null) { - headerFilterStrategy = new VertxWebsocketHeaderFilterStrategy(); + headerFilterStrategy = new DefaultHeaderFilterStrategy(); } return headerFilterStrategy; } diff --git a/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketHeaderFilterStrategy.java b/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketHeaderFilterStrategy.java deleted file mode 100644 index 232de276eb633..0000000000000 --- a/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketHeaderFilterStrategy.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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.vertx.websocket; - -import org.apache.camel.support.DefaultHeaderFilterStrategy; - -/** - * Default header filter strategy for Vert.x WebSocket endpoints. - *

- * Filters out Camel internal headers (starting with "Camel" or "camel") in both directions to prevent external - * WebSocket clients from injecting internal Camel headers via query or path parameters. - */ -public class VertxWebsocketHeaderFilterStrategy extends DefaultHeaderFilterStrategy { - - public VertxWebsocketHeaderFilterStrategy() { - setLowerCase(true); - setOutFilterStartsWith(CAMEL_FILTER_STARTS_WITH); - setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH); - } -} diff --git a/components/camel-vertx/camel-vertx-websocket/src/test/java/org/apache/camel/component/vertx/websocket/VertxWebsocketHeaderFilterStrategyTest.java b/components/camel-vertx/camel-vertx-websocket/src/test/java/org/apache/camel/component/vertx/websocket/VertxWebsocketHeaderFilterStrategyTest.java deleted file mode 100644 index 3f2d7f1ffc26f..0000000000000 --- a/components/camel-vertx/camel-vertx-websocket/src/test/java/org/apache/camel/component/vertx/websocket/VertxWebsocketHeaderFilterStrategyTest.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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.vertx.websocket; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -public class VertxWebsocketHeaderFilterStrategyTest { - - private final VertxWebsocketHeaderFilterStrategy strategy = new VertxWebsocketHeaderFilterStrategy(); - - @Test - void inboundCamelHeadersAreFiltered() { - assertTrue(strategy.applyFilterToExternalHeaders("CamelHttpUri", "http://evil.example", null)); - assertTrue(strategy.applyFilterToExternalHeaders("CamelFileName", "../../etc/passwd", null)); - assertTrue(strategy.applyFilterToExternalHeaders("CamelBeanMethodName", "evilMethod", null)); - } - - @Test - void inboundLowercaseCamelHeadersAreFiltered() { - assertTrue(strategy.applyFilterToExternalHeaders("camelHttpUri", "http://evil.example", null)); - assertTrue(strategy.applyFilterToExternalHeaders("camelfilename", "../../etc/passwd", null)); - } - - @Test - void outboundCamelHeadersAreFiltered() { - assertTrue(strategy.applyFilterToCamelHeaders("CamelHttpUri", "value", null)); - assertTrue(strategy.applyFilterToCamelHeaders("camelHttpUri", "value", null)); - } - - @Test - void nonCamelHeadersPassThrough() { - assertFalse(strategy.applyFilterToExternalHeaders("Content-Type", "application/json", null)); - assertFalse(strategy.applyFilterToExternalHeaders("X-Request-Id", "abc-123", null)); - assertFalse(strategy.applyFilterToCamelHeaders("Content-Type", "application/json", null)); - } -} diff --git a/components/camel-xmpp/src/main/java/org/apache/camel/component/xmpp/XmppBinding.java b/components/camel-xmpp/src/main/java/org/apache/camel/component/xmpp/XmppBinding.java index bf954eed19acb..b4862547c03f3 100644 --- a/components/camel-xmpp/src/main/java/org/apache/camel/component/xmpp/XmppBinding.java +++ b/components/camel-xmpp/src/main/java/org/apache/camel/component/xmpp/XmppBinding.java @@ -22,6 +22,7 @@ import org.apache.camel.Exchange; import org.apache.camel.spi.HeaderFilterStrategy; +import org.apache.camel.support.DefaultHeaderFilterStrategy; import org.apache.camel.util.ObjectHelper; import org.jivesoftware.smack.packet.DefaultExtensionElement; import org.jivesoftware.smack.packet.ExtensionElement; @@ -43,7 +44,7 @@ public class XmppBinding { private HeaderFilterStrategy headerFilterStrategy; public XmppBinding() { - this.headerFilterStrategy = new XmppHeaderFilterStrategy(); + this.headerFilterStrategy = new DefaultHeaderFilterStrategy(); } public XmppBinding(HeaderFilterStrategy headerFilterStrategy) { diff --git a/components/camel-xmpp/src/main/java/org/apache/camel/component/xmpp/XmppEndpoint.java b/components/camel-xmpp/src/main/java/org/apache/camel/component/xmpp/XmppEndpoint.java index 41e635418a6b8..ccd0d62ee9ac1 100644 --- a/components/camel-xmpp/src/main/java/org/apache/camel/component/xmpp/XmppEndpoint.java +++ b/components/camel-xmpp/src/main/java/org/apache/camel/component/xmpp/XmppEndpoint.java @@ -34,6 +34,7 @@ import org.apache.camel.spi.UriParam; import org.apache.camel.spi.UriPath; import org.apache.camel.support.DefaultEndpoint; +import org.apache.camel.support.DefaultHeaderFilterStrategy; import org.apache.camel.util.ObjectHelper; import org.apache.camel.util.StringHelper; import org.jivesoftware.smack.ConnectionConfiguration; @@ -102,7 +103,7 @@ public class XmppEndpoint extends DefaultEndpoint implements HeaderFilterStrateg @UriParam(label = "consumer", defaultValue = "10") private int connectionPollDelay = 10; @UriParam(label = "filter") - private HeaderFilterStrategy headerFilterStrategy = new XmppHeaderFilterStrategy(); + private HeaderFilterStrategy headerFilterStrategy = new DefaultHeaderFilterStrategy(); @UriParam(label = "advanced") private ConnectionConfiguration connectionConfig; diff --git a/components/camel-xmpp/src/main/java/org/apache/camel/component/xmpp/XmppHeaderFilterStrategy.java b/components/camel-xmpp/src/main/java/org/apache/camel/component/xmpp/XmppHeaderFilterStrategy.java deleted file mode 100644 index cd2b78b25c42a..0000000000000 --- a/components/camel-xmpp/src/main/java/org/apache/camel/component/xmpp/XmppHeaderFilterStrategy.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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.xmpp; - -import org.apache.camel.support.DefaultHeaderFilterStrategy; - -public class XmppHeaderFilterStrategy extends DefaultHeaderFilterStrategy { - - public XmppHeaderFilterStrategy() { - initialize(); - } - - protected void initialize() { - setLowerCase(true); - // filter headers begin with "Camel" or "org.apache.camel" - setOutFilterStartsWith(CAMEL_FILTER_STARTS_WITH); - setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH); - } - -} diff --git a/components/camel-xmpp/src/test/java/org/apache/camel/component/xmpp/XmppHeaderFilterStrategyTest.java b/components/camel-xmpp/src/test/java/org/apache/camel/component/xmpp/XmppHeaderFilterStrategyTest.java deleted file mode 100644 index 64718e909210c..0000000000000 --- a/components/camel-xmpp/src/test/java/org/apache/camel/component/xmpp/XmppHeaderFilterStrategyTest.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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.xmpp; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -public class XmppHeaderFilterStrategyTest { - - private final XmppHeaderFilterStrategy strategy = new XmppHeaderFilterStrategy(); - - @Test - void inboundCamelHeadersAreFiltered() { - assertTrue(strategy.applyFilterToExternalHeaders("CamelHttpUri", "http://evil.example", null)); - assertTrue(strategy.applyFilterToExternalHeaders("CamelFileName", "../../etc/passwd", null)); - assertTrue(strategy.applyFilterToExternalHeaders("CamelBeanMethodName", "evilMethod", null)); - } - - @Test - void inboundLowercaseCamelHeadersAreFiltered() { - assertTrue(strategy.applyFilterToExternalHeaders("camelHttpUri", "http://evil.example", null)); - assertTrue(strategy.applyFilterToExternalHeaders("camelfilename", "../../etc/passwd", null)); - } - - @Test - void outboundCamelHeadersAreFiltered() { - assertTrue(strategy.applyFilterToCamelHeaders("CamelHttpUri", "value", null)); - assertTrue(strategy.applyFilterToCamelHeaders("camelHttpUri", "value", null)); - } - - @Test - void nonCamelHeadersPassThrough() { - assertFalse(strategy.applyFilterToExternalHeaders("Content-Type", "application/json", null)); - assertFalse(strategy.applyFilterToExternalHeaders("X-Request-Id", "abc-123", null)); - assertFalse(strategy.applyFilterToCamelHeaders("Content-Type", "application/json", null)); - } -} diff --git a/core/camel-core/src/test/java/org/apache/camel/impl/DefaultHeaderFilterStrategyTest.java b/core/camel-core/src/test/java/org/apache/camel/impl/DefaultHeaderFilterStrategyTest.java index 73324480c25b0..b2d2eb129f54b 100644 --- a/core/camel-core/src/test/java/org/apache/camel/impl/DefaultHeaderFilterStrategyTest.java +++ b/core/camel-core/src/test/java/org/apache/camel/impl/DefaultHeaderFilterStrategyTest.java @@ -212,6 +212,36 @@ public void testInStartsWith() { assertTrue(comp.applyFilterToExternalHeaders("camelJETTYSession", "true", exchange)); } + @Test + public void testInStartsWithDefaultFiltering() { + DefaultHeaderFilterStrategy comp = new DefaultHeaderFilterStrategy(); + + Exchange exchange = new DefaultExchange(context); + + assertFalse(comp.applyFilterToExternalHeaders("foo", "bar", exchange)); + assertFalse(comp.applyFilterToExternalHeaders("content-type", "text/plain", exchange)); + assertTrue(comp.applyFilterToExternalHeaders("CamelVersion", "4.21", exchange)); + assertTrue(comp.applyFilterToExternalHeaders("camelJettySession", "true", exchange)); + assertTrue(comp.applyFilterToExternalHeaders("CAMELFooBar", "x", exchange)); + assertFalse(comp.applyFilterToExternalHeaders("org.apache.camel.foo", "x", exchange)); + assertFalse(comp.applyFilterToExternalHeaders("org.apache.camel", "x", exchange)); + } + + @Test + public void testOutStartsWithDefaultFiltering() { + DefaultHeaderFilterStrategy comp = new DefaultHeaderFilterStrategy(); + + Exchange exchange = new DefaultExchange(context); + + assertFalse(comp.applyFilterToCamelHeaders("foo", "bar", exchange)); + assertFalse(comp.applyFilterToCamelHeaders("content-type", "text/plain", exchange)); + assertTrue(comp.applyFilterToCamelHeaders("CamelVersion", "4.21", exchange)); + assertTrue(comp.applyFilterToCamelHeaders("camelJettySession", "true", exchange)); + assertTrue(comp.applyFilterToCamelHeaders("CAMELFooBar", "x", exchange)); + assertFalse(comp.applyFilterToCamelHeaders("org.apache.camel.foo", "x", exchange)); + assertFalse(comp.applyFilterToCamelHeaders("org.apache.camel", "x", exchange)); + } + @Test public void testInStartsWithLowerCase() { DefaultHeaderFilterStrategy comp = new DefaultHeaderFilterStrategy(); diff --git a/core/camel-support/src/main/java/org/apache/camel/support/DefaultHeaderFilterStrategy.java b/core/camel-support/src/main/java/org/apache/camel/support/DefaultHeaderFilterStrategy.java index 88fabe5f1932a..ec20fb6712fce 100644 --- a/core/camel-support/src/main/java/org/apache/camel/support/DefaultHeaderFilterStrategy.java +++ b/core/camel-support/src/main/java/org/apache/camel/support/DefaultHeaderFilterStrategy.java @@ -42,15 +42,16 @@ public class DefaultHeaderFilterStrategy implements HeaderFilterStrategy { /** - * A filter pattern that only accepts keys starting with Camel. + * A filter pattern that only accepts keys starting with Camel or org.apache.camel. * * @deprecated use {@link #CAMEL_FILTER_STARTS_WITH} */ @Deprecated(since = "3.9.0") - public static final Pattern CAMEL_FILTER_PATTERN = Pattern.compile("(?i)Camel[.a-zA-z0-9]*"); + public static final Pattern CAMEL_FILTER_PATTERN + = Pattern.compile("(?i)(Camel|org\\.apache\\.camel)[.a-zA-Z0-9]*"); /** - * A filter pattern for keys starting with Camel, or camel. + * A filter pattern for keys starting with Camel or camel. */ public static final String[] CAMEL_FILTER_STARTS_WITH = new String[] { "Camel", "camel" }; @@ -59,14 +60,14 @@ public class DefaultHeaderFilterStrategy implements HeaderFilterStrategy { + " Multiple patterns can be separated by comma") private Set inFilter; private Pattern inFilterPattern; - private String[] inFilterStartsWith; + private String[] inFilterStartsWith = CAMEL_FILTER_STARTS_WITH.clone(); @Metadata(javaType = "java.lang.String", description = "Sets the out direction filter set. The out direction is referred to copying headers from a Camel message to an external message." + " Multiple patterns can be separated by comma") private Set outFilter; private Pattern outFilterPattern; - private String[] outFilterStartsWith; + private String[] outFilterStartsWith = CAMEL_FILTER_STARTS_WITH.clone(); @Metadata(label = "advanced", defaultValue = "true", description = "Whether header names should be converted to lower case before checking it with the filter Set. This ensures that all variations of header names will be taken into account." @@ -377,9 +378,10 @@ private boolean doFiltering(Direction direction, String headerName, Object heade } 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 + // optimize if it's 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"); + boolean match = headerName.startsWith("Camel") || headerName.startsWith("camel") + || headerName.startsWith("org.apache.camel"); if (match) { return true; } @@ -387,13 +389,13 @@ private boolean tryPattern(String headerName, String lower, Pattern pattern) { if (lower == null) { lower = headerName.toLowerCase(); } - match = lower.startsWith("camel"); + match = lower.startsWith("camel") || lower.startsWith("org.apache.camel"); if (match) { return true; } } - } else if (pattern.matcher(headerName).matches()) { - return true; + } else { + return pattern.matcher(headerName).matches(); } return false; } @@ -419,13 +421,9 @@ private boolean evalFilterMatch(String headerName, String lower, Set fil if (lower == null) { lower = headerName.toLowerCase(); } - if (filter.contains(lower)) { - return true; - } + return filter.contains(lower); } else { - if (filter.contains(headerName)) { - return true; - } + return filter.contains(headerName); } return false; } diff --git a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc index a75f995c5473a..a53b742c3eb76 100644 --- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc +++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc @@ -27,6 +27,37 @@ and enable compile-time null checking with tools like NullAway. If you want to l your own code or tooling, add `org.jspecify:jspecify` explicitly to your project dependencies. The `org.apache.camel.support.DefaultHeaderFilterStrategy` changed default setting for lowercase from `false` to `true`. +If your application relies on case-sensitive header name matching (for example, two headers that differ only in +case such as `X-Foo` and `x-foo`), restore the previous behavior by calling `setLowerCase(false)` on your strategy. + +The `DefaultHeaderFilterStrategy` now blocks headers whose names start with `Camel` or `camel` +(case-insensitive) by default in both the inbound (external to Camel) and outbound +(Camel to external) directions. Previously this required each component to explicitly call +`setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH)` and `setOutFilterStartsWith(CAMEL_FILTER_STARTS_WITH)`. + +This affects anyone who: + +* Configures `DefaultHeaderFilterStrategy` directly, OR +* Extends `DefaultHeaderFilterStrategy` in a custom component without explicitly calling `setInFilterStartsWith` or `setOutFilterStartsWith`. + +If these headers need to pass through, opt out by calling `setInFilterStartsWith((String[]) null)` and/or +`setOutFilterStartsWith((String[]) null)`, or by supplying a custom filter array. +See `ClassicJmsHeaderFilterStrategy` for a worked example of the opt-out pattern. + +The following component-specific header filter strategy classes have been removed because +`DefaultHeaderFilterStrategy` now provides equivalent behavior by default: + +* `CoAPHeaderFilterStrategy` +* `CometdHeaderFilterStrategy` +* `IggyHeaderFilterStrategy` +* `NatsHeaderFilterStrategy` +* `VertxWebsocketHeaderFilterStrategy` +* `XmppHeaderFilterStrategy` + +If your code references any of these classes directly, replace them with `DefaultHeaderFilterStrategy`. + +The class `org.apache.camel.http.common.HttpProtocolHeaderFilterStrategy` has been deprecated. +Use `org.apache.camel.http.base.HttpProtocolHeaderFilterStrategy` directly instead. ==== Error Registry SPI changes