Skip to content

jzheaux/cve-2023-34035-mitigations

Repository files navigation

This repo is a set of samples to demonstrate the arrangements wherein applications may be vulnerable to CVE-2023-34035.

An application is vulnerable when all of the following are true:

Spring MVC is on the classpath

DispatcherServlet and at least one other servlet are mapped; one of them having a path-based servlet mapping (for example, /path/**)

The application uses requestMatchers(String) to refer to endpoints whose servlet mapping is of the form /path/**

Samples

There are a set of samples that use Spring Boot and a set that do not.

The samples that contain failing tests are vulnerable to CVE-2023-34035. The samples whose tests pass are not vulnerable.

In all cases, each of these samples contains the same mitigation error from Spring Security, though note that such a mitigation is temporary in many circumstances, pending the next maintenance release.

servlet:java-configuration:dispatcher-servlet-path

This sample represents a vulnerable application where DispatcherServlet is deployed to /mvc/* instead of the default /.

It is vulnerable since Spring MVC is on the classpath, DispatcherServlet and at least one other servlet is mapped — one of them with a non-root, path-based servlet mapping (in this case, DispatcherServlet), and the application uses requestMatchers(String) to secure those endpoints.

servlet:java-configuration:jetty

This sample represents a safe application where DispatcherServlet is deployed to / (the default).

It is not vulnerable. While Spring MVC is on the classpath and DispatcherServlet is in use, it is deployed to / and there are no non-root, path-based servlet mappings.

servlet:java-configuration:other-servlets

This sample represents a vulnerable application where DispatcherServlet is deployed as well as a custom servlet MyServlet.

It is vulnerable since Spring MVC is on the classpath, DispatcherServlet and at least one other servlet is mapped — one of them with a non-root, path-based servlet mapping (in this case, MyServlet), and the application uses requestMatchers(String) to secure those endpoints.

servlet:java-configuration:tomcat

This sample represents a safe application where DispatcherServlet is deployed to / (the default).

It is not vulnerable. While Spring MVC is on the classpath and DispatcherServlet is in use, it is deployed to / and there are no non-root, path-based servlet mappings.

servlet:java-configuration:two-dispatcher-servlets

This sample represents a vulnerable application where DispatcherServlet is deployed as well as a custom servlet MyServlet.

It is vulnerable since Spring MVC is on the classpath, DispatcherServlet and at least one other servlet is mapped — one of them with a non-root, path-based servlet mapping (in this case, one of the two DispatcherServlets), and the application uses requestMatchers(String) to secure those endpoints.

servlet:spring-boot:java:dispatcher-servlet-path

This sample represents a vulnerable application where DispatcherServlet is deployed to /mvc/* instead of the default /.

It is vulnerable since Spring MVC is on the classpath, DispatcherServlet and at least one other servlet is mapped — one of them with a non-root, path-based servlet mapping (in this case, DispatcherServlet), and the application uses requestMatchers(String) to secure those endpoints.

servlet:spring-boot:java:jetty

This sample represents a safe application where DispatcherServlet is deployed to / (the default).

It is not vulnerable. While Spring MVC is on the classpath and DispatcherServlet is in use, it is deployed to / and there are no non-root, path-based servlet mappings.

servlet:spring-boot:java:other-servlets

This sample represents a vulnerable application where DispatcherServlet is deployed as well as a custom servlet MyServlet.

It is vulnerable since Spring MVC is on the classpath, DispatcherServlet and at least one other servlet is mapped — one of them with a non-root, path-based servlet mapping (in this case, MyServlet), and the application uses requestMatchers(String) to secure those endpoints.

servlet:spring-boot:java:tomcat

This sample represents a safe application where DispatcherServlet is deployed to / (the default).

It is not vulnerable. While Spring MVC is on the classpath and DispatcherServlet is in use, it is deployed to / and there are no non-root, path-based servlet mappings.

servlet:spring-boot:java:undertow

This sample represents a safe application where DispatcherServlet is deployed to / (the default).

It is not vulnerable. While Spring MVC is on the classpath and DispatcherServlet is in use, it is deployed to / and there are no non-root, path-based servlet mappings.

Mitigations

In the event that you get an error like the following:

Bash
This method cannot decide whether these patterns are Spring MVC patterns or not.
If this endpoint is a Spring MVC endpoint, please use `requestMatchers(MvcRequestMatcher)`;
otherwise, please use `requestMatchers(AntPathRequestMatcher)`.

you should follow it.

Note
The 5.8.5, 6.0.5, 6.1.2, and 6.2.0-M1 versions of Spring Security have some false positives. Now that in many cases the following is temporary, pending the release of 5.8.6, 6.0.6, 6.1.3, and 6.2.0-M2.

As alluded to by the error message, the primary mitigation is to use a complete RequestMatcher. This is so that the servlet mapping can be more clearly accounted for.

For example, if an application has a servlet deployed to /my-servlet/* and is authorizing that traffic like so:

Java
@Bean
SecurityFilterChain appSecurity(HttpSecurity http) throws Exception {
    http
        .authorizeHttpRequests((authorize) -> authorize
            .requestMatchers("/my-servlet/**").hasRole("USER")
            .requestMatchers("/spring-mvc-controller/**").hasRole("USER")
            .anyRequest().authenticated()
        )
        // ...
    return http.build();
}

then, the application should instead do:

Java
import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher;

@Bean
MvcRequestMatcher.Builder mvc(HandlerMappingIntrospector introspector) {
	return new MvcRequestMatcher.Builder(introspector);
}

@Bean
SecurityFilterChain appSecurity(HttpSecurity http, MvcRequestMatcher.Builder mvc) throws Exception {
    http
        .authorizeHttpRequests((authorize) -> authorize
            .requestMatchers(antMatcher("/my-servlet/*")).hasRole("USER")
            .requestMatchers(mvc.pattern("/spring-mvc-controller/**")).hasRole("USER")
            .anyRequest().authenticated()
        )
        // ...
    return http.build();
}

Or, if DispatcherServlet is deployed to a different path, like /spring-mvc/*, then instead of:

Java
@Bean
SecurityFilterChain appSecurity(HttpSecurity http) throws Exception {
    http
        .authorizeHttpRequests((authorize) -> authorize
            .requestMatchers("/spring-mvc/controller/**")).hasRole("USER")
            .anyRequest().authenticated()
        )
        // ...
    return http.build();
}

an application should do:

Java
@Bean
MvcRequestMatcher.Builder mvc(HandlerMappingIntrospector introspector) {
	return new MvcRequestMatcher.Builder(introspector).servletPath("/spring-mvc");
}

@Bean
SecurityFilterChain appSecurity(HttpSecurity http, MvcRequestMatcher.Builder mvc) throws Exception {
    http
        .authorizeHttpRequests((authorize) -> authorize
            .requestMatchers(mvc.pattern("/controller/**")).hasRole("USER")
            .anyRequest().authenticated()
        )
        // ...
    return http.build();
}

Separating the servlet path when constructing an MvcRequestMatcher is important to ensure that the request is correctly matched.

Branches

In this repo, there is a branch for each minor release of Spring Security. On that branch, there is a commit for each affected sample with the needed mitigation.

For example, on the 5.8.x branch, there are eight commits to repair the eight samples that require mitigation.

When 5.8.6, 6.0.6, 6.1.3, and 6.2.0-M2 are released, additional changes will be made to those branches so the best-practice mitigation is clear.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages