Skip to content

DefaultWebInvocationPrivilegeEvaluator can't handle rules based on remote address #10664

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

Closed
fast-reflexes opened this issue Dec 24, 2021 · 1 comment
Assignees
Labels
in: web An issue in web modules (web, webmvc) status: duplicate A duplicate of another issue

Comments

@fast-reflexes
Copy link
Contributor

Describe the bug
When the ErrorPageSecurityFilter kicks in, it uses the DefaultWebInvocationPrivilegeEvaluator to determine if some error pages should be shown or if just a status code should be sent. If the pattern controlling access to error pages contain patterns based on remote address, the invocation fails with an exception:

java.lang.UnsupportedOperationException: public abstract java.lang.String javax.servlet.ServletRequest.getRemoteAddr() is not supported
    at org.springframework.security.web.FilterInvocation$UnsupportedOperationExceptionInvocationHandler.invoke(FilterInvocation.java:326) ~[spring-security-web-5.6.1.jar:5.6.1]
    at com.sun.proxy.$Proxy68.getRemoteAddr(Unknown Source) ~[na:na]
    at javax.servlet.ServletRequestWrapper.getRemoteAddr(ServletRequestWrapper.java:241) ~[tomcat-embed-core-9.0.56.jar:4.0.FR]
    at org.springframework.security.web.util.matcher.IpAddressMatcher.matches(IpAddressMatcher.java:65) ~[spring-security-web-5.6.1.jar:5.6.1]
    at org.springframework.security.web.access.expression.WebSecurityExpressionRoot.hasIpAddress(WebSecurityExpressionRoot.java:51) ~[spring-security-web-5.6.1.jar:5.6.1]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
    at org.springframework.expression.spel.support.ReflectiveMethodExecutor.execute(ReflectiveMethodExecutor.java:129) ~[spring-expression-5.3.14.jar:5.3.14]
    at org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:139) ~[spring-expression-5.3.14.jar:5.3.14]
    at org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:95) ~[spring-expression-5.3.14.jar:5.3.14]
    at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:117) ~[spring-expression-5.3.14.jar:5.3.14]
    at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:308) ~[spring-expression-5.3.14.jar:5.3.14]
    at org.springframework.security.access.expression.ExpressionUtils.evaluateAsBoolean(ExpressionUtils.java:30) ~[spring-security-core-5.6.1.jar:5.6.1]
    at org.springframework.security.web.access.expression.WebExpressionVoter.vote(WebExpressionVoter.java:59) ~[spring-security-web-5.6.1.jar:5.6.1]
    at org.springframework.security.web.access.expression.WebExpressionVoter.vote(WebExpressionVoter.java:39) ~[spring-security-web-5.6.1.jar:5.6.1]
    at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:60) ~[spring-security-core-5.6.1.jar:5.6.1]
    at org.springframework.security.web.access.DefaultWebInvocationPrivilegeEvaluator.isAllowed(DefaultWebInvocationPrivilegeEvaluator.java:100) ~[spring-security-web-5.6.1.jar:5.6.1]
    at org.springframework.security.web.access.DefaultWebInvocationPrivilegeEvaluator.isAllowed(DefaultWebInvocationPrivilegeEvaluator.java:67) ~[spring-security-web-5.6.1.jar:5.6.1]
    at org.springframework.boot.web.servlet.filter.ErrorPageSecurityFilter.isAllowed(ErrorPageSecurityFilter.java:84) ~[spring-boot-2.6.2.jar:2.6.2]
    at org.springframework.boot.web.servlet.filter.ErrorPageSecurityFilter.doFilter(ErrorPageSecurityFilter.java:72) ~[spring-boot-2.6.2.jar:2.6.2]
    ....

To Reproduce

  1. Download project https://github.com/fast-reflexes/spring-boot-bug/tree/getRemoteAddrNotImplemented
    It is a project with the following security config:

    override fun configure(http: HttpSecurity) {
        http
            .authorizeRequests()
            .antMatchers("/error/**").hasIpAddress("127.0.0.1")
            .antMatchers("/non-existing/**").denyAll()
            .antMatchers("/test/**", "/favicon.ico").permitAll()
            .anyRequest().denyAll()
    }
    
  2. Start the app with ./gradlew bootRun

  3. Access localhost:8080/non-existing

  4. Check exception in console

Expected behavior
Expected behaviour is to either allow access to the Spring error page or to just send a status code, depending on the remote address pattern and remote address itself. Definitely not an exception and downgrading to the Tomcat error page.

Sample

See above

@marcusdacoregio
Copy link
Contributor

Hi @fast-reflexes, we are investigating alternatives to the ErrorPageSecurityFilter here #10919.

I recommend you to take a look at #11055 (comment) where I provided some workaround.

I'm closing this so we can centralize the comments and effort in just one ticket. Thank you very much for the report and stay tuned to the other tickets.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web An issue in web modules (web, webmvc) status: duplicate A duplicate of another issue
Projects
None yet
Development

No branches or pull requests

2 participants