Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spring Security 6.1.2 String requestMatchers error UnsupportedOperationException #13609

Open
codingtim opened this issue Aug 3, 2023 · 4 comments
Labels
status: waiting-for-triage An issue we've not yet triaged type: bug A general bug

Comments

@codingtim
Copy link

codingtim commented Aug 3, 2023

Upgrading our application to Spring 6 with Spring Security 6.1.2 and Tomcat 10.1 resulted in the following UnsupportedOperationException:

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.web.SecurityFilterChain]: Factory method 'filterChain' threw exception with message: Section 4.4 of the Servlet 3.0 specification does not permit this method to be called from a ServletContextListener that was not defined in web.xml, a web-fragment.xml file nor annotated with @WebListener
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:171)
	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:655)
	... 78 common frames omitted
Caused by: java.lang.UnsupportedOperationException: Section 4.4 of the Servlet 3.0 specification does not permit this method to be called from a ServletContextListener that was not defined in web.xml, a web-fragment.xml file nor annotated with @WebListener
	at org.apache.catalina.core.StandardContext$NoPluggabilityServletContext.getServletRegistrations(StandardContext.java:6233)
	at org.springframework.security.config.annotation.web.AbstractRequestMatcherRegistry.requestMatchers(AbstractRequestMatcherRegistry.java:197)
	at org.springframework.security.config.annotation.web.AbstractRequestMatcherRegistry.requestMatchers(AbstractRequestMatcherRegistry.java:248)
	at x.y.z.SecurityLocalConfiguration.lambda$filterChain$0(SecurityLocalConfiguration.java:42)
	at org.springframework.security.config.annotation.web.builders.HttpSecurity.authorizeHttpRequests(HttpSecurity.java:1466)
	at x.y.z.SecurityLocalConfiguration.filterChain(SecurityLocalConfiguration.java:41)
	at x.y.z.SecurityLocalConfiguration$$SpringCGLIB$$0.CGLIB$filterChain$2(<generated>)
	at x.y.z.SecurityLocalConfiguration$$SpringCGLIB$$2.invoke(<generated>)
	at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:258)
	at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:331)
	at x.y.z.SecurityLocalConfiguration$$SpringCGLIB$$0.filterChain(<generated>)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:139)
	... 79 common frames omitted

The code that caused this is:

@Bean
public SecurityFilterChain filterChain(HttpSecurity http, Filter autoLoginFilter) throws Exception {
    return http
            .csrf(AbstractHttpConfigurer::disable)
            .authorizeHttpRequests(authorize -> authorize
                    .requestMatchers("/alive").permitAll()
                    .anyRequest().authenticated()
            )
            .build();
}

Our current workaround is to not use requestMatchers with String arguments but to pass a AntPathRequestMatcher.
This ensures our application works again.
Working code:

@Bean
public SecurityFilterChain filterChain(HttpSecurity http, Filter autoLoginFilter) throws Exception {
    return http
            .csrf(AbstractHttpConfigurer::disable)
            .authorizeHttpRequests(authorize -> authorize
                    .requestMatchers(new AntPathRequestMatcher("/alive")).permitAll()
                    .anyRequest().authenticated()
            )
            .build();
}

The implementation of the requestMatchers method was altered in response to CVE https://spring.io/security/cve-2023-34035
PR and commit can be found in this issue: #13551

The requestMatchers method has been changed to call servletContext.getServletRegistrations(); in commit
Tomcat does not seem to allow this and throws the UnsupportedOperationException.
This also matches the javadoc of the getServletRegistrations method

While searching for a solution I found this old issue #4027 that had the same exception after a code change that also used servletContext.getServletRegistrations();.
This was reverted by this PR: #4031

It seems that the mitigation for cve-2023-34035 might need a different solution to ensure it works on tomcat 10.1?

@codingtim codingtim added status: waiting-for-triage An issue we've not yet triaged type: bug A general bug labels Aug 3, 2023
@stevegcc
Copy link

I've run into the same issue and I've reverted to Spring Security 6.0.4 as per the recommendation here. This works for me.

I wasn't willing to go down the path of using AntPathRequestMatchers as it doesn't look like it allows defining multiple paths for a single HTTP method and I have a lot of configuration setup like the config below where there are several paths per method that have the same authority requirements.

.requestMatchers(
    POST,
    "/accounts",
    "/auth/forgot-password",
    "/webhooks/**"
 ).permitAll()

@jesudornenkrone
Copy link

jesudornenkrone commented Aug 22, 2023

I ran into an similar issue, so i reverted back to spring-security 6.1.1 which ist not ideal, because of CVE-2023-34034.

Here my code, that causes the error mesage:

@configuration
@EnableWebSecurity
public class AxWebSecurityConfig {
@bean
@order(1)
public SecurityFilterChain filterChainTardis(HttpSecurity httpSecurityIn) throws Exception {
...

	return httpSecurityIn.build();
}

@Bean
@Order(2)
public SecurityFilterChain filterChainSSO(HttpSecurity httpSecurityIn) throws Exception {
	...

	return httpSecurityIn.build();
}

@Bean
@Order(3)
public SecurityFilterChain filterChainUserNamePassword(HttpSecurity httpSecurityIn) throws Exception {
	...

	return httpSecurityIn.build();
}

}

@jesudornenkrone
Copy link

jesudornenkrone commented Aug 24, 2023

Okay, I traced the problem a little. The Issue is that i use a WebApplicationInitializer adding a ContextLoaderListener. If I remove the ContextLoaderListener from the equation, it works (but I am not sure, if every part of the application is loaded).

However I thought I followed the example from javadoc of org.springframework.web.WebApplicationInitializer. So how can I do this compatible with Spring-Security 6.1.2+:

public class MyWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
@OverRide
protected void beforeSpringSecurityFilterChain(final ServletContext servletContextIn) {
....
servletContextIn.addListener(new MyContextLoaderListener(applicationContext);
}
}

public class MyContextLoaderListener extends ContextLoaderListener {

public AxContextLoaderListener(AnnotationConfigWebApplicationContext applicationContext) {
	super(applicationContext);
}

@Override
public void contextInitialized(final ServletContextEvent sce) {
	super.contextInitialized(sce);
	...
}

...

}

@JohnZ1385
Copy link

any updates on this? I'm seeing similar issues on 5.8.9

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: waiting-for-triage An issue we've not yet triaged type: bug A general bug
Projects
None yet
Development

No branches or pull requests

4 participants