Use separate project for integration tests so we can start WebGoat and WebWolf
This commit is contained in:
parent
139651615e
commit
ff530e926e
1
pom.xml
1
pom.xml
@ -143,6 +143,7 @@
|
||||
<module>webgoat-lessons</module>
|
||||
<module>webgoat-server</module>
|
||||
<module>webwolf</module>
|
||||
<module>webgoat-integration-tests</module>
|
||||
</modules>
|
||||
|
||||
<dependencies>
|
||||
|
@ -30,7 +30,6 @@
|
||||
*/
|
||||
package org.owasp.webgoat;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.owasp.webgoat.plugins.PluginEndpointPublisher;
|
||||
import org.owasp.webgoat.plugins.PluginsLoader;
|
||||
import org.owasp.webgoat.session.Course;
|
||||
@ -38,30 +37,17 @@ import org.owasp.webgoat.session.UserSessionData;
|
||||
import org.owasp.webgoat.session.WebSession;
|
||||
import org.owasp.webgoat.session.WebgoatContext;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.web.support.SpringBootServletInitializer;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.context.annotation.ScopedProxyMode;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
@SpringBootApplication
|
||||
@Slf4j
|
||||
public class WebGoat extends SpringBootServletInitializer {
|
||||
|
||||
@Override
|
||||
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
|
||||
return application.sources(WebGoat.class);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
SpringApplication.run(WebGoat.class, args);
|
||||
}
|
||||
@Configuration
|
||||
public class WebGoat {
|
||||
|
||||
@Bean(name = "pluginTargetDirectory")
|
||||
public File pluginTargetDirectory(@Value("${webgoat.user.directory}") final String webgoatHome) {
|
||||
|
@ -58,7 +58,7 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
|
||||
* Constructor for the Lesson object
|
||||
*/
|
||||
public AbstractLesson() {
|
||||
id = new Integer(++count);
|
||||
id = ++count;
|
||||
}
|
||||
|
||||
|
||||
|
@ -36,40 +36,40 @@ import lombok.Getter;
|
||||
*/
|
||||
public enum Category {
|
||||
|
||||
INTRODUCTION("Introduction", new Integer(5)),
|
||||
GENERAL("General", new Integer(100)),
|
||||
INTRODUCTION("Introduction", 5),
|
||||
GENERAL("General", 100),
|
||||
|
||||
INJECTION("(A1) Injection", new Integer(300)),
|
||||
AUTHENTICATION("(A2) Broken Authentication", new Integer(302)),
|
||||
INSECURE_COMMUNICATION("(A3) Sensitive Data Exposure", new Integer(303)),
|
||||
XXE("(A4) XML External Entities (XXE)", Integer.valueOf(304)),
|
||||
ACCESS_CONTROL("(A5) Broken Access Control", new Integer(305)),
|
||||
INJECTION("(A1) Injection", 300),
|
||||
AUTHENTICATION("(A2) Broken Authentication", 302),
|
||||
INSECURE_COMMUNICATION("(A3) Sensitive Data Exposure", 303),
|
||||
XXE("(A4) XML External Entities (XXE)", 304),
|
||||
ACCESS_CONTROL("(A5) Broken Access Control", 305),
|
||||
|
||||
XSS("(A7) Cross-Site Scripting (XSS)", new Integer(307)),
|
||||
INSECURE_DESERIALIZATION("(A8) Insecure Deserialization", new Integer(308)),
|
||||
VULNERABLE_COMPONENTS("(A9) Vulnerable Components", new Integer(309)),
|
||||
XSS("(A7) Cross-Site Scripting (XSS)", 307),
|
||||
INSECURE_DESERIALIZATION("(A8) Insecure Deserialization", 308),
|
||||
VULNERABLE_COMPONENTS("(A9) Vulnerable Components", 309),
|
||||
|
||||
REQUEST_FORGERIES("(A8:2013) Request Forgeries", new Integer(318)),
|
||||
REQUEST_FORGERIES("(A8:2013) Request Forgeries", 318),
|
||||
|
||||
|
||||
REQ_FORGERIES("Request Forgeries", new Integer(450)),
|
||||
REQ_FORGERIES("Request Forgeries", 450),
|
||||
|
||||
INSECURE_CONFIGURATION("Insecure Configuration", new Integer(600)),
|
||||
INSECURE_STORAGE("Insecure Storage", new Integer(800)),
|
||||
INSECURE_CONFIGURATION("Insecure Configuration", 600),
|
||||
INSECURE_STORAGE("Insecure Storage", 800),
|
||||
|
||||
|
||||
AJAX_SECURITY("AJAX Security", new Integer(1000)),
|
||||
BUFFER_OVERFLOW("Buffer Overflows", new Integer(1100)),
|
||||
CODE_QUALITY("Code Quality", new Integer(1200)),
|
||||
CONCURRENCY("Concurrency", new Integer(1300)),
|
||||
ERROR_HANDLING("Improper Error Handling", new Integer(1400)),
|
||||
DOS("Denial of Service", new Integer(1500)),
|
||||
MALICIOUS_EXECUTION("Malicious Execution", new Integer(1600)),
|
||||
CLIENT_SIDE("Client side", new Integer(1700)),
|
||||
SESSION_MANAGEMENT("Session Management Flaws", new Integer(1800)),
|
||||
WEB_SERVICES("Web Services", new Integer(1900)),
|
||||
ADMIN_FUNCTIONS("Admin Functions", new Integer(2000)),
|
||||
CHALLENGE("Challenges", new Integer(3000));
|
||||
AJAX_SECURITY("AJAX Security", 1000),
|
||||
BUFFER_OVERFLOW("Buffer Overflows", 1100),
|
||||
CODE_QUALITY("Code Quality", 1200),
|
||||
CONCURRENCY("Concurrency", 1300),
|
||||
ERROR_HANDLING("Improper Error Handling", 1400),
|
||||
DOS("Denial of Service", 1500),
|
||||
MALICIOUS_EXECUTION("Malicious Execution", 1600),
|
||||
CLIENT_SIDE("Client side", 1700),
|
||||
SESSION_MANAGEMENT("Session Management Flaws", 1800),
|
||||
WEB_SERVICES("Web Services", 1900),
|
||||
ADMIN_FUNCTIONS("Admin Functions", 2000),
|
||||
CHALLENGE("Challenges", 3000);
|
||||
|
||||
@Getter
|
||||
private String name;
|
||||
|
@ -51,7 +51,7 @@ public abstract class LessonAdapter extends AbstractLesson {
|
||||
// Do Nothing - called when restart lesson is pressed. Each lesson can do something
|
||||
}
|
||||
|
||||
private final static Integer DEFAULT_RANKING = new Integer(1000);
|
||||
private final static Integer DEFAULT_RANKING = 1000;
|
||||
|
||||
/**
|
||||
* <p>getDefaultRanking.</p>
|
||||
|
@ -16,7 +16,7 @@ import javax.validation.constraints.Size;
|
||||
public class UserForm {
|
||||
|
||||
@NotNull
|
||||
@Size(min=6, max=20)
|
||||
@Size(min=6, max=40)
|
||||
@Pattern(regexp = "[a-z0-9-]*", message = "can only contain lowercase letters, digits, and -")
|
||||
private String username;
|
||||
@NotNull
|
||||
|
@ -22,7 +22,7 @@ import static org.mockito.Mockito.when;
|
||||
* @since 5/20/17.
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
@TestPropertySource(locations = "classpath:/application-test.properties")
|
||||
@TestPropertySource(locations = {"classpath:/application-webgoat.properties", "classpath:/application-test.properties"})
|
||||
public abstract class LessonTest {
|
||||
|
||||
@LocalServerPort
|
||||
|
66
webgoat-integration-tests/pom.xml
Normal file
66
webgoat-integration-tests/pom.xml
Normal file
@ -0,0 +1,66 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>webgoat-integration-tests</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<parent>
|
||||
<groupId>org.owasp.webgoat</groupId>
|
||||
<artifactId>webgoat-parent</artifactId>
|
||||
<version>v8.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.owasp.webgoat</groupId>
|
||||
<artifactId>webgoat-server</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.owasp.webgoat</groupId>
|
||||
<artifactId>webgoat-server</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<classifier>internal</classifier>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.owasp.webgoat</groupId>
|
||||
<artifactId>webwolf</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<classifier>internal</classifier>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.owasp.webgoat</groupId>
|
||||
<artifactId>webwolf</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.rest-assured</groupId>
|
||||
<artifactId>rest-assured</artifactId>
|
||||
<version>4.0.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>${maven-surefire-plugin.version}</version>
|
||||
<configuration>
|
||||
<forkCount>0</forkCount>
|
||||
<reuseForks>true</reuseForks>
|
||||
<argLine>
|
||||
--illegal-access=permit
|
||||
</argLine>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
@ -0,0 +1,127 @@
|
||||
package org.owasp.webgoat;
|
||||
|
||||
import io.restassured.RestAssured;
|
||||
import io.restassured.http.ContentType;
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public class GeneralLessonTest extends IntegrationTest {
|
||||
|
||||
@Test
|
||||
public void httpBasics() {
|
||||
startLesson("HttpBasics");
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.clear();
|
||||
params.put("person", "goatuser");
|
||||
checkAssignment(url("HttpBasics/attack1"), params, true);
|
||||
|
||||
params.clear();
|
||||
params.put("answer", "POST");
|
||||
params.put("magic_answer", "33");
|
||||
params.put("magic_num", "4");
|
||||
checkAssignment(url("HttpBasics/attack2"), params, false);
|
||||
|
||||
params.clear();
|
||||
params.put("answer", "POST");
|
||||
params.put("magic_answer", "33");
|
||||
params.put("magic_num", "33");
|
||||
checkAssignment(url("HttpBasics/attack2"), params, true);
|
||||
|
||||
checkResults("/HttpBasics/");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void httpProxies() {
|
||||
startLesson("HttpProxies");
|
||||
Assert.assertThat(RestAssured.given()
|
||||
.when().config(restConfig).cookie("JSESSIONID", getWebGoatCookie()).header("x-request-intercepted", "true")
|
||||
.contentType(ContentType.JSON)
|
||||
.get(url("HttpProxies/intercept-request?changeMe=Requests are tampered easily"))
|
||||
.then()
|
||||
.statusCode(200).extract().path("lessonCompleted"), CoreMatchers.is(true));
|
||||
|
||||
checkResults("/HttpProxies/");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cia() {
|
||||
startLesson("CIA");
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.clear();
|
||||
params.put("question_0_solution", "Solution 3: By stealing a database where names and emails are stored and uploading it to a website.");
|
||||
params.put("question_1_solution", "Solution 1: By changing the names and emails of one or more users stored in a database.");
|
||||
params.put("question_2_solution", "Solution 4: By launching a denial of service attack on the servers.");
|
||||
params.put("question_3_solution", "Solution 2: The systems security is compromised even if only one goal is harmed.");
|
||||
checkAssignment(url("/WebGoat/cia/quiz"), params, true);
|
||||
checkResults("/cia/");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void securePasswords() {
|
||||
startLesson("SecurePasswords");
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.clear();
|
||||
params.put("password", "ajnaeliclm^&&@kjn.");
|
||||
checkAssignment(url("/WebGoat/SecurePasswords/assignment"), params, true);
|
||||
checkResults("SecurePasswords/");
|
||||
|
||||
startLesson("AuthBypass");
|
||||
params.clear();
|
||||
params.put("secQuestion2", "John");
|
||||
params.put("secQuestion3", "Main");
|
||||
params.put("jsEnabled", "1");
|
||||
params.put("verifyMethod", "SEC_QUESTIONS");
|
||||
params.put("userId", "12309746");
|
||||
checkAssignment(url("/WebGoat/auth-bypass/verify-account"), params, true);
|
||||
checkResults("/auth-bypass/");
|
||||
|
||||
startLesson("HttpProxies");
|
||||
Assert.assertThat(RestAssured.given().when().config(restConfig).cookie("JSESSIONID", getWebGoatCookie()).header("x-request-intercepted", "true")
|
||||
.contentType(ContentType.JSON)
|
||||
.get(url("/WebGoat/HttpProxies/intercept-request?changeMe=Requests are tampered easily")).then()
|
||||
.statusCode(200).extract().path("lessonCompleted"), CoreMatchers.is(true));
|
||||
checkResults("/HttpProxies/");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void chrome() {
|
||||
startLesson("ChromeDevTools");
|
||||
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.clear();
|
||||
params.put("param1", "42");
|
||||
params.put("param2", "24");
|
||||
|
||||
String result =
|
||||
RestAssured.given()
|
||||
.when()
|
||||
.config(restConfig)
|
||||
.cookie("JSESSIONID", getWebGoatCookie())
|
||||
.header("webgoat-requested-by", "dom-xss-vuln")
|
||||
.header("X-Requested-With", "XMLHttpRequest")
|
||||
.formParams(params)
|
||||
.post(url("/WebGoat/CrossSiteScripting/phone-home-xss"))
|
||||
.then()
|
||||
.statusCode(200)
|
||||
.extract().path("output");
|
||||
String secretNumber = result.substring("phoneHome Response is ".length());
|
||||
|
||||
params.clear();
|
||||
params.put("successMessage", secretNumber);
|
||||
checkAssignment(url("/WebGoat/ChromeDevTools/dummy"), params, true);
|
||||
|
||||
params.clear();
|
||||
params.put("number", "24");
|
||||
params.put("network_num", "24");
|
||||
checkAssignment(url("/WebGoat/ChromeDevTools/network"), params, true);
|
||||
|
||||
checkResults("/ChromeDevTools/");
|
||||
}
|
||||
}
|
@ -0,0 +1,200 @@
|
||||
package org.owasp.webgoat;
|
||||
|
||||
import io.restassured.RestAssured;
|
||||
import io.restassured.config.RestAssuredConfig;
|
||||
import io.restassured.config.SSLConfig;
|
||||
import lombok.Getter;
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.owasp.webwolf.WebWolf;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public abstract class IntegrationTest {
|
||||
|
||||
private static String WEBGOAT_URL = "http://localhost:8080/WebGoat/";
|
||||
private static String WEBWOLF_URL = "http://localhost:9090/";
|
||||
|
||||
//This also allows to test the application with HTTPS when outside testing option is used
|
||||
protected static RestAssuredConfig restConfig = RestAssuredConfig.newConfig().sslConfig(new SSLConfig().relaxedHTTPSValidation());
|
||||
|
||||
@Getter
|
||||
private String webGoatCookie;
|
||||
@Getter
|
||||
private String webWolfCookie;
|
||||
@Getter
|
||||
private String webgoatUser = UUID.randomUUID().toString();
|
||||
|
||||
private static boolean started = false;
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeAll() {
|
||||
if (!started) {
|
||||
started = true;
|
||||
if (!areAlreadyRunning()) {
|
||||
SpringApplicationBuilder wgs = new SpringApplicationBuilder(StartWebGoat.class)
|
||||
.properties(Map.of("spring.config.name", "application-webgoat"));
|
||||
wgs.run();
|
||||
SpringApplicationBuilder wws = new SpringApplicationBuilder(WebWolf.class)
|
||||
.properties(Map.of("spring.config.name", "application-webwolf"));
|
||||
wws.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean areAlreadyRunning() {
|
||||
return checkIfServerIsRunnningOn(9090) && checkIfServerIsRunnningOn(8080);
|
||||
}
|
||||
|
||||
private static boolean checkIfServerIsRunnningOn(int port) {
|
||||
try (var ignored = new ServerSocket(port)) {
|
||||
return false;
|
||||
} catch (IOException e) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
protected String url(String url) {
|
||||
url = url.replaceFirst("/WebGoat/", "");
|
||||
url = url.replaceFirst("/WebGoat", "");
|
||||
url = url.startsWith("/") ? url.replaceFirst("/", "") : url;
|
||||
return WEBGOAT_URL + url;
|
||||
}
|
||||
|
||||
protected String webWolfUrl(String url) {
|
||||
url = url.startsWith("/") ? url.replaceFirst("/", "") : url;
|
||||
return WEBWOLF_URL + url;
|
||||
}
|
||||
|
||||
@Before
|
||||
public void login() {
|
||||
webGoatCookie = RestAssured.given()
|
||||
.when()
|
||||
.config(restConfig)
|
||||
.formParam("username", webgoatUser)
|
||||
.formParam("password", "password")
|
||||
.formParam("matchingPassword", "password")
|
||||
.formParam("agree", "agree")
|
||||
.post(url("register.mvc"))
|
||||
.then()
|
||||
.cookie("JSESSIONID")
|
||||
.statusCode(302)
|
||||
.extract()
|
||||
.cookie("JSESSIONID");
|
||||
|
||||
webWolfCookie = RestAssured.given()
|
||||
.when()
|
||||
.config(restConfig)
|
||||
.formParam("username", webgoatUser)
|
||||
.formParam("password", "password")
|
||||
.post(WEBWOLF_URL + "login")
|
||||
.then()
|
||||
.cookie("WEBWOLFSESSION")
|
||||
.statusCode(302)
|
||||
.extract()
|
||||
.cookie("WEBWOLFSESSION");
|
||||
}
|
||||
|
||||
@After
|
||||
public void logout() {
|
||||
RestAssured.given()
|
||||
.when()
|
||||
.config(restConfig)
|
||||
.get(WEBGOAT_URL + "logout")
|
||||
.then()
|
||||
.statusCode(200);
|
||||
}
|
||||
|
||||
/**
|
||||
* At start of a lesson. The .lesson.lesson is visited and the lesson is reset.
|
||||
*
|
||||
* @param lessonName
|
||||
*/
|
||||
public void startLesson(String lessonName) {
|
||||
RestAssured.given()
|
||||
.when()
|
||||
.config(restConfig)
|
||||
.cookie("JSESSIONID", getWebGoatCookie())
|
||||
.get(url(lessonName + ".lesson.lesson"))
|
||||
.then()
|
||||
.statusCode(200);
|
||||
|
||||
RestAssured.given()
|
||||
.when()
|
||||
.config(restConfig)
|
||||
.cookie("JSESSIONID", getWebGoatCookie())
|
||||
.get(url("service/restartlesson.mvc"))
|
||||
.then()
|
||||
.statusCode(200);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method for most common type of test.
|
||||
* POST with parameters.
|
||||
* Checks for 200 and lessonCompleted as indicated by expectedResult
|
||||
*
|
||||
* @param url
|
||||
* @param params
|
||||
* @param expectedResult
|
||||
*/
|
||||
public void checkAssignment(String url, Map<String, ?> params, boolean expectedResult) {
|
||||
Assert.assertThat(
|
||||
RestAssured.given()
|
||||
.when()
|
||||
.config(restConfig)
|
||||
.cookie("JSESSIONID", getWebGoatCookie())
|
||||
.formParams(params)
|
||||
.post(url)
|
||||
.then()
|
||||
.statusCode(200)
|
||||
.extract().path("lessonCompleted"), CoreMatchers.is(expectedResult));
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method for most common type of test.
|
||||
* PUT with parameters.
|
||||
* Checks for 200 and lessonCompleted as indicated by expectedResult
|
||||
*
|
||||
* @param url
|
||||
* @param params
|
||||
* @param expectedResult
|
||||
*/
|
||||
public void checkAssignmentWithPUT(String url, Map<String, ?> params, boolean expectedResult) {
|
||||
Assert.assertThat(
|
||||
RestAssured.given()
|
||||
.when()
|
||||
.config(restConfig)
|
||||
.cookie("JSESSIONID", getWebGoatCookie())
|
||||
.formParams(params)
|
||||
.put(url)
|
||||
.then()
|
||||
.statusCode(200)
|
||||
.extract().path("lessonCompleted"), CoreMatchers.is(expectedResult));
|
||||
}
|
||||
|
||||
public void checkResults(String prefix) {
|
||||
Assert.assertThat(RestAssured.given()
|
||||
.when()
|
||||
.config(restConfig)
|
||||
.cookie("JSESSIONID", getWebGoatCookie())
|
||||
.get(url("service/lessonoverview.mvc"))
|
||||
.then()
|
||||
.statusCode(200).extract().jsonPath().getList("solved"), CoreMatchers.everyItem(CoreMatchers.is(true)));
|
||||
|
||||
Assert.assertThat(RestAssured.given()
|
||||
.when()
|
||||
.config(restConfig)
|
||||
.cookie("JSESSIONID", getWebGoatCookie())
|
||||
.get(url("service/lessonoverview.mvc"))
|
||||
.then()
|
||||
.statusCode(200).extract().jsonPath().getList("assignment.path"), CoreMatchers.everyItem(CoreMatchers.startsWith(prefix)));
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
package org.owasp.webgoat;
|
||||
|
||||
import io.restassured.RestAssured;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class PasswordResetLessonTest extends IntegrationTest {
|
||||
|
||||
@Test
|
||||
public void solveAssignment() {
|
||||
//WebGoat
|
||||
startLesson("PasswordReset");
|
||||
clickForgotEmailLink("tom@webgoat-cloud.org");
|
||||
|
||||
//WebWolf
|
||||
var link = getPasswordResetLinkFromLandingPage();
|
||||
|
||||
//WebGoat
|
||||
changePassword(link);
|
||||
checkAssignment(url("PasswordReset/reset/login"), Map.of("email", "tom@webgoat-cloud.org", "password", "123456"), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sendEmailShouldBeAvailabeInWebWolf() {
|
||||
startLesson("PasswordReset");
|
||||
clickForgotEmailLink(getWebgoatUser() + "@webgoat.org");
|
||||
|
||||
var responseBody = RestAssured.given()
|
||||
.when()
|
||||
.config(restConfig)
|
||||
.cookie("WEBWOLFSESSION", getWebWolfCookie())
|
||||
.get(webWolfUrl("/WebWolf/mail"))
|
||||
.then()
|
||||
.extract().response().getBody().asString();
|
||||
|
||||
Assertions.assertThat(responseBody).contains("Hi, you requested a password reset link");
|
||||
}
|
||||
|
||||
private void changePassword(String link) {
|
||||
RestAssured.given()
|
||||
.when()
|
||||
.config(restConfig)
|
||||
.cookie("JSESSIONID", getWebGoatCookie())
|
||||
.formParams("resetLink", link, "password", "123456")
|
||||
.post(url("PasswordReset/reset/change-password"))
|
||||
.then()
|
||||
.statusCode(200);
|
||||
}
|
||||
|
||||
private String getPasswordResetLinkFromLandingPage() {
|
||||
var responseBody = RestAssured.given()
|
||||
.when()
|
||||
.config(restConfig)
|
||||
.cookie("WEBWOLFSESSION", getWebWolfCookie())
|
||||
.get(webWolfUrl("WebWolf/requests"))
|
||||
.then()
|
||||
.extract().response().getBody().asString();
|
||||
int startIndex = responseBody.lastIndexOf("\"path\" : \"/PasswordReset/reset/reset-password/");
|
||||
var link = responseBody.substring(startIndex + "\"path\" : \"/PasswordReset/reset/reset-password/".length(), responseBody.indexOf(",", startIndex) - 1);
|
||||
return link;
|
||||
}
|
||||
|
||||
private void clickForgotEmailLink(String user) {
|
||||
RestAssured.given()
|
||||
.when()
|
||||
.header("host", "localhost:9090")
|
||||
.config(restConfig)
|
||||
.cookie("JSESSIONID", getWebGoatCookie())
|
||||
.formParams("email", user)
|
||||
.post(url("PasswordReset/ForgotPassword/create-password-reset-link"))
|
||||
.then()
|
||||
.statusCode(200);
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package org.owasp.webgoat;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class SqlInjectionAdvancedTest extends IntegrationTest {
|
||||
|
||||
@Test
|
||||
public void runTests() {
|
||||
startLesson("SqlInjectionAdvanced");
|
||||
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.clear();
|
||||
params.put("username_reg", "tom' AND substring(password,1,1)='t");
|
||||
params.put("password_reg", "password");
|
||||
params.put("email_reg", "someone@microsoft.com");
|
||||
params.put("confirm_password", "password");
|
||||
checkAssignmentWithPUT(url("/WebGoat/SqlInjectionAdvanced/challenge"), params, true);
|
||||
|
||||
params.clear();
|
||||
params.put("username_login", "tom");
|
||||
params.put("password_login", "thisisasecretfortomonly");
|
||||
checkAssignment(url("/WebGoat/SqlInjectionAdvanced/challenge_Login"), params, true);
|
||||
|
||||
params.clear();
|
||||
params.put("userid_6a", "'; SELECT * FROM user_system_data;--");
|
||||
checkAssignment(url("/WebGoat/SqlInjectionAdvanced/attack6a"), params, true);
|
||||
|
||||
params.clear();
|
||||
params.put("userid_6a", "Smith' union select userid,user_name, user_name,user_name,password,cookie,userid from user_system_data --");
|
||||
checkAssignment(url("/WebGoat/SqlInjectionAdvanced/attack6a"), params, true);
|
||||
|
||||
params.clear();
|
||||
params.put("userid_6b", "passW0rD");
|
||||
checkAssignment(url("/WebGoat/SqlInjectionAdvanced/attack6b"), params, true);
|
||||
|
||||
params.clear();
|
||||
params.put("question_0_solution", "Solution 4: A statement has got values instead of a prepared statement");
|
||||
params.put("question_1_solution", "Solution 3: ?");
|
||||
params.put("question_2_solution", "Solution 2: Prepared statements are compiled once by the database management system waiting for input and are pre-compiled this way.");
|
||||
params.put("question_3_solution", "Solution 3: Placeholders can prevent that the users input gets attached to the SQL query resulting in a seperation of code and data.");
|
||||
params.put("question_4_solution", "Solution 4: The database registers 'Robert' ); DROP TABLE Students;--'.");
|
||||
checkAssignment(url("/WebGoat/SqlInjectionAdvanced/quiz"), params, true);
|
||||
|
||||
checkResults("/SqlInjectionAdvanced/");
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
package org.owasp.webgoat;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class SqlInjectionLessonTest extends IntegrationTest {
|
||||
|
||||
private static final String sql_2 = "select department from employees where last_name='Franco'";
|
||||
private static final String sql_3 = "update employees set department='Sales' where last_name='Barnett'";
|
||||
private static final String sql_4_drop = "alter table employees drop column phone";
|
||||
private static final String sql_4_add = "alter table employees add column phone varchar(20)";
|
||||
private static final String sql_5 = "grant alter table to UnauthorizedUser";
|
||||
private static final String sql_9_account = " ' ";
|
||||
private static final String sql_9_operator = "or";
|
||||
private static final String sql_9_injection = "'1'='1";
|
||||
private static final String sql_10_login_count = "2";
|
||||
private static final String sql_10_userid = "1 or 1=1";
|
||||
|
||||
private static final String sql_11_a = "Smith' or '1' = '1";
|
||||
private static final String sql_11_b = "3SL99A' or '1'='1";
|
||||
|
||||
private static final String sql_12_a = "Smith";
|
||||
private static final String sql_12_b = "3SL99A' ; update employees set salary= '100000' where last_name='Smith";
|
||||
|
||||
private static final String sql_13 = "%update% '; drop table access_log ; --'";
|
||||
|
||||
@Test
|
||||
public void runTests() {
|
||||
startLesson("SqlInjection");
|
||||
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.clear();
|
||||
params.put("query", sql_2);
|
||||
checkAssignment(url("/WebGoat/SqlInjection/attack2"), params, true);
|
||||
|
||||
params.clear();
|
||||
params.put("query", sql_3);
|
||||
checkAssignment(url("/WebGoat/SqlInjection/attack3"), params, true);
|
||||
|
||||
params.clear();
|
||||
params.put("query", sql_4_drop);
|
||||
checkAssignment(url("/WebGoat/SqlInjection/attack4"), params, false);
|
||||
|
||||
params.clear();
|
||||
params.put("query", sql_4_add);
|
||||
checkAssignment(url("/WebGoat/SqlInjection/attack4"), params, true);
|
||||
|
||||
params.clear();
|
||||
params.put("query", sql_5);
|
||||
checkAssignment(url("/WebGoat/SqlInjection/attack5"), params, true);
|
||||
|
||||
params.clear();
|
||||
params.put("operator", sql_9_operator);
|
||||
params.put("account", sql_9_account);
|
||||
params.put("injection", sql_9_injection);
|
||||
checkAssignment(url("/WebGoat/SqlInjection/assignment5a"), params, true);
|
||||
|
||||
params.clear();
|
||||
params.put("login_count", sql_10_login_count);
|
||||
params.put("userid", sql_10_userid);
|
||||
checkAssignment(url("/WebGoat/SqlInjection/assignment5b"), params, true);
|
||||
|
||||
params.clear();
|
||||
params.put("name", sql_11_a);
|
||||
params.put("auth_tan", sql_11_b);
|
||||
checkAssignment(url("/WebGoat/SqlInjection/attack8"), params, true);
|
||||
|
||||
params.clear();
|
||||
params.put("name", sql_12_a);
|
||||
params.put("auth_tan", sql_12_b);
|
||||
checkAssignment(url("/WebGoat/SqlInjection/attack9"), params, true);
|
||||
|
||||
params.clear();
|
||||
params.put("action_string", sql_13);
|
||||
checkAssignment(url("/WebGoat/SqlInjection/attack10"), params, true);
|
||||
|
||||
checkResults("/SqlInjection/");
|
||||
|
||||
}
|
||||
}
|
@ -1,37 +1,39 @@
|
||||
package org.owasp.webgoat;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class SqlInjectionMitigation_TestHelper extends TestHelper {
|
||||
|
||||
public void runTests(String webgoatURL, String cookie) {
|
||||
|
||||
startLesson(cookie, webgoatURL, "SqlInjectionMitigations");
|
||||
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.clear();
|
||||
params.put("field1", "getConnection");
|
||||
params.put("field2", "PreparedStatement prep");
|
||||
params.put("field3", "prepareStatement");
|
||||
params.put("field4", "?");
|
||||
params.put("field5", "?");
|
||||
params.put("field6", "prep.setString(1,\"\")");
|
||||
params.put("field7", "prep.setString(2,\\\"\\\")");
|
||||
checkAssignment(cookie, webgoatURL+"/WebGoat/SqlInjectionMitigations/attack10a", params, true);
|
||||
|
||||
params.put("editor", "try {\r\n" +
|
||||
" Connection conn = DriverManager.getConnection(DBURL,DBUSER,DBPW);\r\n" +
|
||||
" PreparedStatement prep = conn.prepareStatement(\"select id from users where name = ?\");\r\n" +
|
||||
" prep.setString(1,\"me\");\r\n" +
|
||||
" prep.execute();\r\n" +
|
||||
" System.out.println(conn); //should output 'null'\r\n" +
|
||||
"} catch (Exception e) {\r\n" +
|
||||
" System.out.println(\"Oops. Something went wrong!\");\r\n" +
|
||||
"}");
|
||||
checkAssignment(cookie, webgoatURL+"/WebGoat/SqlInjectionMitigations/attack10b", params, true);
|
||||
|
||||
//checkResults(cookie, webgoatURL, "/SqlInjectionMitigations/");
|
||||
|
||||
}
|
||||
}
|
||||
package org.owasp.webgoat;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class SqlInjectionMitigationTest extends IntegrationTest {
|
||||
|
||||
@Test
|
||||
public void runTests() {
|
||||
startLesson("SqlInjectionMitigations");
|
||||
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.clear();
|
||||
params.put("field1", "getConnection");
|
||||
params.put("field2", "PreparedStatement prep");
|
||||
params.put("field3", "prepareStatement");
|
||||
params.put("field4", "?");
|
||||
params.put("field5", "?");
|
||||
params.put("field6", "prep.setString(1,\"\")");
|
||||
params.put("field7", "prep.setString(2,\\\"\\\")");
|
||||
checkAssignment(url("/WebGoat/SqlInjectionMitigations/attack10a"), params, true);
|
||||
|
||||
params.put("editor", "try {\r\n" +
|
||||
" Connection conn = DriverManager.getConnection(DBURL,DBUSER,DBPW);\r\n" +
|
||||
" PreparedStatement prep = conn.prepareStatement(\"select id from users where name = ?\");\r\n" +
|
||||
" prep.setString(1,\"me\");\r\n" +
|
||||
" prep.execute();\r\n" +
|
||||
" System.out.println(conn); //should output 'null'\r\n" +
|
||||
"} catch (Exception e) {\r\n" +
|
||||
" System.out.println(\"Oops. Something went wrong!\");\r\n" +
|
||||
"}");
|
||||
checkAssignment(url("/WebGoat/SqlInjectionMitigations/attack10b"), params, true);
|
||||
|
||||
//checkResults(webGoatCookie, webgoatURL, "/SqlInjectionMitigations/");
|
||||
|
||||
}
|
||||
}
|
@ -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>
|
||||
|
||||
-->
|
@ -7,7 +7,6 @@ import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.web.bind.annotation.CookieValue;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
@ -17,69 +16,67 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.springframework.util.StringUtils.*;
|
||||
import static org.springframework.web.bind.annotation.RequestMethod.POST;
|
||||
|
||||
/**
|
||||
* Part of the password reset assignment. Used to send the e-mail.
|
||||
*
|
||||
* @author nbaars
|
||||
* @since 8/20/17.
|
||||
*/
|
||||
@AssignmentPath("/PasswordReset/ForgotPassword")
|
||||
public class ResetLinkAssignmentForgotPassword extends AssignmentEndpoint {
|
||||
|
||||
private final RestTemplate restTemplate;
|
||||
private final String webWolfMailURL;
|
||||
private final RestTemplate restTemplate;
|
||||
private final String webWolfMailURL;
|
||||
|
||||
public ResetLinkAssignmentForgotPassword(RestTemplate restTemplate,
|
||||
@Value("${webwolf.url.mail}") String webWolfMailURL) {
|
||||
this.restTemplate = restTemplate;
|
||||
this.webWolfMailURL = webWolfMailURL;
|
||||
}
|
||||
public ResetLinkAssignmentForgotPassword(RestTemplate restTemplate,
|
||||
@Value("${webwolf.url.mail}") String webWolfMailURL) {
|
||||
this.restTemplate = restTemplate;
|
||||
this.webWolfMailURL = webWolfMailURL;
|
||||
}
|
||||
|
||||
@RequestMapping(method = POST, value = "/create-password-reset-link")
|
||||
@ResponseBody
|
||||
public AttackResult sendPasswordResetLink(@RequestParam String email, HttpServletRequest request, @CookieValue("JSESSIONID") String cookie) {
|
||||
String resetLink = UUID.randomUUID().toString();
|
||||
ResetLinkAssignment.resetLinks.add(resetLink);
|
||||
String host = request.getHeader("host");
|
||||
if (org.springframework.util.StringUtils.hasText(email)) {
|
||||
if (email.equals(ResetLinkAssignment.TOM_EMAIL) && host.contains("9090")) { //User indeed changed the host header.
|
||||
ResetLinkAssignment.userToTomResetLink.put(getWebSession().getUserName(), resetLink);
|
||||
fakeClickingLinkEmail(host, resetLink);
|
||||
} else {
|
||||
@RequestMapping(method = POST, value = "/create-password-reset-link")
|
||||
@ResponseBody
|
||||
public AttackResult sendPasswordResetLink(@RequestParam String email, HttpServletRequest request) {
|
||||
String resetLink = UUID.randomUUID().toString();
|
||||
ResetLinkAssignment.resetLinks.add(resetLink);
|
||||
String host = request.getHeader("host");
|
||||
if (hasText(email)) {
|
||||
if (email.equals(ResetLinkAssignment.TOM_EMAIL) && host.contains("9090")) { //User indeed changed the host header.
|
||||
ResetLinkAssignment.userToTomResetLink.put(getWebSession().getUserName(), resetLink);
|
||||
fakeClickingLinkEmail(host, resetLink);
|
||||
} else {
|
||||
try {
|
||||
sendMailToUser(email, host, resetLink);
|
||||
} catch (Exception e) {
|
||||
return failed().output("E-mail can't be send. please try again.").build();
|
||||
}
|
||||
}
|
||||
}
|
||||
return success().feedback("email.send").feedbackArgs(email).build();
|
||||
}
|
||||
|
||||
private void sendMailToUser(@RequestParam String email, String host, String resetLink) {
|
||||
int index = email.indexOf("@");
|
||||
String username = email.substring(0, index == -1 ? email.length() : index);
|
||||
PasswordResetEmail mail = PasswordResetEmail.builder()
|
||||
.title("Your password reset link")
|
||||
.contents(String.format(ResetLinkAssignment.TEMPLATE, host, resetLink))
|
||||
.sender("password-reset@webgoat-cloud.net")
|
||||
.recipient(username).build();
|
||||
this.restTemplate.postForEntity(webWolfMailURL, mail, Object.class);
|
||||
}
|
||||
|
||||
private void fakeClickingLinkEmail(String host, String resetLink) {
|
||||
try {
|
||||
sendMailToUser(email, host, resetLink);
|
||||
} catch(Exception e) { return failed().output("E-mail can't be send. please try again.").build(); }
|
||||
}
|
||||
HttpHeaders httpHeaders = new HttpHeaders();
|
||||
HttpEntity httpEntity = new HttpEntity(httpHeaders);
|
||||
new RestTemplate().exchange(String.format("http://%s/PasswordReset/reset/reset-password/%s", host, resetLink), HttpMethod.GET, httpEntity, Void.class);
|
||||
} catch (Exception e) {
|
||||
//don't care
|
||||
}
|
||||
}
|
||||
return success().feedback("email.send").feedbackArgs(email).build();
|
||||
}
|
||||
|
||||
private void sendMailToUser(@RequestParam String email, String host, String resetLink) {
|
||||
int index = email.indexOf("@");
|
||||
String username = email.substring(0, index == -1 ? email.length() : index);
|
||||
PasswordResetEmail mail = PasswordResetEmail.builder()
|
||||
.title("Your password reset link")
|
||||
.contents(String.format(ResetLinkAssignment.TEMPLATE, host, resetLink))
|
||||
.sender("password-reset@webgoat-cloud.net")
|
||||
.recipient(username)
|
||||
.time(LocalDateTime.now()).build();
|
||||
this.restTemplate.postForEntity(webWolfMailURL, mail, Object.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* We need to add the current cookie of the user otherwise we cannot distinguish in WebWolf for
|
||||
* which user we need to trace the incoming request. In normal situation this HOST will be in your
|
||||
* full control so every incoming request would be valid.
|
||||
*/
|
||||
private void fakeClickingLinkEmail(String host, String resetLink) {
|
||||
try {
|
||||
HttpHeaders httpHeaders = new HttpHeaders();
|
||||
HttpEntity httpEntity = new HttpEntity(httpHeaders);
|
||||
new RestTemplate().exchange(String.format("http://%s/PasswordReset/reset/reset-password/%s", host, resetLink), HttpMethod.GET, httpEntity, Void.class);
|
||||
} catch (Exception e) {
|
||||
//don't care
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -9,6 +9,8 @@ password-questions-wrong-user=You need to find a different user you are logging
|
||||
password-questions-unknown-user=User {0} is not a valid user.
|
||||
password-questions-one-successful=You answered one question successfully please try another one.
|
||||
|
||||
email.send=An e-mail has been send to {0}
|
||||
|
||||
password-reset-no-user=Please supply a valid e-mail address.
|
||||
password-reset-solved=Congratulations you solved the assignment, please type in the following code in the e-mail field: {0}
|
||||
password-reset-not-solved=Sorry but you did not redirect the reset link to WebWolf
|
||||
|
@ -139,17 +139,6 @@
|
||||
<artifactId>secure-passwords</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.rest-assured</groupId>
|
||||
<artifactId>rest-assured</artifactId>
|
||||
<version>4.0.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!--uncommment below to run/include lesson template in WebGoat Build-->
|
||||
<!--<dependency>-->
|
||||
<!--<groupId>org.owasp.webgoat.lesson</groupId>-->
|
||||
@ -199,6 +188,22 @@
|
||||
<fork>true</fork>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.1.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>test-compile</phase>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<classifier>internal</classifier>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
@ -27,6 +27,11 @@ package org.owasp.webgoat;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.web.support.SpringBootServletInitializer;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Main entry point, this project is here to get all the lesson jars included to the final jar file
|
||||
@ -36,10 +41,11 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
*/
|
||||
@SpringBootApplication
|
||||
@Slf4j
|
||||
public class StartWebGoat {
|
||||
public class StartWebGoat extends SpringBootServletInitializer {
|
||||
|
||||
public static void main(String[] args) {
|
||||
log.info("Starting WebGoat with args: {}", args);
|
||||
SpringApplication.run(WebGoat.class, args);
|
||||
System.setProperty("spring.config.name", "application-webgoat");
|
||||
SpringApplication.run(StartWebGoat.class, args);
|
||||
}
|
||||
}
|
||||
|
@ -1,137 +0,0 @@
|
||||
package org.owasp.webgoat;
|
||||
|
||||
import static io.restassured.RestAssured.given;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import io.restassured.http.ContentType;
|
||||
|
||||
|
||||
public class General_TestHelper extends TestHelper {
|
||||
|
||||
|
||||
public void httpBasics(String webgoatURL, String cookie) {
|
||||
|
||||
startLesson(cookie, webgoatURL, "HttpBasics");
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.clear();
|
||||
params.put("person", "goatuser");
|
||||
checkAssignment(cookie, webgoatURL+"/WebGoat/HttpBasics/attack1", params, true);
|
||||
|
||||
params.clear();
|
||||
params.put("answer", "POST");
|
||||
params.put("magic_answer", "33");
|
||||
params.put("magic_num", "4");
|
||||
checkAssignment(cookie, webgoatURL+"/WebGoat/HttpBasics/attack2", params, false);
|
||||
|
||||
params.clear();
|
||||
params.put("answer", "POST");
|
||||
params.put("magic_answer", "33");
|
||||
params.put("magic_num", "33");
|
||||
checkAssignment(cookie, webgoatURL+"/WebGoat/HttpBasics/attack2", params, true);
|
||||
|
||||
checkResults(cookie, webgoatURL, "/HttpBasics/");
|
||||
|
||||
}
|
||||
|
||||
public void httpProxies(String webgoatURL, String cookie) {
|
||||
|
||||
startLesson(cookie, webgoatURL, "HttpProxies");
|
||||
assertThat(given()
|
||||
.when().config(restConfig).cookie("JSESSIONID", cookie).header("x-request-intercepted", "true")
|
||||
.contentType(ContentType.JSON)
|
||||
//.log().all()
|
||||
.get(webgoatURL + "/WebGoat/HttpProxies/intercept-request?changeMe=Requests are tampered easily").then()
|
||||
//.log().all()
|
||||
.statusCode(200).extract().path("lessonCompleted"), is(true));
|
||||
|
||||
checkResults(cookie, webgoatURL, "/HttpProxies/");
|
||||
|
||||
}
|
||||
|
||||
public void cia(String webgoatURL, String cookie) {
|
||||
|
||||
startLesson(cookie, webgoatURL, "CIA");
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.clear();
|
||||
params.put("question_0_solution", "Solution 3: By stealing a database where names and emails are stored and uploading it to a website.");
|
||||
params.put("question_1_solution", "Solution 1: By changing the names and emails of one or more users stored in a database.");
|
||||
params.put("question_2_solution", "Solution 4: By launching a denial of service attack on the servers.");
|
||||
params.put("question_3_solution", "Solution 2: The systems security is compromised even if only one goal is harmed.");
|
||||
checkAssignment(cookie, webgoatURL+"/WebGoat/cia/quiz", params, true);
|
||||
checkResults(cookie, webgoatURL, "/cia/");
|
||||
|
||||
}
|
||||
|
||||
public void securePasswords(String webgoatURL, String cookie) {
|
||||
|
||||
startLesson(cookie, webgoatURL, "SecurePasswords");
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.clear();
|
||||
params.put("password", "ajnaeliclm^&&@kjn.");
|
||||
checkAssignment(cookie, webgoatURL+"/WebGoat/SecurePasswords/assignment", params, true);
|
||||
checkResults(cookie, webgoatURL, "SecurePasswords/");
|
||||
|
||||
startLesson(cookie, webgoatURL, "AuthBypass");
|
||||
params.clear();
|
||||
params.put("secQuestion2", "John");
|
||||
params.put("secQuestion3", "Main");
|
||||
params.put("jsEnabled", "1");
|
||||
params.put("verifyMethod", "SEC_QUESTIONS");
|
||||
params.put("userId", "12309746");
|
||||
checkAssignment(cookie, webgoatURL + "/WebGoat/auth-bypass/verify-account", params, true);
|
||||
checkResults(cookie, webgoatURL, "/auth-bypass/");
|
||||
|
||||
startLesson(cookie, webgoatURL, "HttpProxies");
|
||||
assertThat(given().when().config(restConfig).cookie("JSESSIONID", cookie).header("x-request-intercepted", "true")
|
||||
.contentType(ContentType.JSON)
|
||||
//.log().all()
|
||||
.get(webgoatURL + "/WebGoat/HttpProxies/intercept-request?changeMe=Requests are tampered easily").then()
|
||||
//.log().all()
|
||||
.statusCode(200).extract().path("lessonCompleted"), is(true));
|
||||
checkResults(cookie, webgoatURL, "/HttpProxies/");
|
||||
|
||||
}
|
||||
|
||||
public void chrome(String webgoatURL, String cookie) {
|
||||
|
||||
startLesson(cookie, webgoatURL, "ChromeDevTools");
|
||||
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.clear();
|
||||
params.put("param1", "42");
|
||||
params.put("param2", "24");
|
||||
|
||||
String result =
|
||||
given()
|
||||
.when()
|
||||
.config(restConfig)
|
||||
.cookie("JSESSIONID", cookie)
|
||||
.header("webgoat-requested-by","dom-xss-vuln")
|
||||
.header("X-Requested-With", "XMLHttpRequest")
|
||||
.formParams(params)
|
||||
.post(webgoatURL+"/WebGoat/CrossSiteScripting/phone-home-xss")
|
||||
.then()
|
||||
//.log().all()
|
||||
.statusCode(200)
|
||||
.extract().path("output");
|
||||
String secretNumber = result.substring("phoneHome Response is ".length());
|
||||
|
||||
params.clear();
|
||||
params.put("successMessage", secretNumber);
|
||||
checkAssignment(cookie, webgoatURL+"/WebGoat/ChromeDevTools/dummy", params, true);
|
||||
|
||||
params.clear();
|
||||
params.put("number", "24");
|
||||
params.put("network_num", "24");
|
||||
checkAssignment(cookie, webgoatURL+"/WebGoat/ChromeDevTools/network", params, true);
|
||||
|
||||
checkResults(cookie, webgoatURL, "/ChromeDevTools/");
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
package org.owasp.webgoat;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class SqlInjectionAdvanced_TestHelper extends TestHelper {
|
||||
|
||||
public void runTests(String webgoatURL, String cookie) {
|
||||
|
||||
startLesson(cookie, webgoatURL, "SqlInjectionAdvanced");
|
||||
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.clear();
|
||||
params.put("username_reg", "tom' AND substring(password,1,1)='t");
|
||||
params.put("password_reg", "password");
|
||||
params.put("email_reg", "someone@microsoft.com");
|
||||
params.put("confirm_password", "password");
|
||||
checkAssignmentWithPUT(cookie, webgoatURL+"/WebGoat/SqlInjectionAdvanced/challenge", params, true);
|
||||
|
||||
params.clear();
|
||||
params.put("username_login", "tom");
|
||||
params.put("password_login", "thisisasecretfortomonly");
|
||||
checkAssignment(cookie, webgoatURL+"/WebGoat/SqlInjectionAdvanced/challenge_Login", params, true);
|
||||
|
||||
params.clear();
|
||||
params.put("userid_6a", "'; SELECT * FROM user_system_data;--");
|
||||
checkAssignment(cookie, webgoatURL+"/WebGoat/SqlInjectionAdvanced/attack6a", params, true);
|
||||
|
||||
params.clear();
|
||||
params.put("userid_6a", "Smith' union select userid,user_name, user_name,user_name,password,cookie,userid from user_system_data --");
|
||||
checkAssignment(cookie, webgoatURL+"/WebGoat/SqlInjectionAdvanced/attack6a", params, true);
|
||||
|
||||
params.clear();
|
||||
params.put("userid_6b", "passW0rD");
|
||||
checkAssignment(cookie, webgoatURL+"/WebGoat/SqlInjectionAdvanced/attack6b", params, true);
|
||||
|
||||
params.clear();
|
||||
params.put("question_0_solution", "Solution 4: A statement has got values instead of a prepared statement");
|
||||
params.put("question_1_solution", "Solution 3: ?");
|
||||
params.put("question_2_solution", "Solution 2: Prepared statements are compiled once by the database management system waiting for input and are pre-compiled this way.");
|
||||
params.put("question_3_solution", "Solution 3: Placeholders can prevent that the users input gets attached to the SQL query resulting in a seperation of code and data.");
|
||||
params.put("question_4_solution", "Solution 4: The database registers 'Robert' ); DROP TABLE Students;--'.");
|
||||
checkAssignment(cookie, webgoatURL+"/WebGoat/SqlInjectionAdvanced/quiz", params, true);
|
||||
|
||||
checkResults(cookie, webgoatURL, "/SqlInjectionAdvanced/");
|
||||
|
||||
}
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
package org.owasp.webgoat;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class SqlInjection_TestHelper extends TestHelper {
|
||||
|
||||
private static final String sql_2 = "select department from employees where last_name='Franco'";
|
||||
private static final String sql_3 = "update employees set department='Sales' where last_name='Barnett'";
|
||||
private static final String sql_4_drop = "alter table employees drop column phone";
|
||||
private static final String sql_4_add = "alter table employees add column phone varchar(20)";
|
||||
private static final String sql_5 = "grant alter table to UnauthorizedUser";
|
||||
private static final String sql_9_account = " ' ";
|
||||
private static final String sql_9_operator = "or";
|
||||
private static final String sql_9_injection = "'1'='1";
|
||||
private static final String sql_10_login_count = "2";
|
||||
private static final String sql_10_userid = "1 or 1=1";
|
||||
|
||||
private static final String sql_11_a = "Smith' or '1' = '1";
|
||||
private static final String sql_11_b = "3SL99A' or '1'='1";
|
||||
|
||||
private static final String sql_12_a = "Smith";
|
||||
private static final String sql_12_b = "3SL99A' ; update employees set salary= '100000' where last_name='Smith";
|
||||
|
||||
private static final String sql_13 = "%update% '; drop table access_log ; --'";
|
||||
|
||||
public void runTests(String webgoatURL, String cookie) {
|
||||
|
||||
startLesson(cookie, webgoatURL, "SqlInjection");
|
||||
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.clear();
|
||||
params.put("query", sql_2);
|
||||
checkAssignment(cookie, webgoatURL+"/WebGoat/SqlInjection/attack2", params, true);
|
||||
|
||||
params.clear();
|
||||
params.put("query", sql_3);
|
||||
checkAssignment(cookie, webgoatURL+"/WebGoat/SqlInjection/attack3", params, true);
|
||||
|
||||
params.clear();
|
||||
params.put("query", sql_4_drop);
|
||||
checkAssignment(cookie, webgoatURL+"/WebGoat/SqlInjection/attack4", params, false);
|
||||
|
||||
params.clear();
|
||||
params.put("query", sql_4_add);
|
||||
checkAssignment(cookie, webgoatURL+"/WebGoat/SqlInjection/attack4", params, true);
|
||||
|
||||
params.clear();
|
||||
params.put("query", sql_5);
|
||||
checkAssignment(cookie, webgoatURL+"/WebGoat/SqlInjection/attack5", params, true);
|
||||
|
||||
params.clear();
|
||||
params.put("operator", sql_9_operator);
|
||||
params.put("account", sql_9_account);
|
||||
params.put("injection", sql_9_injection);
|
||||
checkAssignment(cookie, webgoatURL+"/WebGoat/SqlInjection/assignment5a", params, true);
|
||||
|
||||
params.clear();
|
||||
params.put("login_count", sql_10_login_count);
|
||||
params.put("userid", sql_10_userid);
|
||||
checkAssignment(cookie, webgoatURL+"/WebGoat/SqlInjection/assignment5b", params, true);
|
||||
|
||||
params.clear();
|
||||
params.put("name", sql_11_a);
|
||||
params.put("auth_tan", sql_11_b);
|
||||
checkAssignment(cookie, webgoatURL+"/WebGoat/SqlInjection/attack8", params, true);
|
||||
|
||||
params.clear();
|
||||
params.put("name", sql_12_a);
|
||||
params.put("auth_tan", sql_12_b);
|
||||
checkAssignment(cookie, webgoatURL+"/WebGoat/SqlInjection/attack9", params, true);
|
||||
|
||||
params.clear();
|
||||
params.put("action_string", sql_13);
|
||||
checkAssignment(cookie, webgoatURL+"/WebGoat/SqlInjection/attack10", params, true);
|
||||
|
||||
checkResults(cookie, webgoatURL, "/SqlInjection/");
|
||||
|
||||
}
|
||||
}
|
@ -1,118 +0,0 @@
|
||||
package org.owasp.webgoat;
|
||||
|
||||
import static io.restassured.RestAssured.given;
|
||||
import static org.hamcrest.CoreMatchers.everyItem;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.startsWith;
|
||||
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import io.restassured.config.RestAssuredConfig;
|
||||
import io.restassured.config.SSLConfig;
|
||||
|
||||
public class TestHelper {
|
||||
|
||||
//This also allows to test the application with HTTPS when outside testing option is used
|
||||
protected RestAssuredConfig restConfig = RestAssuredConfig.newConfig().sslConfig(new SSLConfig().relaxedHTTPSValidation());
|
||||
|
||||
/**
|
||||
* At start of a lesson. The .lesson.lesson is visited and the lesson is reset.
|
||||
* @param cookie
|
||||
* @param url
|
||||
* @param lessonName
|
||||
*/
|
||||
public void startLesson(String cookie, String url, String lessonName) {
|
||||
given()
|
||||
.when()
|
||||
.config(restConfig)
|
||||
.cookie("JSESSIONID", cookie)
|
||||
.get(url+"/WebGoat/"+lessonName+".lesson.lesson")
|
||||
.then()
|
||||
.statusCode(200);
|
||||
|
||||
given()
|
||||
.when()
|
||||
.config(restConfig)
|
||||
.cookie("JSESSIONID", cookie)
|
||||
.get(url+"/WebGoat/service/restartlesson.mvc")
|
||||
.then()
|
||||
.statusCode(200);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method for most common type of test.
|
||||
* POST with parameters.
|
||||
* Checks for 200 and lessonCompleted as indicated by expectedResult
|
||||
* @param webgoatCookie
|
||||
* @param url
|
||||
* @param params
|
||||
* @param expectedResult
|
||||
*/
|
||||
public void checkAssignment(String webgoatCookie, String url, Map<String, ?> params, boolean expectedResult) {
|
||||
assertThat(
|
||||
given()
|
||||
.when()
|
||||
.config(restConfig)
|
||||
.cookie("JSESSIONID", webgoatCookie)
|
||||
.formParams(params)
|
||||
.post(url)
|
||||
.then()
|
||||
//.log().all()
|
||||
.statusCode(200)
|
||||
.extract().path("lessonCompleted"), is(expectedResult));
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method for most common type of test.
|
||||
* PUT with parameters.
|
||||
* Checks for 200 and lessonCompleted as indicated by expectedResult
|
||||
* @param webgoatCookie
|
||||
* @param url
|
||||
* @param params
|
||||
* @param expectedResult
|
||||
*/
|
||||
public void checkAssignmentWithPUT(String webgoatCookie, String url, Map<String, ?> params, boolean expectedResult) {
|
||||
assertThat(
|
||||
given()
|
||||
.when()
|
||||
.config(restConfig)
|
||||
.cookie("JSESSIONID", webgoatCookie)
|
||||
.formParams(params)
|
||||
.put(url)
|
||||
.then()
|
||||
//.log().all()
|
||||
.statusCode(200)
|
||||
.extract().path("lessonCompleted"), is(expectedResult));
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method at the end of a lesson.
|
||||
* Check if all path paramters are correct for the progress.
|
||||
* Check if all are solved.
|
||||
* @param webgoatCookie
|
||||
* @param webgoatURL
|
||||
* @param prefix
|
||||
*/
|
||||
public void checkResults(String webgoatCookie, String webgoatURL, String prefix) {
|
||||
assertThat(given()
|
||||
.when()
|
||||
.config(restConfig)
|
||||
.cookie("JSESSIONID", webgoatCookie)
|
||||
.get(webgoatURL+"/WebGoat/service/lessonoverview.mvc")
|
||||
.then()
|
||||
//.log().all()
|
||||
.statusCode(200).extract().jsonPath().getList("solved"),everyItem(is(true)));
|
||||
|
||||
assertThat(given()
|
||||
.when()
|
||||
.config(restConfig)
|
||||
.cookie("JSESSIONID", webgoatCookie)
|
||||
.get(webgoatURL+"/WebGoat/service/lessonoverview.mvc")
|
||||
.then()
|
||||
//.log().all()
|
||||
.statusCode(200).extract().jsonPath().getList("assignment.path"),everyItem(startsWith(prefix)));
|
||||
|
||||
}
|
||||
}
|
@ -1,162 +0,0 @@
|
||||
package org.owasp.webgoat;
|
||||
|
||||
import static io.restassured.RestAssured.given;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.context.embedded.LocalServerPort;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes=WebGoat.class, webEnvironment = WebEnvironment.RANDOM_PORT)
|
||||
@EnableAutoConfiguration
|
||||
public class WebGoatIntegrationTest extends TestHelper {
|
||||
|
||||
/*
|
||||
* Unique port for http server. Database port is not yet overruled. But this is
|
||||
* not a problem for the integration test.
|
||||
*/
|
||||
@LocalServerPort
|
||||
int randomServerPort;
|
||||
|
||||
private General_TestHelper generalTestHelper = new General_TestHelper();
|
||||
private SqlInjection_TestHelper sqlInjectionHelper = new SqlInjection_TestHelper();
|
||||
private SqlInjectionAdvanced_TestHelper sqlInjectionAdvancedHelper = new SqlInjectionAdvanced_TestHelper();
|
||||
private SqlInjectionMitigation_TestHelper sqlInjectionMitigationHelper = new SqlInjectionMitigation_TestHelper();
|
||||
|
||||
String webgoatURL = System.getProperty("WEBGOAT_URL","");
|
||||
String webgoatUser = System.getProperty("WEBGOAT_USER","");
|
||||
String webgoatPassword = System.getProperty("WEBGOAT_PASSWORD","password");
|
||||
String cookie = "";
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
|
||||
/*
|
||||
* If no system properties are set, the test runs against the random port
|
||||
* of the webgoat application that starts with this test.
|
||||
* If set you can use it to test an oustide running application. If testing
|
||||
* against outside running applications, the tests that require WebWolf can be tested as well.
|
||||
*/
|
||||
//TODO add support for testing the lessons that require WebWolf as well.
|
||||
if (webgoatURL.equals("")) {
|
||||
webgoatURL = "http://127.0.0.1:"+randomServerPort;
|
||||
}
|
||||
|
||||
/*
|
||||
* If not defined a random user will be registered and used in the test.
|
||||
* If you run against an outside application and want to visually see the results,
|
||||
* you can set a username.
|
||||
*/
|
||||
if (webgoatUser.equals("")) {
|
||||
webgoatUser = "tester"+Math.round(Math.random()*1000);
|
||||
}
|
||||
|
||||
//check if user exists
|
||||
String location = given()
|
||||
.when()
|
||||
.config(restConfig)
|
||||
.formParam("username", webgoatUser)
|
||||
.formParam("password", "password")
|
||||
.post(webgoatURL+"/WebGoat/login")
|
||||
.then()
|
||||
//.log().all()
|
||||
.cookie("JSESSIONID")
|
||||
.statusCode(302)
|
||||
.extract().header("Location");
|
||||
|
||||
//register when not existing, otherwise log in and save the cookie
|
||||
if (location.endsWith("error")) {
|
||||
|
||||
cookie = given()
|
||||
.when()
|
||||
.config(restConfig)
|
||||
.formParam("username", webgoatUser)
|
||||
.formParam("password", "password")
|
||||
.formParam("matchingPassword", "password")
|
||||
.formParam("agree", "agree")
|
||||
.post(webgoatURL+"/WebGoat/register.mvc")
|
||||
.then()
|
||||
.cookie("JSESSIONID")
|
||||
.statusCode(302)
|
||||
.extract()
|
||||
.cookie("JSESSIONID");
|
||||
|
||||
} else {
|
||||
|
||||
cookie = given()
|
||||
.when()
|
||||
.config(restConfig)
|
||||
.formParam("username", webgoatUser)
|
||||
.formParam("password", "password")
|
||||
.post(webgoatURL+"/WebGoat/login")
|
||||
.then()
|
||||
//.log().all()
|
||||
.cookie("JSESSIONID")
|
||||
.statusCode(302)
|
||||
.extract().cookie("JSESSIONID");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGeneral_HttpBasics() {
|
||||
|
||||
generalTestHelper.httpBasics(webgoatURL, cookie);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGeneral_HttpProxies() {
|
||||
|
||||
generalTestHelper.httpProxies(webgoatURL, cookie);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGeneral_CIA() {
|
||||
|
||||
generalTestHelper.cia(webgoatURL, cookie);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGeneral_Chrome() {
|
||||
|
||||
generalTestHelper.chrome(webgoatURL, cookie);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSecurePassords() {
|
||||
|
||||
generalTestHelper.securePasswords(webgoatURL, cookie);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSQLInjection() {
|
||||
|
||||
sqlInjectionHelper.runTests(webgoatURL, cookie);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSQLInjectionAdvanced() {
|
||||
|
||||
sqlInjectionAdvancedHelper.runTests(webgoatURL, cookie);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSQLInjectionMitigation() {
|
||||
|
||||
sqlInjectionMitigationHelper.runTests(webgoatURL, cookie);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -110,6 +110,22 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.1.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>test-compile</phase>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<classifier>internal</classifier>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
|
@ -1,29 +1,24 @@
|
||||
package org.owasp.webwolf;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.owasp.webwolf.requests.WebWolfTraceRepository;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.actuate.trace.TraceRepository;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.web.support.SpringBootServletInitializer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@SpringBootApplication
|
||||
@Slf4j
|
||||
public class WebWolf extends SpringBootServletInitializer {
|
||||
public class WebWolf {
|
||||
|
||||
@Bean
|
||||
public TraceRepository traceRepository() {
|
||||
return new WebWolfTraceRepository();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
|
||||
return application.sources(WebWolf.class);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
public static void main(String[] args) {
|
||||
System.setProperty("spring.config.name", "application-webwolf");
|
||||
SpringApplication.run(WebWolf.class, args);
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ public class Email implements Serializable {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
@JsonIgnore
|
||||
private LocalDateTime time = LocalDateTime.now();
|
||||
@Column(length = 1024)
|
||||
private String contents;
|
||||
|
@ -42,7 +42,7 @@ public class Requests {
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public ModelAndView get(HttpServletRequest request) {
|
||||
public ModelAndView get() {
|
||||
ModelAndView m = new ModelAndView("requests");
|
||||
List<Tracert> traces = traceRepository.findAllTraces().stream()
|
||||
.map(t -> new Tracert(t.getTimestamp(), path(t), toJsonString(t))).collect(toList());
|
||||
|
@ -7,7 +7,10 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.actuate.trace.Trace;
|
||||
import org.springframework.boot.actuate.trace.TraceRepository;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Keep track of all the incoming requests, we are only keeping track of request originating from
|
||||
@ -20,7 +23,7 @@ import java.util.*;
|
||||
public class WebWolfTraceRepository implements TraceRepository {
|
||||
|
||||
private final EvictingQueue<Trace> traces = EvictingQueue.create(10000);
|
||||
private List<String> exclusionList = Lists.newArrayList("/WebWolf/home", "/WebWolf/mail","/WebWolf/files", "/images/", "/login", "/favicon.ico", "/js/", "/webjars/", "/WebWolf/requests", "/css/", "/mail");
|
||||
private List<String> exclusionList = Lists.newArrayList("/WebWolf/home", "/WebWolf/mail", "/WebWolf/files", "/images/", "/login", "/favicon.ico", "/js/", "/webjars/", "/WebWolf/requests", "/css/", "/mail");
|
||||
|
||||
@Override
|
||||
public List<Trace> findAll() {
|
||||
@ -40,21 +43,9 @@ public class WebWolfTraceRepository implements TraceRepository {
|
||||
|
||||
@Override
|
||||
public void add(Map<String, Object> map) {
|
||||
Optional<String> host = getFromHeaders("host", map);
|
||||
String path = (String) map.getOrDefault("path", "");
|
||||
if (host.isPresent() && !isInExclusionList(path)) {
|
||||
if (!isInExclusionList(path)) {
|
||||
traces.add(new Trace(new Date(), map));
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<String> getFromHeaders(String header, Map<String, Object> map) {
|
||||
Map<String, Object> headers = (Map<String, Object>) map.get("headers");
|
||||
if (headers != null) {
|
||||
Map<String, Object> request = (Map<String, Object>) headers.get("request");
|
||||
if (request != null) {
|
||||
return Optional.ofNullable((String) request.get(header));
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ import javax.validation.constraints.Size;
|
||||
public class UserForm {
|
||||
|
||||
@NotNull
|
||||
@Size(min=6, max=20)
|
||||
@Size(min=6, max=40)
|
||||
private String username;
|
||||
@NotNull
|
||||
@Size(min=6, max=10)
|
||||
|
@ -1,22 +0,0 @@
|
||||
package org.owasp.webwolf.user;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.springframework.data.annotation.Id;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author nbaars
|
||||
* @since 8/20/17.
|
||||
*/
|
||||
@Getter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class WebGoatUserCookie implements Serializable {
|
||||
|
||||
@Id
|
||||
private String username;
|
||||
private String cookie;
|
||||
}
|
@ -10,6 +10,7 @@ spring.datasource.url=jdbc:hsqldb:hsql://${WEBGOAT_HOST:127.0.0.1}:${WEBGOAT_HSQ
|
||||
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.HSQLDialect
|
||||
spring.jpa.hibernate.ddl-auto=update
|
||||
spring.messages.basename=i18n/messages
|
||||
spring.jmx.enabled=false
|
||||
|
||||
logging.level.org.springframework=INFO
|
||||
logging.level.org.springframework.boot.devtools=WARN
|
Loading…
x
Reference in New Issue
Block a user