CVE-2026-40973

Incorrectly Configured Access Control
Affects
Spring Boot
in
Spring
No items found.
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
Exclamation circle icon
Patch Available

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

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:

  1. Files.exists(path) follows symbolic links, so a symlink planted at the target path is treated as the application's temp directory.
  2. 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.
  3. 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:

  1. Upgrade to a currently-supported Spring Boot release (3.5.14 or 4.0.6 or later).
  2. 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.

Vulnerability Details
Severity
Level
CVSS Assessment
Low
>=0 <4
Medium
>=4 <6
High
>=6 <8
Critical
>=8 <10
High
ID
CVE-2026-40973
PROJECT Affected
Spring Boot
Versions Affected
>=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
NES Versions Affected
Published date
April 25, 2026
≈ Fix date
April 23, 2026
Category
Incorrectly Configured Access Control
Vex Document
Download VEXHow do I use it?
Sign up for the latest vulnerability alerts fixed in
NES for Spring
Rss feed icon
Subscribe via RSS
or

By clicking “submit” I acknowledge receipt of our Privacy Policy.

Thanks for signing up for our Newsletter! We look forward to connecting with you.
Oops! Something went wrong while submitting the form.