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

high

How NO_PROXY bypass via crafted URL happens in Node.js axios and how to fix it

A high-severity vulnerability (CVE-2026-42043) in axios versions prior to 1.15.1 allowed attackers to bypass NO_PROXY environment variable restrictions using specially crafted URLs. This meant HTTP requests intended to stay internal could be routed through an attacker-controlled proxy, potentially exposing sensitive data. The fix upgrades axios to version 1.15.1, which correctly validates URLs against NO_PROXY rules.

critical

How JSON request validation bypass happens in Node.js API handlers and how to fix it

A critical validation bypass in the `/api/agents/jobs` endpoint allowed attackers to send malformed JSON with arbitrary properties that could trigger prototype pollution or unexpected behavior. The fix added comprehensive validation checks including array detection and property existence verification to prevent malicious payloads from reaching downstream processing logic.

critical

How Server-Side Request Forgery happens in Node.js httpProxy.js and how to fix it

A critical Server-Side Request Forgery (SSRF) vulnerability was discovered in `hubcmdui/routes/httpProxy.js` where the `/proxy/test` endpoint passed a user-controlled `testUrl` parameter directly to `axios.get()` without any validation. An attacker could exploit this to probe internal infrastructure — including AWS metadata endpoints, Redis instances, and private network ranges. The fix introduces a strict URL validation function that blocks private IP ranges, loopback addresses, and non-HTTP(S)

critical

How Remote Configuration Injection happens in JavaScript fetch() and how to fix it

A critical vulnerability in `js/config.js` allowed attackers to inject malicious configuration data through DNS spoofing or man-in-the-middle attacks. The application fetched remote JSON configuration from GitHub without validating the response structure, enabling arbitrary code execution through crafted payloads. A single validation check now ensures only properly-formed configuration objects are accepted.

high

How missing Dependabot cooldown configuration happens in GitHub Actions and how to fix it

A high-severity vulnerability was discovered in the `.github/dependabot.yml` configuration file where no cooldown period was set for dependency updates. This exposed the Node.js library and its downstream consumers to potentially malicious or unstable packages immediately after publication. The fix adds a 7-day cooldown period to all package ecosystem entries, providing a critical safety buffer before accepting newly published package versions.

high

How command injection happens in Ruby backticks and how to fix it

A Jekyll plugin used unsafe Ruby backticks to execute a `git log` command with an unescaped file path, creating a command injection vulnerability. By switching to `Open3.capture2()` with argument array syntax, the fix prevents shell interpretation and eliminates the attack surface entirely.