DirectoryTraversalFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { final String decodedRequestURI = URLDecoder.decode(request.getRequestURI(), StandardCharsets.UTF_8.name()); URI requestURI; try { requestURI = new URI(decodedRequestURI); } catch (URISyntaxException e) { response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid URI path provided."); return; } final URI normalizedURI = requestURI.normalize(); if (!requestURI.equals(normalizedURI)) { response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid path provided. Please make sure there are no sequences like \"path/..\" in your request url."); return; } filterChain.doFilter(request, response); }    }
@Test public void shouldDisallowTraversalPaths() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest("get", "http: MockHttpServletResponse response = new MockHttpServletResponse(); MockFilterChain chain = new MockFilterChain(); filter.doFilterInternal(request, response, chain); assertThat(response.getStatus()).isEqualTo(HttpServletResponse.SC_BAD_REQUEST); }
@Test public void shouldDisallowTraversalPathsWithEncodedDots() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest("get", "http: MockHttpServletResponse response = new MockHttpServletResponse(); MockFilterChain chain = new MockFilterChain(); filter.doFilterInternal(request, response, chain); assertThat(response.getStatus()).isEqualTo(HttpServletResponse.SC_BAD_REQUEST); }
@Test public void shouldDisallowTraversalPathsWithEncodedDotsAndSlash() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest("get", "http: MockHttpServletResponse response = new MockHttpServletResponse(); MockFilterChain chain = new MockFilterChain(); filter.doFilterInternal(request, response, chain); assertThat(response.getStatus()).isEqualTo(HttpServletResponse.SC_BAD_REQUEST); }
@Test public void shouldDisallowTraversalPathsWithEncodedSlash() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest("get", "http: MockHttpServletResponse response = new MockHttpServletResponse(); MockFilterChain chain = new MockFilterChain(); filter.doFilterInternal(request, response, chain); assertThat(response.getStatus()).isEqualTo(HttpServletResponse.SC_BAD_REQUEST); }
@Test public void shouldAllowNormalizedPath() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest("get", "http: MockHttpServletResponse response = new MockHttpServletResponse(); MockFilterChain chain = new MockFilterChain(); filter.doFilterInternal(request, response, chain); assertThat(response.getStatus()).isNotEqualTo(HttpServletResponse.SC_BAD_REQUEST); }