From a8c4d6ceada54d150ab21b6489b5c9d1c657b889 Mon Sep 17 00:00:00 2001 From: Joe Grandja <10884212+jgrandja@users.noreply.github.com> Date: Mon, 28 Oct 2024 07:38:45 -0400 Subject: [PATCH] Require Locale argument for toLower/toUpperCase usage --- ...romAssertionAttributesUserDetailsService.java | 4 +++- .../config/http/HttpConfigurationBuilder.java | 5 +++-- .../AuthenticationObservationConvention.java | 6 ++++-- ...impleAttributes2GrantedAuthoritiesMapper.java | 6 +++--- .../authority/mapping/SimpleAuthorityMapper.java | 7 ++++--- .../MapReactiveUserDetailsService.java | 5 +++-- .../userdetails/memory/UserAttributeEditor.java | 5 +++-- .../provisioning/InMemoryUserDetailsManager.java | 15 ++++++++------- .../crypto/password/LdapShaPasswordEncoder.java | 7 ++++--- etc/checkstyle/checkstyle-suppressions.xml | 4 ++++ etc/checkstyle/checkstyle.xml | 16 ++++++++++++++++ .../security/ldap/LdapEncoder.java | 6 ++++-- .../ldap/authentication/LdapEncoder.java | 6 ++++-- ...ctiveDirectoryLdapAuthenticationProvider.java | 11 ++++++----- .../DefaultLdapAuthoritiesPopulator.java | 3 ++- .../ldap/userdetails/LdapUserDetailsManager.java | 7 ++++--- .../ldap/userdetails/LdapUserDetailsMapper.java | 3 ++- .../NestedLdapAuthoritiesPopulator.java | 5 +++-- ...h2AuthorizedClientExchangeFilterFunction.java | 5 +++-- ...h2AuthorizedClientExchangeFilterFunction.java | 5 +++-- .../taglibs/authz/AbstractAuthorizeTag.java | 5 +++-- .../security/web/PortResolverImpl.java | 4 +++- .../security/web/util/UrlUtils.java | 3 ++- .../web/util/matcher/AntPathRequestMatcher.java | 7 ++++--- 24 files changed, 98 insertions(+), 52 deletions(-) diff --git a/cas/src/main/java/org/springframework/security/cas/userdetails/GrantedAuthorityFromAssertionAttributesUserDetailsService.java b/cas/src/main/java/org/springframework/security/cas/userdetails/GrantedAuthorityFromAssertionAttributesUserDetailsService.java index df19e1033a9..517120aa46c 100644 --- a/cas/src/main/java/org/springframework/security/cas/userdetails/GrantedAuthorityFromAssertionAttributesUserDetailsService.java +++ b/cas/src/main/java/org/springframework/security/cas/userdetails/GrantedAuthorityFromAssertionAttributesUserDetailsService.java @@ -18,6 +18,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Locale; import org.apereo.cas.client.validation.Assertion; @@ -73,7 +74,8 @@ protected UserDetails loadUserDetails(final Assertion assertion) { } private SimpleGrantedAuthority createSimpleGrantedAuthority(Object o) { - return new SimpleGrantedAuthority(this.convertToUpperCase ? o.toString().toUpperCase() : o.toString()); + return new SimpleGrantedAuthority( + this.convertToUpperCase ? o.toString().toUpperCase(Locale.ROOT) : o.toString()); } /** diff --git a/config/src/main/java/org/springframework/security/config/http/HttpConfigurationBuilder.java b/config/src/main/java/org/springframework/security/config/http/HttpConfigurationBuilder.java index e8526a3540d..53635b5aa0b 100644 --- a/config/src/main/java/org/springframework/security/config/http/HttpConfigurationBuilder.java +++ b/config/src/main/java/org/springframework/security/config/http/HttpConfigurationBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Locale; import io.micrometer.observation.ObservationRegistry; import jakarta.servlet.ServletRequest; @@ -313,7 +314,7 @@ void setCsrfIgnoreRequestMatchers(List requestMatchers) { // Needed to account for placeholders static String createPath(String path, boolean lowerCase) { - return lowerCase ? path.toLowerCase() : path; + return lowerCase ? path.toLowerCase(Locale.ENGLISH) : path; } BeanMetadataElement getSecurityContextHolderStrategyForAuthenticationFilters() { diff --git a/core/src/main/java/org/springframework/security/authentication/AuthenticationObservationConvention.java b/core/src/main/java/org/springframework/security/authentication/AuthenticationObservationConvention.java index 149fa275dbc..4d0b6c693da 100644 --- a/core/src/main/java/org/springframework/security/authentication/AuthenticationObservationConvention.java +++ b/core/src/main/java/org/springframework/security/authentication/AuthenticationObservationConvention.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,8 @@ package org.springframework.security.authentication; +import java.util.Locale; + import io.micrometer.common.KeyValues; import io.micrometer.observation.Observation; import io.micrometer.observation.ObservationConvention; @@ -53,7 +55,7 @@ public String getContextualName(AuthenticationObservationContext context) { if (authenticationType.endsWith("Authentication")) { authenticationType = authenticationType.substring(0, authenticationType.lastIndexOf("Authentication")); } - return "authenticate " + authenticationType.toLowerCase(); + return "authenticate " + authenticationType.toLowerCase(Locale.ENGLISH); } return "authenticate"; } diff --git a/core/src/main/java/org/springframework/security/core/authority/mapping/SimpleAttributes2GrantedAuthoritiesMapper.java b/core/src/main/java/org/springframework/security/core/authority/mapping/SimpleAttributes2GrantedAuthoritiesMapper.java index c07137bb8fc..3e907f89209 100755 --- a/core/src/main/java/org/springframework/security/core/authority/mapping/SimpleAttributes2GrantedAuthoritiesMapper.java +++ b/core/src/main/java/org/springframework/security/core/authority/mapping/SimpleAttributes2GrantedAuthoritiesMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -79,10 +79,10 @@ public List getGrantedAuthorities(Collection attribute */ private GrantedAuthority getGrantedAuthority(String attribute) { if (isConvertAttributeToLowerCase()) { - attribute = attribute.toLowerCase(Locale.getDefault()); + attribute = attribute.toLowerCase(Locale.ROOT); } else if (isConvertAttributeToUpperCase()) { - attribute = attribute.toUpperCase(Locale.getDefault()); + attribute = attribute.toUpperCase(Locale.ROOT); } if (isAddPrefixIfAlreadyExisting() || !attribute.startsWith(getAttributePrefix())) { return new SimpleGrantedAuthority(getAttributePrefix() + attribute); diff --git a/core/src/main/java/org/springframework/security/core/authority/mapping/SimpleAuthorityMapper.java b/core/src/main/java/org/springframework/security/core/authority/mapping/SimpleAuthorityMapper.java index 2bb66a73b67..18af306e727 100644 --- a/core/src/main/java/org/springframework/security/core/authority/mapping/SimpleAuthorityMapper.java +++ b/core/src/main/java/org/springframework/security/core/authority/mapping/SimpleAuthorityMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ import java.util.Collection; import java.util.HashSet; +import java.util.Locale; import java.util.Set; import org.springframework.beans.factory.InitializingBean; @@ -71,10 +72,10 @@ public Set mapAuthorities(Collection 0 && !name.startsWith(this.prefix)) { name = this.prefix + name; diff --git a/core/src/main/java/org/springframework/security/core/userdetails/MapReactiveUserDetailsService.java b/core/src/main/java/org/springframework/security/core/userdetails/MapReactiveUserDetailsService.java index 10712776a73..ecb459bc3cc 100644 --- a/core/src/main/java/org/springframework/security/core/userdetails/MapReactiveUserDetailsService.java +++ b/core/src/main/java/org/springframework/security/core/userdetails/MapReactiveUserDetailsService.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ import java.util.Arrays; import java.util.Collection; +import java.util.Locale; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -91,7 +92,7 @@ private UserDetails withNewPassword(UserDetails userDetails, String newPassword) } private String getKey(String username) { - return username.toLowerCase(); + return username.toLowerCase(Locale.ROOT); } } diff --git a/core/src/main/java/org/springframework/security/core/userdetails/memory/UserAttributeEditor.java b/core/src/main/java/org/springframework/security/core/userdetails/memory/UserAttributeEditor.java index 09f10c18d0b..2b6422e2cb4 100644 --- a/core/src/main/java/org/springframework/security/core/userdetails/memory/UserAttributeEditor.java +++ b/core/src/main/java/org/springframework/security/core/userdetails/memory/UserAttributeEditor.java @@ -19,6 +19,7 @@ import java.beans.PropertyEditorSupport; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import org.springframework.util.StringUtils; @@ -45,10 +46,10 @@ public void setAsText(String s) throws IllegalArgumentException { userAttrib.setPassword(currentToken); } else { - if (currentToken.toLowerCase().equals("enabled")) { + if (currentToken.toLowerCase(Locale.ENGLISH).equals("enabled")) { userAttrib.setEnabled(true); } - else if (currentToken.toLowerCase().equals("disabled")) { + else if (currentToken.toLowerCase(Locale.ENGLISH).equals("disabled")) { userAttrib.setEnabled(false); } else { diff --git a/core/src/main/java/org/springframework/security/provisioning/InMemoryUserDetailsManager.java b/core/src/main/java/org/springframework/security/provisioning/InMemoryUserDetailsManager.java index 9faac275e03..6381b8b7627 100644 --- a/core/src/main/java/org/springframework/security/provisioning/InMemoryUserDetailsManager.java +++ b/core/src/main/java/org/springframework/security/provisioning/InMemoryUserDetailsManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ import java.util.Collection; import java.util.Enumeration; import java.util.HashMap; +import java.util.Locale; import java.util.Map; import java.util.Properties; @@ -96,23 +97,23 @@ private User createUserDetails(String name, UserAttribute attr) { @Override public void createUser(UserDetails user) { Assert.isTrue(!userExists(user.getUsername()), "user should not exist"); - this.users.put(user.getUsername().toLowerCase(), new MutableUser(user)); + this.users.put(user.getUsername().toLowerCase(Locale.ROOT), new MutableUser(user)); } @Override public void deleteUser(String username) { - this.users.remove(username.toLowerCase()); + this.users.remove(username.toLowerCase(Locale.ROOT)); } @Override public void updateUser(UserDetails user) { Assert.isTrue(userExists(user.getUsername()), "user should exist"); - this.users.put(user.getUsername().toLowerCase(), new MutableUser(user)); + this.users.put(user.getUsername().toLowerCase(Locale.ROOT), new MutableUser(user)); } @Override public boolean userExists(String username) { - return this.users.containsKey(username.toLowerCase()); + return this.users.containsKey(username.toLowerCase(Locale.ROOT)); } @Override @@ -143,14 +144,14 @@ public void changePassword(String oldPassword, String newPassword) { @Override public UserDetails updatePassword(UserDetails user, String newPassword) { String username = user.getUsername(); - MutableUserDetails mutableUser = this.users.get(username.toLowerCase()); + MutableUserDetails mutableUser = this.users.get(username.toLowerCase(Locale.ROOT)); mutableUser.setPassword(newPassword); return mutableUser; } @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { - UserDetails user = this.users.get(username.toLowerCase()); + UserDetails user = this.users.get(username.toLowerCase(Locale.ROOT)); if (user == null) { throw new UsernameNotFoundException(username); } diff --git a/crypto/src/main/java/org/springframework/security/crypto/password/LdapShaPasswordEncoder.java b/crypto/src/main/java/org/springframework/security/crypto/password/LdapShaPasswordEncoder.java index eb9687c0fc0..35f7224a7c8 100644 --- a/crypto/src/main/java/org/springframework/security/crypto/password/LdapShaPasswordEncoder.java +++ b/crypto/src/main/java/org/springframework/security/crypto/password/LdapShaPasswordEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ import java.security.MessageDigest; import java.util.Base64; +import java.util.Locale; import org.springframework.security.crypto.codec.Utf8; import org.springframework.security.crypto.keygen.BytesKeyGenerator; @@ -50,11 +51,11 @@ public class LdapShaPasswordEncoder implements PasswordEncoder { private static final String SSHA_PREFIX = "{SSHA}"; - private static final String SSHA_PREFIX_LC = SSHA_PREFIX.toLowerCase(); + private static final String SSHA_PREFIX_LC = SSHA_PREFIX.toLowerCase(Locale.ENGLISH); private static final String SHA_PREFIX = "{SHA}"; - private static final String SHA_PREFIX_LC = SHA_PREFIX.toLowerCase(); + private static final String SHA_PREFIX_LC = SHA_PREFIX.toLowerCase(Locale.ENGLISH); private BytesKeyGenerator saltGenerator; diff --git a/etc/checkstyle/checkstyle-suppressions.xml b/etc/checkstyle/checkstyle-suppressions.xml index 74b7de0b19b..15c4b900adf 100644 --- a/etc/checkstyle/checkstyle-suppressions.xml +++ b/etc/checkstyle/checkstyle-suppressions.xml @@ -40,4 +40,8 @@ + + + + diff --git a/etc/checkstyle/checkstyle.xml b/etc/checkstyle/checkstyle.xml index 343114cf765..9b4b616eb0e 100644 --- a/etc/checkstyle/checkstyle.xml +++ b/etc/checkstyle/checkstyle.xml @@ -30,5 +30,21 @@ + + + + + + + + + + + + + + diff --git a/ldap/src/main/java/org/springframework/security/ldap/LdapEncoder.java b/ldap/src/main/java/org/springframework/security/ldap/LdapEncoder.java index a3911aa180d..57d45a444cc 100644 --- a/ldap/src/main/java/org/springframework/security/ldap/LdapEncoder.java +++ b/ldap/src/main/java/org/springframework/security/ldap/LdapEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2005-2010 the original author or authors. + * Copyright 2005-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,8 @@ package org.springframework.security.ldap; +import java.util.Locale; + import org.springframework.ldap.BadLdapGrammarException; /** @@ -72,7 +74,7 @@ private LdapEncoder() { } protected static String toTwoCharHex(char c) { - String raw = Integer.toHexString(c).toUpperCase(); + String raw = Integer.toHexString(c).toUpperCase(Locale.ENGLISH); return (raw.length() > 1) ? raw : "0" + raw; } diff --git a/ldap/src/main/java/org/springframework/security/ldap/authentication/LdapEncoder.java b/ldap/src/main/java/org/springframework/security/ldap/authentication/LdapEncoder.java index f79f4843ae2..e037e3d2efd 100644 --- a/ldap/src/main/java/org/springframework/security/ldap/authentication/LdapEncoder.java +++ b/ldap/src/main/java/org/springframework/security/ldap/authentication/LdapEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2005-2010 the original author or authors. + * Copyright 2005-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,8 @@ package org.springframework.security.ldap.authentication; +import java.util.Locale; + import org.springframework.ldap.BadLdapGrammarException; /** @@ -72,7 +74,7 @@ private LdapEncoder() { } protected static String toTwoCharHex(char c) { - String raw = Integer.toHexString(c).toUpperCase(); + String raw = Integer.toHexString(c).toUpperCase(Locale.ENGLISH); return (raw.length() > 1) ? raw : "0" + raw; } diff --git a/ldap/src/main/java/org/springframework/security/ldap/authentication/ad/ActiveDirectoryLdapAuthenticationProvider.java b/ldap/src/main/java/org/springframework/security/ldap/authentication/ad/ActiveDirectoryLdapAuthenticationProvider.java index f4cb4830576..a85d316f6d0 100644 --- a/ldap/src/main/java/org/springframework/security/ldap/authentication/ad/ActiveDirectoryLdapAuthenticationProvider.java +++ b/ldap/src/main/java/org/springframework/security/ldap/authentication/ad/ActiveDirectoryLdapAuthenticationProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ import java.util.HashMap; import java.util.Hashtable; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -144,9 +145,9 @@ public final class ActiveDirectoryLdapAuthenticationProvider extends AbstractLda */ public ActiveDirectoryLdapAuthenticationProvider(String domain, String url, String rootDn) { Assert.isTrue(StringUtils.hasText(url), "Url cannot be empty"); - this.domain = StringUtils.hasText(domain) ? domain.toLowerCase() : null; + this.domain = StringUtils.hasText(domain) ? domain.toLowerCase(Locale.ROOT) : null; this.url = url; - this.rootDn = StringUtils.hasText(rootDn) ? rootDn.toLowerCase() : null; + this.rootDn = StringUtils.hasText(rootDn) ? rootDn.toLowerCase(Locale.ROOT) : null; } /** @@ -155,7 +156,7 @@ public ActiveDirectoryLdapAuthenticationProvider(String domain, String url, Stri */ public ActiveDirectoryLdapAuthenticationProvider(String domain, String url) { Assert.isTrue(StringUtils.hasText(url), "Url cannot be empty"); - this.domain = StringUtils.hasText(domain) ? domain.toLowerCase() : null; + this.domain = StringUtils.hasText(domain) ? domain.toLowerCase(Locale.ROOT) : null; this.url = url; this.rootDn = (this.domain != null) ? rootDnFromDomain(this.domain) : null; } @@ -350,7 +351,7 @@ private String rootDnFromDomain(String domain) { } String createBindPrincipal(String username) { - if (this.domain == null || username.toLowerCase().endsWith(this.domain)) { + if (this.domain == null || username.toLowerCase(Locale.ROOT).endsWith(this.domain)) { return username; } return username + "@" + this.domain; diff --git a/ldap/src/main/java/org/springframework/security/ldap/userdetails/DefaultLdapAuthoritiesPopulator.java b/ldap/src/main/java/org/springframework/security/ldap/userdetails/DefaultLdapAuthoritiesPopulator.java index b69985d2b4a..a57fd4ca8e0 100644 --- a/ldap/src/main/java/org/springframework/security/ldap/userdetails/DefaultLdapAuthoritiesPopulator.java +++ b/ldap/src/main/java/org/springframework/security/ldap/userdetails/DefaultLdapAuthoritiesPopulator.java @@ -20,6 +20,7 @@ import java.util.Collection; import java.util.HashSet; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.function.Function; @@ -179,7 +180,7 @@ else if (groupSearchBase.length() == 0) { return null; } if (this.convertToUpperCase) { - role = role.toUpperCase(); + role = role.toUpperCase(Locale.ROOT); } return new SimpleGrantedAuthority(this.rolePrefix + role); }; diff --git a/ldap/src/main/java/org/springframework/security/ldap/userdetails/LdapUserDetailsManager.java b/ldap/src/main/java/org/springframework/security/ldap/userdetails/LdapUserDetailsManager.java index 4b69532e8da..92c089ac131 100644 --- a/ldap/src/main/java/org/springframework/security/ldap/userdetails/LdapUserDetailsManager.java +++ b/ldap/src/main/java/org/springframework/security/ldap/userdetails/LdapUserDetailsManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ import java.util.LinkedList; import java.util.List; import java.util.ListIterator; +import java.util.Locale; import javax.naming.Context; import javax.naming.NameNotFoundException; @@ -124,7 +125,7 @@ public class LdapUserDetailsManager implements UserDetailsManager { NamingEnumeration ne = roleAttr.getAll(); Object group = ne.next(); String role = group.toString(); - return new SimpleGrantedAuthority(this.rolePrefix + role.toUpperCase()); + return new SimpleGrantedAuthority(this.rolePrefix + role.toUpperCase(Locale.ROOT)); }; private String[] attributesToRetrieve; @@ -289,7 +290,7 @@ public boolean userExists(String username) { @Deprecated protected DistinguishedName buildGroupDn(String group) { DistinguishedName dn = new DistinguishedName(this.groupSearchBase); - dn.add(this.groupRoleAttributeName, group.toLowerCase()); + dn.add(this.groupRoleAttributeName, group.toLowerCase(Locale.ROOT)); return dn; } diff --git a/ldap/src/main/java/org/springframework/security/ldap/userdetails/LdapUserDetailsMapper.java b/ldap/src/main/java/org/springframework/security/ldap/userdetails/LdapUserDetailsMapper.java index 470c8d7842e..4ee85ee4462 100644 --- a/ldap/src/main/java/org/springframework/security/ldap/userdetails/LdapUserDetailsMapper.java +++ b/ldap/src/main/java/org/springframework/security/ldap/userdetails/LdapUserDetailsMapper.java @@ -17,6 +17,7 @@ package org.springframework.security.ldap.userdetails; import java.util.Collection; +import java.util.Locale; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -127,7 +128,7 @@ protected String mapPassword(Object passwordValue) { protected GrantedAuthority createAuthority(Object role) { if (role instanceof String) { if (this.convertToUpperCase) { - role = ((String) role).toUpperCase(); + role = ((String) role).toUpperCase(Locale.ROOT); } return new SimpleGrantedAuthority(this.rolePrefix + role); } diff --git a/ldap/src/main/java/org/springframework/security/ldap/userdetails/NestedLdapAuthoritiesPopulator.java b/ldap/src/main/java/org/springframework/security/ldap/userdetails/NestedLdapAuthoritiesPopulator.java index b61068ec8f5..5726513d303 100644 --- a/ldap/src/main/java/org/springframework/security/ldap/userdetails/NestedLdapAuthoritiesPopulator.java +++ b/ldap/src/main/java/org/springframework/security/ldap/userdetails/NestedLdapAuthoritiesPopulator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ import java.util.HashSet; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Set; @@ -193,7 +194,7 @@ private void performNestedSearch(String userDn, String username, Set parseAuthParameters(String wwwAuthenticateHeader) { // @formatter:off return Stream.of(wwwAuthenticateHeader) .filter((header) -> StringUtils.hasLength(header)) - .filter((header) -> header.toLowerCase().startsWith("bearer")) + .filter((header) -> header.toLowerCase(Locale.ENGLISH).startsWith("bearer")) .map((header) -> header.substring("bearer".length())) .map((header) -> header.split(",")) .flatMap(Stream::of) diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/reactive/function/client/ServletOAuth2AuthorizedClientExchangeFilterFunction.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/reactive/function/client/ServletOAuth2AuthorizedClientExchangeFilterFunction.java index d03f648d04d..abd0397e71f 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/reactive/function/client/ServletOAuth2AuthorizedClientExchangeFilterFunction.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/reactive/function/client/ServletOAuth2AuthorizedClientExchangeFilterFunction.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ import java.util.Collections; import java.util.HashMap; +import java.util.Locale; import java.util.Map; import java.util.function.Consumer; import java.util.stream.Collectors; @@ -654,7 +655,7 @@ private OAuth2Error resolveErrorIfPossible(int statusCode) { private Map parseAuthParameters(String wwwAuthenticateHeader) { // @formatter:off return Stream.of(wwwAuthenticateHeader).filter((header) -> StringUtils.hasLength(header)) - .filter((header) -> header.toLowerCase().startsWith("bearer")) + .filter((header) -> header.toLowerCase(Locale.ENGLISH).startsWith("bearer")) .map((header) -> header.substring("bearer".length())) .map((header) -> header.split(",")) .flatMap(Stream::of) diff --git a/taglibs/src/main/java/org/springframework/security/taglibs/authz/AbstractAuthorizeTag.java b/taglibs/src/main/java/org/springframework/security/taglibs/authz/AbstractAuthorizeTag.java index ff688940352..a778359fabd 100644 --- a/taglibs/src/main/java/org/springframework/security/taglibs/authz/AbstractAuthorizeTag.java +++ b/taglibs/src/main/java/org/springframework/security/taglibs/authz/AbstractAuthorizeTag.java @@ -1,5 +1,5 @@ /* - * Copyright 2004-2022 the original author or authors. + * Copyright 2004-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package org.springframework.security.taglibs.authz; import java.io.IOException; +import java.util.Locale; import java.util.Map; import jakarta.servlet.ServletContext; @@ -169,7 +170,7 @@ public String getMethod() { } public void setMethod(String method) { - this.method = (method != null) ? method.toUpperCase() : null; + this.method = (method != null) ? method.toUpperCase(Locale.ENGLISH) : null; } private SecurityContext getContext() { diff --git a/web/src/main/java/org/springframework/security/web/PortResolverImpl.java b/web/src/main/java/org/springframework/security/web/PortResolverImpl.java index 94c200e216a..037838d8cbd 100644 --- a/web/src/main/java/org/springframework/security/web/PortResolverImpl.java +++ b/web/src/main/java/org/springframework/security/web/PortResolverImpl.java @@ -16,6 +16,8 @@ package org.springframework.security.web; +import java.util.Locale; + import jakarta.servlet.ServletRequest; import org.springframework.util.Assert; @@ -45,7 +47,7 @@ public PortMapper getPortMapper() { @Override public int getServerPort(ServletRequest request) { int serverPort = request.getServerPort(); - String scheme = request.getScheme().toLowerCase(); + String scheme = request.getScheme().toLowerCase(Locale.ENGLISH); Integer mappedPort = getMappedPort(serverPort, scheme); return (mappedPort != null) ? mappedPort : serverPort; } diff --git a/web/src/main/java/org/springframework/security/web/util/UrlUtils.java b/web/src/main/java/org/springframework/security/web/util/UrlUtils.java index e1346a86b7e..3098b69794f 100644 --- a/web/src/main/java/org/springframework/security/web/util/UrlUtils.java +++ b/web/src/main/java/org/springframework/security/web/util/UrlUtils.java @@ -16,6 +16,7 @@ package org.springframework.security.web.util; +import java.util.Locale; import java.util.regex.Pattern; import jakarta.servlet.http.HttpServletRequest; @@ -49,7 +50,7 @@ public static String buildFullRequestUrl(HttpServletRequest r) { */ public static String buildFullRequestUrl(String scheme, String serverName, int serverPort, String requestURI, String queryString) { - scheme = scheme.toLowerCase(); + scheme = scheme.toLowerCase(Locale.ENGLISH); StringBuilder url = new StringBuilder(); url.append(scheme).append("://").append(serverName); // Only add port if not default diff --git a/web/src/main/java/org/springframework/security/web/util/matcher/AntPathRequestMatcher.java b/web/src/main/java/org/springframework/security/web/util/matcher/AntPathRequestMatcher.java index da9874b4d9e..e3049b83742 100644 --- a/web/src/main/java/org/springframework/security/web/util/matcher/AntPathRequestMatcher.java +++ b/web/src/main/java/org/springframework/security/web/util/matcher/AntPathRequestMatcher.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package org.springframework.security.web.util.matcher; import java.util.Collections; +import java.util.Locale; import java.util.Map; import jakarta.servlet.http.HttpServletRequest; @@ -303,7 +304,7 @@ private static final class SubpathMatcher implements Matcher { private SubpathMatcher(String subpath, boolean caseSensitive) { Assert.isTrue(!subpath.contains("*"), "subpath cannot contain \"*\""); - this.subpath = caseSensitive ? subpath : subpath.toLowerCase(); + this.subpath = caseSensitive ? subpath : subpath.toLowerCase(Locale.ROOT); this.length = subpath.length(); this.caseSensitive = caseSensitive; } @@ -311,7 +312,7 @@ private SubpathMatcher(String subpath, boolean caseSensitive) { @Override public boolean matches(String path) { if (!this.caseSensitive) { - path = path.toLowerCase(); + path = path.toLowerCase(Locale.ROOT); } return path.startsWith(this.subpath) && (path.length() == this.length || path.charAt(this.length) == '/'); }