CVE-2026-41843
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 Spring ecosystem, providing the core container, web stacks, and infrastructure that the wider Spring portfolio is built on. Its two web stacks, Spring MVC (servlet-based, in spring-webmvc) and Spring WebFlux (reactive, in spring-webflux), both ship a static-resource handling pipeline that can serve files from the file system. That pipeline supports versioned resources: when configured with a VersionResourceResolver and a content-based version strategy, the framework embeds a content hash into resource URLs for cache-busting, and strips that version back out of the request path before resolving the underlying file.
A medium-severity vulnerability (CVE-2026-41843) has been identified in this versioned-resource path handling. The version-stripping logic removed every occurrence of the version substring from the request path rather than only the trailing one, and the resolver did not re-validate the stripped path before resolving it against the file system. An attacker who knows the version metadata of a served resource can craft a request whose stripped path escapes the configured resource locations, allowing files outside those locations to be read.
Per OWASP, a path traversal (directory traversal) attack aims to access files and directories stored outside the web root folder; by manipulating variables that reference files with parent-directory ('dot-dot-slash') sequences and their variations, or by using absolute file paths, it may be possible to access arbitrary files and directories on the file system. This issue is exactly that failure mode: a crafted, version-bearing request path is transformed into a path that resolves outside the intended static-resource directory.
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:H/I:N/A:N. The attack vector is Network because the request arrives over HTTP, attack complexity is High because the attacker must already know the version metadata (content hash) of a targeted resource for the crafted path to be processed by the version resolver, and no privileges or user interaction are required. The impact is Confidentiality-only and High because the flaw can disclose file contents from outside the configured resource locations; there is no integrity or availability impact, since the path is only resolved for reading.
This issue affects Spring Framework >=4.3.0 <=4.3.30, >=5.3.0 <=5.3.48, >=6.1.0 <=6.1.27, >=6.2.0 <=6.2.18, >=7.0.0 <=7.0.7 when versioned static resources are served from the file system.
Details
Module Info
- Product: Spring Framework
- Affected packages: spring-webmvc, spring-webflux
- Affected versions: >=4.3.0 <=4.3.30, >=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-webmvc
- Package manager: Maven
- Fixed in:
- NES for Spring Framework 4.3.x, 5.3.x, 6.1.x
- Spring Framework 6.2.19, 7.0.8 (OSS)
Vulnerability Info
The vulnerability is in the versioned-resource resolution pipeline, which exists in mirrored form in both web stacks: org.springframework.web.servlet.resource in spring-webmvc and org.springframework.web.reactive.resource in spring-webflux. The fix is related to CVE-2026-41842. It is only reachable when an application configures a VersionResourceResolver with a content-based version strategy on a file-system-backed resource handler, so a deployment is exposed only if it both serves static resources from the file system and has versioned resource support enabled.
When a request for a versioned resource arrives, the version strategy's removeVersion method strips the embedded version token out of the request path so the underlying (unversioned) file can be located. Pre-fix, that method used StringUtils.delete, which removes every occurrence of the -<version> substring from the path:
return StringUtils.delete(requestPath, "-" + version);Because the content hash is attacker-knowable, a request path can be crafted so the version substring appears more than once, including inside a directory-traversal segment. StringUtils.delete then strips the token from all of those positions at once, producing a simplePath that no longer matches the intended cache-busting suffix and instead points outside the configured resource location. The resolver passed that simplePath straight to the resolution chain without re-validating it, so the traversed path was resolved and its file contents could be returned.
The advisory lists the affected range starting at 5.3.0, reflecting Spring's currently-supported scope. The vulnerable code (the StringUtils.delete-based removeVersion and the unguarded resolver) predates 5.3 and is present in the 4.3.x line as well, so older lines covered by NES support are also affected.
Steps To Reproduce
1. Build a Spring MVC (or Spring WebFlux) application on an affected Spring Framework version that serves static resources from the file system with versioned-resource support enabled:
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**")
.addResourceLocations(new FileSystemResource("/var/www/static/"))
.resourceChain(true)
.addResolver(new VersionResourceResolver()
.addContentVersionStrategy("/**"));
}
2. Request a legitimate versioned resource and note the content-hash version token the application assigns, for example /resources/css/app-<hash>.css. This token is the resource metadata the attack relies on.
3. Craft a request whose path repeats the -<hash> version substring so that, after the pre-fix StringUtils.delete removes all occurrences at once, the resulting simplePath resolves outside the configured /var/www/static/ location.
4. Send the crafted request. On a vulnerable version the resolver strips the version from every position, fails to re-validate the stripped path, and resolves a file outside the intended resource location, returning its contents.
5. After upgrading to a fixed version (Spring Framework 6.2.19, 7.0.8, or a HeroDevs NES version), repeat the crafted request. removeVersion now strips only the trailing token and VersionResourceResolver rejects the traversing path via ResourceHandlerUtils.shouldIgnoreInputPath, so the request no longer escapes the resource location.
Mitigation
Spring Framework 4.3.x, 5.3.x, and 6.1.x have reached the end of their open source support lifecycle and will not receive open source patches for this vulnerability; see the Spring support policy for current support timelines.
Users of the affected components should apply one of the following mitigations:
- Upgrade to a currently supported version of Spring Framework that contains the fix. The OSS fix ships in Spring Framework 6.2.19 (6.2.x line) and 7.0.8 (7.0.x line).
- As an interim hardening step on a vulnerable deployment, disable versioned-resource support or serve static resources from the classpath rather than the file system, since the issue is only reachable when file-system resources are served with a content-based VersionResourceResolver.
- Leverage a commercial support partner like HeroDevs for post-EOL security support through Never-Ending Support (NES) for Spring Framework.
Credits
- This issue was discovered internally by the Spring team.