CVE-2026-41840
This Vulnerability has been fixed in the Never-Ending Support (NES) version offered by HeroDevs.
Overview
Spring Framework is the foundational application framework for the Java platform, providing dependency injection, web frameworks, data access, and more. Its reactive web stack, Spring WebFlux, includes a fully reactive multipart codec in the spring-web module. When a WebFlux application accepts a multipart/form-data request, the codec streams the request body through MultipartParser, which emits buffered tokens to PartGenerator, which in turn assembles each Part and spills large file parts to a temporary file on disk. Each buffered token carries a reference-counted DataBuffer that must be released once it has been consumed or discarded.
A medium-severity vulnerability (CVE-2026-41840) has been identified in this reactive multipart pipeline. Under specific conditions, buffers carried by multipart tokens are not released, so each affected request leaks reference-counted (often native, pooled) memory. An attacker who can send multipart requests to a WebFlux endpoint can repeatedly trigger the condition to leak memory and, over time, exhaust the application's resources and deny service.
Per OWASP, a Denial of Service (DoS) attack is meant to shut down a machine or network, making it inaccessible to its intended users, by flooding the target with traffic or sending it information that triggers a crash. This issue is the resource-exhaustion variant: a remote actor does not crash the service with a single request but drives it toward failure by repeatedly leaking memory through an otherwise normal-looking feature.
The CVSS v3.1 base score for this vulnerability is 5.9 (Medium) with vector AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H. The attack vector is Network because the multipart request is sent over HTTP, attack complexity is High because triggering the leak depends on timing-sensitive conditions such as slow temporary-file creation under load or a client that aborts the upload mid-stream, and no privileges or user interaction are required. The impact is Availability-only and High; there is no confidentiality or integrity impact because the flaw leaks and fails to release buffers rather than exposing or modifying data.
This issue affects Spring Framework >=5.3.0 <=5.3.48, >=6.1.0 <=6.1.27, >=6.2.0 <=6.2.18, and >=7.0.0 <=7.0.7.
Details
Module Info
- Product: Spring Framework
- Affected packages: spring-web
- Affected versions: >=5.3.0 <=5.3.48, >=6.1.0 <=6.1.27, >=6.2.0 <=6.2.18, >=7.0.0 <=7.0.7
- GitHub repository: https://github.com/spring-projects/spring-framework
- Published packages: https://central.sonatype.com/artifact/org.springframework/spring-web
- Package manager: Maven
- Fixed in:
- NES for Spring Framework 5.3.x, 6.1.x
- Spring Framework 7.0.8, 6.2.19 (OSS)
Vulnerability Info
The vulnerability is in the reactive multipart codec of the spring-web module, specifically in the interaction between MultipartParser, PartGenerator, and DefaultPartHttpMessageReader in package org.springframework.http.codec.multipart. This codec is used only by the reactive Spring WebFlux stack; classic Spring MVC multipart handling is not affected. The pipeline parses an incoming multipart/form-data body into a stream of tokens, each BodyToken carrying a reference-counted DataBuffer. Large file parts are written to a temporary file rather than held in memory, and the buffers backing the streamed tokens must be released after they are consumed or when the stream is discarded.
There are two related leak conditions. First, while PartGenerator is in its CreateFileState (the brief window during which a temporary file is being created for a large part), the generator could still request and receive a new BodyToken. In that state the token is invalid and is rejected with Body token not expected, which fails the entire request pipeline and leaks the DataBuffer the rejected token carried. This is most likely to occur when temporary-file creation is slow relative to the upload rate, for example under concurrency or on a slow filesystem. Second, on the error path that rejects a request for exceeding the configured maximum number of parts, the remaining queued tokens were discarded without releasing their buffers.
Pre-fix, the CreateFileState did not prevent the generator from requesting additional tokens, and the too-many-parts branch in DefaultPartHttpMessageReader emitted the error directly without draining outstanding buffers
// PartGenerator: CreateFileState had no canRequest() override, so the
// default (requesting allowed) applied while the temp file was being created.
// DefaultPartHttpMessageReader: too-many-parts path
return Mono.error(new DecodingException("Too many parts (" + partCount.get() + "/" +
this.maxParts + " allowed)"));
The reactive multipart codec was introduced in Spring Framework 5.3.0. Spring Framework 4.3.x and earlier have no reactive WebFlux multipart parser and are not affected by this issue. The advisory's listed range starting at 5.3.0 reflects both the supported scope and the feature's introduction point.
Steps To Reproduce
1. Deploy a Spring WebFlux application on an affected Spring Framework version (for example 6.1.27 or 5.3.48) that exposes an endpoint accepting multipart/form-data, for example a controller method with a @RequestPart or Flux<Part> parameter, running on a reactive server such as Reactor Netty.
2. Configure or rely on the default behavior whereby file parts larger than the in-memory threshold are spilled to temporary files on disk, so that uploads exercise the CreateFileState / temporary-file path of PartGenerator.
3. Send many concurrent multipart requests with large file parts, using a load generator with a short client-side timeout so that a meaningful fraction of connections abort mid-upload. The combination of slow temporary-file creation under load and client aborts drives the pipeline into the unreleased-buffer conditions described above.
4. Run the JVM with Netty leak detection enabled to observe the leak directly:
-Dio.netty.leakDetection.level=advancedThe application log will show LEAK: ByteBuf.release() was not called before it's garbage-collected reports originating in the multipart parsing path, and process memory will trend upward across the run.
5. Repeat the load against a fixed version (7.0.8, 6.2.19, or a HeroDevs NES build). The leak reports no longer appear and memory use stabilizes, because the outstanding buffers are now released on every abort and error path.
Mitigation
Only recent versions of Spring Framework receive community support and updates. The 5.3.x and 6.1.x lines no longer receive open-source security fixes for this vulnerability; the upstream fix for those lines ships only in the Commercial (Enterprise) releases.
Users of the affected components should apply one of the following mitigations:
- Upgrade to a currently supported version of Spring Framework. The OSS fix ships in Spring Framework 7.0.8 (7.0.x line) and 6.2.19 (6.2.x line).
- Leverage a commercial support partner like HeroDevs for post-EOL security support through Never-Ending Support (NES) for Spring Framework, which provides the fix for the 5.3.x and 6.1.x lines without requiring a major-version upgrade.
Credits
- This vulnerability was discovered internally by the Spring Framework team.