Back to Blog
high SEVERITY5 min read

How Spring Boot EndpointRequest.to() security bypass happens in Java Spring Boot and how to fix it

CVE-2025-22235 is a high-severity vulnerability in Spring Boot where `EndpointRequest.to()` creates an incorrect request matcher when an actuator endpoint is not exposed, potentially allowing unauthorized access to protected endpoints. The fix upgrades Spring Boot from 3.4.4 to 3.4.5 in the anti-corruption-layer service's `pom.xml`. This is particularly dangerous because actuator endpoints can expose sensitive operational data and administrative functions.

O
By Orbis AppSec
Published June 7, 2026Reviewed June 7, 2026

Answer Summary

CVE-2025-22235 is a high-severity security bypass vulnerability in Spring Boot (Java) where `EndpointRequest.to()` generates an incorrect security matcher when an actuator endpoint is not exposed, potentially matching unintended URLs and allowing unauthorized access. The CWE is CWE-284 (Improper Access Control). The fix is to upgrade `org.springframework.boot:spring-boot` from version 3.4.4 to 3.4.5 (or 3.3.11 for the 3.3.x branch) in your Maven or Gradle configuration.

Vulnerability at a Glance

cweCWE-284
fixUpgrade spring-boot from 3.4.4 to 3.4.5
riskUnauthorized access to actuator endpoints or security rule misapplication
languageJava (Spring Boot)
root causeEndpointRequest.to() generates a wrong matcher when the target actuator endpoint is not exposed
vulnerabilitySecurity bypass via incorrect request matcher in Spring Boot Actuator

How Spring Boot EndpointRequest.to() Security Bypass Happens in Java Spring Boot and How to Fix It

Introduction

In the anti-corruption-layer service's pom.xml, Orbis AppSec's scanner flagged a high-severity vulnerability (CVE-2025-22235) in org.springframework.boot:spring-boot version 3.4.4. The issue lies deep within Spring Boot's security infrastructure: when you use EndpointRequest.to() to create a security matcher for an actuator endpoint that isn't currently exposed, the resulting matcher is incorrect — potentially matching the wrong URLs or creating an overly permissive security rule.

This matters because many Spring Boot applications use EndpointRequest.to() in their SecurityFilterChain configuration to apply specific access rules to actuator endpoints like /actuator/health, /actuator/env, or /actuator/shutdown. When the matcher misbehaves, your carefully crafted security rules may not protect what you think they're protecting.

The vulnerable dependency was declared in the project's root pom.xml:

<spring-boot.version>3.4.4</spring-boot.version>

The Vulnerability Explained

Spring Boot Actuator provides operational endpoints for monitoring and managing your application. Developers commonly write security configurations like:

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    http.authorizeHttpRequests(auth -> auth
        .requestMatchers(EndpointRequest.to("shutdown")).hasRole("ADMIN")
        .requestMatchers(EndpointRequest.to("health", "info")).permitAll()
        .anyRequest().authenticated()
    );
    return http.build();
}

The critical flaw in Spring Boot 3.4.4 (and earlier affected versions) is that when EndpointRequest.to("shutdown") is called but the shutdown endpoint is not exposed (which is the default — most dangerous endpoints are disabled by default), the resulting RequestMatcher doesn't correctly resolve to "match nothing." Instead, it can create a matcher that behaves unexpectedly.

The Attack Scenario

Consider this real-world scenario with the anti-corruption-layer service:

  1. A developer configures security rules using EndpointRequest.to() for an endpoint that isn't exposed (e.g., shutdown, env, or beans).
  2. The incorrect matcher could potentially match other request paths that weren't intended to be covered by that rule.
  3. If the rule was permitAll() (common for health checks), an attacker could access paths that should require authentication.
  4. If the rule was restrictive (e.g., denyAll()), the wrong matcher could inadvertently block legitimate requests, causing a denial-of-service condition.

Because this is a Java service handling HTTP requests, the vulnerability is remotely exploitable — any client that can reach the service can potentially exploit the misconfigured matchers.

Why This Is Particularly Dangerous

