CVE-2026-40973
This Vulnerability has been fixed in the Never-Ending Support (NES) version offered by HeroDevs.
Overview
Spring Boot is an open-source framework from the Spring team that simplifies building production-grade Java applications by providing opinionated auto-configuration, embedded servlet containers, and convention-based starters. A high-severity vulnerability (CVE-2026-40973) has been identified in Spring Boot's ApplicationTemp helper, which exposes a predictable, attacker-pre-creatable directory under the system temp location to the running application without verifying that the directory is owned by the Spring Boot process user or that it has safe POSIX permissions.
When server.servlet.session.persistent is enabled, the servlet container persists serialized HttpSession state inside the ApplicationTemp tree. A local threat actor on the same host who wins the race to create (or symlink) the predictable target directory before Spring Boot starts can read session state, forge a session to hijack another user's account, or drop a Java deserialization gadget payload that is executed under the application's user on the next restart.
Per OWASP: "Insecure use of temporary files can leak sensitive information to other users of the system, or may allow a local attacker to gain elevated privileges by replacing the contents of a temporary file or by race condition." The weakness in Spring Boot is structurally this class of bug combined with missing access-control verification on a directory the application treats as trusted storage.
This issue affects Spring Boot >=2.7.0 <=2.7.32, >=3.3.0 <=3.3.18, >=3.4.0 <=3.4.15, >=3.5.0 <=3.5.13, and >=4.0.0 <=4.0.5.
Details
Module Info
- Product: Spring Boot
- Affected packages: spring-boot
- Affected versions: >=2.7.0 <=2.7.32, >=3.3.0 <=3.3.18, >=3.4.0 <=3.4.15, >=3.5.0 <=3.5.13, >=4.0.0 <=4.0.5
- GitHub repository: https://github.com/spring-projects/spring-boot
- Published packages: https://central.sonatype.com/artifact/org.springframework.boot/spring-boot
- Package manager: maven
- Fixed in:
- NES for Spring Boot 1.5.x, 2.5.x, 2.7.x, 3.2.x,, 3.3.x, 3.4.x
- OSS Spring Boot 3.5.14, 4.0.6
Vulnerability Info
ApplicationTemp in the org.springframework.boot.system package computes a per-application temp directory under java.io.tmpdir (typically /tmp on Linux). The directory name is a SHA-1 hash derived from values that a co-resident local user can read from /proc/<pid>/cmdline or ps -ef: user.dir, java.home, java.class.path, sun.boot.class.path, home.getSource, home.getDir and sun.java.command. The path is therefore predictable.
ApplicationTemp.createDirectory(Path) contained the following exists-then-skip logic with no validation of a pre-existing directory:
private Path createDirectory(Path path) {
try {
if (!Files.exists(path)) {
Files.createDirectory(path, getFileAttributes(path.getFileSystem(), DIRECTORY_PERMISSIONS));
}
// If the path already exists (e.g. pre-planted by a local attacker,
// or a symlink to a file the attacker chose), control falls through
// to the return below with no ownership, permission, or link-status
// check. The attacker-controlled directory becomes the app temp dir.
return path;
}
catch (IOException ex) {
// Only reached when Files.createDirectory above actually fails
// (e.g. permission denied). The attack path never reaches this.
throw new IllegalStateException("Unable to create application temp directory " + path, ex);
}
}
Three defects combine:
- Files.exists(path) follows symbolic links, so a symlink planted at the target path is treated as the application's temp directory.
- If the path already exists, Spring Boot never reads PosixFileAttributes to check ownership or mode. A directory owned by an unprivileged local attacker is silently accepted.
- The path is predictable and lives under a world-writable location, so pre-creating it before the Spring Boot JVM starts is straightforward.
When server.servlet.session.persistent=true, default false, the embedded servlet container serializes HttpSession state into files inside this directory. Because the attacker owns the directory, they can read the serialized session state (confidentiality impact), overwrite a serialized session with one that carries another user's principal and granted authorities (integrity impact, account takeover), or substitute a Java deserialization gadget-chain payload for the legitimate SESSIONS.ser file. On the next container restart, the servlet engine calls ObjectInputStream.readObject on the attacker-controlled bytes and executes code in the context of the Spring Boot JVM user (availability and full RCE impact).
Mitigation
Only recent versions of Spring Boot receive community support and updates. See Spring Boot support page for the current OSS support policy. We recommend the following courses of action:
- Upgrade to a currently-supported Spring Boot release (3.5.14 or 4.0.6 or later).
- Adopt HeroDevs Never-Ending Support for Spring Boot to receive the backported ApplicationTemp ownership verification on 1.5.x, 2.5.x, 2.7.x, 3.2.x, 3.3.x, and 3.4.x while planning a longer-term upgrade. See NES for Spring for details.
Credits
No external finder is credited in the upstream advisory as of April 24, 2026.