Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring 5.0.3 RequestRejectedException: The request was rejected because the URL was not normalized

Not sure if this is a bug with Spring 5.0.3 or a new feature to fix things on my end.

After the upgrade, I am getting this error. Interestingly this error is only on my local machine. Same code on test environment with HTTPS protocol works fine.

Continuing...

The reason I am getting this error is because my URL for loading the resultant JSP page is /location/thisPage.jsp. Evaluating code request.getRequestURI() gives me result /WEB-INF/somelocation//location/thisPage.jsp. If I fix URL of JSP page to this location/thisPage.jsp, things work fine.

So my question is, should I remove / from JSP path in code because that's what is required going forward. Or Spring has introduced a bug as the only difference between my machine and test environment is protocol HTTP versus HTTPS.

 org.springframework.security.web.firewall.RequestRejectedException: The request was rejected because the URL was not normalized.     at org.springframework.security.web.firewall.StrictHttpFirewall.getFirewalledRequest(StrictHttpFirewall.java:123)     at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:194)     at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:186)     at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357)     at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270) 
like image 280
java_dude Avatar asked Jan 26 '18 00:01

java_dude


People also ask

How do I disable Stricthttpfirewall?

There is no way to disable this as it is considered extremely risky to disable this constraint. A few options to allow this behavior is to normalize the request prior to the firewall or using DefaultHttpFirewall instead.

What is FirewalledRequest?

FirewalledRequest(javax.servlet.http.HttpServletRequest request) Constructs a request object wrapping the given request.

What is Spring Security in Java?

Spring Security is a powerful and highly customizable authentication and access-control framework. It is the de-facto standard for securing Spring-based applications. Spring Security is a framework that focuses on providing both authentication and authorization to Java applications.


2 Answers

Spring Security Documentation mentions the reason for blocking // in the request.

For example, it could contain path-traversal sequences (like /../) or multiple forward slashes (//) which could also cause pattern-matches to fail. Some containers normalize these out before performing the servlet mapping, but others don’t. To protect against issues like these, FilterChainProxy uses an HttpFirewall strategy to check and wrap the request. Un-normalized requests are automatically rejected by default, and path parameters and duplicate slashes are removed for matching purposes.

So there are two possible solutions -

  1. remove double slash (preferred approach)
  2. Allow // in Spring Security by customizing the StrictHttpFirewall using the below code.

Step 1 Create custom firewall that allows slash in URL.

@Bean public HttpFirewall allowUrlEncodedSlashHttpFirewall() {     StrictHttpFirewall firewall = new StrictHttpFirewall();     firewall.setAllowUrlEncodedSlash(true);         return firewall; } 

Step 2 And then configure this bean in websecurity

@Override public void configure(WebSecurity web) throws Exception {     //@formatter:off     super.configure(web);     web.httpFirewall(allowUrlEncodedSlashHttpFirewall()); .... } 

Step 2 is an optional step, Spring Boot just needs a bean to be declared of type HttpFirewall and it will auto-configure it in filter chain.

Spring Security 5.4 Update

In Spring security 5.4 and above (Spring Boot >= 2.4.0), we can get rid of too many logs complaining about the request rejected by creating the below bean.

import org.springframework.security.web.firewall.RequestRejectedHandler; import org.springframework.security.web.firewall.HttpStatusRequestRejectedHandler;  @Bean RequestRejectedHandler requestRejectedHandler() {    return new HttpStatusRequestRejectedHandler(); } 
like image 138
Munish Chandel Avatar answered Oct 13 '22 00:10

Munish Chandel


setAllowUrlEncodedSlash(true) didn't work for me. Still internal method isNormalized return false when having double slash.

I replaced StrictHttpFirewall with DefaultHttpFirewall by having the following code only:

@Bean public HttpFirewall defaultHttpFirewall() {     return new DefaultHttpFirewall(); } 

Working well for me.
Any risk by using DefaultHttpFirewall?

like image 23
maor chetrit Avatar answered Oct 13 '22 01:10

maor chetrit