VYPR
Low severity3.1GHSA Advisory· Published May 16, 2025· Updated Apr 15, 2026

CVE-2025-22233

CVE-2025-22233

Description

CVE-2024-38820 ensured Locale-independent, lowercase conversion for both the configured disallowedFields patterns and for request parameter names. However, there are still cases where it is possible to bypass the disallowedFields checks.

Affected Spring Products and Versions

Spring Framework: * 6.2.0 - 6.2.6

  • 6.1.0 - 6.1.19
  • 6.0.0 - 6.0.27
  • 5.3.0 - 5.3.42
  • Older, unsupported versions are also affected

Mitigation

Users of affected versions should upgrade to the corresponding fixed version.

Affected version(s)Fix Version Availability 6.2.x 6.2.7 OSS6.1.x 6.1.20 OSS6.0.x 6.0.28 Commercial https://enterprise.spring.io/ 5.3.x 5.3.43 Commercial https://enterprise.spring.io/ No further mitigation steps are necessary.

Generally, we recommend using a dedicated model object with properties only for data binding, or using constructor binding since constructor arguments explicitly declare what to bind together with turning off setter binding through the declarativeBinding flag. See the Model Design section in the reference documentation.

For setting binding, prefer the use of allowedFields (an explicit list) over disallowedFields.

Credit

This issue was responsibly reported by the TERASOLUNA Framework Development Team from NTT DATA Group Corporation.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

A bypass of disallowedFields checks in Spring Framework data binding remains possible after incomplete fix for CVE-2024-38820.

Vulnerability

Overview

CVE-2025-22233 is a security vulnerability in Spring Framework where the data binding mechanism can bypass the disallowedFields check, even after the incomplete fix for CVE-2024-38820 was applied. The previous fix ensured locale-independent, lowercase conversion for both disallowedFields patterns and request parameter names, but the issue persists in other cases [1]. The affected versions include Spring Framework 5.3.x up to 5.3.42, 6.0.x up to 6.0.27, 6.1.x up to 6.1.19, and 6.2.x up to 6.2.6 [1].

Root

Cause and Exploitation

The problem lies in how the framework performs pattern matching for disallowed fields. In the fix commits (edfcc6f and ee62701), the handling was updated to use the PatternMatchUtils with an ignore-case option, removing the earlier locale-based conversion [2][3]. The change notes indicate that the default implementation stores patterns in canonical form and makes pattern matching case-insensitive. However, the advisory confirms that bypass is still possible, suggesting additional attack vectors remain [1]. The attack requires network access and a valid (low-privileged) user session, as reflected by the CVSS vector [4].

Impact

A successful bypass allows an attacker to bind malicious request parameters to fields that were intended to be blocked by the disallowedFields list. This could lead to unintended data modification on the server side. The CVSS v3 base score is 3.1 (Low), with no impact on confidentiality or availability, but a low impact on integrity [4]. The attack complexity is high, and user interaction is not required [4].

Mitigation

Users should upgrade to the fixed versions: 6.2.7 (open source), 6.1.20 (open source), 6.0.28 (commercial), or 5.3.43 (commercial) [1]. No additional mitigation steps are necessary beyond upgrading. The vendor recommends preferring allowedFields over disallowedFields and using dedicated model objects or constructor binding as defensive measures [1].

AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.springframework:spring-contextMaven
>= 6.2.0, < 6.2.76.2.7
org.springframework:spring-contextMaven
>= 6.1.0, < 6.1.206.1.20
org.springframework:spring-contextMaven
>= 6.0.0, <= 6.0.23
org.springframework:spring-contextMaven
<= 5.3.39

Affected products

1

Patches

2
ee62701f5634

Make use of PatternMatchUtils ignoreCase option

