A new vulnerability, CVE-2025-22233, has been discovered in the Spring Framework. This issue is a follow-up to CVE-2024-38820, which tried to make sure both parameter names and blocked field patterns were compared in a case-insensitive way that didn’t depend on any system locale. Despite this, researchers found ways to get through Spring’s "disallowedFields" data binding check. Let’s break down what this means for developers, look at the affected versions, see some simple exploit examples, and understand the best way to stay safe.
Background: Data Binding in Spring
Data binding lets Spring automatically match HTTP request parameters (like those in a form or JSON post) to Java objects in your app. To keep attackers from matching (or "binding") sensitive request data to fields you don’t want exposed, Spring lets you use disallowedFields — a list of fields that should *never* be automatically set.
Here’s how it works in a controller
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.setDisallowedFields("admin", "role", "isSuperUser");
}
This tells Spring, "Never bind these fields from user input."
What Went Wrong? (The "Bypass" Problem)
After CVE-2024-38820, Spring compared both the blocked field list and the incoming parameter names in a way that should ignore locale (so "ROLE" or "role" would not sneak by). However, researchers from the TERASOLUNA Framework Development Team at NTT DATA found there are still cases where a smart attacker can bypass this field check.
Example Exploit
The bypass happens thanks to *unexpected representations* of field names, especially by using Unicode characters or alternate encodings that are not properly lowercased by Java’s default toLowerCase method.
Attack scenario: User submits a request with a tricky parameter such as adm\u200bin (where \u200b is a zero-width space) or uses a strange Unicode character that looks similar to l in "role" but isn’t caught by simple case conversions.
Send this as a POST request
POST /updateUser
Content-Type: application/x-www-form-urlencoded
user=alice&roℓe=admin
*(Here, ‘ℓ’ is Unicode U+2113, a different character than lowercase l—role will not match if the blocklist doesn’t use normalization beyond locale and lowercase.)*
Or, using a sneaky invisible character
user=alice&admin=true
*(The second “admin” includes a zero-width space.)*
If Spring only lowercases parameter names (but doesn’t normalize for Unicode visually-similar or invisible characters), the disallowedFields protection is bypassed, and an attacker can bind whatever they want.
Upgrade! The safest thing to do is to get to a fixed version
| Affected version(s) | Fixed Version | Available at |
|---------------------|--------------|--------------|
| 6.2.x | 6.2.7 | OSS |
| 6.1.x | 6.1.20 | OSS |
| 6..x | 6..28 | Commercial|
| 5.3.x | 5.3.43 | Commercial|
No further mitigation is necessary once you upgrade.
Use dedicated model objects for binding user input—not your core domain objects.
4. To make things even safer, use constructor binding. This way, only explicitly provided inputs become part of your model.
Reference material for model design:
https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-controller/ann-methods/modelattrs.html#webmvc-ann-model-design
TL;DR
- This issue allows attackers to bypass field restrictions in Spring’s data binding, potentially leading to privilege escalations or data tampering.
Upgrade to 6.2.7, 6.1.20, 6..28, or 5.3.43 (as appropriate) to stay safe.
- See the official advisory CVE-2024-38820 for original details.
Credit
Thanks to the TERASOLUNA Framework Development Team from NTT DATA Group Corporation for responsible reporting.
*Stay safe and always keep your frameworks up to date!*
Timeline
Published on: 05/16/2025 20:15:22 UTC
Last modified on: 05/19/2025 13:35:20 UTC