-
Notifications
You must be signed in to change notification settings - Fork 41.6k
Description
Background
ErrorPageSecurityFilter
was recently added as a step to solve obscure cases where the /error
path was allowed in some cases where it shouldn't be allowed. The ErrorPageSecurityFilter
is installed as a filter outside Spring Security's filter chain. The purpose of the filter is to process ERROR
dispatches and to determine whether the /error
path is allowed given the current authentication. If it is, it should return the intended error page, otherwise, it should only return the status but no content.
This problem was raised in:
- Error page is accessible when no credentials are provided #26356
- Spring security 5 "Bad credentials" exception not shown with errorDetails spring-security#4467
- Spring Security AuthenticationException message inconsistency #26357
The filter was added to Spring Boot 2.6.0 in:
Previous problems
1. Inheriting from HttpFilter
instead of Filter
The ErrorPageSecurityFilter
inherits from HttpFilter
instead of Filter
which causes ClassDefNotFound
exception in some cases:
- ErrorPageSecurityFilter prevents deployment to a Servlet 3.1 compatible container #28790
- https://stackoverflow.com/questions/70087604/why-do-i-have-classnotfoundexception-javax-servlet-http-httpfilter-for-a-war-af/70087906
2. MockMvc
fails to exclude the filter for non-ERROR
dispatches
This problem was raised and discussed in:
- Page with permitAll is no longer accessible via auto-configured MockMvc #28759
- Spring Security 5.6.0 breaks multiple configurations in tests spring-security#10544
The problem is that Spring ApplicationFilterChain
takes into account whether the current request is an ERROR
dispatch or not, and adapts the filter chain to use accordingly, effectively excluding the new ErrorPageSecurityFilter
for non-ERROR
dispatches. The MockFilterChain
used by MockMvc
ignores dispatch type and so includes the ErrorPageSecurityFilter
in all dispatches which may cause problems, especially in connection to the bug reported in this issue.
A ticket to fix this was added here:
A temporary fix in which the filter itself checks whether the current dispatch is an ERROR
or not was devised for release 2.6.1 here:
Bug
Previous problem 2 is also related to the bug reported in this issue and the fact that both reporters have problems with multiple WebSecurityConfigurerAdapters
is indicative of this. The problem is that the ErrorPageSecurityFilter
relies on bean WebInvocationPrivilegeEvaluator
, normally instantiated as a DefaultWebInvocationPrivilegeEvaluator
which only takes the last processed WebSecurityConfigurerAdapter
into account. This results in many times in that ErrorPageSecurityFilter
makes the wrong decision about the access rights to the /error
path. This happens typically with a configuration like:
@EnableWebSecurity(debug = true)
@Order(0)
class Config: WebSecurityConfigurerAdapter() {
override fun configure(http: HttpSecurity) {
http
.requestMatchers()
.antMatchers("/error/**")
.and()
.authorizeRequests()
.anyRequest().permitAll()
}
}
@EnableWebSecurity(debug = true)
@Order(1)
class CatchAllConfig: WebSecurityConfigurerAdapter() {
override fun configure(http: HttpSecurity) {
http
.authorizeRequests()
.anyRequest().denyAll()
}
}
... where the ErrorPageSecurityFilter
would always deny access to the /error
path despite a security config which grants access to the /error
path to anyone.
Since this is ultimately a problem in Spring Security a ticket about this has been filed there:
This ticket is only for reference and should be closed at the same time as the above ticket is closed. For more information, check that ticket.