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

A brief summary of CVE-2026-40972, a high severity timing attack vulnerability in Spring Boot DevTools that allows adjacent network attackers to recover the remote secret and achieve code execution. Includes patch details and 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 that allows adjacent network attackers to reconstruct the remote secret character by character. Once that secret is recovered, the attacker can push arbitrary class files through the DevTools live reload mechanism, turning a subtle cryptographic weakness into full remote code execution.

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

Technical Information

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

The vulnerability exists in the HttpHeaderAccessManager class, located in the spring-boot-devtools module under org.springframework.boot.devtools.remote.server. This class is responsible for gating access to the remote DevTools endpoint by validating a secret provided in an HTTP header against an expected value configured via the spring.devtools.remote.secret property.

The original implementation stored the expected secret as a String and compared it against the incoming header value using Java's standard String.equals() method. This is the classic timing oracle pattern described by CWE-208 (Observable Timing Discrepancy). String.equals() short-circuits: it returns false as soon as it encounters the first mismatched character. This means a request carrying a secret whose first N characters match the expected value will take measurably longer to reject than a request that differs at position 0.

Attack Flow

The exploitation path proceeds as follows:

  1. Prerequisite: The target Spring Boot application has DevTools remote support enabled, meaning 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, varying the secret header value one character at a time. By collecting statistical measurements of response times, the attacker identifies which character value at each position produces a slightly longer comparison time, indicating a match.

  3. Secret reconstruction: Character by character, the attacker builds up the full secret. While network jitter introduces noise (reflected in the AC:H rating), a patient attacker with sufficient samples can filter out the signal. On a low latency local network, this becomes considerably more practical.

  4. Class upload and code execution: With the recovered secret, the attacker authenticates to the DevTools remote endpoint as a legitimate IDE client. The DevTools protocol allows uploading changed classes, which the server side live reload mechanism processes and loads into the running application. The attacker uploads a malicious class, achieving 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 primary factor keeping this from a critical rating, but on a quiet local network segment the timing signal can be quite clear.

Patch Information

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

The fix targets a single file: HttpHeaderAccessManager.java. The patch is compact (7 additions, 3 deletions) but addresses the root cause precisely:

+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); }

Two key changes are worth understanding:

  1. Storage format change: The expected secret is now stored as a byte[] (converted via StandardCharsets.UTF_8) rather than as a String. This is a prerequisite for using the constant-time comparison API.

  2. Constant-time comparison: The old String.equals() call is replaced with MessageDigest.isEqual(). This method, part of the java.security package, is specifically designed for comparing cryptographic values. It always iterates over the full length of both byte arrays regardless of where differences occur, making the comparison time independent of the secret's content. A null check (providedSecret != null) was also added as a guard, since String.equals() inherently handled null safely (by returning false), whereas 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 available versions (4.0.6 and 3.5.14) both list "Remote DevTools performs comparison incorrectly" in their release notes. Older supported branches received the same fix but are only available through Spring Enterprise Support.

The vendor states that no further mitigation steps are necessary once the patch is applied. For environments where immediate patching is not possible, DevTools remote support should be disabled entirely, especially in production, where it should never be enabled in the first place.

Affected Systems and Versions

The vulnerability affects any Spring Boot application that has DevTools remote support enabled (i.e., the spring.devtools.remote.secret property is set) across the following 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)

Versions that are no longer supported by the vendor are also affected per the vendor advisory. Organizations running unsupported versions must upgrade to a supported release train.

The vulnerable component is specifically the remote DevTools server side endpoint (HttpHeaderAccessManager in spring-boot-devtools). Applications that do not set spring.devtools.remote.secret and do not 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, indicating an active period of security review. Notable vulnerabilities addressed 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

This coordinated release allowed organizations to address multiple security flaws in a single maintenance window. The vendor's restriction of fixes for older branches (3.4.x, 3.3.x, 2.7.x) to Enterprise Support Only is worth noting for organizations that rely on open source releases, as it effectively requires a major version upgrade to maintain security without a commercial support agreement.

References

Detect & fix
what others miss

Security magnifying glass visualization