CVE-2026-40976: Spring Boot 4.0 Actuator Authorization Bypass
How a missing dependency on spring-boot-health silently disables the default web security filter chain

On April 23, 2026, the Spring team disclosed CVE-2026-40976, a Critical authorization bypass affecting Spring Boot 4.0.0 through 4.0.5. The vulnerability has a CVSS 3.1 base score of 9.1 (vector: AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N) and is fully unauthenticated. When a specific dependency combination is present, Spring Boot's default web security filter chain silently fails to enforce authorization, exposing every Actuator endpoint, including /actuator/env, /actuator/heapdump, and /actuator/configprops, to anonymous network attackers. Spring has shipped a fix in Spring Boot 4.0.6.
This is not a misconfiguration. Applications that follow Spring Boot's documented defaults can be vulnerable.
What is CVE-2026-40976?
CVE-2026-40976 is an authorization bypass (CWE-862: Missing Authorization) in Spring Boot's default web security filter chain. The bug lives at the intersection of two newer Boot 4.0 design choices: the modular split of spring-boot-actuator-autoconfigure and spring-boot-health, and the autoconfigured security defaults that Boot applies when no user-supplied SecurityFilterChain bean is present.
In Spring Boot 4.0, health endpoint support was extracted out of spring-boot-actuator-autoconfigure into a dedicated spring-boot-health module. The default web security configuration assumed health autoconfiguration would always be available alongside the rest of the Actuator. When spring-boot-actuator-autoconfigure is on the classpath but spring-boot-health is not, the conditional logic that would normally produce an authorization rule for Actuator endpoints does not execute. The default filter chain is registered, but it contains no authorization rule covering the Actuator path. Every endpoint is reachable anonymously.
The result is a default-deny security model that quietly becomes default-allow under one specific dependency configuration.
Severity and exploit conditions
The CVSS vector breaks down as follows:
For an application to be vulnerable, the Spring advisory specifies that all of the following must be true:
- The application is a servlet-based web application
- The application has no Spring Security configuration of its own (no user-defined SecurityFilterChain bean) and relies on Boot's default web security filter chain
- The application's classpath includes spring-boot-actuator-autoconfigure
- The application's classpath does not include spring-boot-health
If any one of these is false, the application is not vulnerable. In practice, this configuration is most likely in:
- Custom Boot starters or internal platform libraries that pull in Actuator without health
- Applications that have intentionally excluded health endpoints (e.g., to avoid conflicts with an external health probe)
- Slimmed-down container images that explicitly exclude spring-boot-health to reduce dependency footprint
- Generated or scaffolded projects where the dependency declarations were trimmed manually
The combination is uncommon by accident but trivially common by design choice. Any team that has deliberately excluded health endpoints on Boot 4.0.0 through 4.0.5 should treat this as an immediate, unauthenticated, network-reachable exposure.
What an attacker can do
When the default filter chain fails to enforce authorization, the entire /actuator tree is reachable anonymously. Spring Boot's default Actuator surface includes endpoints that are designed to assume privileged access. With no authentication enforced, an attacker can:
- Exfiltrate secrets via /actuator/env. This endpoint returns the application's Environment, including resolved property values from configuration files, environment variables, and external configuration sources. Database passwords, API keys, OAuth client secrets, and JWT signing keys are commonly present here.
- Capture a full heap dump via /actuator/heapdump. The dump contains live object state, including credentials in memory, session tokens, and decrypted configuration values. Once downloaded, it can be analyzed offline indefinitely.
- Enumerate beans and configuration via /actuator/beans, /actuator/configprops, and /actuator/conditions. These reveal the full application architecture, including which integrations are wired up and how they are configured.
- Modify runtime logging via /actuator/loggers. An attacker can suppress security-relevant log output before mounting a follow-on attack, or enable verbose logging on sensitive components to capture data through log aggregation pipelines.
- Trigger thread dumps via /actuator/threaddump, exposing in-flight request data and call stacks.
- Force application restarts or shutdowns via /actuator/shutdown or /actuator/restart if those endpoints are enabled.
The /actuator/env and /actuator/heapdump exposures alone are typically sufficient to escalate from "anonymous network access" to "full credential compromise" in a single request chain.
Who is affected?
This vulnerability is specific to the Spring Boot 4.0 release line. Earlier major versions of Spring Boot bundle health endpoint support inside spring-boot-actuator-autoconfigure and are not affected by this specific dependency-state bug.
EOL Spring Boot 2.7 and 3.x users running Actuator are not exposed to this CVE. They remain exposed to other Spring Boot Actuator vulnerabilities historically, including CVE-2026-22731, the Actuator authentication bypass disclosed in March 2026, which does affect older branches and is covered by NES for Spring.
Mitigation guidance
The defense-in-depth recommendation matters specifically for this CVE. An application that exposes Actuator only on an internal management port behind a network boundary would not be exploitable by an external attacker even in the vulnerable dependency state. Network segmentation is not a substitute for the patch, but it converts a Critical anonymous remote vulnerability into a much narrower internal-only risk.
Why this CVE matters beyond Boot 4.0
Two design lessons stand out, both relevant to anyone maintaining a framework's security defaults.
Modular splits create new failure modes. The decision to extract spring-boot-health into a separate module was sound from a packaging perspective: not every application needs health endpoints, and modular dependencies reduce footprint. But the autoconfigured security defaults assumed a coupling that was no longer guaranteed. Whenever a framework splits a previously bundled component, the security configuration that depended on the bundled state must be audited for assumptions that no longer hold.
Default-deny only works if the deny rule actually registers. The default web security filter chain in Spring Boot is meant to be a safety net for applications that have not yet defined their own security configuration. CVE-2026-40976 is a case where the safety net silently developed a hole. Applications that followed every documented best practice, including not overriding the default security filter chain, were nonetheless exposed.
For teams operating large Spring Boot estates, this is a reminder that "we use the defaults" is not a security posture. Defaults change between versions, modules split, and the conditional logic that decides which rule applies can fail in ways that produce no warning, no error, and no log line.
Related Spring CVEs
CVE-2026-40976 is the third significant Spring Actuator-related disclosure in the past two months:
- CVE-2026-22731: Authentication bypass in Spring Boot Actuator when endpoints are declared under specific paths already configured for Health Group additional paths. Affects Spring Boot 3.x and earlier branches that NES covers for EOL versions.
- CVE-2026-22732: HTTP security headers regression in Spring Security's servlet integration. Affects Spring Security 5.7 through 7.0.
Teams running multiple Spring Boot versions across an estate should review all three together. Each one targets a different layer of the request handling pipeline (autoconfiguration, endpoint routing, response headers) and the combined surface is broader than any single advisory implies.
Taking action
For teams on Spring Boot 4.0, the fix is straightforward: upgrade to 4.0.6. The patch is available via Maven Central and the Spring repository, and no further configuration changes are required.
For teams that cannot upgrade immediately, adding an explicit dependency on spring-boot-health is a one-line pom.xml or build.gradle change that closes the exposure without requiring any application code changes.
For teams running EOL Spring Boot versions (2.7, 3.0, 3.1, 3.2), this specific CVE does not apply, but the underlying lesson does: Spring's autoconfiguration surface is large, evolving, and produces real CVEs on a regular cadence. NES for Spring provides a secure drop-in replacement for EOL Spring Boot lines, with remediation for the CVEs that do affect those versions, so security teams can stay protected without a forced major version migration.


