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:
parent
3d651526be
commit
ae261f201a
@ -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);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user