← All Case Studies
CVE-2026-22731 HIGH — CVSS 8.2

Authentication Bypass under Actuator Health Groups Paths

When Spring Boot maps a custom health group to an additional server path, actuator path mapping can bypass authentication on subpaths — admin endpoints reachable without credentials.

Affected Spring Boot 3.x < 3.4.15, Spring Boot 4.x < 4.0.4
Patched 3.4.15 / 3.5.12 / 4.0.4 (March 2026)
Package spring-boot (~22M weekly downloads)
CWE CWE-285 (Improper Authorization)
// what happened
  • Affected: Spring Boot 3.x < 3.4.15, 4.x < 4.0.4 with custom health groups mapped to additional server paths
  • The vulnerable pattern: management.endpoints.web.base-path combined with custom health group server:/healthz mapping — actuator path mapping overrides auth on subpaths like /healthz/admin
  • Root cause: Spring Boot's actuator web endpoint path mapping delegates to the server's path mapping, which can nest additional paths under the actuator base — when a health group is mapped to an absolute server path, the auth configuration for the actuator context does not propagate to subpaths of that mapped path
  • Fix: commits in 3.4.15 / 3.5.12 / 4.0.4 ensure actuator path mapping respects the security configuration of the target server path; apply explicit @PreAuthorize or path-specific security rules as defense-in-depth
  • Impact: Unauthenticated access to admin actuator endpoints (loggers, beans, env, health-details) when nested under custom health group paths. With heap dump or env endpoints exposed, an attacker reads configuration secrets, environment variables, and application state.

Spring Boot's actuator module supports custom health groups — named groups of health indicators that can be enabled and configured independently. When a health group is mapped to an additional server path via server:/healthz, the actuator endpoint path mapping delegates to the server's path routing. The problem: the actuator's authentication configuration applies only to the base path, not to subpaths of a mapped server path.

For example, with management.endpoints.web.base-path=/healthz and a custom health group mapped to server:/healthz, the subpath /healthz/admin (admin actuator endpoint) becomes accessible without authentication — the auth requirement from the actuator context does not extend to subpaths that the server routes through the health-group mapped path.

Real-world impact: An attacker who can reach the Spring Boot actuator endpoint (even from a different network segment, as this often bypasses WAF/firewall rules that only check the outer request path) navigates to /healthz/admin and gains access to loggers, beans, environment variables, and the heap dump endpoint. Environment variables contain database passwords, API keys, and cloud credentials. The heap dump contains every object in memory — session tokens, user data, in-flight API calls.


src/main/resources/application.properties — Spring Boot < 3.4.15 / < 4.0.4 (vulnerable) VULNERABLE: Custom health group mapped to additional server path; auth bypass on subpaths # Enable the health endpoint management.endpoint.health.enabled=true # Base path for all web-accessible actuator endpoints # All actuator endpoints accessible at /healthz/* management.endpoints.web.base-path=/healthz # Custom health group mapped to an ADDITIONAL server path # The health group's endpoints become accessible at /healthz/admin too # This is the root cause: actuator auth config doesn't cover subpaths of mapped paths management.endpoint.health.groups=myCustomGroup management.endpoint.health.group.myCustomGroup.path=/admin # Result: /healthz, /healthz/admin, /healthz/details — all unauthenticated # Any subpath of /healthz that matches the mapped group path bypasses auth
application.properties — attempting to secure (still vulnerable) # Trying to add security — but this only applies to the base actuator path, # not to subpaths that are routed via custom health group path mapping: management.security.enabled=true management.endpoints.web.allow-clear=false # The problem: server:/healthz maps the health group to a server path that # is outside the security boundary that management.security defines. # /healthz/admin is handled by the server path mapping, not the actuator filter chain.

// patch — Spring Boot 3.4.15 / 3.5.12 / 4.0.4
spring-boot-project/spring-boot/src/main/java/.../actuator/web/EndpointPathMapping.java — upstream fix Fixed in 3.4.15, 3.5.12, 4.0.4 — ensures health group mapped paths respect actuator auth config // BEFORE (vulnerable): // When a health group is mapped to server:/healthz, the endpoint path mapping // did not apply the actuator's security constraints to subpaths of the mapped path. // The server-level path mapping bypassed the @EnableWebSecurity annotation's // filter chain for those subpaths. // AFTER (fixed): // EndpointPathMapping now propagates security constraints from the actuator // context to all paths registered by health group path mapping. // Health group path mappings are now registered WITH their security constraints // so subpaths like /healthz/admin inherit the authentication requirement. // Key change: HealthGroupWebEndpointPathMapping now links the security // configuration of the actuator context to the server path registration. // If management.security.enabled=true, all subpaths of mapped health group paths // require authentication.

