CVE-2026-40022
Description
When authentication is enabled on the Apache Camel embedded HTTP server or embedded management server (camel-platform-http-main) and a non-root context path such as /api or /admin is configured via camel.server.path or camel.management.path, the BasicAuthenticationConfigurer and JWTAuthenticationConfigurer classes derive the authentication path from properties.getPath() when camel.server.authenticationPath / camel.management.authenticationPath is not explicitly set. Combined with the Vert.x sub-router mounting model - the sub-router is mounted at _path_* and the authentication handler is registered inside the sub-router at the resolved path - this causes the authentication handler to match only the exact configured context path, not its subpaths. Unauthenticated requests to subpaths such as /api/_route_ or /admin/observe/info therefore reach protected business routes and management endpoints without being challenged for credentials. The /observe/info endpoint can disclose runtime metadata such as the user, working directory, home directory, process ID, JVM and operating system information.
This issue affects Apache Camel: from 4.14.1 before 4.14.6, from 4.18.0 before 4.18.2.
Users are recommended to upgrade to version 4.20.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, they are suggested to upgrade to 4.14.6. If users are on the 4.18.x LTS releases stream, they are suggested to upgrade to 4.18.2.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.apache.camel:camel-platform-http-mainMaven | >= 4.14.1, < 4.14.6 | 4.14.6 |
org.apache.camel:camel-platform-http-mainMaven | >= 4.18.0, < 4.18.2 | 4.18.2 |
org.apache.camel:camel-platform-http-mainMaven | >= 4.19.0, < 4.20.0 | 4.20.0 |
Affected products
1Patches
3a9ebee94af97chore: default authentication path to /* in platform-http-main
8 files changed · +268 −28
components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/authentication/BasicAuthenticationConfigurer.java+2 −14 modified@@ -23,21 +23,14 @@ import org.apache.camel.main.HttpManagementServerConfigurationProperties; import org.apache.camel.main.HttpServerConfigurationProperties; -import static org.apache.camel.util.ObjectHelper.isNotEmpty; - public class BasicAuthenticationConfigurer implements MainAuthenticationConfigurer { @Override public void configureAuthentication( AuthenticationConfig authenticationConfig, HttpServerConfigurationProperties properties) { String authPropertiesFileName = properties.getBasicPropertiesFile(); - String path - = isNotEmpty(properties.getAuthenticationPath()) ? properties.getAuthenticationPath() : properties.getPath(); - // root means to authenticate everything - if ("/".equals(path)) { - path = "/*"; - } + String path = resolveAuthenticationPath(properties.getAuthenticationPath(), properties.getPath()); AuthenticationConfigEntry entry = new AuthenticationConfigEntry(); entry.setPath(path); @@ -54,12 +47,7 @@ public void configureAuthentication( AuthenticationConfig authenticationConfig, HttpManagementServerConfigurationProperties properties) { String authPropertiesFileName = properties.getBasicPropertiesFile(); - String path - = isNotEmpty(properties.getAuthenticationPath()) ? properties.getAuthenticationPath() : properties.getPath(); - // root means to authenticate everything - if ("/".equals(path)) { - path = "/*"; - } + String path = resolveAuthenticationPath(properties.getAuthenticationPath(), properties.getPath()); AuthenticationConfigEntry entry = new AuthenticationConfigEntry(); entry.setPath(path);
components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/authentication/JWTAuthenticationConfigurer.java+2 −14 modified@@ -28,21 +28,14 @@ import org.apache.camel.main.HttpManagementServerConfigurationProperties; import org.apache.camel.main.HttpServerConfigurationProperties; -import static org.apache.camel.util.ObjectHelper.isNotEmpty; - public class JWTAuthenticationConfigurer implements MainAuthenticationConfigurer { @Override public void configureAuthentication( AuthenticationConfig authenticationConfig, HttpServerConfigurationProperties properties) { - String path - = isNotEmpty(properties.getAuthenticationPath()) ? properties.getAuthenticationPath() : properties.getPath(); - // root means to authenticate everything - if ("/".equals(path)) { - path = "/*"; - } + String path = resolveAuthenticationPath(properties.getAuthenticationPath(), properties.getPath()); AuthenticationConfigEntry entry = new AuthenticationConfigEntry(); entry.setPath(path); @@ -71,12 +64,7 @@ public void configureAuthentication( AuthenticationConfig authenticationConfig, HttpManagementServerConfigurationProperties properties) { - String path - = isNotEmpty(properties.getAuthenticationPath()) ? properties.getAuthenticationPath() : properties.getPath(); - // root means to authenticate everything - if ("/".equals(path)) { - path = "/*"; - } + String path = resolveAuthenticationPath(properties.getAuthenticationPath(), properties.getPath()); AuthenticationConfigEntry entry = new AuthenticationConfigEntry(); entry.setPath(path);
components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/authentication/MainAuthenticationConfigurer.java+12 −0 modified@@ -19,6 +19,7 @@ import org.apache.camel.component.platform.http.vertx.auth.AuthenticationConfig; import org.apache.camel.main.HttpManagementServerConfigurationProperties; import org.apache.camel.main.HttpServerConfigurationProperties; +import org.apache.camel.util.ObjectHelper; /** * Configure authentication on the embedded HTTP server. @@ -30,4 +31,15 @@ public interface MainAuthenticationConfigurer { void configureAuthentication( AuthenticationConfig authenticationConfig, HttpManagementServerConfigurationProperties properties); + /** + * Resolves the effective authentication path. When no explicit authentication path is configured, defaults to + * {@code /*} so that all subpaths under the context path are protected. + */ + default String resolveAuthenticationPath(String authenticationPath, String contextPath) { + if (ObjectHelper.isNotEmpty(authenticationPath)) { + return authenticationPath; + } + return "/*"; + } + }
components/camel-platform-http-main/src/test/java/org/apache/camel/component/platform/http/main/authentication/BasicAuthenticationNonRootPathTest.java+88 −0 added@@ -0,0 +1,88 @@ +/* + * 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.main.authentication; + +import org.apache.camel.CamelContext; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.main.Main; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import static io.restassured.RestAssured.given; +import static org.hamcrest.Matchers.equalTo; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +/** + * Tests that authentication is enforced on all subpaths when a non-root context path is configured and + * authenticationPath is not explicitly set. + */ +public class BasicAuthenticationNonRootPathTest { + + private static Main main; + + @BeforeAll + static void init() { + main = new Main(); + main.setPropertyPlaceholderLocations("basic-auth-nonroot-path.properties"); + main.configure().addRoutesBuilder(new PlatformHttpRouteBuilder()); + main.start(); + } + + @AfterAll + static void tearDown() { + main.stop(); + } + + @Test + public void testUnauthenticatedRequestToSubpathShouldReturn401() { + CamelContext camelContext = main.getCamelContext(); + assertNotNull(camelContext); + + // Unauthenticated request to a subpath must be rejected + given() + .when() + .get("/api/hello") + .then() + .statusCode(401) + .body(equalTo("Unauthorized")); + } + + @Test + public void testAuthenticatedRequestToSubpathShouldReturn200() { + CamelContext camelContext = main.getCamelContext(); + assertNotNull(camelContext); + + // With valid credentials, the request should succeed + given() + .auth().basic("camel", "propertiesPass") + .when() + .get("/api/hello") + .then() + .statusCode(200) + .body(equalTo("hello-response")); + } + + private static class PlatformHttpRouteBuilder extends RouteBuilder { + + @Override + public void configure() throws Exception { + from("platform-http:/hello?httpMethodRestrict=GET") + .setBody(constant("hello-response")); + } + } +}
components/camel-platform-http-main/src/test/java/org/apache/camel/component/platform/http/main/authentication/BasicAuthenticationSelectivePathTest.java+104 −0 added@@ -0,0 +1,104 @@ +/* + * 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.main.authentication; + +import org.apache.camel.CamelContext; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.main.Main; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import static io.restassured.RestAssured.given; +import static org.hamcrest.Matchers.equalTo; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +/** + * Tests that when an explicit authenticationPath is configured (e.g. /secure/*), only matching subpaths require + * authentication while other subpaths remain accessible without credentials. + */ +public class BasicAuthenticationSelectivePathTest { + + private static Main main; + + @BeforeAll + static void init() { + main = new Main(); + main.setPropertyPlaceholderLocations("basic-auth-nonroot-path-selective.properties"); + main.configure().addRoutesBuilder(new PlatformHttpRouteBuilder()); + main.start(); + } + + @AfterAll + static void tearDown() { + main.stop(); + } + + @Test + public void testUnauthenticatedRequestToSecurePathShouldReturn401() { + CamelContext camelContext = main.getCamelContext(); + assertNotNull(camelContext); + + // /secure/data is covered by authenticationPath=/secure/*, must require credentials + given() + .when() + .get("/api/secure/data") + .then() + .statusCode(401) + .body(equalTo("Unauthorized")); + } + + @Test + public void testAuthenticatedRequestToSecurePathShouldReturn200() { + CamelContext camelContext = main.getCamelContext(); + assertNotNull(camelContext); + + given() + .auth().basic("camel", "propertiesPass") + .when() + .get("/api/secure/data") + .then() + .statusCode(200) + .body(equalTo("secure-data-response")); + } + + @Test + public void testUnauthenticatedRequestToPublicPathShouldReturn200() { + CamelContext camelContext = main.getCamelContext(); + assertNotNull(camelContext); + + // /public is NOT covered by authenticationPath=/secure/*, so it should be accessible + given() + .when() + .get("/api/public") + .then() + .statusCode(200) + .body(equalTo("public-response")); + } + + private static class PlatformHttpRouteBuilder extends RouteBuilder { + + @Override + public void configure() throws Exception { + from("platform-http:/secure/data?httpMethodRestrict=GET") + .setBody(constant("secure-data-response")); + + from("platform-http:/public?httpMethodRestrict=GET") + .setBody(constant("public-response")); + } + } +}
components/camel-platform-http-main/src/test/resources/basic-auth-nonroot-path.properties+21 −0 added@@ -0,0 +1,21 @@ +## --------------------------------------------------------------------------- +## 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. +## --------------------------------------------------------------------------- +camel.server.enabled=true +camel.server.path=/api + +camel.server.authenticationEnabled=true +camel.server.basicPropertiesFile=camel-platform-http-vertx-auth.properties
components/camel-platform-http-main/src/test/resources/basic-auth-nonroot-path-selective.properties+22 −0 added@@ -0,0 +1,22 @@ +## --------------------------------------------------------------------------- +## 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. +## --------------------------------------------------------------------------- +camel.server.enabled=true +camel.server.path=/api + +camel.server.authenticationEnabled=true +camel.server.authenticationPath=/secure/* +camel.server.basicPropertiesFile=camel-platform-http-vertx-auth.properties
docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_14.adoc+17 −0 modified@@ -4,6 +4,23 @@ This document is for helping you upgrade your Apache Camel application from Camel 4.x to 4.y. For example, if you are upgrading Camel 4.0 to 4.2, then you should follow the guides from both 4.0 to 4.1 and 4.1 to 4.2. +== Upgrading from 4.14.5 to 4.14.6 + +=== camel-platform-http-main + +When `authenticationEnabled` is set to `true` and no explicit `authenticationPath` is configured, +the default authentication path is now `/*`. This means all subpaths under the configured context path +are protected by authentication. + +Previously, the authentication path defaulted to the value of `path` (e.g. `/api`), which only covered +that exact path. If you relied on this behavior and need selective path protection, set +`authenticationPath` explicitly: + +[source,properties] +---- +camel.server.authenticationPath=/secure/* +---- + == Upgrading from 4.14.2 to 4.14.3 === camel-tika
7b5b8c0283c0chore: default authentication path to /* in platform-http-main
8 files changed · +266 −27
components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/authentication/BasicAuthenticationConfigurer.java+2 −13 modified@@ -26,7 +26,6 @@ import org.apache.camel.main.HttpServerConfigurationProperties; import static io.vertx.ext.web.handler.BasicAuthHandler.DEFAULT_REALM; -import static org.apache.camel.util.ObjectHelper.isNotEmpty; public class BasicAuthenticationConfigurer implements MainAuthenticationConfigurer { @@ -35,12 +34,7 @@ public void configureAuthentication( AuthenticationConfig authenticationConfig, HttpServerConfigurationProperties properties) { String authPropertiesFileName = properties.getBasicPropertiesFile(); - String path - = isNotEmpty(properties.getAuthenticationPath()) ? properties.getAuthenticationPath() : properties.getPath(); - // root means to authenticate everything - if ("/".equals(path)) { - path = "/*"; - } + String path = resolveAuthenticationPath(properties.getAuthenticationPath(), properties.getPath()); String realm = properties.getAuthenticationRealm() != null ? properties.getAuthenticationRealm() : DEFAULT_REALM; AuthenticationConfigEntry entry = new AuthenticationConfigEntry(); @@ -64,12 +58,7 @@ public void configureAuthentication( AuthenticationConfig authenticationConfig, HttpManagementServerConfigurationProperties properties) { String authPropertiesFileName = properties.getBasicPropertiesFile(); - String path - = isNotEmpty(properties.getAuthenticationPath()) ? properties.getAuthenticationPath() : properties.getPath(); - // root means to authenticate everything - if ("/".equals(path)) { - path = "/*"; - } + String path = resolveAuthenticationPath(properties.getAuthenticationPath(), properties.getPath()); String realm = properties.getAuthenticationRealm() != null ? properties.getAuthenticationRealm() : DEFAULT_REALM; AuthenticationConfigEntry entry = new AuthenticationConfigEntry();
components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/authentication/JWTAuthenticationConfigurer.java+2 −14 modified@@ -28,21 +28,14 @@ import org.apache.camel.main.HttpManagementServerConfigurationProperties; import org.apache.camel.main.HttpServerConfigurationProperties; -import static org.apache.camel.util.ObjectHelper.isNotEmpty; - public class JWTAuthenticationConfigurer implements MainAuthenticationConfigurer { @Override public void configureAuthentication( AuthenticationConfig authenticationConfig, HttpServerConfigurationProperties properties) { - String path - = isNotEmpty(properties.getAuthenticationPath()) ? properties.getAuthenticationPath() : properties.getPath(); - // root means to authenticate everything - if ("/".equals(path)) { - path = "/*"; - } + String path = resolveAuthenticationPath(properties.getAuthenticationPath(), properties.getPath()); String realm = properties.getAuthenticationRealm() != null ? properties.getAuthenticationRealm() : null; AuthenticationConfigEntry entry = new AuthenticationConfigEntry(); @@ -72,12 +65,7 @@ public void configureAuthentication( AuthenticationConfig authenticationConfig, HttpManagementServerConfigurationProperties properties) { - String path - = isNotEmpty(properties.getAuthenticationPath()) ? properties.getAuthenticationPath() : properties.getPath(); - // root means to authenticate everything - if ("/".equals(path)) { - path = "/*"; - } + String path = resolveAuthenticationPath(properties.getAuthenticationPath(), properties.getPath()); String realm = properties.getAuthenticationRealm() != null ? properties.getAuthenticationRealm() : null; AuthenticationConfigEntry entry = new AuthenticationConfigEntry();
components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/authentication/MainAuthenticationConfigurer.java+12 −0 modified@@ -19,6 +19,7 @@ import org.apache.camel.component.platform.http.vertx.auth.AuthenticationConfig; import org.apache.camel.main.HttpManagementServerConfigurationProperties; import org.apache.camel.main.HttpServerConfigurationProperties; +import org.apache.camel.util.ObjectHelper; /** * Configure authentication on the embedded HTTP server. @@ -30,4 +31,15 @@ public interface MainAuthenticationConfigurer { void configureAuthentication( AuthenticationConfig authenticationConfig, HttpManagementServerConfigurationProperties properties); + /** + * Resolves the effective authentication path. When no explicit authentication path is configured, defaults to + * {@code /*} so that all subpaths under the context path are protected. + */ + default String resolveAuthenticationPath(String authenticationPath, String contextPath) { + if (ObjectHelper.isNotEmpty(authenticationPath)) { + return authenticationPath; + } + return "/*"; + } + }
components/camel-platform-http-main/src/test/java/org/apache/camel/component/platform/http/main/authentication/BasicAuthenticationNonRootPathTest.java+88 −0 added@@ -0,0 +1,88 @@ +/* + * 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.main.authentication; + +import org.apache.camel.CamelContext; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.main.Main; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import static io.restassured.RestAssured.given; +import static org.hamcrest.Matchers.equalTo; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +/** + * Tests that authentication is enforced on all subpaths when a non-root context path is configured and + * authenticationPath is not explicitly set. + */ +public class BasicAuthenticationNonRootPathTest { + + private static Main main; + + @BeforeAll + static void init() { + main = new Main(); + main.setPropertyPlaceholderLocations("basic-auth-nonroot-path.properties"); + main.configure().addRoutesBuilder(new PlatformHttpRouteBuilder()); + main.start(); + } + + @AfterAll + static void tearDown() { + main.stop(); + } + + @Test + public void testUnauthenticatedRequestToSubpathShouldReturn401() { + CamelContext camelContext = main.getCamelContext(); + assertNotNull(camelContext); + + // Unauthenticated request to a subpath must be rejected + given() + .when() + .get("/api/hello") + .then() + .statusCode(401) + .body(equalTo("Unauthorized")); + } + + @Test + public void testAuthenticatedRequestToSubpathShouldReturn200() { + CamelContext camelContext = main.getCamelContext(); + assertNotNull(camelContext); + + // With valid credentials, the request should succeed + given() + .auth().basic("camel", "propertiesPass") + .when() + .get("/api/hello") + .then() + .statusCode(200) + .body(equalTo("hello-response")); + } + + private static class PlatformHttpRouteBuilder extends RouteBuilder { + + @Override + public void configure() throws Exception { + from("platform-http:/hello?httpMethodRestrict=GET") + .setBody(constant("hello-response")); + } + } +}
components/camel-platform-http-main/src/test/java/org/apache/camel/component/platform/http/main/authentication/BasicAuthenticationSelectivePathTest.java+104 −0 added@@ -0,0 +1,104 @@ +/* + * 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.main.authentication; + +import org.apache.camel.CamelContext; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.main.Main; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import static io.restassured.RestAssured.given; +import static org.hamcrest.Matchers.equalTo; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +/** + * Tests that when an explicit authenticationPath is configured (e.g. /secure/*), only matching subpaths require + * authentication while other subpaths remain accessible without credentials. + */ +public class BasicAuthenticationSelectivePathTest { + + private static Main main; + + @BeforeAll + static void init() { + main = new Main(); + main.setPropertyPlaceholderLocations("basic-auth-nonroot-path-selective.properties"); + main.configure().addRoutesBuilder(new PlatformHttpRouteBuilder()); + main.start(); + } + + @AfterAll + static void tearDown() { + main.stop(); + } + + @Test + public void testUnauthenticatedRequestToSecurePathShouldReturn401() { + CamelContext camelContext = main.getCamelContext(); + assertNotNull(camelContext); + + // /secure/data is covered by authenticationPath=/secure/*, must require credentials + given() + .when() + .get("/api/secure/data") + .then() + .statusCode(401) + .body(equalTo("Unauthorized")); + } + + @Test + public void testAuthenticatedRequestToSecurePathShouldReturn200() { + CamelContext camelContext = main.getCamelContext(); + assertNotNull(camelContext); + + given() + .auth().basic("camel", "propertiesPass") + .when() + .get("/api/secure/data") + .then() + .statusCode(200) + .body(equalTo("secure-data-response")); + } + + @Test + public void testUnauthenticatedRequestToPublicPathShouldReturn200() { + CamelContext camelContext = main.getCamelContext(); + assertNotNull(camelContext); + + // /public is NOT covered by authenticationPath=/secure/*, so it should be accessible + given() + .when() + .get("/api/public") + .then() + .statusCode(200) + .body(equalTo("public-response")); + } + + private static class PlatformHttpRouteBuilder extends RouteBuilder { + + @Override + public void configure() throws Exception { + from("platform-http:/secure/data?httpMethodRestrict=GET") + .setBody(constant("secure-data-response")); + + from("platform-http:/public?httpMethodRestrict=GET") + .setBody(constant("public-response")); + } + } +}
components/camel-platform-http-main/src/test/resources/basic-auth-nonroot-path.properties+21 −0 added@@ -0,0 +1,21 @@ +## --------------------------------------------------------------------------- +## 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. +## --------------------------------------------------------------------------- +camel.server.enabled=true +camel.server.path=/api + +camel.server.authenticationEnabled=true +camel.server.basicPropertiesFile=camel-platform-http-vertx-auth.properties
components/camel-platform-http-main/src/test/resources/basic-auth-nonroot-path-selective.properties+22 −0 added@@ -0,0 +1,22 @@ +## --------------------------------------------------------------------------- +## 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. +## --------------------------------------------------------------------------- +camel.server.enabled=true +camel.server.path=/api + +camel.server.authenticationEnabled=true +camel.server.authenticationPath=/secure/* +camel.server.basicPropertiesFile=camel-platform-http-vertx-auth.properties
docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_19.adoc+15 −0 modified@@ -160,6 +160,21 @@ After: uri: mock:end ---- +=== camel-platform-http-main + +When `authenticationEnabled` is set to `true` and no explicit `authenticationPath` is configured, +the default authentication path is now `/*`. This means all subpaths under the configured context path +are protected by authentication. + +Previously, the authentication path defaulted to the value of `path` (e.g. `/api`), which only covered +that exact path. If you relied on this behavior and need selective path protection, set +`authenticationPath` explicitly: + +[source,properties] +---- +camel.server.authenticationPath=/secure/* +---- + === camel-csimple (Deprecation) The `csimple` (compiled simple) language has been deprecated. Use the `simple` language instead.
6ec12cbebfc1chore: default authentication path to /* in platform-http-main
8 files changed · +268 −28
components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/authentication/BasicAuthenticationConfigurer.java+2 −13 modified@@ -26,7 +26,6 @@ import org.apache.camel.main.HttpServerConfigurationProperties; import static io.vertx.ext.web.handler.BasicAuthHandler.DEFAULT_REALM; -import static org.apache.camel.util.ObjectHelper.isNotEmpty; public class BasicAuthenticationConfigurer implements MainAuthenticationConfigurer { @@ -35,12 +34,7 @@ public void configureAuthentication( AuthenticationConfig authenticationConfig, HttpServerConfigurationProperties properties) { String authPropertiesFileName = properties.getBasicPropertiesFile(); - String path - = isNotEmpty(properties.getAuthenticationPath()) ? properties.getAuthenticationPath() : properties.getPath(); - // root means to authenticate everything - if ("/".equals(path)) { - path = "/*"; - } + String path = resolveAuthenticationPath(properties.getAuthenticationPath(), properties.getPath()); String realm = properties.getAuthenticationRealm() != null ? properties.getAuthenticationRealm() : DEFAULT_REALM; AuthenticationConfigEntry entry = new AuthenticationConfigEntry(); @@ -64,12 +58,7 @@ public void configureAuthentication( AuthenticationConfig authenticationConfig, HttpManagementServerConfigurationProperties properties) { String authPropertiesFileName = properties.getBasicPropertiesFile(); - String path - = isNotEmpty(properties.getAuthenticationPath()) ? properties.getAuthenticationPath() : properties.getPath(); - // root means to authenticate everything - if ("/".equals(path)) { - path = "/*"; - } + String path = resolveAuthenticationPath(properties.getAuthenticationPath(), properties.getPath()); String realm = properties.getAuthenticationRealm() != null ? properties.getAuthenticationRealm() : DEFAULT_REALM; AuthenticationConfigEntry entry = new AuthenticationConfigEntry();
components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/authentication/JWTAuthenticationConfigurer.java+2 −14 modified@@ -28,21 +28,14 @@ import org.apache.camel.main.HttpManagementServerConfigurationProperties; import org.apache.camel.main.HttpServerConfigurationProperties; -import static org.apache.camel.util.ObjectHelper.isNotEmpty; - public class JWTAuthenticationConfigurer implements MainAuthenticationConfigurer { @Override public void configureAuthentication( AuthenticationConfig authenticationConfig, HttpServerConfigurationProperties properties) { - String path - = isNotEmpty(properties.getAuthenticationPath()) ? properties.getAuthenticationPath() : properties.getPath(); - // root means to authenticate everything - if ("/".equals(path)) { - path = "/*"; - } + String path = resolveAuthenticationPath(properties.getAuthenticationPath(), properties.getPath()); String realm = properties.getAuthenticationRealm() != null ? properties.getAuthenticationRealm() : null; AuthenticationConfigEntry entry = new AuthenticationConfigEntry(); @@ -72,12 +65,7 @@ public void configureAuthentication( AuthenticationConfig authenticationConfig, HttpManagementServerConfigurationProperties properties) { - String path - = isNotEmpty(properties.getAuthenticationPath()) ? properties.getAuthenticationPath() : properties.getPath(); - // root means to authenticate everything - if ("/".equals(path)) { - path = "/*"; - } + String path = resolveAuthenticationPath(properties.getAuthenticationPath(), properties.getPath()); String realm = properties.getAuthenticationRealm() != null ? properties.getAuthenticationRealm() : null; AuthenticationConfigEntry entry = new AuthenticationConfigEntry();
components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/authentication/MainAuthenticationConfigurer.java+12 −0 modified@@ -19,6 +19,7 @@ import org.apache.camel.component.platform.http.vertx.auth.AuthenticationConfig; import org.apache.camel.main.HttpManagementServerConfigurationProperties; import org.apache.camel.main.HttpServerConfigurationProperties; +import org.apache.camel.util.ObjectHelper; /** * Configure authentication on the embedded HTTP server. @@ -30,4 +31,15 @@ public interface MainAuthenticationConfigurer { void configureAuthentication( AuthenticationConfig authenticationConfig, HttpManagementServerConfigurationProperties properties); + /** + * Resolves the effective authentication path. When no explicit authentication path is configured, defaults to + * {@code /*} so that all subpaths under the context path are protected. + */ + default String resolveAuthenticationPath(String authenticationPath, String contextPath) { + if (ObjectHelper.isNotEmpty(authenticationPath)) { + return authenticationPath; + } + return "/*"; + } + }
components/camel-platform-http-main/src/test/java/org/apache/camel/component/platform/http/main/authentication/BasicAuthenticationNonRootPathTest.java+88 −0 added@@ -0,0 +1,88 @@ +/* + * 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.main.authentication; + +import org.apache.camel.CamelContext; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.main.Main; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import static io.restassured.RestAssured.given; +import static org.hamcrest.Matchers.equalTo; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +/** + * Tests that authentication is enforced on all subpaths when a non-root context path is configured and + * authenticationPath is not explicitly set. + */ +public class BasicAuthenticationNonRootPathTest { + + private static Main main; + + @BeforeAll + static void init() { + main = new Main(); + main.setPropertyPlaceholderLocations("basic-auth-nonroot-path.properties"); + main.configure().addRoutesBuilder(new PlatformHttpRouteBuilder()); + main.start(); + } + + @AfterAll + static void tearDown() { + main.stop(); + } + + @Test + public void testUnauthenticatedRequestToSubpathShouldReturn401() { + CamelContext camelContext = main.getCamelContext(); + assertNotNull(camelContext); + + // Unauthenticated request to a subpath must be rejected + given() + .when() + .get("/api/hello") + .then() + .statusCode(401) + .body(equalTo("Unauthorized")); + } + + @Test + public void testAuthenticatedRequestToSubpathShouldReturn200() { + CamelContext camelContext = main.getCamelContext(); + assertNotNull(camelContext); + + // With valid credentials, the request should succeed + given() + .auth().basic("camel", "propertiesPass") + .when() + .get("/api/hello") + .then() + .statusCode(200) + .body(equalTo("hello-response")); + } + + private static class PlatformHttpRouteBuilder extends RouteBuilder { + + @Override + public void configure() throws Exception { + from("platform-http:/hello?httpMethodRestrict=GET") + .setBody(constant("hello-response")); + } + } +}
components/camel-platform-http-main/src/test/java/org/apache/camel/component/platform/http/main/authentication/BasicAuthenticationSelectivePathTest.java+104 −0 added@@ -0,0 +1,104 @@ +/* + * 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.main.authentication; + +import org.apache.camel.CamelContext; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.main.Main; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import static io.restassured.RestAssured.given; +import static org.hamcrest.Matchers.equalTo; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +/** + * Tests that when an explicit authenticationPath is configured (e.g. /secure/*), only matching subpaths require + * authentication while other subpaths remain accessible without credentials. + */ +public class BasicAuthenticationSelectivePathTest { + + private static Main main; + + @BeforeAll + static void init() { + main = new Main(); + main.setPropertyPlaceholderLocations("basic-auth-nonroot-path-selective.properties"); + main.configure().addRoutesBuilder(new PlatformHttpRouteBuilder()); + main.start(); + } + + @AfterAll + static void tearDown() { + main.stop(); + } + + @Test + public void testUnauthenticatedRequestToSecurePathShouldReturn401() { + CamelContext camelContext = main.getCamelContext(); + assertNotNull(camelContext); + + // /secure/data is covered by authenticationPath=/secure/*, must require credentials + given() + .when() + .get("/api/secure/data") + .then() + .statusCode(401) + .body(equalTo("Unauthorized")); + } + + @Test + public void testAuthenticatedRequestToSecurePathShouldReturn200() { + CamelContext camelContext = main.getCamelContext(); + assertNotNull(camelContext); + + given() + .auth().basic("camel", "propertiesPass") + .when() + .get("/api/secure/data") + .then() + .statusCode(200) + .body(equalTo("secure-data-response")); + } + + @Test + public void testUnauthenticatedRequestToPublicPathShouldReturn200() { + CamelContext camelContext = main.getCamelContext(); + assertNotNull(camelContext); + + // /public is NOT covered by authenticationPath=/secure/*, so it should be accessible + given() + .when() + .get("/api/public") + .then() + .statusCode(200) + .body(equalTo("public-response")); + } + + private static class PlatformHttpRouteBuilder extends RouteBuilder { + + @Override + public void configure() throws Exception { + from("platform-http:/secure/data?httpMethodRestrict=GET") + .setBody(constant("secure-data-response")); + + from("platform-http:/public?httpMethodRestrict=GET") + .setBody(constant("public-response")); + } + } +}
components/camel-platform-http-main/src/test/resources/basic-auth-nonroot-path.properties+21 −0 added@@ -0,0 +1,21 @@ +## --------------------------------------------------------------------------- +## 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. +## --------------------------------------------------------------------------- +camel.server.enabled=true +camel.server.path=/api + +camel.server.authenticationEnabled=true +camel.server.basicPropertiesFile=camel-platform-http-vertx-auth.properties
components/camel-platform-http-main/src/test/resources/basic-auth-nonroot-path-selective.properties+22 −0 added@@ -0,0 +1,22 @@ +## --------------------------------------------------------------------------- +## 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. +## --------------------------------------------------------------------------- +camel.server.enabled=true +camel.server.path=/api + +camel.server.authenticationEnabled=true +camel.server.authenticationPath=/secure/* +camel.server.basicPropertiesFile=camel-platform-http-vertx-auth.properties
docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_18.adoc+17 −1 modified@@ -11,6 +11,23 @@ Note that manual migration is still required. See the xref:camel-upgrade-recipes-tool.adoc[documentation] page for details. ==== +== Upgrading from 4.18.1 to 4.18.2 + +=== camel-platform-http-main + +When `authenticationEnabled` is set to `true` and no explicit `authenticationPath` is configured, +the default authentication path is now `/*`. This means all subpaths under the configured context path +are protected by authentication. + +Previously, the authentication path defaulted to the value of `path` (e.g. `/api`), which only covered +that exact path. If you relied on this behavior and need selective path protection, set +`authenticationPath` explicitly: + +[source,properties] +---- +camel.server.authenticationPath=/secure/* +---- + == Upgrading Camel 4.17 to 4.18 === camel-simple @@ -91,7 +108,6 @@ to the API specification. All together this would make Camel behave similar for Rest DSL for both _code first_ and _contract first_ style. - === camel-ftp (SFTP) and camel-jsch (SCP) ==== JSch upgrade
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
10- www.openwall.com/lists/oss-security/2026/04/26/5nvdMailing ListThird Party AdvisoryWEB
- camel.apache.org/security/CVE-2026-40022.htmlnvdVendor AdvisoryWEB
- github.com/advisories/GHSA-27vm-5vpj-rp5gghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2026-40022ghsaADVISORY
- github.com/apache/camel/commit/6ec12cbebfc1b6360cdaac1c1f8c681864911695ghsaWEB
- github.com/apache/camel/commit/7b5b8c0283c0ab8d703d868ded7614018762a553ghsaWEB
- github.com/apache/camel/commit/a9ebee94af976ac2afd7906d2e76673067d8be86ghsaWEB
- github.com/apache/camel/pull/22474ghsaWEB
- github.com/apache/camel/pull/22475ghsaWEB
- github.com/apache/camel/pull/22476ghsaWEB
News mentions
0No linked articles in our index yet.