feat: show directly requested file in requests overview
When a call directly hits a file it is now show up in the requests overview. This helps the user whether an attack from WebGoat actually requested the uploaded file. Closes: gh-1551
This commit is contained in:
		| @ -22,8 +22,6 @@ | ||||
|  | ||||
| package org.owasp.webgoat.webwolf.requests; | ||||
|  | ||||
| import static java.util.stream.Collectors.toList; | ||||
|  | ||||
| import com.fasterxml.jackson.core.JsonProcessingException; | ||||
| import com.fasterxml.jackson.databind.ObjectMapper; | ||||
| import java.time.Instant; | ||||
| @ -67,10 +65,10 @@ public class Requests { | ||||
|     var model = new ModelAndView("requests"); | ||||
|     String username = (null != authentication) ? authentication.getName() : "anonymous"; | ||||
|     var traces = | ||||
|         traceRepository.findAllTraces().stream() | ||||
|         traceRepository.findAll().stream() | ||||
|             .filter(t -> allowedTrace(t, username)) | ||||
|             .map(t -> new Tracert(t.getTimestamp(), path(t), toJsonString(t))) | ||||
|             .collect(toList()); | ||||
|             .toList(); | ||||
|     model.addObject("traces", traces); | ||||
|  | ||||
|     return model; | ||||
| @ -93,7 +91,7 @@ public class Requests { | ||||
|   } | ||||
|  | ||||
|   private String path(HttpExchange t) { | ||||
|     return (String) t.getRequest().getUri().getPath(); | ||||
|     return t.getRequest().getUri().getPath(); | ||||
|   } | ||||
|  | ||||
|   private String toJsonString(HttpExchange t) { | ||||
|  | ||||
| @ -22,6 +22,9 @@ | ||||
|  | ||||
| package org.owasp.webgoat.webwolf.requests; | ||||
|  | ||||
| import static org.owasp.webgoat.webwolf.requests.WebWolfTraceRepository.Exclusion.contains; | ||||
| import static org.owasp.webgoat.webwolf.requests.WebWolfTraceRepository.Exclusion.endsWith; | ||||
|  | ||||
| import com.google.common.collect.EvictingQueue; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| @ -36,31 +39,50 @@ import org.springframework.boot.actuate.web.exchanges.HttpExchangeRepository; | ||||
|  * @since 8/13/17. | ||||
|  */ | ||||
| public class WebWolfTraceRepository implements HttpExchangeRepository { | ||||
|   private enum MatchingMode { | ||||
|     CONTAINS, | ||||
|     ENDS_WITH, | ||||
|     EQUALS; | ||||
|   } | ||||
|  | ||||
|   record Exclusion(String path, MatchingMode mode) { | ||||
|     public boolean matches(String path) { | ||||
|       return switch (mode) { | ||||
|         case CONTAINS -> path.contains(this.path); | ||||
|         case ENDS_WITH -> path.endsWith(this.path); | ||||
|         case EQUALS -> path.equals(this.path); | ||||
|       }; | ||||
|     } | ||||
|  | ||||
|     public static Exclusion contains(String exclusionPattern) { | ||||
|       return new Exclusion(exclusionPattern, MatchingMode.CONTAINS); | ||||
|     } | ||||
|  | ||||
|     public static Exclusion endsWith(String exclusionPattern) { | ||||
|       return new Exclusion(exclusionPattern, MatchingMode.ENDS_WITH); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   private final EvictingQueue<HttpExchange> traces = EvictingQueue.create(10000); | ||||
|   private final List<String> exclusionList = | ||||
|   private final List<Exclusion> exclusionList = | ||||
|       List.of( | ||||
|           "/tmpdir", | ||||
|           "/home", | ||||
|           "/files", | ||||
|           "/images/", | ||||
|           "/js/", | ||||
|           "/webjars/", | ||||
|           "/requests", | ||||
|           "/css/", | ||||
|           "/mail"); | ||||
|           contains("/tmpdir"), | ||||
|           contains("/home"), | ||||
|           endsWith("/files"), | ||||
|           contains("/images/"), | ||||
|           contains("/js/"), | ||||
|           contains("/webjars/"), | ||||
|           contains("/requests"), | ||||
|           contains("/css/"), | ||||
|           contains("/mail")); | ||||
|  | ||||
|   @Override | ||||
|   public List<HttpExchange> findAll() { | ||||
|     return List.of(); | ||||
|   } | ||||
|  | ||||
|   public List<HttpExchange> findAllTraces() { | ||||
|     return new ArrayList<>(traces); | ||||
|   } | ||||
|  | ||||
|   private boolean isInExclusionList(String path) { | ||||
|     return exclusionList.stream().anyMatch(e -> path.contains(e)); | ||||
|     return exclusionList.stream().anyMatch(e -> e.matches(path)); | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
|  | ||||
| @ -0,0 +1,41 @@ | ||||
| package org.owasp.webgoat.webwolf.requests; | ||||
|  | ||||
| import static org.mockito.Mockito.mock; | ||||
| import static org.mockito.Mockito.when; | ||||
|  | ||||
| import java.net.URI; | ||||
| import org.assertj.core.api.Assertions; | ||||
| import org.junit.jupiter.api.DisplayName; | ||||
| import org.junit.jupiter.api.Test; | ||||
| import org.springframework.boot.actuate.web.exchanges.HttpExchange; | ||||
|  | ||||
| class WebWolfTraceRepositoryTest { | ||||
|  | ||||
|   @Test | ||||
|   @DisplayName("When a user hits a file upload it should be recorded") | ||||
|   void shouldAddFilesRequest() { | ||||
|     HttpExchange httpExchange = mock(); | ||||
|     HttpExchange.Request request = mock(); | ||||
|     when(httpExchange.getRequest()).thenReturn(request); | ||||
|     when(request.getUri()).thenReturn(URI.create("http://localhost:9090/files/test1234/test.jpg")); | ||||
|     WebWolfTraceRepository repository = new WebWolfTraceRepository(); | ||||
|  | ||||
|     repository.add(httpExchange); | ||||
|  | ||||
|     Assertions.assertThat(repository.findAll()).hasSize(1); | ||||
|   } | ||||
|  | ||||
|   @Test | ||||
|   @DisplayName("When a user hits file upload page ('/files') it should be recorded") | ||||
|   void shouldAddNotAddFilesRequestOverview() { | ||||
|     HttpExchange httpExchange = mock(); | ||||
|     HttpExchange.Request request = mock(); | ||||
|     when(httpExchange.getRequest()).thenReturn(request); | ||||
|     when(request.getUri()).thenReturn(URI.create("http://localhost:9090/files")); | ||||
|     WebWolfTraceRepository repository = new WebWolfTraceRepository(); | ||||
|  | ||||
|     repository.add(httpExchange); | ||||
|  | ||||
|     Assertions.assertThat(repository.findAll()).hasSize(0); | ||||
|   } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user