The fix ensures that when Spring Boot registers health group paths with the server, it also registers the corresponding authentication requirements from the actuator security configuration. Subpaths of mapped health group paths now inherit the auth requirement — /healthz/admin requires authentication when management.security.enabled=true.


🟠 PullLight — High Finding
[Auth Bypass] Actuator health group path mapping bypasses authentication on subpaths — application.properties

management.endpoint.health.groups=myCustomGroup + management.endpoint.health.group.myCustomGroup.path=/admin maps the admin health group endpoint to /healthz/admin, but the actuator's security configuration does not apply to subpaths of server-mapped paths. With management.endpoints.web.base-path=/healthz, the endpoint at /healthz/admin is accessible without authentication — exposing loggers, beans, env, heapdump endpoints. This is CWE-285 (Improper Authorization). Heap dump or env endpoints exposed via this bypass expose database passwords, cloud credentials, and session state. Upgrade to Spring Boot 3.4.15+ / 3.5.12+ / 4.0.4+. As defense-in-depth, add explicit @PreAuthorize("isAuthenticated()") to admin-sensitive actuator endpoints, or apply path-specific security rules in your SecurityFilterChain bean: request.antMatchers("/healthz/**").authenticated().
```suggestion // Fix Option 1: Upgrade Spring Boot to patched version // Fix Option 2: Add explicit Spring Security rules: @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.authorizeHttpRequests(authz -> authz .requestMatchers("/healthz/**").authenticated() // enforce auth on all actuator subpaths .anyRequest().permitAll() ); return http.build(); } // Fix Option 3: Apply @PreAuthorize to sensitive actuator endpoints @Bean @ConditionalOnProperty(name = "management.endpoint.loggers.enabled", havingValue = "true") public class LoggersEndpointSecurity { @PreAuthorize("isAuthenticated()") public LoggersEndpoint loggersEndpoint() { ... } } ```

// why this happened
Spring Boot's actuator module and the Spring Security filter chain are configured independently. When a health group's path is mapped to a server path via server:/healthz, the registration happens at the server level, outside the actuator's security filter configuration. The actuator security configuration (management.security.enabled=true) controls access to the actuator context, but when the server handles a request to /healthz/admin, it routes through the health group's path mapping — which was registered without the authentication constraint. The bug is a path registration ordering issue: health group paths are registered before the security filter chain is applied to them. Spring Boot's fix ensures that path registration and security constraint registration happen together as an atomic operation.

Three reasons this vulnerability hides from standard PR review

  • The config looks like standard Spring Boot setup. Actuator endpoints with custom health group paths are a documented, recommended pattern for exposing health metrics at custom URLs. There's no obvious "this is a security risk" signal in the configuration itself.
  • The auth bypass requires two conditions to interact. You need both management.endpoints.web.base-path=/healthz AND a health group path mapping (server:/healthz) — neither looks dangerous in isolation. The interaction between them is what causes the bypass.
  • Security configuration lives in a different file than the vulnerable pattern. The actuator security config (management.security.enabled) is in a different properties block or YAML file from the health group path mapping. Reviewers typically look at one or the other, not the security implications of their interaction.

March 19, 2026 Spring Security advisory published: CVE-2026-22731
March 2026 Spring Boot 3.4.15 and 3.5.12 released with patch for path registration ordering
March 2026 Spring Boot 4.0.4 released with the same fix for the 4.x branch
April 2026 PullLight adds CVE-2026-22731 detection — flags actuator health group path configurations that nest auth-required endpoints under mapped server paths

Don't let this happen to your PRs

More Case Studies
8.7axios SSRF via NO_PROXY Bypass (CVE-2024-39338)
8.6Next.js WebSocket SSRF (CVE-2026-44578)
8.1ip Package SSRF (CVE-2024-29415)
7.2Next.js Auth Bypass (CVE-2025-29927)