Skip to content

CVE-2022-31692 Spring Security Authorization bypass

CVE-2022-31692 is a vulnerability in Spring Security that allows authorization bypass when running with specific configurations. The good news is that only very specific configurations are exploitable. However, if you’ve configured Spring Security in this way, attackers can access protected resources without authorization.

This post demonstrates the vulnerability, the problem configuration and suggested fixes. A demonstration vulnerable application is on GitHub.

The vulnerability

Consider this security configuration:

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http.authorizeHttpRequests((authorize) -> authorize
            .antMatchers("/", "/index.html", "/forward").permitAll()
            .anyRequest().authenticated()
            .shouldFilterAllDispatcherTypes(true)
    ).httpBasic();
    return http.build();
}

This sets up a landing page (/ and index.html) and a path (/forward) as unsecured (permitAll()). Anyone can access these resources without authentication. All other resources require authentication. The application has a resource (restricted.html) that is not in the permitAll list and so requires authentication.

When we attempt to access the restricted.html, we’re presented with a login dialog and then a HTTP 401 error if we fail to login:

Let’s look now at the /forward resource. It’s a @Controller with a @GetMapping to forward to another page:

@GetMapping("/forward")
public String redirect() {
    return "forward:/restricted.html";
}

Spring Security permits the controller resource. The forward target is not permitted. The expected behaviour is that the forward is invoked and then the restricted.html page requests authentication. Actual behaviour is this:

Spring Security has granted access. We’ve used a forward to bypass the security configured on our restricted.html resource.

Configuration

First, I’ll note that creating an unrestricted forward to a restricted resource seems to be a bad idea. If nothing else it confuses your intentions. However, we’ve configured Spring Security with

spring.security.filter.dispatcher-types = request, error, async, forward, include

and we’ve set .shouldFilterAllDispatcherTypes(true) so forwards should be handled by Spring Security. Note that if you don’t set these options, Spring Security does not ‘manage’ forwards and allows access to the restricted resource, even after upgrading to the fixed version.

Generally forwards and path based security don’t mix. If you must use forwards, it’s good practice to have the forward path in the same security boundary as the target. That is, if you have a forward to a restricted target you should apply the same restrictions to the forward. Unrestricted forwards should forward only to unrestricted targets. Allowing users to control the target of a forward is an extremely bad idea as it allows exactly this type of privilege escalation.

Fixes

There are two obvious fixes:

  1. Don’t use forwards!
  2. Upgrade Spring Security

Ideally do both.

You should use forwards with care as they can lead to subtle bugs including privilege escalation and open redirect vulnerabilities.

Regularly upgrading components to current versions is generally good practice, particularly security related components. Spring Security fixed the bug in 5.6.9 and 5.7.5 and they recommend upgrading to at least these versions.

Published inSecurity

One Comment

Leave a Reply

Your email address will not be published. Required fields are marked *