Automated Threat Modeling

Spring Boot DevTools CVE-2026-40972: Brief Summary of a Timing Attack Leading to Remote Code Execution

CVE-2026-40972 is a high-severity timing attack vulnerability in Spring Boot DevTools. An attacker on an adjacent network can recover the remote secret and use it to execute code. This summary covers the patch and the affected version ranges.

CVE Analysis

8 min read

ZeroPath CVE Analysis
ZeroPath CVE Analysis

2026-04-27

Spring Boot DevTools CVE-2026-40972: Brief Summary of a Timing Attack Leading to Remote Code Execution
Experimental AI-Generated Content

This CVE analysis is an experimental publication that is completely AI-generated. The content may contain errors or inaccuracies and is subject to change as more information becomes available. We are continuously refining our process.

If you have feedback, questions, or notice any errors, please reach out to us.

[email protected]

Introduction

A single call to String.equals() in Spring Boot's DevTools remote access manager has been leaking timing information. An attacker on an adjacent network can use that leak to reconstruct the remote secret one character at a time. With the secret in hand, the attacker can push arbitrary class files through the DevTools live reload mechanism. A subtle cryptographic weakness ends in full remote code execution.

CVE-2026-40972 has a CVSS v3.1 score of 7.5 and affects five Spring Boot release trains, from the legacy 2.7.x line to the current 4.0.x series. Spring Boot holds a dominant position in enterprise Java development, so the blast radius is significant for any organization that has inadvertently left DevTools remote support enabled outside a tightly controlled development environment.

Technical Information

Root Cause: Non-Constant-Time Secret Comparison (CWE-208)

The vulnerability is in the HttpHeaderAccessManager class, in the spring-boot-devtools module under org.springframework.boot.devtools.remote.server. This class controls access to the remote DevTools endpoint. It checks a secret sent in an HTTP header against the expected value set by the spring.devtools.remote.secret property.

The original implementation stored the expected secret as a String and compared it to the incoming header value with Java's standard String.equals() method. This is the classic timing oracle pattern described by CWE-208 (Observable Timing Discrepancy). String.equals() short-circuits, returning false as soon as it reaches the first mismatched character. A request whose secret matches the first N characters of the expected value therefore takes measurably longer to reject than a request that differs at position 0.

Attack Flow

The attack proceeds in four steps:

  1. Prerequisite: The target Spring Boot application has DevTools remote support enabled, which means the spring.devtools.remote.secret property is set. The attacker must be on the same network (adjacent network access, per the CVSS vector AV:A).

  2. Timing oracle probing: The attacker sends repeated HTTP requests to the DevTools remote endpoint, changing the secret header value one character at a time. From statistical measurements of the response times, the attacker finds the character at each position that produces a slightly longer comparison, which indicates a match.

  3. Secret reconstruction: Repeating this for every position yields the full secret. Network jitter adds noise (reflected in the AC:H rating), but a patient attacker with enough samples can separate the signal from the noise. On a low-latency local network, the attack becomes considerably more practical.

  4. Class upload and code execution: The attacker uses the recovered secret to authenticate to the DevTools remote endpoint as a legitimate IDE client. The DevTools protocol lets clients upload changed classes, and the server-side live reload mechanism processes them and loads them into the running application. The attacker uploads a malicious class and gets remote code execution.

CVSS Breakdown

The full CVSS v3.1 vector is AV:A/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H, which breaks down as:

MetricValuePractical Meaning
Attack VectorAdjacent (A)Attacker must be on the same network as the target application
Attack ComplexityHigh (H)Timing attacks require precise measurements and favorable network conditions
Privileges RequiredNone (N)No prior authentication is needed to initiate the timing attack
User InteractionNone (N)The exploit runs entirely without victim participation
Impact (C, I, A)High (H)Complete compromise of confidentiality, integrity, and availability via RCE

The high attack complexity is the main thing keeping this below a critical rating. On a quiet local network segment, though, the timing signal can be quite clear.

Patch Information

The Spring Boot team fixed CVE-2026-40972 in a patch authored by Andy Wilkinson and committed on April 23, 2026 (commit 4b0862cc). The commit message states the intent directly: "Use constant-time comparison for remote DevTools secret."

The patch changes one file, HttpHeaderAccessManager.java, with 7 additions and 3 deletions, and it goes straight at the root cause:

+import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; - private final String expectedSecret; + private final byte[] expectedSecret; public HttpHeaderAccessManager(String headerName, String expectedSecret) { ... - this.expectedSecret = expectedSecret; + this.expectedSecret = expectedSecret.getBytes(StandardCharsets.UTF_8); } @Override public boolean isAllowed(ServerHttpRequest request) { String providedSecret = request.getHeaders().getFirst(this.headerName); - return this.expectedSecret.equals(providedSecret); + return (providedSecret != null) + && MessageDigest.isEqual(providedSecret.getBytes(StandardCharsets.UTF_8), this.expectedSecret); }

The patch makes two changes:

  1. Storage format change: The class now stores the expected secret as a byte[] (converted via StandardCharsets.UTF_8) instead of a String. The constant-time comparison API needs bytes, so this change comes first.

  2. Constant-time comparison: MessageDigest.isEqual() replaces the old String.equals() call. This method, in the java.security package, is designed for comparing cryptographic values. It always walks the full length of both byte arrays, no matter where they differ, so the comparison time does not depend on the secret's content. The patch also adds a null check (providedSecret != null) as a guard. String.equals() handled null safely by returning false, but calling getBytes() on a null reference would throw a NullPointerException.

The fix was originally tracked as issue #50169 (milestone 3.5.14) and forward-ported to the 4.0.x branch as issue #50176 (milestone 4.0.6).

Fixed Versions

Affected Version RangeFixed VersionAvailability
4.0.0 to 4.0.54.0.6OSS
3.5.0 to 3.5.133.5.14OSS
3.4.0 to 3.4.153.4.16Enterprise Support Only
3.3.0 to 3.3.183.3.19Enterprise Support Only
2.7.0 to 2.7.322.7.33Enterprise Support Only

The two OSS releases, 4.0.6 and 3.5.14, both list "Remote DevTools performs comparison incorrectly" in their release notes. The older supported branches received the same fix, but those releases are available only through Spring Enterprise Support.

The vendor states that no further mitigation is necessary once the patch is applied. Where you cannot patch right away, disable DevTools remote support entirely, and especially in production, where it should never be enabled in the first place.

Affected Systems and Versions

The vulnerability affects any Spring Boot application with DevTools remote support enabled (that is, the spring.devtools.remote.secret property is set) in these version ranges:

  • Spring Boot 4.0.0 through 4.0.5 (fixed in 4.0.6)
  • Spring Boot 3.5.0 through 3.5.13 (fixed in 3.5.14)
  • Spring Boot 3.4.0 through 3.4.15 (fixed in 3.4.16)
  • Spring Boot 3.3.0 through 3.3.18 (fixed in 3.3.19)
  • Spring Boot 2.7.0 through 2.7.32 (fixed in 2.7.33)

According to the vendor advisory, versions the vendor no longer supports are also affected. Organizations running unsupported versions must upgrade to a supported release train.

The vulnerable component is the remote DevTools server-side endpoint (HttpHeaderAccessManager in spring-boot-devtools). Applications that neither set spring.devtools.remote.secret nor include DevTools in their deployed artifacts are not affected.

Vendor Security History

The April 23, 2026 Spring Boot release bundled fixes for nine distinct CVEs, which points to an active period of security review. Notable fixes in that release, alongside CVE-2026-40972, include:

CVE IDSeverityDescription
CVE-2026-40976CriticalDefault security filter chain has no authorization rule with Actuator but without Health
CVE-2026-40972HighDevTools remote secret comparison is vulnerable to timing attacks
CVE-2026-40973HighPredictable temp directory accepted without ownership verification
CVE-2026-40974MediumCassandra SSL auto configuration disables TLS hostname verification

Because the fixes shipped together, organizations could address all of them in a single maintenance window. Organizations that rely on open source releases should note that the vendor restricts fixes for the older branches (3.4.x, 3.3.x, 2.7.x) to Enterprise Support Only. Without a commercial support agreement, staying secure on those branches effectively requires a major version upgrade.

References

Detect & fix
what others miss

Works with
  • GitHub
  • GitLab
  • Bitbucket
  • Azure DevOps Services
  • Gerrit
  • CVS
  • Jira
  • Linear
  • Slack
  • Security Compass
Explore integrations
Security magnifying glass visualization