The insidious nature of this vulnerability is that:
- It only manifests when endpoints are not exposed — the exact scenario where developers assume they're safe
- Security configurations appear correct in code review
- Standard integration tests may pass because they often test exposed endpoints
- The mismatch between intended and actual security behavior is silent

The Fix

The fix is straightforward but critical: upgrade org.springframework.boot:spring-boot from version 3.4.4 to 3.4.5.

Before (vulnerable):

<spring-boot.version>3.4.4</spring-boot.version>

After (fixed):

<spring-boot.version>3.4.5</spring-boot.version>

This single-line change in the root pom.xml at line 42 updates the Spring Boot version property that governs all Spring Boot dependencies across the project, including the anti-corruption-layer module where the vulnerability was detected.

In Spring Boot 3.4.5, the EndpointRequest.to() method correctly handles the case where the specified actuator endpoint is not exposed. When an endpoint isn't available, the matcher now properly resolves to a "match nothing" state, ensuring that:
- Security rules for unexposed endpoints don't accidentally apply to other paths
- The security configuration behaves exactly as the developer intended
- No unintended access is granted through matcher confusion

For projects still on the 3.3.x branch, the equivalent fix is upgrading to 3.3.11.

Prevention & Best Practices

  1. Keep dependencies current: Use automated dependency management tools to stay on top of security patches. Spring Boot releases security fixes regularly.

  2. Test security configurations with unexposed endpoints: Write integration tests that verify your SecurityFilterChain behaves correctly even when actuator endpoints are disabled:

@Test
void whenEndpointNotExposed_securityRulesStillApplyCorrectly() {
    // Test that non-exposed endpoint matchers don't affect other paths
    webTestClient.get().uri("/api/sensitive-data")
        .exchange()
        .expectStatus().isUnauthorized();
}
  1. Explicitly configure endpoint exposure: Don't rely on defaults alone. Be explicit in application.yml:
management:
  endpoints:
    web:
      exposure:
        include: health, info
        exclude: env, beans, shutdown
  1. Use Software Composition Analysis (SCA): Tools like Trivy, Snyk, or OWASP Dependency-Check can flag known CVEs in your dependency tree before they reach production.

  2. Apply the principle of least privilege: Only expose actuator endpoints that are strictly necessary, and always require authentication for sensitive ones.

Key Takeaways

  • EndpointRequest.to() with unexposed endpoints is silently broken in Spring Boot ≤3.4.4 — your security rules may not be doing what you think they're doing.
  • The anti-corruption-layer's pom.xml controlled the Spring Boot version for the entire project — a single version property change fixes the vulnerability across all modules.
  • Default actuator endpoint exposure settings (most endpoints disabled) actually triggered this bug — the "secure by default" configuration paradoxically created the conditions for the vulnerability.
  • Dependency version bumps from 3.4.4 → 3.4.5 are not just feature updates — they contain critical security fixes that address matcher logic in Spring Security integration.
  • Static security rules in code can become dynamically incorrect when the underlying framework has bugs in matcher resolution — always verify with runtime tests.

How Orbis AppSec Detected This

  • Source: The pom.xml dependency declaration for org.springframework.boot:spring-boot version 3.4.4 in the anti-corruption-layer module
  • Sink: EndpointRequest.to() matcher creation in Spring Boot's security filter chain, which produces incorrect URL matching logic when actuator endpoints are not exposed
  • Missing control: The vulnerable Spring Boot version lacked proper handling for the "endpoint not exposed" case in EndpointRequest.to(), failing to return a correct "match nothing" matcher
  • CWE: CWE-284 (Improper Access Control)
  • Fix: Upgraded spring-boot.version from 3.4.4 to 3.4.5 in the root pom.xml, which includes the corrected matcher logic

Orbis AppSec automatically detected this vulnerability and opened a pull request with the fix. Try Orbis AppSec on your repositories to find and fix issues like this automatically.

Conclusion

CVE-2025-22235 is a subtle but high-impact vulnerability that undermines the security guarantees developers expect from Spring Boot's actuator endpoint matchers. The fact that it only manifests when endpoints are not exposed makes it particularly treacherous — the very configuration that seems most secure is the one that triggers the bug. By upgrading to Spring Boot 3.4.5 (or 3.3.11), you ensure that EndpointRequest.to() correctly handles all endpoint states, and your security configuration works exactly as intended. Always keep your framework dependencies updated, and use automated scanning to catch these issues before they reach production.

