Summary

In Spring Security 6 RequestRejectedException behaviour was changed to return 400 (bad request) if URL contains text forbidden by HTTP firewall like ";", "//" etc. (https://github.com/spring-projects/spring-security/issues/7568). However, after upgrading to Spring Boot 3.0.2, if the project contains spring-boot-starter-actuator as a dependency, the application responds with 200 instead of 400.

How to replicate

Create a new Spring Boot 3 application and implement the simple test:

@SpringBootTest
@AutoConfigureMockMvc
public class BadRequestTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void testBadRequest() throws Exception {
        mockMvc.perform(get("/orders;sds")).andExpect(status().isBadRequest());
    }

}

This test will succeed as expected.

Then add the dependency:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

The test will fail.

The reason

As I can see it happens because the requestRejectedHandler in the FilterChainProxy has been replaced with an ObservationMarkingRequestRejectedHandler which doesn't correctly handle the RequestRejectedException.

Workaround

As I workaround I excluded these autoconfigurations: - org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration - org.springframework.boot.actuate.autoconfigure.observation.web.servlet.WebMvcObservationAutoConfiguration

But I think that ObservationMarkingRequestRejectedHandler should handle such exception correctly by default and the response should be 400 as expected.

Comment From: wilkinsona

Thanks for the report. This is a duplicate of https://github.com/spring-projects/spring-security/issues/12548.

While we don't consider this to be security vulnerability, in the future please consider reporting security-related problems that have the potential to be a vulnerability by following the instructions in https://spring.io/security-policy.