0

My question: How do I unit test my Filter class

Problem to solve: My Spring-Boot app includes Spring-Security with default config. This means that if a malicious URL is requested a RequestRejectedException is thrown.

e.g.

2023-06-20 10:08:19,716     ERROR ....[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception
org.springframework.security.web.firewall.RequestRejectedException: The request was rejected because the URL contained a potentially malicious String "%2e"
        at org.springframework.security.web.firewall.StrictHttpFirewall.rejectedBlacklistedUrls(StrictHttpFirewall.java:349)
        at org.springframework.security.web.firewall.StrictHttpFirewall.getFirewalledRequest(StrictHttpFirewall.java:316)
        at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:194)
        at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)

This exception bubbles up to become an ERROR in my application log, which in turn triggers an alert.

My fix: I've written a Filter class to check all ServletRequests and handle the RequestRejectedException (if thrown). It's a solution from a related thread here: https://stackoverflow.com/a/52635656/22144884

How do I test it? The filter class is working well, but I need to write a unit test and I'm not sure how to approach it.

I need to assert that if the StrictHttpFirewall throws a RequestRejectedException, my filter class will catch it and handle it. Can I do this as a unit test, or do I need to have the application running so that I can actually test against the Spring-Security firewall?

Your advice on how to write the simplest test is appreciated!

I tried this:

public class RequestRejectedExceptionFilterTest {
    private final RequestRejectedExceptionFilter filter = new RequestRejectedExceptionFilter();
    
    @Test(expected = RequestRejectedException.class)
    public void redirectTest() throws IOException, ServletException {
        MockHttpServletRequest req = new MockHttpServletRequest();
        MockHttpServletResponse res = new MockHttpServletResponse();
        MockFilterChain chain = new MockFilterChain();
        
        req.setServletPath(";");
        filter.doFilter(req, res, chain);
    }
}

but it doesn't throw a RequestRejectedException. I assume this is because the mock request doesn't actually hit the StrictHTTPFirewall.

Test output:

Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.004 sec <<< FAILURE!
redirectTest(com.mycompany.my_app.filter.RequestRejectedExceptionFilterTest)  Time elapsed: 0.004 sec  <<< FAILURE!
java.lang.AssertionError: Expected exception: org.springframework.security.web.firewall.RequestRejectedException
        at org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:34)
        at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
        at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)

0 Answers0