References

Frequently Asked Questions

What is CVE-2025-22235?

CVE-2025-22235 is a high-severity vulnerability in Spring Boot where the `EndpointRequest.to()` method creates an incorrect request matcher if the specified actuator endpoint is not exposed, potentially causing security rules to match wrong URLs or fail to protect intended endpoints.

How do you prevent actuator security bypass in Spring Boot?

Keep Spring Boot updated to patched versions (3.4.5+ or 3.3.11+), explicitly configure which actuator endpoints are exposed, and verify your security matchers work correctly by testing with unexposed endpoints.

What CWE is CVE-2025-22235?

CWE-284: Improper Access Control. The vulnerability allows security configurations to be applied incorrectly due to a faulty request matcher.

Is restricting actuator endpoint exposure enough to prevent this vulnerability?

No. The bug specifically manifests when endpoints are NOT exposed — the matcher becomes incorrect in that scenario, potentially matching other URLs or creating a permissive rule where restriction was intended.

Can static analysis detect CVE-2025-22235?

Yes. Software composition analysis (SCA) tools like Trivy can detect vulnerable Spring Boot versions in pom.xml or build.gradle files and flag them against the CVE database.

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #3510

Related Articles

medium

How path traversal happens in C file extraction and how to fix it

A path traversal vulnerability in the borpak archive extraction tool allowed attackers to write files to arbitrary locations on the filesystem by crafting malicious .pak archives with `../` sequences in filenames. This medium-severity issue in `tools/borpak/source/borpak.c` could enable system compromise through overwriting critical files like `.bashrc` or cron jobs. The fix implements path validation to ensure extracted files never escape the intended extraction directory.

critical

How SQL injection happens in PostgreSQL dictionary synchronization and how to fix it

A critical SQL injection vulnerability in `zhparser--2.1.sql` allowed attackers to execute arbitrary SQL commands by crafting malicious database names. The vulnerability existed because the dictionary synchronization function constructed COPY commands using string concatenation without proper escaping. This fix implements parameterized queries to safely handle database identifiers.

critical

How command injection happens in Go ffmpeg wrappers and how to fix it

A critical command injection vulnerability was discovered in `drivers/local/util.go` where user-influenced file paths were passed directly to `ffmpeg.Input()` without any sanitization. Because many ffmpeg wrapper libraries construct shell command strings under the hood, an attacker could embed shell metacharacters in a file path to execute arbitrary OS commands with server-level privileges. The fix introduces a `sanitizeFilePath()` function that validates paths are absolute, clean, and point to

critical

How heap buffer overflow happens in C++ JPEG2000 decoding and how to fix it

A critical heap buffer overflow vulnerability was discovered in the OpenJPEG wrapper for Android (jp2forandroid). The `opj_read_from_byte_array()` function performed memcpy operations without validating that the source offset hadn't exceeded the buffer length, allowing maliciously crafted JPEG2000 images to trigger arbitrary code execution. A simple bounds check before the copy operation now prevents this exploitation path.

critical

How heap buffer overflow happens in C UART response handling and how to fix it

A critical heap buffer overflow vulnerability was discovered in the AT client response handler (`sm_at_client.c`) where incoming UART data was copied into a fixed-size buffer without verifying available capacity. A compromised modem or malicious UART data could trigger arbitrary heap corruption. The fix replaces an assertion-only guard with proper bounds clamping using `MIN()` to ensure writes never exceed the `at_cmd_resp` buffer allocation.

high

How heap buffer overflow happens in C JMA archive extraction and how to fix it

A heap buffer overflow vulnerability in `jma/jma.cpp` allowed a crafted JMA ROM archive to trigger out-of-bounds memory writes during file extraction. The flaw existed at line 446, where `memcpy` was called with `first_chunk_offset` and `copy_amount` values derived directly from archive header metadata without any validation that those values stayed within the bounds of either the source or destination buffer. The fix adds a pre-copy bounds check that rejects malformed archives before the danger