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:
- Don’t use forwards!
- 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.
[…] is another authorization bypass in Spring Security. Like CVE-2022-31692 it’s nasty because it allows completely unrestricted access to supposedly protected […]