1 file changed · +18 16
  • spring-context/src/main/java/org/springframework/validation/DataBinder.java+18 16 modified
    @@ -27,7 +27,6 @@
     import java.util.HashMap;
     import java.util.HashSet;
     import java.util.List;
    -import java.util.Locale;
     import java.util.Map;
     import java.util.Optional;
     import java.util.Set;
    @@ -550,14 +549,13 @@ public String[] getAllowedFields() {
     	 * <p>Mark fields as disallowed, for example to avoid unwanted
     	 * modifications by malicious users when binding HTTP request parameters.
     	 * <p>Supports {@code "xxx*"}, {@code "*xxx"}, {@code "*xxx*"}, and
    -	 * {@code "xxx*yyy"} matches (with an arbitrary number of pattern parts), as
    -	 * well as direct equality.
    -	 * <p>The default implementation of this method stores disallowed field patterns
    -	 * in {@linkplain PropertyAccessorUtils#canonicalPropertyName(String) canonical}
    -	 * form and also transforms disallowed field patterns to
    -	 * {@linkplain String#toLowerCase() lowercase} to support case-insensitive
    -	 * pattern matching in {@link #isAllowed}. Subclasses which override this
    -	 * method must therefore take both of these transformations into account.
    +	 * {@code "xxx*yyy"} matches (with an arbitrary number of pattern parts),
    +	 * as well as direct equality.
    +	 * <p>The default implementation of this method stores disallowed field
    +	 * patterns in {@linkplain PropertyAccessorUtils#canonicalPropertyName(String)
    +	 * canonical} form, and subsequently pattern matching in {@link #isAllowed}
    +	 * is case-insensitive. Subclasses that override this method must therefore
    +	 * take this transformation into account.
     	 * <p>More sophisticated matching can be implemented by overriding the
     	 * {@link #isAllowed} method.
     	 * <p>Alternatively, specify a list of <i>allowed</i> field patterns.
    @@ -575,8 +573,7 @@ public void setDisallowedFields(@Nullable String... disallowedFields) {
     		else {
     			String[] fieldPatterns = new String[disallowedFields.length];
     			for (int i = 0; i < fieldPatterns.length; i++) {
    -				String field = PropertyAccessorUtils.canonicalPropertyName(disallowedFields[i]);
    -				fieldPatterns[i] = field.toLowerCase(Locale.ROOT);
    +				fieldPatterns[i] = PropertyAccessorUtils.canonicalPropertyName(disallowedFields[i]);
     			}
     			this.disallowedFields = fieldPatterns;
     		}
    @@ -1302,9 +1299,9 @@ protected void checkAllowedFields(MutablePropertyValues mpvs) {
     	 * Determine if the given field is allowed for binding.
     	 * <p>Invoked for each passed-in property value.
     	 * <p>Checks for {@code "xxx*"}, {@code "*xxx"}, {@code "*xxx*"}, and
    -	 * {@code "xxx*yyy"} matches (with an arbitrary number of pattern parts), as
    -	 * well as direct equality, in the configured lists of allowed field patterns
    -	 * and disallowed field patterns.
    +	 * {@code "xxx*yyy"} matches (with an arbitrary number of pattern parts),
    +	 * as well as direct equality, in the configured lists of allowed field
    +	 * patterns and disallowed field patterns.
     	 * <p>Matching against allowed field patterns is case-sensitive; whereas,
     	 * matching against disallowed field patterns is case-insensitive.
     	 * <p>A field matching a disallowed pattern will not be accepted even if it
    @@ -1320,8 +1317,13 @@ protected void checkAllowedFields(MutablePropertyValues mpvs) {
     	protected boolean isAllowed(String field) {
     		String[] allowed = getAllowedFields();
     		String[] disallowed = getDisallowedFields();
    -		return ((ObjectUtils.isEmpty(allowed) || PatternMatchUtils.simpleMatch(allowed, field)) &&
    -				(ObjectUtils.isEmpty(disallowed) || !PatternMatchUtils.simpleMatch(disallowed, field.toLowerCase(Locale.ROOT))));
    +		if (!ObjectUtils.isEmpty(allowed) && !PatternMatchUtils.simpleMatch(allowed, field)) {
    +			return false;
    +		}
    +		if (!ObjectUtils.isEmpty(disallowed)) {
    +			return !PatternMatchUtils.simpleMatchIgnoreCase(disallowed, field);
    +		}
    +		return true;
     	}
     
     	/**
    
edfcc6ffb188

Make use of PatternMatchUtils ignoreCase option

1 file changed · +18 17
  • spring-context/src/main/java/org/springframework/validation/DataBinder.java+18 17 modified
    @@ -27,7 +27,6 @@
     import java.util.HashMap;
     import java.util.HashSet;
     import java.util.List;
    -import java.util.Locale;
     import java.util.Map;
     import java.util.Optional;
     import java.util.Set;
    @@ -543,15 +542,13 @@ public String[] getAllowedFields() {
     	 * <p>Mark fields as disallowed, for example to avoid unwanted
     	 * modifications by malicious users when binding HTTP request parameters.
     	 * <p>Supports {@code "xxx*"}, {@code "*xxx"}, {@code "*xxx*"}, and
    -	 * {@code "xxx*yyy"} matches (with an arbitrary number of pattern parts), as
    -	 * well as direct equality.
    -	 * <p>The default implementation of this method stores disallowed field patterns
    -	 * in {@linkplain PropertyAccessorUtils#canonicalPropertyName(String) canonical}
    -	 * form. As of Spring Framework 5.2.21, the default implementation also transforms
    -	 * disallowed field patterns to {@linkplain String#toLowerCase() lowercase} to
    -	 * support case-insensitive pattern matching in {@link #isAllowed}. Subclasses
    -	 * which override this method must therefore take both of these transformations
    -	 * into account.
    +	 * {@code "xxx*yyy"} matches (with an arbitrary number of pattern parts),
    +	 * as well as direct equality.
    +	 * <p>The default implementation of this method stores disallowed field
    +	 * patterns in {@linkplain PropertyAccessorUtils#canonicalPropertyName(String)
    +	 * canonical} form, and subsequently pattern matching in {@link #isAllowed}
    +	 * is case-insensitive. Subclasses that override this method must therefore
    +	 * take this transformation into account.
     	 * <p>More sophisticated matching can be implemented by overriding the
     	 * {@link #isAllowed} method.
     	 * <p>Alternatively, specify a list of <i>allowed</i> field patterns.
    @@ -569,8 +566,7 @@ public void setDisallowedFields(@Nullable String... disallowedFields) {
     		else {
     			String[] fieldPatterns = new String[disallowedFields.length];
     			for (int i = 0; i < fieldPatterns.length; i++) {
    -				String field = PropertyAccessorUtils.canonicalPropertyName(disallowedFields[i]);
    -				fieldPatterns[i] = field.toLowerCase(Locale.ROOT);
    +				fieldPatterns[i] = PropertyAccessorUtils.canonicalPropertyName(disallowedFields[i]);
     			}
     			this.disallowedFields = fieldPatterns;
     		}
    @@ -1140,9 +1136,9 @@ protected void checkAllowedFields(MutablePropertyValues mpvs) {
     	 * Determine if the given field is allowed for binding.
     	 * <p>Invoked for each passed-in property value.
     	 * <p>Checks for {@code "xxx*"}, {@code "*xxx"}, {@code "*xxx*"}, and
    -	 * {@code "xxx*yyy"} matches (with an arbitrary number of pattern parts), as
    -	 * well as direct equality, in the configured lists of allowed field patterns
    -	 * and disallowed field patterns.
    +	 * {@code "xxx*yyy"} matches (with an arbitrary number of pattern parts),
    +	 * as well as direct equality, in the configured lists of allowed field
    +	 * patterns and disallowed field patterns.
     	 * <p>Matching against allowed field patterns is case-sensitive; whereas,
     	 * matching against disallowed field patterns is case-insensitive.
     	 * <p>A field matching a disallowed pattern will not be accepted even if it
    @@ -1158,8 +1154,13 @@ protected void checkAllowedFields(MutablePropertyValues mpvs) {
     	protected boolean isAllowed(String field) {
     		String[] allowed = getAllowedFields();
     		String[] disallowed = getDisallowedFields();
    -		return ((ObjectUtils.isEmpty(allowed) || PatternMatchUtils.simpleMatch(allowed, field)) &&
    -				(ObjectUtils.isEmpty(disallowed) || !PatternMatchUtils.simpleMatch(disallowed, field.toLowerCase(Locale.ROOT))));
    +		if (!ObjectUtils.isEmpty(allowed) && !PatternMatchUtils.simpleMatch(allowed, field)) {
    +			return false;
    +		}
    +		if (!ObjectUtils.isEmpty(disallowed)) {
    +			return !PatternMatchUtils.simpleMatchIgnoreCase(disallowed, field);
    +		}
    +		return true;
     	}
     
     	/**
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

7

News mentions

0

No linked articles in our index yet.