From ff530e926e5c81eb26c114bced9614bdd886c26d Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Sun, 25 Aug 2019 17:43:14 +0200 Subject: [PATCH 1/4] Use separate project for integration tests so we can start WebGoat and WebWolf --- pom.xml | 1 + .../main/java/org/owasp/webgoat/WebGoat.java | 20 +- .../owasp/webgoat/lessons/AbstractLesson.java | 2 +- .../org/owasp/webgoat/lessons/Category.java | 52 ++--- .../owasp/webgoat/lessons/LessonAdapter.java | 2 +- .../org/owasp/webgoat/users/UserForm.java | 2 +- ...perties => application-webgoat.properties} | 0 .../org/owasp/webgoat/plugins/LessonTest.java | 2 +- webgoat-integration-tests/pom.xml | 66 ++++++ .../org/owasp/webgoat/GeneralLessonTest.java | 127 +++++++++++ .../org/owasp/webgoat/IntegrationTest.java | 200 ++++++++++++++++++ .../webgoat/PasswordResetLessonTest.java | 76 +++++++ .../webgoat/SqlInjectionAdvancedTest.java | 49 +++++ .../owasp/webgoat/SqlInjectionLessonTest.java | 82 +++++++ .../webgoat/SqlInjectionMitigationTest.java | 76 +++---- .../src/test/resources/logback-test.xml | 15 ++ .../ResetLinkAssignmentForgotPassword.java | 99 +++++---- .../resources/i18n/WebGoatLabels.properties | 2 + webgoat-server/pom.xml | 27 ++- .../java/org/owasp/webgoat/StartWebGoat.java | 10 +- .../org/owasp/webgoat/General_TestHelper.java | 137 ------------ .../SqlInjectionAdvanced_TestHelper.java | 48 ----- .../webgoat/SqlInjection_TestHelper.java | 80 ------- .../java/org/owasp/webgoat/TestHelper.java | 118 ----------- .../owasp/webgoat/WebGoatIntegrationTest.java | 162 -------------- webwolf/pom.xml | 16 ++ .../main/java/org/owasp/webwolf/WebWolf.java | 15 +- .../java/org/owasp/webwolf/mailbox/Email.java | 1 + .../org/owasp/webwolf/requests/Requests.java | 2 +- .../requests/WebWolfTraceRepository.java | 21 +- .../java/org/owasp/webwolf/user/UserForm.java | 2 +- .../owasp/webwolf/user/WebGoatUserCookie.java | 22 -- ...perties => application-webwolf.properties} | 1 + 33 files changed, 793 insertions(+), 742 deletions(-) rename webgoat-container/src/main/resources/{application.properties => application-webgoat.properties} (100%) create mode 100644 webgoat-integration-tests/pom.xml create mode 100644 webgoat-integration-tests/src/test/java/org/owasp/webgoat/GeneralLessonTest.java create mode 100644 webgoat-integration-tests/src/test/java/org/owasp/webgoat/IntegrationTest.java create mode 100644 webgoat-integration-tests/src/test/java/org/owasp/webgoat/PasswordResetLessonTest.java create mode 100644 webgoat-integration-tests/src/test/java/org/owasp/webgoat/SqlInjectionAdvancedTest.java create mode 100644 webgoat-integration-tests/src/test/java/org/owasp/webgoat/SqlInjectionLessonTest.java rename webgoat-server/src/test/java/org/owasp/webgoat/SqlInjectionMitigation_TestHelper.java => webgoat-integration-tests/src/test/java/org/owasp/webgoat/SqlInjectionMitigationTest.java (65%) create mode 100644 webgoat-integration-tests/src/test/resources/logback-test.xml delete mode 100644 webgoat-server/src/test/java/org/owasp/webgoat/General_TestHelper.java delete mode 100644 webgoat-server/src/test/java/org/owasp/webgoat/SqlInjectionAdvanced_TestHelper.java delete mode 100644 webgoat-server/src/test/java/org/owasp/webgoat/SqlInjection_TestHelper.java delete mode 100644 webgoat-server/src/test/java/org/owasp/webgoat/TestHelper.java delete mode 100644 webgoat-server/src/test/java/org/owasp/webgoat/WebGoatIntegrationTest.java delete mode 100644 webwolf/src/main/java/org/owasp/webwolf/user/WebGoatUserCookie.java rename webwolf/src/main/resources/{application.properties => application-webwolf.properties} (98%) diff --git a/pom.xml b/pom.xml index c82018731..7036fabab 100644 --- a/pom.xml +++ b/pom.xml @@ -143,6 +143,7 @@ webgoat-lessons webgoat-server webwolf + webgoat-integration-tests diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/WebGoat.java b/webgoat-container/src/main/java/org/owasp/webgoat/WebGoat.java index e18374c23..131c482ab 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/WebGoat.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/WebGoat.java @@ -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) { diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/lessons/AbstractLesson.java b/webgoat-container/src/main/java/org/owasp/webgoat/lessons/AbstractLesson.java index 1336fa326..16eca3f45 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/lessons/AbstractLesson.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/lessons/AbstractLesson.java @@ -58,7 +58,7 @@ public abstract class AbstractLesson extends Screen implements ComparablegetDefaultRanking.

diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/users/UserForm.java b/webgoat-container/src/main/java/org/owasp/webgoat/users/UserForm.java index 1e0c44000..38d6b3947 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/users/UserForm.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/users/UserForm.java @@ -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 diff --git a/webgoat-container/src/main/resources/application.properties b/webgoat-container/src/main/resources/application-webgoat.properties similarity index 100% rename from webgoat-container/src/main/resources/application.properties rename to webgoat-container/src/main/resources/application-webgoat.properties diff --git a/webgoat-container/src/test/java/org/owasp/webgoat/plugins/LessonTest.java b/webgoat-container/src/test/java/org/owasp/webgoat/plugins/LessonTest.java index 3e6dffe9e..cd59ab8d9 100644 --- a/webgoat-container/src/test/java/org/owasp/webgoat/plugins/LessonTest.java +++ b/webgoat-container/src/test/java/org/owasp/webgoat/plugins/LessonTest.java @@ -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 diff --git a/webgoat-integration-tests/pom.xml b/webgoat-integration-tests/pom.xml new file mode 100644 index 000000000..de8e86b47 --- /dev/null +++ b/webgoat-integration-tests/pom.xml @@ -0,0 +1,66 @@ + + 4.0.0 + webgoat-integration-tests + jar + + org.owasp.webgoat + webgoat-parent + v8.0.0-SNAPSHOT + + + + + org.owasp.webgoat + webgoat-server + ${project.version} + + + org.owasp.webgoat + webgoat-server + ${project.version} + internal + + + org.owasp.webgoat + webwolf + ${project.version} + internal + + + org.owasp.webgoat + webwolf + ${project.version} + + + org.springframework.boot + spring-boot-starter-test + test + + + io.rest-assured + rest-assured + 4.0.0 + test + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + 0 + true + + --illegal-access=permit + + + + + + + diff --git a/webgoat-integration-tests/src/test/java/org/owasp/webgoat/GeneralLessonTest.java b/webgoat-integration-tests/src/test/java/org/owasp/webgoat/GeneralLessonTest.java new file mode 100644 index 000000000..80dfbc496 --- /dev/null +++ b/webgoat-integration-tests/src/test/java/org/owasp/webgoat/GeneralLessonTest.java @@ -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 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 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 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 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/"); + } +} diff --git a/webgoat-integration-tests/src/test/java/org/owasp/webgoat/IntegrationTest.java b/webgoat-integration-tests/src/test/java/org/owasp/webgoat/IntegrationTest.java new file mode 100644 index 000000000..f26dec4f3 --- /dev/null +++ b/webgoat-integration-tests/src/test/java/org/owasp/webgoat/IntegrationTest.java @@ -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 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 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))); + + } +} diff --git a/webgoat-integration-tests/src/test/java/org/owasp/webgoat/PasswordResetLessonTest.java b/webgoat-integration-tests/src/test/java/org/owasp/webgoat/PasswordResetLessonTest.java new file mode 100644 index 000000000..ebe2b210a --- /dev/null +++ b/webgoat-integration-tests/src/test/java/org/owasp/webgoat/PasswordResetLessonTest.java @@ -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); + } +} diff --git a/webgoat-integration-tests/src/test/java/org/owasp/webgoat/SqlInjectionAdvancedTest.java b/webgoat-integration-tests/src/test/java/org/owasp/webgoat/SqlInjectionAdvancedTest.java new file mode 100644 index 000000000..5bb9b5bcf --- /dev/null +++ b/webgoat-integration-tests/src/test/java/org/owasp/webgoat/SqlInjectionAdvancedTest.java @@ -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 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/"); + } +} diff --git a/webgoat-integration-tests/src/test/java/org/owasp/webgoat/SqlInjectionLessonTest.java b/webgoat-integration-tests/src/test/java/org/owasp/webgoat/SqlInjectionLessonTest.java new file mode 100644 index 000000000..941b088e6 --- /dev/null +++ b/webgoat-integration-tests/src/test/java/org/owasp/webgoat/SqlInjectionLessonTest.java @@ -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 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/"); + + } +} diff --git a/webgoat-server/src/test/java/org/owasp/webgoat/SqlInjectionMitigation_TestHelper.java b/webgoat-integration-tests/src/test/java/org/owasp/webgoat/SqlInjectionMitigationTest.java similarity index 65% rename from webgoat-server/src/test/java/org/owasp/webgoat/SqlInjectionMitigation_TestHelper.java rename to webgoat-integration-tests/src/test/java/org/owasp/webgoat/SqlInjectionMitigationTest.java index 70389dee2..d51af280c 100644 --- a/webgoat-server/src/test/java/org/owasp/webgoat/SqlInjectionMitigation_TestHelper.java +++ b/webgoat-integration-tests/src/test/java/org/owasp/webgoat/SqlInjectionMitigationTest.java @@ -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 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 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/"); + + } +} diff --git a/webgoat-integration-tests/src/test/resources/logback-test.xml b/webgoat-integration-tests/src/test/resources/logback-test.xml new file mode 100644 index 000000000..2ee84585a --- /dev/null +++ b/webgoat-integration-tests/src/test/resources/logback-test.xml @@ -0,0 +1,15 @@ + + + + + \ No newline at end of file diff --git a/webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/ResetLinkAssignmentForgotPassword.java b/webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/ResetLinkAssignmentForgotPassword.java index daceaa377..88bb7cd24 100644 --- a/webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/ResetLinkAssignmentForgotPassword.java +++ b/webgoat-lessons/password-reset/src/main/java/org/owasp/webgoat/plugin/ResetLinkAssignmentForgotPassword.java @@ -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 - } - } } diff --git a/webgoat-lessons/password-reset/src/main/resources/i18n/WebGoatLabels.properties b/webgoat-lessons/password-reset/src/main/resources/i18n/WebGoatLabels.properties index 283ab18b4..2b88df6a4 100644 --- a/webgoat-lessons/password-reset/src/main/resources/i18n/WebGoatLabels.properties +++ b/webgoat-lessons/password-reset/src/main/resources/i18n/WebGoatLabels.properties @@ -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 diff --git a/webgoat-server/pom.xml b/webgoat-server/pom.xml index 5c0ae93b2..312887d4c 100644 --- a/webgoat-server/pom.xml +++ b/webgoat-server/pom.xml @@ -139,17 +139,6 @@ secure-passwords ${project.version} - - org.springframework.boot - spring-boot-starter-test - test - - - io.rest-assured - rest-assured - 4.0.0 - test - @@ -199,6 +188,22 @@ true + + org.apache.maven.plugins + maven-jar-plugin + 3.1.2 + + + test-compile + + jar + + + internal + + + + diff --git a/webgoat-server/src/main/java/org/owasp/webgoat/StartWebGoat.java b/webgoat-server/src/main/java/org/owasp/webgoat/StartWebGoat.java index 473114c0e..bf7b8a223 100644 --- a/webgoat-server/src/main/java/org/owasp/webgoat/StartWebGoat.java +++ b/webgoat-server/src/main/java/org/owasp/webgoat/StartWebGoat.java @@ -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); } } diff --git a/webgoat-server/src/test/java/org/owasp/webgoat/General_TestHelper.java b/webgoat-server/src/test/java/org/owasp/webgoat/General_TestHelper.java deleted file mode 100644 index 694084f50..000000000 --- a/webgoat-server/src/test/java/org/owasp/webgoat/General_TestHelper.java +++ /dev/null @@ -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 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 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 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 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/"); - - } - - -} diff --git a/webgoat-server/src/test/java/org/owasp/webgoat/SqlInjectionAdvanced_TestHelper.java b/webgoat-server/src/test/java/org/owasp/webgoat/SqlInjectionAdvanced_TestHelper.java deleted file mode 100644 index 7328475f2..000000000 --- a/webgoat-server/src/test/java/org/owasp/webgoat/SqlInjectionAdvanced_TestHelper.java +++ /dev/null @@ -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 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/"); - - } -} diff --git a/webgoat-server/src/test/java/org/owasp/webgoat/SqlInjection_TestHelper.java b/webgoat-server/src/test/java/org/owasp/webgoat/SqlInjection_TestHelper.java deleted file mode 100644 index 1f1db2ab4..000000000 --- a/webgoat-server/src/test/java/org/owasp/webgoat/SqlInjection_TestHelper.java +++ /dev/null @@ -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 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/"); - - } -} diff --git a/webgoat-server/src/test/java/org/owasp/webgoat/TestHelper.java b/webgoat-server/src/test/java/org/owasp/webgoat/TestHelper.java deleted file mode 100644 index fd2b67141..000000000 --- a/webgoat-server/src/test/java/org/owasp/webgoat/TestHelper.java +++ /dev/null @@ -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 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 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))); - - } -} diff --git a/webgoat-server/src/test/java/org/owasp/webgoat/WebGoatIntegrationTest.java b/webgoat-server/src/test/java/org/owasp/webgoat/WebGoatIntegrationTest.java deleted file mode 100644 index 12967099e..000000000 --- a/webgoat-server/src/test/java/org/owasp/webgoat/WebGoatIntegrationTest.java +++ /dev/null @@ -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); - - } - - -} diff --git a/webwolf/pom.xml b/webwolf/pom.xml index c0126b712..54c0eb81f 100644 --- a/webwolf/pom.xml +++ b/webwolf/pom.xml @@ -110,6 +110,22 @@ org.springframework.boot spring-boot-maven-plugin + + org.apache.maven.plugins + maven-jar-plugin + 3.1.2 + + + test-compile + + jar + + + internal + + + + org.apache.maven.plugins maven-surefire-plugin diff --git a/webwolf/src/main/java/org/owasp/webwolf/WebWolf.java b/webwolf/src/main/java/org/owasp/webwolf/WebWolf.java index 768b78347..1153f14cb 100644 --- a/webwolf/src/main/java/org/owasp/webwolf/WebWolf.java +++ b/webwolf/src/main/java/org/owasp/webwolf/WebWolf.java @@ -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); } } diff --git a/webwolf/src/main/java/org/owasp/webwolf/mailbox/Email.java b/webwolf/src/main/java/org/owasp/webwolf/mailbox/Email.java index c97e0ba4e..aa31da1f7 100644 --- a/webwolf/src/main/java/org/owasp/webwolf/mailbox/Email.java +++ b/webwolf/src/main/java/org/owasp/webwolf/mailbox/Email.java @@ -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; diff --git a/webwolf/src/main/java/org/owasp/webwolf/requests/Requests.java b/webwolf/src/main/java/org/owasp/webwolf/requests/Requests.java index d92bb4bf1..7bf9bd162 100644 --- a/webwolf/src/main/java/org/owasp/webwolf/requests/Requests.java +++ b/webwolf/src/main/java/org/owasp/webwolf/requests/Requests.java @@ -42,7 +42,7 @@ public class Requests { } @GetMapping - public ModelAndView get(HttpServletRequest request) { + public ModelAndView get() { ModelAndView m = new ModelAndView("requests"); List traces = traceRepository.findAllTraces().stream() .map(t -> new Tracert(t.getTimestamp(), path(t), toJsonString(t))).collect(toList()); diff --git a/webwolf/src/main/java/org/owasp/webwolf/requests/WebWolfTraceRepository.java b/webwolf/src/main/java/org/owasp/webwolf/requests/WebWolfTraceRepository.java index 23e95ba02..d08ed00f6 100644 --- a/webwolf/src/main/java/org/owasp/webwolf/requests/WebWolfTraceRepository.java +++ b/webwolf/src/main/java/org/owasp/webwolf/requests/WebWolfTraceRepository.java @@ -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 traces = EvictingQueue.create(10000); - private List exclusionList = Lists.newArrayList("/WebWolf/home", "/WebWolf/mail","/WebWolf/files", "/images/", "/login", "/favicon.ico", "/js/", "/webjars/", "/WebWolf/requests", "/css/", "/mail"); + private List exclusionList = Lists.newArrayList("/WebWolf/home", "/WebWolf/mail", "/WebWolf/files", "/images/", "/login", "/favicon.ico", "/js/", "/webjars/", "/WebWolf/requests", "/css/", "/mail"); @Override public List findAll() { @@ -40,21 +43,9 @@ public class WebWolfTraceRepository implements TraceRepository { @Override public void add(Map map) { - Optional 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 getFromHeaders(String header, Map map) { - Map headers = (Map) map.get("headers"); - if (headers != null) { - Map request = (Map) headers.get("request"); - if (request != null) { - return Optional.ofNullable((String) request.get(header)); - } - } - return Optional.empty(); - } } diff --git a/webwolf/src/main/java/org/owasp/webwolf/user/UserForm.java b/webwolf/src/main/java/org/owasp/webwolf/user/UserForm.java index 7e9d82a82..bb983126e 100644 --- a/webwolf/src/main/java/org/owasp/webwolf/user/UserForm.java +++ b/webwolf/src/main/java/org/owasp/webwolf/user/UserForm.java @@ -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) diff --git a/webwolf/src/main/java/org/owasp/webwolf/user/WebGoatUserCookie.java b/webwolf/src/main/java/org/owasp/webwolf/user/WebGoatUserCookie.java deleted file mode 100644 index 618d6df25..000000000 --- a/webwolf/src/main/java/org/owasp/webwolf/user/WebGoatUserCookie.java +++ /dev/null @@ -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; -} diff --git a/webwolf/src/main/resources/application.properties b/webwolf/src/main/resources/application-webwolf.properties similarity index 98% rename from webwolf/src/main/resources/application.properties rename to webwolf/src/main/resources/application-webwolf.properties index 981ce87aa..cb3c0f617 100644 --- a/webwolf/src/main/resources/application.properties +++ b/webwolf/src/main/resources/application-webwolf.properties @@ -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 From 2283f945a97a9875867dcf8c228cd659b77929db Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Sun, 25 Aug 2019 17:53:36 +0200 Subject: [PATCH 2/4] Fix failing configuration --- .../src/main/java/org/owasp/webgoat/WebGoat.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/WebGoat.java b/webgoat-container/src/main/java/org/owasp/webgoat/WebGoat.java index 131c482ab..21838d192 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/WebGoat.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/WebGoat.java @@ -37,16 +37,16 @@ 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.autoconfigure.SpringBootApplication; 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; -@Configuration +@SpringBootApplication public class WebGoat { @Bean(name = "pluginTargetDirectory") From 0982bd982c2ad8a827da2abdb97c630117aea62a Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Sun, 8 Sep 2019 18:52:12 +0200 Subject: [PATCH 3/4] Review comments processed: - Ports can now be changed - User is now a default user making it easier to login and look around after a failure --- .../org/owasp/webgoat/IntegrationTest.java | 60 +++++++++++++------ 1 file changed, 41 insertions(+), 19 deletions(-) diff --git a/webgoat-integration-tests/src/test/java/org/owasp/webgoat/IntegrationTest.java b/webgoat-integration-tests/src/test/java/org/owasp/webgoat/IntegrationTest.java index f26dec4f3..6d41a6b34 100644 --- a/webgoat-integration-tests/src/test/java/org/owasp/webgoat/IntegrationTest.java +++ b/webgoat-integration-tests/src/test/java/org/owasp/webgoat/IntegrationTest.java @@ -17,10 +17,15 @@ import java.net.ServerSocket; import java.util.Map; import java.util.UUID; +import static io.restassured.RestAssured.given; + public abstract class IntegrationTest { - private static String WEBGOAT_URL = "http://localhost:8080/WebGoat/"; - private static String WEBWOLF_URL = "http://localhost:9090/"; + protected static int WG_PORT = 8080; + protected static int WW_PORT = 9090; + private static String WEBGOAT_URL = "http://127.0.0.1:" + WG_PORT + "/WebGoat/"; + private static String WEBWOLF_URL = "http://127.0.0.1:" + WW_PORT + "/"; + //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()); @@ -38,23 +43,19 @@ public abstract class IntegrationTest { public static void beforeAll() { if (!started) { started = true; - if (!areAlreadyRunning()) { + if (!isAlreadyRunning()) { SpringApplicationBuilder wgs = new SpringApplicationBuilder(StartWebGoat.class) - .properties(Map.of("spring.config.name", "application-webgoat")); + .properties(Map.of("spring.config.name", "application-webgoat", "WEBGOAT_PORT", WG_PORT)); wgs.run(); SpringApplicationBuilder wws = new SpringApplicationBuilder(WebWolf.class) - .properties(Map.of("spring.config.name", "application-webwolf")); + .properties(Map.of("spring.config.name", "application-webwolf", "WEBWOLF_PORT", WW_PORT)); wws.run(); } } } - private static boolean areAlreadyRunning() { - return checkIfServerIsRunnningOn(9090) && checkIfServerIsRunnningOn(8080); - } - - private static boolean checkIfServerIsRunnningOn(int port) { - try (var ignored = new ServerSocket(port)) { + private static boolean isAlreadyRunning() { + try (var ignored = new ServerSocket(WG_PORT)) { return false; } catch (IOException e) { return true; @@ -75,19 +76,40 @@ public abstract class IntegrationTest { @Before public void login() { - webGoatCookie = RestAssured.given() + String location = given() .when() .config(restConfig) .formParam("username", webgoatUser) .formParam("password", "password") - .formParam("matchingPassword", "password") - .formParam("agree", "agree") - .post(url("register.mvc")) - .then() + .post(url("login")).then() .cookie("JSESSIONID") .statusCode(302) - .extract() - .cookie("JSESSIONID"); + .extract().header("Location"); + if (location.endsWith("?error")) { + 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"); + } else { + webGoatCookie = given() + .when() + .config(restConfig) + .formParam("username", webgoatUser) + .formParam("password", "password") + .post(url("login")).then() + .cookie("JSESSIONID") + .statusCode(302) + .extract().cookie("JSESSIONID"); + } webWolfCookie = RestAssured.given() .when() @@ -107,7 +129,7 @@ public abstract class IntegrationTest { RestAssured.given() .when() .config(restConfig) - .get(WEBGOAT_URL + "logout") + .get(url("logout")) .then() .statusCode(200); } From bf52e7a99229d12f6ea9dcbabe59902d41670e69 Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Mon, 9 Sep 2019 11:37:26 +0200 Subject: [PATCH 4/4] Fixed checking of server already running --- .../java/org/owasp/webgoat/IntegrationTest.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/webgoat-integration-tests/src/test/java/org/owasp/webgoat/IntegrationTest.java b/webgoat-integration-tests/src/test/java/org/owasp/webgoat/IntegrationTest.java index 6d41a6b34..9114fcad1 100644 --- a/webgoat-integration-tests/src/test/java/org/owasp/webgoat/IntegrationTest.java +++ b/webgoat-integration-tests/src/test/java/org/owasp/webgoat/IntegrationTest.java @@ -13,7 +13,7 @@ import org.owasp.webwolf.WebWolf; import org.springframework.boot.builder.SpringApplicationBuilder; import java.io.IOException; -import java.net.ServerSocket; +import java.net.Socket; import java.util.Map; import java.util.UUID; @@ -43,10 +43,12 @@ public abstract class IntegrationTest { public static void beforeAll() { if (!started) { started = true; - if (!isAlreadyRunning()) { + if (!isAlreadyRunning(WG_PORT)) { SpringApplicationBuilder wgs = new SpringApplicationBuilder(StartWebGoat.class) .properties(Map.of("spring.config.name", "application-webgoat", "WEBGOAT_PORT", WG_PORT)); wgs.run(); + } + if (!isAlreadyRunning(WW_PORT)) { SpringApplicationBuilder wws = new SpringApplicationBuilder(WebWolf.class) .properties(Map.of("spring.config.name", "application-webwolf", "WEBWOLF_PORT", WW_PORT)); wws.run(); @@ -54,11 +56,11 @@ public abstract class IntegrationTest { } } - private static boolean isAlreadyRunning() { - try (var ignored = new ServerSocket(WG_PORT)) { - return false; - } catch (IOException e) { + private static boolean isAlreadyRunning(int port) { + try (var ignored = new Socket("127.0.0.1", port)) { return true; + } catch (IOException e) { + return false; } }