From 48df79ce5784160eb1af02cc03581cffbeef84fd Mon Sep 17 00:00:00 2001 From: Richard Salac Date: Fri, 17 Jul 2026 10:39:43 +0200 Subject: [PATCH] cherry-pick Signed-off-by: Richard Salac --- .github/workflows/integration-tests.yml | 2 ++ .../src/main/resources/bin/start.sh | 2 ++ .../ApimlStrictServerWebExchangeFirewall.java | 2 +- .../config/NewSecurityConfiguration.java | 30 +++++++++++++++---- 4 files changed, 29 insertions(+), 7 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index a281531946..9794fdaa27 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -147,12 +147,14 @@ jobs: env: APIML_SECURITY_X509_ACCEPTFORWARDEDCERT: true APIML_SECURITY_X509_CERTIFICATESURL: https://cloud-gateway-service:10023/gateway/certificates + APIML_SECURITY_ENABLESTRICTURLVALIDATION: false gateway-service-2: image: ghcr.io/balhar-jakub/gateway-service:${{ github.run_id }}-${{ github.run_number }} env: APIML_SERVICE_HOSTNAME: gateway-service-2 APIML_SERVICE_APIMLID: apiml2 SERVER_INTERNAL_PORT: 10027 + APIML_SECURITY_ENABLESTRICTURLVALIDATION: false cloud-gateway-service: image: ghcr.io/balhar-jakub/cloud-gateway-service:${{ github.run_id }}-${{ github.run_number }} env: diff --git a/gateway-package/src/main/resources/bin/start.sh b/gateway-package/src/main/resources/bin/start.sh index 315457e0d0..b1a5b26041 100755 --- a/gateway-package/src/main/resources/bin/start.sh +++ b/gateway-package/src/main/resources/bin/start.sh @@ -54,6 +54,7 @@ # - ZWE_configs_apiml_security_authorization_provider # - ZWE_configs_apiml_security_authorization_resourceClass # - ZWE_configs_apiml_security_authorization_resourceNamePrefix +# - ZWE_configs_apiml_security_enableStrictUrlValidation # - ZWE_configs_apiml_security_jwtInitializerTimeout # - ZWE_configs_apiml_security_useInternalMapper # - ZWE_configs_apiml_security_x509_enabled @@ -376,6 +377,7 @@ _BPX_JOBNAME=${ZWE_zowe_job_prefix}${GATEWAY_CODE} java \ -Dapiml.security.authorization.provider=${ZWE_configs_apiml_security_authorization_provider:-} \ -Dapiml.security.authorization.resourceClass=${ZWE_configs_apiml_security_authorization_resourceClass:-ZOWE} \ -Dapiml.security.authorization.resourceNamePrefix=${ZWE_configs_apiml_security_authorization_resourceNamePrefix:-APIML.} \ + -Dapiml.security.enableStrictUrlValidation=${ZWE_configs_apiml_security_enableStrictUrlValidation:-true} \ -Dapiml.security.forwardHeader.trustedProxies=${ZWE_configs_apiml_security_forwardHeader_trustedProxies:-${ZWE_components_cloudGateway_apiml_security_forwardHeader_trustedProxies:-}} \ -Dapiml.security.jwtInitializerTimeout=${ZWE_configs_apiml_security_jwtInitializerTimeout:-5} \ -Dapiml.security.oidc.clientId=${ZWE_configs_apiml_security_oidc_clientId:-} \ diff --git a/gateway-service/src/main/java/org/zowe/apiml/gateway/security/config/ApimlStrictServerWebExchangeFirewall.java b/gateway-service/src/main/java/org/zowe/apiml/gateway/security/config/ApimlStrictServerWebExchangeFirewall.java index bddf19cd77..6a0386a37c 100644 --- a/gateway-service/src/main/java/org/zowe/apiml/gateway/security/config/ApimlStrictServerWebExchangeFirewall.java +++ b/gateway-service/src/main/java/org/zowe/apiml/gateway/security/config/ApimlStrictServerWebExchangeFirewall.java @@ -26,7 +26,7 @@ public class ApimlStrictServerWebExchangeFirewall extends StrictHttpFirewall { "/api-doc" }; - private StrictHttpFirewall nonRoutingFirewall = new StrictHttpFirewall(); + private StrictHttpFirewall nonRoutingFirewall = new StrictHttpFirewall(); boolean isPathToRoute(String path, String[] prefixes) { // homepage diff --git a/gateway-service/src/main/java/org/zowe/apiml/gateway/security/config/NewSecurityConfiguration.java b/gateway-service/src/main/java/org/zowe/apiml/gateway/security/config/NewSecurityConfiguration.java index c3e684cdcb..d06a8c5ed5 100644 --- a/gateway-service/src/main/java/org/zowe/apiml/gateway/security/config/NewSecurityConfiguration.java +++ b/gateway-service/src/main/java/org/zowe/apiml/gateway/security/config/NewSecurityConfiguration.java @@ -120,6 +120,9 @@ public class NewSecurityConfiguration { @Value("${apiml.health.protected:false}") private boolean isHealthEndpointProtected; + @Value("${apiml.security.enableStrictUrlValidation:true}") + private boolean isStrictUrlValidationEnabled; + /** * Login and Logout endpoints *

@@ -598,12 +601,7 @@ class DefaultSecurity { // Web security only needs to be configured once, putting it to multiple filter chains causes multiple evaluations of the same rules @Bean public WebSecurityCustomizer webSecurityCustomizer() { - StrictHttpFirewall firewall = new ApimlStrictServerWebExchangeFirewall(); - firewall.setAllowUrlEncodedSlash(true); - firewall.setAllowBackSlash(true); - firewall.setAllowUrlEncodedPercent(true); - firewall.setAllowUrlEncodedPeriod(true); - firewall.setAllowSemicolon(true); + final StrictHttpFirewall firewall = buildHttpFirewall(); return web -> { web.httpFirewall(firewall); @@ -623,6 +621,26 @@ public WebSecurityCustomizer webSecurityCustomizer() { } }; } + + /** + * Strict URL validation is enabled by default. Setting + * apiml.security.enableStrictUrlValidation=false reverts to the original, relaxed + * behavior where routed requests allow encoded slashes, backslashes, percent, period + * and semicolon characters. + */ + private StrictHttpFirewall buildHttpFirewall() { + if (isStrictUrlValidationEnabled) { + return new StrictHttpFirewall(); + } + + ApimlStrictServerWebExchangeFirewall firewall = new ApimlStrictServerWebExchangeFirewall(); + firewall.setAllowUrlEncodedSlash(true); + firewall.setAllowBackSlash(true); + firewall.setAllowUrlEncodedPercent(true); + firewall.setAllowUrlEncodedPeriod(true); + firewall.setAllowSemicolon(true); + return firewall; + } } @Bean