18

I'm getting a ton of errors in production for

org.springframework.security.web.firewall.RequestRejectedException: The request was rejected because the URL was not normalized.

Supposedly this is caused by a // in my urls, but I have no idea where they are coming from. How can I tell what url is causing this? Hard to fix when you don't know what's going on.

I do realize that there is a related question, but that doesn't address how to diagnose the problem URLs. It only addresses how to turn off the strict firewall.

CorayThan
  • 17,174
  • 28
  • 113
  • 161
  • 3
    @Deadpool That is a question about how to stop this error by changing Spring configuration. I want to know how to determine the cause of the error. (What URLs are causing it.) And there are no answers to my question in that question, although it is closely related. – CorayThan Feb 02 '19 at 03:20
  • Hi @CorayThan, Did you get any solution to the problem as I see similar issues in my UAT and Prod logs. Regards, Maulik – Maulik Kayastha Apr 08 '20 at 07:56
  • @MaulikKayastha I don't think I did. Was quite a while ago. I'd try out the answers people gave if I were you. – CorayThan Apr 09 '20 at 09:18

3 Answers3

3

HttpFirewall will check the request at the very beginning in the FilterChainProxy even before invoking any filters in the SecurityFilterChain. So your best bet is to a setup a Filter that is placed in front of FilterChainProxy and this Filter is used to catch RequestRejectedException and log its details.

(1) Implement a Filter that catch this exception :

public class LogFilter implements Filter{

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {
        try {
            chain.doFilter(request, response);
        } catch (Exception e) {
            if( e instanceof RequestRejectedException ) {
                logger.info("Catch RequestRejectedException....");
                logger.info((HttpServletRequest)request).getRequestURI()); //log the request detail such as its URI
            }
            throw e;
        }
    }
}

(2) Configure and register the filter

@Bean
public FilterRegistrationBean someFilterRegistration() {
    FilterRegistrationBean registration = new FilterRegistrationBean();
    registration.setFilter(new LogFilter());
    registration.addUrlPatterns("/*");
    registration.setOrder(RegistrationBean.HIGHEST_PRECEDENCE); //Must has higher precedence than FilterChainProxy
    return registration;
} 
Ken Chan
  • 84,777
  • 26
  • 143
  • 172
2

Sorry for not posting this as a comment, but I can't do that yet.

Have you tried another logging level and logging to a file? I am not home right now, but if not try these lines:

logging.level.=ERROR
logging.file=/home/spring.log

Maybe also try DEBUG as logging level

Otherwhys (allthough a bit hacky) try to just replace every // with a /

As a third option I found this script, you might get it to work.

@ExceptionHandler(RequestRejectedException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public String handleRequestRejectedException(final HttpServletRequest request, final RequestRejectedException ex)
{
    if (LOGGER.isLoggable(Level.INFO))
    {
        LOGGER.log(Level.INFO, "Request Rejected", ex);
    }

    LOGGER.log(Level.WARNING, "Rejected request for [" + request.getRequestURL().toString() + "]. Reason: " + ex.getMessage());
    return "errorPage";
}

Good luck, if you don't succeed I will be back tomorrow.

GutZuFusss
  • 138
  • 1
  • 2
  • 15
0

My problem was that I had a configuration to use Spring Security and also enabled @CrossOrigin Annotation on the controller class, bellow is what I just added to my configuration method.

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // ...
        http.cors(); //Only this
    }
}

You can also check here for reference: https://www.baeldung.com/spring-cors

Neri
  • 738
  • 1
  • 8
  • 19