From 7c317b53b91b878a6d090e9dea437c46ce1e6dd2 Mon Sep 17 00:00:00 2001 From: Erius2579 Date: Mon, 9 Feb 2026 06:50:29 +0100 Subject: [PATCH 1/2] Fix non-ASCII characters in headers being rejected (#5377) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add HttpFirewall bean to allow non-ASCII characters in header values - Configure StrictHttpFirewall to accept valid UTF-8 encoded header values - Fixes issue where Remote-User header with non-ASCII characters (e.g., "Dvořák") was rejected with 400 Bad Request even when authentication is disabled - Also allow non-ASCII characters in parameter values for consistency Fixes #5377 --- .../configuration/SecurityConfiguration.java | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/app/proprietary/src/main/java/stirling/software/proprietary/security/configuration/SecurityConfiguration.java b/app/proprietary/src/main/java/stirling/software/proprietary/security/configuration/SecurityConfiguration.java index 64c92488b3..9d99c63a35 100644 --- a/app/proprietary/src/main/java/stirling/software/proprietary/security/configuration/SecurityConfiguration.java +++ b/app/proprietary/src/main/java/stirling/software/proprietary/security/configuration/SecurityConfiguration.java @@ -28,6 +28,8 @@ import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository; +import org.springframework.security.web.firewall.HttpFirewall; +import org.springframework.security.web.firewall.StrictHttpFirewall; import org.springframework.security.web.savedrequest.NullRequestCache; import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher; import org.springframework.web.cors.CorsConfiguration; @@ -136,6 +138,57 @@ public static PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } + /** + * Configures HttpFirewall to allow non-ASCII characters in header values. + * This fixes issues with reverse proxies (like Authelia) that may set headers + * with non-ASCII characters (e.g., "Remote-User: Dvořák"). + * + *

By default, StrictHttpFirewall rejects header values containing non-ASCII characters. + * This configuration allows valid UTF-8 encoded characters while maintaining security. + * + * @return Configured HttpFirewall that allows non-ASCII characters in headers + */ + @Bean + public HttpFirewall httpFirewall() { + StrictHttpFirewall firewall = new StrictHttpFirewall(); + // Allow non-ASCII characters in header values + // This is needed for reverse proxies that may set headers with non-ASCII usernames + firewall.setAllowedHeaderValues( + headerValue -> { + if (headerValue == null) { + return false; + } + // Allow all header values including non-ASCII characters + // The default StrictHttpFirewall rejects non-ASCII, but we need to allow + // them for headers like Remote-User that may contain international names + // This fixes issue #5377 where Remote-User header with non-ASCII + // characters (e.g., "Dvořák") was rejected with 400 Bad Request + try { + // Validate that the value is valid UTF-8 + headerValue.getBytes(java.nio.charset.StandardCharsets.UTF_8); + return true; + } catch (Exception e) { + // Reject invalid encoding + return false; + } + }); + // Also allow non-ASCII in parameter values for consistency + firewall.setAllowedParameterValues( + parameterValue -> { + if (parameterValue == null) { + return false; + } + try { + // Validate UTF-8 encoding + parameterValue.getBytes(java.nio.charset.StandardCharsets.UTF_8); + return true; + } catch (Exception e) { + return false; + } + }); + return firewall; + } + @Bean public CorsConfigurationSource corsConfigurationSource() { List configuredOrigins = null; From c4a0bde4999401bfc3c75ead27e0af349b52598b Mon Sep 17 00:00:00 2001 From: Erius2579 Date: Tue, 17 Mar 2026 19:58:48 +0100 Subject: [PATCH 2/2] Refine HttpFirewall header validation for issue #5377 Made-with: Cursor --- .../configuration/SecurityConfiguration.java | 54 ++++++------------- 1 file changed, 16 insertions(+), 38 deletions(-) diff --git a/app/proprietary/src/main/java/stirling/software/proprietary/security/configuration/SecurityConfiguration.java b/app/proprietary/src/main/java/stirling/software/proprietary/security/configuration/SecurityConfiguration.java index 9d99c63a35..df5c4ce5f5 100644 --- a/app/proprietary/src/main/java/stirling/software/proprietary/security/configuration/SecurityConfiguration.java +++ b/app/proprietary/src/main/java/stirling/software/proprietary/security/configuration/SecurityConfiguration.java @@ -1,6 +1,7 @@ package stirling.software.proprietary.security.configuration; import java.util.List; +import java.util.regex.Pattern; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; @@ -139,53 +140,30 @@ public static PasswordEncoder passwordEncoder() { } /** - * Configures HttpFirewall to allow non-ASCII characters in header values. - * This fixes issues with reverse proxies (like Authelia) that may set headers - * with non-ASCII characters (e.g., "Remote-User: Dvořák"). + * Configures HttpFirewall to allow non-ASCII characters in header values. This fixes issues + * with reverse proxies (like Authelia) that may set headers with non-ASCII characters (e.g., + * "Remote-User: Dvořák"). * - *

By default, StrictHttpFirewall rejects header values containing non-ASCII characters. - * This configuration allows valid UTF-8 encoded characters while maintaining security. + *

By default, StrictHttpFirewall rejects header values containing non-ASCII characters. This + * configuration allows valid UTF-8 encoded characters while maintaining security. * * @return Configured HttpFirewall that allows non-ASCII characters in headers */ @Bean public HttpFirewall httpFirewall() { StrictHttpFirewall firewall = new StrictHttpFirewall(); - // Allow non-ASCII characters in header values - // This is needed for reverse proxies that may set headers with non-ASCII usernames + // Allow non-ASCII characters but continue to reject control characters such as newlines. + // Pattern adapted from Spring Security's StrictHttpFirewall documentation. + Pattern allowedChars = Pattern.compile("[\\p{IsAssigned}&&[^\\p{IsControl}]]*"); + firewall.setAllowedHeaderValues( - headerValue -> { - if (headerValue == null) { - return false; - } - // Allow all header values including non-ASCII characters - // The default StrictHttpFirewall rejects non-ASCII, but we need to allow - // them for headers like Remote-User that may contain international names - // This fixes issue #5377 where Remote-User header with non-ASCII - // characters (e.g., "Dvořák") was rejected with 400 Bad Request - try { - // Validate that the value is valid UTF-8 - headerValue.getBytes(java.nio.charset.StandardCharsets.UTF_8); - return true; - } catch (Exception e) { - // Reject invalid encoding - return false; - } - }); - // Also allow non-ASCII in parameter values for consistency + headerValue -> + headerValue != null && allowedChars.matcher(headerValue).matches()); + + // Apply the same rules to parameter values for consistency. firewall.setAllowedParameterValues( - parameterValue -> { - if (parameterValue == null) { - return false; - } - try { - // Validate UTF-8 encoding - parameterValue.getBytes(java.nio.charset.StandardCharsets.UTF_8); - return true; - } catch (Exception e) { - return false; - } - }); + parameterValue -> + parameterValue != null && allowedChars.matcher(parameterValue).matches()); return firewall; }