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:
Nanne Baars 2023-12-04 21:34:16 +01:00
parent 3d651526be
commit ae261f201a
3 changed files with 81 additions and 20 deletions

View File

@ -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) {

View File

@ -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

View File

@ -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);
}
}