diff --git a/pom.xml b/pom.xml index d6e0026b4..793b41846 100644 --- a/pom.xml +++ b/pom.xml @@ -110,8 +110,7 @@ 2.5.10 - - 3.4.1 + 5.3.1 3.3.0 3.3.1 @@ -141,8 +140,10 @@ UTF-8 3.1.1.RELEASE 5.3.3 + / 8080 0.53 + / 9090 2.27.2 1.2 @@ -327,6 +328,10 @@ org.springframework.boot spring-boot-starter-thymeleaf + + org.springframework.boot + spring-boot-starter-oauth2-client + org.thymeleaf.extras thymeleaf-extras-springsecurity6 @@ -511,7 +516,7 @@ ${basedir}/src/test/resources/logback-test.xml - -Xmx512m -Dwebgoatport=${webgoat.port} -Dwebwolfport=${webwolf.port} + -Xmx512m -Dwebgoatport=${webgoat.port} -Dwebwolfport=${webwolf.port} -Dwebwolfcontext=${webwolf.context} -Dwebgoatcontext=${webgoat.context} org/owasp/webgoat/*Test @@ -534,6 +539,7 @@ maven-surefire-plugin ${maven-surefire-plugin.version} + 600 --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED @@ -707,7 +713,9 @@ -Dwebgoat.user.directory=${java.io.tmpdir}/webgoat_${webgoat.port} -Dspring.main.banner-mode=off -Dwebgoat.port=${webgoat.port} + -Dwebgoat.context=${webgoat.context} -Dwebwolf.port=${webwolf.port} + -Dwebwolf.context=${webwolf.context} --add-opens java.base/java.lang=ALL-UNNAMED --add-opens @@ -733,6 +741,7 @@ ${project.build.directory}/webgoat-${project.version}.jar false + 120 http://localhost:${webgoat.port}/WebGoat/actuator/health diff --git a/robot/goat.robot b/robot/goat.robot index 972fdf421..c75b01c7b 100644 --- a/robot/goat.robot +++ b/robot/goat.robot @@ -11,7 +11,7 @@ ${BROWSER} chrome ${SLEEP} 100 ${DELAY} 0.25 ${ENDPOINT} http://127.0.0.1:8080/WebGoat -${ENDPOINT_WOLF} http://127.0.0.1:9090 +${ENDPOINT_WOLF} http://127.0.0.1:9090/WebWolf ${USERNAME} robotuser ${PASSWORD} password ${HEADLESS} ${FALSE} @@ -27,9 +27,9 @@ Initial_Page Open Browser ${ENDPOINT} ${BROWSER} options=add_experimental_option('prefs', {'intl.accept_languages': 'en,en_US'}) alias=webgoat END IF ${HEADLESS} - Open Browser ${ENDPOINT_WOLF}/WebWolf ${BROWSER} options=add_argument("-headless");add_argument("--start-maximized");add_experimental_option('prefs', {'intl.accept_languages': 'en,en_US'}) alias=webwolf + Open Browser ${ENDPOINT_WOLF} ${BROWSER} options=add_argument("-headless");add_argument("--start-maximized");add_experimental_option('prefs', {'intl.accept_languages': 'en,en_US'}) alias=webwolf ELSE - Open Browser ${ENDPOINT_WOLF}/WebWolf ${BROWSER} options=add_experimental_option('prefs', {'intl.accept_languages': 'en,en_US'}) alias=webwolf + Open Browser ${ENDPOINT_WOLF} ${BROWSER} options=add_experimental_option('prefs', {'intl.accept_languages': 'en,en_US'}) alias=webwolf END Switch Browser webgoat Maximize Browser Window @@ -93,9 +93,10 @@ Check_Menu_Page Check_WebWolf Switch Browser webwolf - location should be ${ENDPOINT_WOLF}/WebWolf - Go To ${ENDPOINT_WOLF}/mail + location should be ${ENDPOINT_WOLF}/login Input Text username ${USERNAME} Input Text password ${PASSWORD} Click Button Sign In + Go To ${ENDPOINT_WOLF}/mail + Go To ${ENDPOINT_WOLF}/requests diff --git a/src/it/java/org/owasp/webgoat/AccessControlIntegrationTest.java b/src/it/java/org/owasp/webgoat/AccessControlIntegrationTest.java index 761aa07f7..61582fd43 100644 --- a/src/it/java/org/owasp/webgoat/AccessControlIntegrationTest.java +++ b/src/it/java/org/owasp/webgoat/AccessControlIntegrationTest.java @@ -25,7 +25,7 @@ class AccessControlIntegrationTest extends IntegrationTest { .relaxedHTTPSValidation() .cookie("JSESSIONID", getWebGoatCookie()) .contentType(ContentType.JSON) - .get(url("/WebGoat/access-control/users-admin-fix")) + .get(url("access-control/users-admin-fix")) .then() .statusCode(HttpStatus.SC_FORBIDDEN); @@ -40,7 +40,7 @@ class AccessControlIntegrationTest extends IntegrationTest { .cookie("JSESSIONID", getWebGoatCookie()) .contentType(ContentType.JSON) .body(String.format(userTemplate, this.getUser(), this.getUser())) - .post(url("/WebGoat/access-control/users")) + .post(url("access-control/users")) .then() .statusCode(HttpStatus.SC_OK); @@ -51,15 +51,14 @@ class AccessControlIntegrationTest extends IntegrationTest { .relaxedHTTPSValidation() .cookie("JSESSIONID", getWebGoatCookie()) .contentType(ContentType.JSON) - .get(url("/WebGoat/access-control/users-admin-fix")) + .get(url("access-control/users-admin-fix")) .then() .statusCode(200) .extract() .jsonPath() .get("find { it.username == \"Jerry\" }.userHash"); - checkAssignment( - url("/WebGoat/access-control/user-hash-fix"), Map.of("userHash", userHash), true); + checkAssignment(url("access-control/user-hash-fix"), Map.of("userHash", userHash), true); } private void assignment2() { @@ -69,18 +68,18 @@ class AccessControlIntegrationTest extends IntegrationTest { .relaxedHTTPSValidation() .cookie("JSESSIONID", getWebGoatCookie()) .contentType(ContentType.JSON) - .get(url("/WebGoat/access-control/users")) + .get(url("access-control/users")) .then() .statusCode(200) .extract() .jsonPath() .get("find { it.username == \"Jerry\" }.userHash"); - checkAssignment(url("/WebGoat/access-control/user-hash"), Map.of("userHash", userHash), true); + checkAssignment(url("access-control/user-hash"), Map.of("userHash", userHash), true); } private void assignment1() { var params = Map.of("hiddenMenu1", "Users", "hiddenMenu2", "Config"); - checkAssignment(url("/WebGoat/access-control/hidden-menu"), params, true); + checkAssignment(url("access-control/hidden-menu"), params, true); } } diff --git a/src/it/java/org/owasp/webgoat/CSRFIntegrationTest.java b/src/it/java/org/owasp/webgoat/CSRFIntegrationTest.java index e590624f2..54d9dc5a3 100644 --- a/src/it/java/org/owasp/webgoat/CSRFIntegrationTest.java +++ b/src/it/java/org/owasp/webgoat/CSRFIntegrationTest.java @@ -64,12 +64,12 @@ public class CSRFIntegrationTest extends IntegrationTest { public void init() { startLesson("CSRF"); webwolfFileDir = getWebWolfFileServerLocation(); - uploadTrickHtml("csrf3.html", trickHTML3.replace("WEBGOATURL", url("/csrf/basic-get-flag"))); - uploadTrickHtml("csrf4.html", trickHTML4.replace("WEBGOATURL", url("/csrf/review"))); - uploadTrickHtml("csrf7.html", trickHTML7.replace("WEBGOATURL", url("/csrf/feedback/message"))); + uploadTrickHtml("csrf3.html", trickHTML3.replace("WEBGOATURL", url("csrf/basic-get-flag"))); + uploadTrickHtml("csrf4.html", trickHTML4.replace("WEBGOATURL", url("csrf/review"))); + uploadTrickHtml("csrf7.html", trickHTML7.replace("WEBGOATURL", url("csrf/feedback/message"))); uploadTrickHtml( "csrf8.html", - trickHTML8.replace("WEBGOATURL", url("/login")).replace("USERNAME", this.getUser())); + trickHTML8.replace("WEBGOATURL", url("login")).replace("USERNAME", this.getUser())); } @TestFactory @@ -103,7 +103,7 @@ public class CSRFIntegrationTest extends IntegrationTest { .relaxedHTTPSValidation() .cookie("WEBWOLFSESSION", getWebWolfCookie()) .multiPart("file", htmlName, htmlContent.getBytes()) - .post(webWolfUrl("/WebWolf/fileupload")) + .post(webWolfUrl("fileupload")) .then() .extract() .response() @@ -118,7 +118,7 @@ public class CSRFIntegrationTest extends IntegrationTest { .relaxedHTTPSValidation() .cookie("JSESSIONID", getWebGoatCookie()) .cookie("WEBWOLFSESSION", getWebWolfCookie()) - .get(webWolfUrl("/files/" + this.getUser() + "/" + htmlName)) + .get(webWolfUrl("files/" + this.getUser() + "/" + htmlName)) .then() .extract() .response() @@ -136,7 +136,7 @@ public class CSRFIntegrationTest extends IntegrationTest { .when() .relaxedHTTPSValidation() .cookie("JSESSIONID", getWebGoatCookie()) - .header("Referer", webWolfUrl("/files/fake.html")) + .header("Referer", webWolfUrl("files/fake.html")) .post(goatURL) .then() .extract() @@ -146,7 +146,7 @@ public class CSRFIntegrationTest extends IntegrationTest { Map params = new HashMap<>(); params.clear(); params.put("confirmFlagVal", flag); - checkAssignment(url("/WebGoat/csrf/confirm-flag-1"), params, true); + checkAssignment(url("csrf/confirm-flag-1"), params, true); } private void checkAssignment4(String goatURL) { @@ -163,7 +163,7 @@ public class CSRFIntegrationTest extends IntegrationTest { .when() .relaxedHTTPSValidation() .cookie("JSESSIONID", getWebGoatCookie()) - .header("Referer", webWolfUrl("/files/fake.html")) + .header("Referer", webWolfUrl("files/fake.html")) .formParams(params) .post(goatURL) .then() @@ -184,7 +184,7 @@ public class CSRFIntegrationTest extends IntegrationTest { .when() .relaxedHTTPSValidation() .cookie("JSESSIONID", getWebGoatCookie()) - .header("Referer", webWolfUrl("/files/fake.html")) + .header("Referer", webWolfUrl("files/fake.html")) .contentType(ContentType.TEXT) .body( "{\"name\":\"WebGoat\",\"email\":\"webgoat@webgoat.org\",\"content\":\"WebGoat is" @@ -198,7 +198,7 @@ public class CSRFIntegrationTest extends IntegrationTest { params.clear(); params.put("confirmFlagVal", flag); - checkAssignment(url("/WebGoat/csrf/feedback"), params, true); + checkAssignment(url("csrf/feedback"), params, true); } private void checkAssignment8(String goatURL) { @@ -217,7 +217,7 @@ public class CSRFIntegrationTest extends IntegrationTest { .when() .relaxedHTTPSValidation() .cookie("JSESSIONID", getWebGoatCookie()) - .header("Referer", webWolfUrl("/files/fake.html")) + .header("Referer", webWolfUrl("files/fake.html")) .params(params) .post(goatURL) .then() @@ -239,7 +239,7 @@ public class CSRFIntegrationTest extends IntegrationTest { .when() .relaxedHTTPSValidation() .cookie("JSESSIONID", newCookie) - .post(url("/csrf/login")) + .post(url("csrf/login")) .then() .statusCode(200) .extract() @@ -253,7 +253,7 @@ public class CSRFIntegrationTest extends IntegrationTest { Overview[] assignments = RestAssured.given() .cookie("JSESSIONID", getWebGoatCookie()) - .get(url("/service/lessonoverview.mvc")) + .get(url("service/lessonoverview.mvc")) .then() .extract() .jsonPath() diff --git a/src/it/java/org/owasp/webgoat/ChallengeIntegrationTest.java b/src/it/java/org/owasp/webgoat/ChallengeIntegrationTest.java index f7f4511f8..30e771432 100644 --- a/src/it/java/org/owasp/webgoat/ChallengeIntegrationTest.java +++ b/src/it/java/org/owasp/webgoat/ChallengeIntegrationTest.java @@ -22,7 +22,7 @@ public class ChallengeIntegrationTest extends IntegrationTest { .when() .relaxedHTTPSValidation() .cookie("JSESSIONID", getWebGoatCookie()) - .get(url("/WebGoat/challenge/logo")) + .get(url("challenge/logo")) .then() .statusCode(200) .extract() @@ -34,14 +34,14 @@ public class ChallengeIntegrationTest extends IntegrationTest { params.put("username", "admin"); params.put("password", "!!webgoat_admin_1234!!".replace("1234", pincode)); - checkAssignment(url("/WebGoat/challenge/1"), params, true); + checkAssignment(url("challenge/1"), params, true); String result = RestAssured.given() .when() .relaxedHTTPSValidation() .cookie("JSESSIONID", getWebGoatCookie()) .formParams(params) - .post(url("/WebGoat/challenge/1")) + .post(url("challenge/1")) .then() .statusCode(200) .extract() @@ -50,7 +50,7 @@ public class ChallengeIntegrationTest extends IntegrationTest { String flag = result.substring(result.indexOf("flag") + 6, result.indexOf("flag") + 42); params.clear(); params.put("flag", flag); - checkAssignment(url("/WebGoat/challenge/flag"), params, true); + checkAssignment(url("challenge/flag"), params, true); checkResults("/challenge/1"); @@ -59,7 +59,7 @@ public class ChallengeIntegrationTest extends IntegrationTest { .when() .relaxedHTTPSValidation() .cookie("JSESSIONID", getWebGoatCookie()) - .get(url("/WebGoat/scoreboard-data")) + .get(url("scoreboard-data")) .then() .statusCode(200) .extract() @@ -83,7 +83,7 @@ public class ChallengeIntegrationTest extends IntegrationTest { .relaxedHTTPSValidation() .cookie("JSESSIONID", getWebGoatCookie()) .formParams(params) - .post(url("/WebGoat/challenge/5")) + .post(url("challenge/5")) .then() .statusCode(200) .extract() @@ -92,7 +92,7 @@ public class ChallengeIntegrationTest extends IntegrationTest { String flag = result.substring(result.indexOf("flag") + 6, result.indexOf("flag") + 42); params.clear(); params.put("flag", flag); - checkAssignment(url("/WebGoat/challenge/flag"), params, true); + checkAssignment(url("challenge/flag"), params, true); checkResults("/challenge/5"); @@ -101,7 +101,7 @@ public class ChallengeIntegrationTest extends IntegrationTest { .when() .relaxedHTTPSValidation() .cookie("JSESSIONID", getWebGoatCookie()) - .get(url("/WebGoat/scoreboard-data")) + .get(url("scoreboard-data")) .then() .statusCode(200) .extract() @@ -120,7 +120,7 @@ public class ChallengeIntegrationTest extends IntegrationTest { .when() .relaxedHTTPSValidation() .cookie("JSESSIONID", getWebGoatCookie()) - .get(url("/WebGoat/challenge/7/.git")) + .get(url("challenge/7/.git")) .then() .statusCode(200) .extract() @@ -132,7 +132,7 @@ public class ChallengeIntegrationTest extends IntegrationTest { .relaxedHTTPSValidation() .cookie("JSESSIONID", getWebGoatCookie()) .formParams("email", getUser() + "@webgoat.org") - .post(url("/WebGoat/challenge/7")) + .post(url("challenge/7")) .then() .statusCode(200) .extract() @@ -144,7 +144,7 @@ public class ChallengeIntegrationTest extends IntegrationTest { .when() .relaxedHTTPSValidation() .cookie("WEBWOLFSESSION", getWebWolfCookie()) - .get(webWolfUrl("/mail")) + .get(webWolfUrl("mail")) .then() .extract() .response() @@ -158,13 +158,13 @@ public class ChallengeIntegrationTest extends IntegrationTest { .when() .relaxedHTTPSValidation() .cookie("JSESSIONID", getWebGoatCookie()) - .get(url("/challenge/7/reset-password/{link}"), "375afe1104f4a487a73823c50a9292a2") + .get(url("challenge/7/reset-password/{link}"), "375afe1104f4a487a73823c50a9292a2") .then() .statusCode(HttpStatus.ACCEPTED.value()) .extract() .asString(); String flag = result.substring(result.indexOf("flag") + 6, result.indexOf("flag") + 42); - checkAssignment(url("/WebGoat/challenge/flag"), Map.of("flag", flag), true); + checkAssignment(url("challenge/flag"), Map.of("flag", flag), true); } } diff --git a/src/it/java/org/owasp/webgoat/CryptoIntegrationTest.java b/src/it/java/org/owasp/webgoat/CryptoIntegrationTest.java index ad9d6f625..efb9c35b1 100644 --- a/src/it/java/org/owasp/webgoat/CryptoIntegrationTest.java +++ b/src/it/java/org/owasp/webgoat/CryptoIntegrationTest.java @@ -52,7 +52,7 @@ public class CryptoIntegrationTest extends IntegrationTest { .when() .relaxedHTTPSValidation() .cookie("JSESSIONID", getWebGoatCookie()) - .get(url("/crypto/encoding/basic")) + .get(url("crypto/encoding/basic")) .then() .extract() .asString(); @@ -64,7 +64,7 @@ public class CryptoIntegrationTest extends IntegrationTest { params.clear(); params.put("answer_user", answer_user); params.put("answer_pwd", answer_pwd); - checkAssignment(url("/crypto/encoding/basic-auth"), params, true); + checkAssignment(url("crypto/encoding/basic-auth"), params, true); } private void checkAssignment3() { @@ -72,7 +72,7 @@ public class CryptoIntegrationTest extends IntegrationTest { Map params = new HashMap<>(); params.clear(); params.put("answer_pwd1", answer_1); - checkAssignment(url("/crypto/encoding/xor"), params, true); + checkAssignment(url("crypto/encoding/xor"), params, true); } private void checkAssignment4() throws NoSuchAlgorithmException { @@ -82,7 +82,7 @@ public class CryptoIntegrationTest extends IntegrationTest { .when() .relaxedHTTPSValidation() .cookie("JSESSIONID", getWebGoatCookie()) - .get(url("/crypto/hashing/md5")) + .get(url("crypto/hashing/md5")) .then() .extract() .asString(); @@ -92,7 +92,7 @@ public class CryptoIntegrationTest extends IntegrationTest { .when() .relaxedHTTPSValidation() .cookie("JSESSIONID", getWebGoatCookie()) - .get(url("/crypto/hashing/sha256")) + .get(url("crypto/hashing/sha256")) .then() .extract() .asString(); @@ -112,7 +112,7 @@ public class CryptoIntegrationTest extends IntegrationTest { params.clear(); params.put("answer_pwd1", answer_1); params.put("answer_pwd2", answer_2); - checkAssignment(url("/WebGoat/crypto/hashing"), params, true); + checkAssignment(url("crypto/hashing"), params, true); } private void checkAssignmentSigning() throws NoSuchAlgorithmException, InvalidKeySpecException { @@ -122,7 +122,7 @@ public class CryptoIntegrationTest extends IntegrationTest { .when() .relaxedHTTPSValidation() .cookie("JSESSIONID", getWebGoatCookie()) - .get(url("/crypto/signing/getprivate")) + .get(url("crypto/signing/getprivate")) .then() .extract() .asString(); @@ -135,7 +135,7 @@ public class CryptoIntegrationTest extends IntegrationTest { params.clear(); params.put("modulus", modulus); params.put("signature", signature); - checkAssignment(url("/crypto/signing/verify"), params, true); + checkAssignment(url("crypto/signing/verify"), params, true); } private void checkAssignmentDefaults() { @@ -151,6 +151,6 @@ public class CryptoIntegrationTest extends IntegrationTest { params.clear(); params.put("secretText", text); params.put("secretFileName", "default_secret"); - checkAssignment(url("/crypto/secure/defaults"), params, true); + checkAssignment(url("crypto/secure/defaults"), params, true); } } diff --git a/src/it/java/org/owasp/webgoat/DeserializationIntegrationTest.java b/src/it/java/org/owasp/webgoat/DeserializationIntegrationTest.java index 29572be45..c3c26f359 100644 --- a/src/it/java/org/owasp/webgoat/DeserializationIntegrationTest.java +++ b/src/it/java/org/owasp/webgoat/DeserializationIntegrationTest.java @@ -26,7 +26,7 @@ public class DeserializationIntegrationTest extends IntegrationTest { params.put( "token", SerializationHelper.toString(new VulnerableTaskHolder("wait", "sleep 5"))); } - checkAssignment(url("/WebGoat/InsecureDeserialization/task"), params, true); + checkAssignment(url("InsecureDeserialization/task"), params, true); checkResults("/InsecureDeserialization/"); } diff --git a/src/it/java/org/owasp/webgoat/GeneralLessonIntegrationTest.java b/src/it/java/org/owasp/webgoat/GeneralLessonIntegrationTest.java index 274ce639c..0ee905d15 100644 --- a/src/it/java/org/owasp/webgoat/GeneralLessonIntegrationTest.java +++ b/src/it/java/org/owasp/webgoat/GeneralLessonIntegrationTest.java @@ -72,7 +72,7 @@ public class GeneralLessonIntegrationTest extends IntegrationTest { 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); + checkAssignment(url("cia/quiz"), params, true); checkResults("/cia/"); } @@ -95,7 +95,7 @@ public class GeneralLessonIntegrationTest extends IntegrationTest { Map params = new HashMap<>(); params.clear(); params.put("payload", solution); - checkAssignment(url("/WebGoat/VulnerableComponents/attack1"), params, true); + checkAssignment(url("VulnerableComponents/attack1"), params, true); checkResults("/VulnerableComponents/"); } } @@ -107,7 +107,7 @@ public class GeneralLessonIntegrationTest extends IntegrationTest { params.clear(); params.put("username", "CaptainJack"); params.put("password", "BlackPearl"); - checkAssignment(url("/WebGoat/InsecureLogin/task"), params, true); + checkAssignment(url("InsecureLogin/task"), params, true); checkResults("/InsecureLogin/"); } @@ -117,7 +117,7 @@ public class GeneralLessonIntegrationTest extends IntegrationTest { Map params = new HashMap<>(); params.clear(); params.put("password", "ajnaeliclm^&&@kjn."); - checkAssignment(url("/WebGoat/SecurePasswords/assignment"), params, true); + checkAssignment(url("SecurePasswords/assignment"), params, true); checkResults("SecurePasswords/"); startLesson("AuthBypass"); @@ -127,7 +127,7 @@ public class GeneralLessonIntegrationTest extends IntegrationTest { params.put("jsEnabled", "1"); params.put("verifyMethod", "SEC_QUESTIONS"); params.put("userId", "12309746"); - checkAssignment(url("/WebGoat/auth-bypass/verify-account"), params, true); + checkAssignment(url("auth-bypass/verify-account"), params, true); checkResults("/auth-bypass/"); startLesson("HttpProxies"); @@ -138,8 +138,7 @@ public class GeneralLessonIntegrationTest extends IntegrationTest { .cookie("JSESSIONID", getWebGoatCookie()) .header("x-request-intercepted", "true") .contentType(ContentType.JSON) - .get( - url("/WebGoat/HttpProxies/intercept-request?changeMe=Requests are tampered easily")) + .get(url("HttpProxies/intercept-request?changeMe=Requests are tampered easily")) .then() .statusCode(200) .extract() @@ -165,7 +164,7 @@ public class GeneralLessonIntegrationTest extends IntegrationTest { .header("webgoat-requested-by", "dom-xss-vuln") .header("X-Requested-With", "XMLHttpRequest") .formParams(params) - .post(url("/WebGoat/CrossSiteScripting/phone-home-xss")) + .post(url("CrossSiteScripting/phone-home-xss")) .then() .statusCode(200) .extract() @@ -174,12 +173,12 @@ public class GeneralLessonIntegrationTest extends IntegrationTest { params.clear(); params.put("successMessage", secretNumber); - checkAssignment(url("/WebGoat/ChromeDevTools/dummy"), params, true); + checkAssignment(url("ChromeDevTools/dummy"), params, true); params.clear(); params.put("number", "24"); params.put("network_num", "24"); - checkAssignment(url("/WebGoat/ChromeDevTools/network"), params, true); + checkAssignment(url("ChromeDevTools/network"), params, true); checkResults("/ChromeDevTools/"); } @@ -194,7 +193,7 @@ public class GeneralLessonIntegrationTest extends IntegrationTest { params.put("jsEnabled", "1"); params.put("verifyMethod", "SEC_QUESTIONS"); params.put("userId", "12309746"); - checkAssignment(url("/auth-bypass/verify-account"), params, true); + checkAssignment(url("auth-bypass/verify-account"), params, true); checkResults("/auth-bypass/"); } @@ -205,7 +204,7 @@ public class GeneralLessonIntegrationTest extends IntegrationTest { params.clear(); params.put("param1", "secr37Value"); params.put("param2", "Main"); - checkAssignment(url("/lesson-template/sample-attack"), params, true); + checkAssignment(url("lesson-template/sample-attack"), params, true); checkResults("/lesson-template/"); } } diff --git a/src/it/java/org/owasp/webgoat/IDORIntegrationTest.java b/src/it/java/org/owasp/webgoat/IDORIntegrationTest.java index dca27650b..eba30f764 100644 --- a/src/it/java/org/owasp/webgoat/IDORIntegrationTest.java +++ b/src/it/java/org/owasp/webgoat/IDORIntegrationTest.java @@ -4,11 +4,9 @@ import static org.junit.jupiter.api.DynamicTest.dynamicTest; import io.restassured.RestAssured; import io.restassured.http.ContentType; -import java.io.IOException; import java.util.Arrays; import java.util.HashMap; import java.util.Map; -import lombok.SneakyThrows; import org.hamcrest.CoreMatchers; import org.hamcrest.MatcherAssert; import org.junit.jupiter.api.AfterEach; @@ -19,7 +17,6 @@ import org.junit.jupiter.api.TestFactory; public class IDORIntegrationTest extends IntegrationTest { @BeforeEach - @SneakyThrows public void init() { startLesson("IDOR"); } @@ -27,56 +24,63 @@ public class IDORIntegrationTest extends IntegrationTest { @TestFactory Iterable testIDORLesson() { return Arrays.asList( - dynamicTest("login", () -> loginIDOR()), dynamicTest("profile", () -> profile())); + dynamicTest("assignment 2 - login", this::loginIDOR), + dynamicTest("profile", this::profile)); } @AfterEach - public void shutdown() throws IOException { + public void shutdown() { checkResults("/IDOR"); } - private void loginIDOR() throws IOException { + private void loginIDOR() { Map params = new HashMap<>(); - params.clear(); params.put("username", "tom"); params.put("password", "cat"); - checkAssignment(url("/WebGoat/IDOR/login"), params, true); + checkAssignment(url("IDOR/login"), params, true); } private void profile() { + + // View profile - assignment 3a MatcherAssert.assertThat( RestAssured.given() .when() .relaxedHTTPSValidation() .cookie("JSESSIONID", getWebGoatCookie()) - .get(url("/WebGoat/IDOR/profile")) + .get(url("IDOR/profile")) .then() .statusCode(200) .extract() .path("userId"), CoreMatchers.is("2342384")); + + // Show difference - assignment 3b Map params = new HashMap<>(); - params.clear(); params.put("attributes", "userId,role"); - checkAssignment(url("/WebGoat/IDOR/diff-attributes"), params, true); + checkAssignment(url("IDOR/diff-attributes"), params, true); + + // View profile another way - assignment 4 params.clear(); params.put("url", "WebGoat/IDOR/profile/2342384"); - checkAssignment(url("/WebGoat/IDOR/profile/alt-path"), params, true); + checkAssignment(url("IDOR/profile/alt-path"), params, true); + // assignment 5a MatcherAssert.assertThat( RestAssured.given() .when() .relaxedHTTPSValidation() .cookie("JSESSIONID", getWebGoatCookie()) - .get(url("/WebGoat/IDOR/profile/2342388")) + .get(url("IDOR/profile/2342388")) .then() .statusCode(200) .extract() .path("lessonCompleted"), CoreMatchers.is(true)); + // assignment 5b MatcherAssert.assertThat( RestAssured.given() .when() @@ -86,7 +90,7 @@ public class IDORIntegrationTest extends IntegrationTest { .body( "{\"role\":\"1\", \"color\":\"red\", \"size\":\"large\", \"name\":\"Buffalo Bill\"," + " \"userId\":\"2342388\"}") - .put(url("/WebGoat/IDOR/profile/2342388")) + .put(url("IDOR/profile/2342388")) .then() .statusCode(200) .extract() diff --git a/src/it/java/org/owasp/webgoat/IntegrationTest.java b/src/it/java/org/owasp/webgoat/IntegrationTest.java index 799d0a946..2694b56a7 100644 --- a/src/it/java/org/owasp/webgoat/IntegrationTest.java +++ b/src/it/java/org/owasp/webgoat/IntegrationTest.java @@ -15,36 +15,37 @@ import org.springframework.http.HttpStatus; public abstract class IntegrationTest { - private static String webGoatPort = Objects.requireNonNull(System.getProperty("webgoatport")); + private static String webGoatPort = + Objects.requireNonNull(System.getProperty("webgoatport", "8080")); + private static String webGoatContext = + Objects.requireNonNull(System.getProperty("webgoatcontext", "/WebGoat/")); @Getter - private static String webWolfPort = Objects.requireNonNull(System.getProperty("webwolfport")); + private static String webWolfPort = + Objects.requireNonNull(System.getProperty("webwolfport", "9090")); + + private static String webWolfContext = + Objects.requireNonNull(System.getProperty("webwolfcontext", "/WebWolf/")); private static boolean useSSL = false; private static String webgoatUrl = - (useSSL ? "https:" : "http:") + "//localhost:" + webGoatPort + "/WebGoat/"; + (useSSL ? "https:" : "http:") + "//localhost:" + webGoatPort + webGoatContext; private static String webWolfUrl = - (useSSL ? "https:" : "http:") + "//localhost:" + webWolfPort + "/"; + (useSSL ? "https:" : "http:") + "//localhost:" + webWolfPort + webWolfContext; @Getter private String webGoatCookie; @Getter private String webWolfCookie; @Getter private final String user = "webgoat"; protected String url(String url) { - url = url.replaceFirst("/WebGoat/", ""); - url = url.replaceFirst("/WebGoat", ""); - url = url.startsWith("/") ? url.replaceFirst("/", "") : url; return webgoatUrl + url; } protected String webWolfUrl(String url) { - url = url.replaceFirst("/WebWolf/", ""); - url = url.replaceFirst("/WebWolf", ""); - url = url.startsWith("/") ? url.replaceFirst("/", "") : url; return webWolfUrl + url; } protected String webWolfFileUrl(String fileName) { - return webWolfUrl("/files") + "/" + getUser() + "/" + fileName; + return webWolfUrl("files") + "/" + getUser() + "/" + fileName; } @BeforeEach @@ -235,7 +236,7 @@ public abstract class IntegrationTest { .when() .relaxedHTTPSValidation() .cookie("WEBWOLFSESSION", getWebWolfCookie()) - .get(webWolfUrl("/file-server-location")) + .get(webWolfUrl("file-server-location")) .then() .extract() .response() @@ -250,7 +251,7 @@ public abstract class IntegrationTest { .when() .relaxedHTTPSValidation() .cookie("JSESSIONID", getWebGoatCookie()) - .get(url("/server-directory")) + .get(url("server-directory")) .then() .extract() .response() @@ -263,7 +264,7 @@ public abstract class IntegrationTest { .when() .relaxedHTTPSValidation() .cookie("WEBWOLFSESSION", getWebWolfCookie()) - .delete(webWolfUrl("/mail")) + .delete(webWolfUrl("mail")) .then() .statusCode(HttpStatus.ACCEPTED.value()); } diff --git a/src/it/java/org/owasp/webgoat/JWTLessonIntegrationTest.java b/src/it/java/org/owasp/webgoat/JWTLessonIntegrationTest.java index f6d2e9e14..c970a1537 100644 --- a/src/it/java/org/owasp/webgoat/JWTLessonIntegrationTest.java +++ b/src/it/java/org/owasp/webgoat/JWTLessonIntegrationTest.java @@ -88,7 +88,7 @@ public class JWTLessonIntegrationTest extends IntegrationTest { .relaxedHTTPSValidation() .cookie("JSESSIONID", getWebGoatCookie()) .formParam("jwt-encode-user", "user") - .post(url("/WebGoat/JWT/decode")) + .post(url("JWT/decode")) .then() .statusCode(200) .extract() @@ -103,7 +103,7 @@ public class JWTLessonIntegrationTest extends IntegrationTest { .when() .relaxedHTTPSValidation() .cookie("JSESSIONID", getWebGoatCookie()) - .get(url("/WebGoat/JWT/secret/gettoken")) + .get(url("JWT/secret/gettoken")) .then() .extract() .response() @@ -117,7 +117,7 @@ public class JWTLessonIntegrationTest extends IntegrationTest { .relaxedHTTPSValidation() .cookie("JSESSIONID", getWebGoatCookie()) .formParam("token", generateToken(secret)) - .post(url("/WebGoat/JWT/secret")) + .post(url("JWT/secret")) .then() .statusCode(200) .extract() @@ -131,7 +131,7 @@ public class JWTLessonIntegrationTest extends IntegrationTest { .when() .relaxedHTTPSValidation() .cookie("JSESSIONID", getWebGoatCookie()) - .get(url("/WebGoat/JWT/votings/login?user=Tom")) + .get(url("JWT/votings/login?user=Tom")) .then() .extract() .cookie("access_token"); @@ -164,7 +164,7 @@ public class JWTLessonIntegrationTest extends IntegrationTest { .relaxedHTTPSValidation() .cookie("JSESSIONID", getWebGoatCookie()) .cookie("access_token", replacedToken) - .post(url("/WebGoat/JWT/votings")) + .post(url("JWT/votings")) .then() .statusCode(200) .extract() @@ -205,7 +205,7 @@ public class JWTLessonIntegrationTest extends IntegrationTest { .relaxedHTTPSValidation() .cookie("JSESSIONID", getWebGoatCookie()) .header("Authorization", "Bearer " + replacedToken) - .post(url("/WebGoat/JWT/refresh/checkout")) + .post(url("JWT/refresh/checkout")) .then() .statusCode(200) .extract() @@ -238,7 +238,7 @@ public class JWTLessonIntegrationTest extends IntegrationTest { .when() .relaxedHTTPSValidation() .cookie("JSESSIONID", getWebGoatCookie()) - .post(url("/WebGoat/JWT/kid/delete?token=" + token)) + .post(url("JWT/kid/delete?token=" + token)) .then() .statusCode(200) .extract() @@ -256,7 +256,7 @@ public class JWTLessonIntegrationTest extends IntegrationTest { .relaxedHTTPSValidation() .cookie("WEBWOLFSESSION", getWebWolfCookie()) .multiPart("file", "jwks.json", jwks.toJson().getBytes()) - .post(webWolfUrl("/fileupload")) + .post(webWolfUrl("fileupload")) .then() .extract() .response() @@ -285,7 +285,7 @@ public class JWTLessonIntegrationTest extends IntegrationTest { .when() .relaxedHTTPSValidation() .cookie("JSESSIONID", getWebGoatCookie()) - .post(url("/WebGoat/JWT/jku/delete?token=" + token)) + .post(url("JWT/jku/delete?token=" + token)) .then() .statusCode(200) .extract() @@ -298,6 +298,6 @@ public class JWTLessonIntegrationTest extends IntegrationTest { params.put("question_0_solution", "Solution 1"); params.put("question_1_solution", "Solution 2"); - checkAssignment(url("/WebGoat/JWT/quiz"), params, true); + checkAssignment(url("JWT/quiz"), params, true); } } diff --git a/src/it/java/org/owasp/webgoat/PasswordResetLessonIntegrationTest.java b/src/it/java/org/owasp/webgoat/PasswordResetLessonIntegrationTest.java index c53be61f8..8c7018c59 100644 --- a/src/it/java/org/owasp/webgoat/PasswordResetLessonIntegrationTest.java +++ b/src/it/java/org/owasp/webgoat/PasswordResetLessonIntegrationTest.java @@ -11,12 +11,13 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DynamicTest; import org.junit.jupiter.api.TestFactory; +import org.springframework.http.HttpHeaders; public class PasswordResetLessonIntegrationTest extends IntegrationTest { @BeforeEach public void init() { - startLesson("/PasswordReset"); + startLesson("PasswordReset"); } @TestFactory @@ -85,7 +86,7 @@ public class PasswordResetLessonIntegrationTest extends IntegrationTest { .when() .relaxedHTTPSValidation() .cookie("WEBWOLFSESSION", getWebWolfCookie()) - .get(webWolfUrl("/WebWolf/mail")) + .get(webWolfUrl("mail")) .then() .extract() .response() @@ -119,7 +120,7 @@ public class PasswordResetLessonIntegrationTest extends IntegrationTest { .when() .relaxedHTTPSValidation() .cookie("WEBWOLFSESSION", getWebWolfCookie()) - .get(webWolfUrl("/WebWolf/requests")) + .get(webWolfUrl("requests")) .then() .extract() .response() @@ -136,7 +137,7 @@ public class PasswordResetLessonIntegrationTest extends IntegrationTest { private void clickForgotEmailLink(String user) { RestAssured.given() .when() - .header("host", String.format("%s:%s", "localhost", getWebWolfPort())) + .header(HttpHeaders.HOST, String.format("%s:%s", "127.0.0.1", getWebWolfPort())) .relaxedHTTPSValidation() .cookie("JSESSIONID", getWebGoatCookie()) .formParams("email", user) diff --git a/src/it/java/org/owasp/webgoat/PathTraversalIntegrationTest.java b/src/it/java/org/owasp/webgoat/PathTraversalIntegrationTest.java index cc00818f8..22a91100f 100644 --- a/src/it/java/org/owasp/webgoat/PathTraversalIntegrationTest.java +++ b/src/it/java/org/owasp/webgoat/PathTraversalIntegrationTest.java @@ -55,7 +55,7 @@ class PathTraversalIT extends IntegrationTest { .cookie("JSESSIONID", getWebGoatCookie()) .multiPart("uploadedFile", "test.jpg", Files.readAllBytes(fileToUpload.toPath())) .param("fullName", "../John Doe") - .post(url("/WebGoat/PathTraversal/profile-upload")) + .post(url("PathTraversal/profile-upload")) .then() .statusCode(200) .extract() @@ -71,7 +71,7 @@ class PathTraversalIT extends IntegrationTest { .cookie("JSESSIONID", getWebGoatCookie()) .multiPart("uploadedFileFix", "test.jpg", Files.readAllBytes(fileToUpload.toPath())) .param("fullNameFix", "..././John Doe") - .post(url("/WebGoat/PathTraversal/profile-upload-fix")) + .post(url("PathTraversal/profile-upload-fix")) .then() .statusCode(200) .extract() @@ -89,7 +89,7 @@ class PathTraversalIT extends IntegrationTest { "uploadedFileRemoveUserInput", "../test.jpg", Files.readAllBytes(fileToUpload.toPath())) - .post(url("/WebGoat/PathTraversal/profile-upload-remove-user-input")) + .post(url("PathTraversal/profile-upload-remove-user-input")) .then() .statusCode(200) .extract() @@ -98,7 +98,7 @@ class PathTraversalIT extends IntegrationTest { } private void assignment4() throws IOException { - var uri = "/WebGoat/PathTraversal/random-picture?id=%2E%2E%2F%2E%2E%2Fpath-traversal-secret"; + var uri = "PathTraversal/random-picture?id=%2E%2E%2F%2E%2E%2Fpath-traversal-secret"; RestAssured.given() .urlEncodingEnabled(false) .when() @@ -110,7 +110,7 @@ class PathTraversalIT extends IntegrationTest { .body(CoreMatchers.is("You found it submit the SHA-512 hash of your username as answer")); checkAssignment( - url("/WebGoat/PathTraversal/random"), + url("PathTraversal/random"), Map.of("secret", Sha512DigestUtils.shaHex(this.getUser())), true); } @@ -133,8 +133,10 @@ class PathTraversalIT extends IntegrationTest { .relaxedHTTPSValidation() .cookie("JSESSIONID", getWebGoatCookie()) .multiPart("uploadedFileZipSlip", "upload.zip", Files.readAllBytes(zipFile.toPath())) - .post(url("/WebGoat/PathTraversal/zip-slip")) + .post(url("PathTraversal/zip-slip")) .then() + .log() + .all() .statusCode(200) .extract() .path("lessonCompleted"), diff --git a/src/it/java/org/owasp/webgoat/ProgressRaceConditionIntegrationTest.java b/src/it/java/org/owasp/webgoat/ProgressRaceConditionIntegrationTest.java index 1228f913c..969ff6d2e 100644 --- a/src/it/java/org/owasp/webgoat/ProgressRaceConditionIntegrationTest.java +++ b/src/it/java/org/owasp/webgoat/ProgressRaceConditionIntegrationTest.java @@ -29,7 +29,7 @@ public class ProgressRaceConditionIntegrationTest extends IntegrationTest { .relaxedHTTPSValidation() .cookie("JSESSIONID", getWebGoatCookie()) .formParams(Map.of("flag", "test")) - .post(url("/challenge/flag")); + .post(url("challenge/flag")); }; ExecutorService executorService = Executors.newFixedThreadPool(NUMBER_OF_PARALLEL_THREADS); List> flagCalls = diff --git a/src/it/java/org/owasp/webgoat/SSRFIntegrationTest.java b/src/it/java/org/owasp/webgoat/SSRFIntegrationTest.java index 0bdd74e1f..e0b42a0aa 100644 --- a/src/it/java/org/owasp/webgoat/SSRFIntegrationTest.java +++ b/src/it/java/org/owasp/webgoat/SSRFIntegrationTest.java @@ -15,11 +15,11 @@ public class SSRFIntegrationTest extends IntegrationTest { params.clear(); params.put("url", "images/jerry.png"); - checkAssignment(url("/WebGoat/SSRF/task1"), params, true); + checkAssignment(url("SSRF/task1"), params, true); params.clear(); params.put("url", "http://ifconfig.pro"); - checkAssignment(url("/WebGoat/SSRF/task2"), params, true); + checkAssignment(url("SSRF/task2"), params, true); checkResults("/SSRF/"); } diff --git a/src/it/java/org/owasp/webgoat/SessionManagementIntegrationTest.java b/src/it/java/org/owasp/webgoat/SessionManagementIntegrationTest.java index 127490106..ba30a1324 100644 --- a/src/it/java/org/owasp/webgoat/SessionManagementIntegrationTest.java +++ b/src/it/java/org/owasp/webgoat/SessionManagementIntegrationTest.java @@ -31,7 +31,7 @@ import org.junit.jupiter.api.Test; */ class SessionManagementIT extends IntegrationTest { - private static final String HIJACK_LOGIN_CONTEXT_PATH = "/WebGoat/HijackSession/login"; + private static final String HIJACK_LOGIN_CONTEXT_PATH = "HijackSession/login"; @Test void hijackSessionTest() { diff --git a/src/it/java/org/owasp/webgoat/SqlInjectionAdvancedIntegrationTest.java b/src/it/java/org/owasp/webgoat/SqlInjectionAdvancedIntegrationTest.java index 64caf659d..feec674c0 100644 --- a/src/it/java/org/owasp/webgoat/SqlInjectionAdvancedIntegrationTest.java +++ b/src/it/java/org/owasp/webgoat/SqlInjectionAdvancedIntegrationTest.java @@ -16,27 +16,27 @@ public class SqlInjectionAdvancedIntegrationTest extends IntegrationTest { params.put("password_reg", "password"); params.put("email_reg", "someone@microsoft.com"); params.put("confirm_password", "password"); - checkAssignmentWithPUT(url("/WebGoat/SqlInjectionAdvanced/challenge"), params, true); + checkAssignmentWithPUT(url("SqlInjectionAdvanced/challenge"), params, true); params.clear(); params.put("username_login", "tom"); params.put("password_login", "thisisasecretfortomonly"); - checkAssignment(url("/WebGoat/SqlInjectionAdvanced/challenge_Login"), params, true); + checkAssignment(url("SqlInjectionAdvanced/challenge_Login"), params, true); params.clear(); params.put("userid_6a", "'; SELECT * FROM user_system_data;--"); - checkAssignment(url("/WebGoat/SqlInjectionAdvanced/attack6a"), params, true); + checkAssignment(url("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); + checkAssignment(url("SqlInjectionAdvanced/attack6a"), params, true); params.clear(); params.put("userid_6b", "passW0rD"); - checkAssignment(url("/WebGoat/SqlInjectionAdvanced/attack6b"), params, true); + checkAssignment(url("SqlInjectionAdvanced/attack6b"), params, true); params.clear(); params.put( @@ -54,7 +54,7 @@ public class SqlInjectionAdvancedIntegrationTest extends IntegrationTest { params.put( "question_4_solution", "Solution 4: The database registers 'Robert' ); DROP TABLE Students;--'."); - checkAssignment(url("/WebGoat/SqlInjectionAdvanced/quiz"), params, true); + checkAssignment(url("SqlInjectionAdvanced/quiz"), params, true); checkResults("/SqlInjectionAdvanced/"); } diff --git a/src/it/java/org/owasp/webgoat/SqlInjectionLessonIntegrationTest.java b/src/it/java/org/owasp/webgoat/SqlInjectionLessonIntegrationTest.java index c18fb8b0e..ac2f8e2fd 100644 --- a/src/it/java/org/owasp/webgoat/SqlInjectionLessonIntegrationTest.java +++ b/src/it/java/org/owasp/webgoat/SqlInjectionLessonIntegrationTest.java @@ -34,44 +34,44 @@ public class SqlInjectionLessonIntegrationTest extends IntegrationTest { Map params = new HashMap<>(); params.clear(); params.put("query", sql_2); - checkAssignment(url("/WebGoat/SqlInjection/attack2"), params, true); + checkAssignment(url("SqlInjection/attack2"), params, true); params.clear(); params.put("query", sql_3); - checkAssignment(url("/WebGoat/SqlInjection/attack3"), params, true); + checkAssignment(url("SqlInjection/attack3"), params, true); params.clear(); params.put("query", sql_4_add); - checkAssignment(url("/WebGoat/SqlInjection/attack4"), params, true); + checkAssignment(url("SqlInjection/attack4"), params, true); params.clear(); params.put("query", sql_5); - checkAssignment(url("/WebGoat/SqlInjection/attack5"), params, true); + checkAssignment(url("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); + checkAssignment(url("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); + checkAssignment(url("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); + checkAssignment(url("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); + checkAssignment(url("SqlInjection/attack9"), params, true); params.clear(); params.put("action_string", sql_13); - checkAssignment(url("/WebGoat/SqlInjection/attack10"), params, true); + checkAssignment(url("SqlInjection/attack10"), params, true); checkResults("/SqlInjection/"); } diff --git a/src/it/java/org/owasp/webgoat/SqlInjectionMitigationIntegrationTest.java b/src/it/java/org/owasp/webgoat/SqlInjectionMitigationIntegrationTest.java index b09bbc4d4..1a1dc39c7 100644 --- a/src/it/java/org/owasp/webgoat/SqlInjectionMitigationIntegrationTest.java +++ b/src/it/java/org/owasp/webgoat/SqlInjectionMitigationIntegrationTest.java @@ -23,7 +23,7 @@ public class SqlInjectionMitigationIntegrationTest extends IntegrationTest { params.put("field5", "?"); params.put("field6", "prep.setString(1,\"\")"); params.put("field7", "prep.setString(2,\\\"\\\")"); - checkAssignment(url("/WebGoat/SqlInjectionMitigations/attack10a"), params, true); + checkAssignment(url("SqlInjectionMitigations/attack10a"), params, true); params.put( "editor", @@ -37,18 +37,18 @@ public class SqlInjectionMitigationIntegrationTest extends IntegrationTest { + "} catch (Exception e) {\r\n" + " System.out.println(\"Oops. Something went wrong!\");\r\n" + "}"); - checkAssignment(url("/WebGoat/SqlInjectionMitigations/attack10b"), params, true); + checkAssignment(url("SqlInjectionMitigations/attack10b"), params, true); params.clear(); params.put( "userid_sql_only_input_validation", "Smith';SELECT/**/*/**/from/**/user_system_data;--"); - checkAssignment(url("/WebGoat/SqlOnlyInputValidation/attack"), params, true); + checkAssignment(url("SqlOnlyInputValidation/attack"), params, true); params.clear(); params.put( "userid_sql_only_input_validation_on_keywords", "Smith';SESELECTLECT/**/*/**/FRFROMOM/**/user_system_data;--"); - checkAssignment(url("/WebGoat/SqlOnlyInputValidationOnKeywords/attack"), params, true); + checkAssignment(url("SqlOnlyInputValidationOnKeywords/attack"), params, true); RestAssured.given() .when() @@ -57,7 +57,7 @@ public class SqlInjectionMitigationIntegrationTest extends IntegrationTest { .contentType(ContentType.JSON) .get( url( - "/WebGoat/SqlInjectionMitigations/servers?column=(case when (true) then hostname" + "SqlInjectionMitigations/servers?column=(case when (true) then hostname" + " else id end)")) .then() .statusCode(200); @@ -67,7 +67,7 @@ public class SqlInjectionMitigationIntegrationTest extends IntegrationTest { .relaxedHTTPSValidation() .cookie("JSESSIONID", getWebGoatCookie()) .contentType(ContentType.JSON) - .get(url("/WebGoat/SqlInjectionMitigations/servers?column=unknown")) + .get(url("SqlInjectionMitigations/servers?column=unknown")) .then() .statusCode(500) .body( @@ -78,7 +78,7 @@ public class SqlInjectionMitigationIntegrationTest extends IntegrationTest { params.clear(); params.put("ip", "104.130.219.202"); - checkAssignment(url("/WebGoat/SqlInjectionMitigations/attack12a"), params, true); + checkAssignment(url("SqlInjectionMitigations/attack12a"), params, true); checkResults(); } diff --git a/src/it/java/org/owasp/webgoat/WebWolfIntegrationTest.java b/src/it/java/org/owasp/webgoat/WebWolfIntegrationTest.java index 6c01aa361..654f86399 100644 --- a/src/it/java/org/owasp/webgoat/WebWolfIntegrationTest.java +++ b/src/it/java/org/owasp/webgoat/WebWolfIntegrationTest.java @@ -3,7 +3,6 @@ package org.owasp.webgoat; import static org.junit.jupiter.api.Assertions.assertTrue; import io.restassured.RestAssured; -import java.io.IOException; import java.util.HashMap; import java.util.Map; import org.junit.jupiter.api.Test; @@ -11,21 +10,20 @@ import org.junit.jupiter.api.Test; public class WebWolfIntegrationTest extends IntegrationTest { @Test - public void runTests() throws IOException { + public void runTests() { startLesson("WebWolfIntroduction"); // Assignment 3 Map params = new HashMap<>(); - params.clear(); params.put("email", this.getUser() + "@webgoat.org"); - checkAssignment(url("/WebGoat/WebWolf/mail/send"), params, false); + checkAssignment(url("WebWolf/mail/send"), params, false); String responseBody = RestAssured.given() .when() .relaxedHTTPSValidation() .cookie("WEBWOLFSESSION", getWebWolfCookie()) - .get(webWolfUrl("/WebWolf/mail")) + .get(webWolfUrl("mail")) .then() .extract() .response() @@ -39,7 +37,7 @@ public class WebWolfIntegrationTest extends IntegrationTest { uniqueCode.lastIndexOf("your unique code is: ") + (21 + this.getUser().length())); params.clear(); params.put("uniqueCode", uniqueCode); - checkAssignment(url("/WebGoat/WebWolf/mail"), params, true); + checkAssignment(url("WebWolf/mail"), params, true); // Assignment 4 RestAssured.given() @@ -47,7 +45,7 @@ public class WebWolfIntegrationTest extends IntegrationTest { .relaxedHTTPSValidation() .cookie("JSESSIONID", getWebGoatCookie()) .queryParams(params) - .get(url("/WebGoat/WebWolf/landing/password-reset")) + .get(url("WebWolf/landing/password-reset")) .then() .statusCode(200); RestAssured.given() @@ -55,7 +53,7 @@ public class WebWolfIntegrationTest extends IntegrationTest { .relaxedHTTPSValidation() .cookie("WEBWOLFSESSION", getWebWolfCookie()) .queryParams(params) - .get(webWolfUrl("/landing")) + .get(webWolfUrl("landing")) .then() .statusCode(200); responseBody = @@ -63,7 +61,7 @@ public class WebWolfIntegrationTest extends IntegrationTest { .when() .relaxedHTTPSValidation() .cookie("WEBWOLFSESSION", getWebWolfCookie()) - .get(webWolfUrl("/WebWolf/requests")) + .get(webWolfUrl("requests")) .then() .extract() .response() @@ -72,7 +70,7 @@ public class WebWolfIntegrationTest extends IntegrationTest { assertTrue(responseBody.contains(uniqueCode)); params.clear(); params.put("uniqueCode", uniqueCode); - checkAssignment(url("/WebGoat/WebWolf/landing"), params, true); + checkAssignment(url("WebWolf/landing"), params, true); checkResults("/WebWolf"); } diff --git a/src/it/java/org/owasp/webgoat/XSSIntegrationTest.java b/src/it/java/org/owasp/webgoat/XSSIntegrationTest.java index 3a4e99551..dc7a19a70 100644 --- a/src/it/java/org/owasp/webgoat/XSSIntegrationTest.java +++ b/src/it/java/org/owasp/webgoat/XSSIntegrationTest.java @@ -14,7 +14,7 @@ public class XSSIntegrationTest extends IntegrationTest { Map params = new HashMap<>(); params.clear(); params.put("checkboxAttack1", "value"); - checkAssignment(url("/CrossSiteScripting/attack1"), params, true); + checkAssignment(url("CrossSiteScripting/attack1"), params, true); params.clear(); params.put("QTY1", "1"); @@ -23,11 +23,11 @@ public class XSSIntegrationTest extends IntegrationTest { params.put("QTY4", "1"); params.put("field1", ""); params.put("field2", "111"); - checkAssignmentWithGet(url("/CrossSiteScripting/attack5a"), params, true); + checkAssignmentWithGet(url("CrossSiteScripting/attack5a"), params, true); params.clear(); params.put("DOMTestRoute", "start.mvc#test"); - checkAssignment(url("/CrossSiteScripting/attack6a"), params, true); + checkAssignment(url("CrossSiteScripting/attack6a"), params, true); params.clear(); params.put("param1", "42"); @@ -41,7 +41,7 @@ public class XSSIntegrationTest extends IntegrationTest { .header("webgoat-requested-by", "dom-xss-vuln") .header("X-Requested-With", "XMLHttpRequest") .formParams(params) - .post(url("/CrossSiteScripting/phone-home-xss")) + .post(url("CrossSiteScripting/phone-home-xss")) .then() .statusCode(200) .extract() @@ -50,7 +50,7 @@ public class XSSIntegrationTest extends IntegrationTest { params.clear(); params.put("successMessage", secretNumber); - checkAssignment(url("/CrossSiteScripting/dom-follow-up"), params, true); + checkAssignment(url("CrossSiteScripting/dom-follow-up"), params, true); params.clear(); params.put( @@ -73,7 +73,7 @@ public class XSSIntegrationTest extends IntegrationTest { "question_4_solution", "Solution 4: No there are many other ways. Like HTML, Flash or any other type of code that" + " the browser executes."); - checkAssignment(url("/CrossSiteScripting/quiz"), params, true); + checkAssignment(url("CrossSiteScripting/quiz"), params, true); params.clear(); params.put( @@ -99,7 +99,7 @@ public class XSSIntegrationTest extends IntegrationTest { + "" + "" + ""); - checkAssignment(url("/CrossSiteScripting/attack3"), params, true); + checkAssignment(url("CrossSiteScripting/attack3"), params, true); params.clear(); params.put( @@ -109,7 +109,7 @@ public class XSSIntegrationTest extends IntegrationTest { + "s.scan(newComment,\"\");" + "CleanResults();" + "MyCommentDAO.addComment(threadID, userID).getCleanHTML());"); - checkAssignment(url("/CrossSiteScripting/attack4"), params, true); + checkAssignment(url("CrossSiteScripting/attack4"), params, true); checkResults("/CrossSiteScripting"); } diff --git a/src/it/java/org/owasp/webgoat/XXEIntegrationTest.java b/src/it/java/org/owasp/webgoat/XXEIntegrationTest.java index fdb06d8ee..1448aec2f 100644 --- a/src/it/java/org/owasp/webgoat/XXEIntegrationTest.java +++ b/src/it/java/org/owasp/webgoat/XXEIntegrationTest.java @@ -45,10 +45,10 @@ public class XXEIntegrationTest extends IntegrationTest { .get(url("service/enable-security.mvc")) .then() .statusCode(200); - checkAssignment(url("/WebGoat/xxe/simple"), ContentType.XML, xxe3, false); - checkAssignment(url("/WebGoat/xxe/content-type"), ContentType.XML, xxe4, false); + checkAssignment(url("xxe/simple"), ContentType.XML, xxe3, false); + checkAssignment(url("xxe/content-type"), ContentType.XML, xxe4, false); checkAssignment( - url("/WebGoat/xxe/blind"), + url("xxe/blind"), ContentType.XML, "" + getSecret() + "", false); @@ -68,7 +68,7 @@ public class XXEIntegrationTest extends IntegrationTest { } String secretFile = webGoatHomeDirectory.concat("/XXE/" + getUser() + "/secret.txt"); String dtd7String = - dtd7.replace("WEBWOLFURL", webWolfUrl("/landing")).replace("SECRET", secretFile); + dtd7.replace("WEBWOLFURL", webWolfUrl("landing")).replace("SECRET", secretFile); // upload DTD RestAssured.given() @@ -76,7 +76,7 @@ public class XXEIntegrationTest extends IntegrationTest { .relaxedHTTPSValidation() .cookie("WEBWOLFSESSION", getWebWolfCookie()) .multiPart("file", "blind.dtd", dtd7String.getBytes()) - .post(webWolfUrl("/fileupload")) + .post(webWolfUrl("fileupload")) .then() .extract() .response() @@ -84,8 +84,8 @@ public class XXEIntegrationTest extends IntegrationTest { .asString(); // upload attack String xxe7String = - xxe7.replace("WEBWOLFURL", webWolfUrl("/files")).replace("USERNAME", this.getUser()); - checkAssignment(url("/WebGoat/xxe/blind"), ContentType.XML, xxe7String, false); + xxe7.replace("WEBWOLFURL", webWolfUrl("files")).replace("USERNAME", this.getUser()); + checkAssignment(url("xxe/blind"), ContentType.XML, xxe7String, false); // read results from WebWolf String result = @@ -93,7 +93,7 @@ public class XXEIntegrationTest extends IntegrationTest { .when() .relaxedHTTPSValidation() .cookie("WEBWOLFSESSION", getWebWolfCookie()) - .get(webWolfUrl("/WebWolf/requests")) + .get(webWolfUrl("requests")) .then() .extract() .response() @@ -114,10 +114,10 @@ public class XXEIntegrationTest extends IntegrationTest { startLesson("XXE", true); webGoatHomeDirectory = webGoatServerDirectory(); webWolfFileServerLocation = getWebWolfFileServerLocation(); - checkAssignment(url("/WebGoat/xxe/simple"), ContentType.XML, xxe3, true); - checkAssignment(url("/WebGoat/xxe/content-type"), ContentType.XML, xxe4, true); + checkAssignment(url("xxe/simple"), ContentType.XML, xxe3, true); + checkAssignment(url("xxe/content-type"), ContentType.XML, xxe4, true); checkAssignment( - url("/WebGoat/xxe/blind"), + url("xxe/blind"), ContentType.XML, "" + getSecret() + "", true); diff --git a/src/main/java/org/owasp/webgoat/container/MvcConfiguration.java b/src/main/java/org/owasp/webgoat/container/MvcConfiguration.java index 94353be2f..6aff15813 100644 --- a/src/main/java/org/owasp/webgoat/container/MvcConfiguration.java +++ b/src/main/java/org/owasp/webgoat/container/MvcConfiguration.java @@ -242,6 +242,7 @@ public class MvcConfiguration implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(localeChangeInterceptor()); + registry.addInterceptor(new UserInterceptor()); } @Bean diff --git a/src/main/java/org/owasp/webgoat/container/UserInterceptor.java b/src/main/java/org/owasp/webgoat/container/UserInterceptor.java new file mode 100644 index 000000000..2570df76c --- /dev/null +++ b/src/main/java/org/owasp/webgoat/container/UserInterceptor.java @@ -0,0 +1,53 @@ +package org.owasp.webgoat.container; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.owasp.webgoat.container.asciidoc.EnvironmentExposure; +import org.springframework.core.env.Environment; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.servlet.HandlerInterceptor; +import org.springframework.web.servlet.ModelAndView; + +public class UserInterceptor implements HandlerInterceptor { + + private Environment env = EnvironmentExposure.getEnv(); + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) + throws Exception { + // Do nothing + return true; + } + + @Override + public void postHandle( + HttpServletRequest request, + HttpServletResponse response, + Object handler, + ModelAndView modelAndView) + throws Exception { + if (null != modelAndView) { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if (null != authentication) { + modelAndView.getModel().put("username", authentication.getName()); + } + if (null != env) { + String githubClientId = + env.getProperty("spring.security.oauth2.client.registration.github.client-id"); + if (null != githubClientId && !githubClientId.equals("dummy")) { + modelAndView.getModel().put("oauth", Boolean.TRUE); + } + } else { + modelAndView.getModel().put("oauth", Boolean.FALSE); + } + } + } + + @Override + public void afterCompletion( + HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) + throws Exception { + // Do nothing + } +} diff --git a/src/main/java/org/owasp/webgoat/container/WebGoat.java b/src/main/java/org/owasp/webgoat/container/WebGoat.java index e721fddee..0efcf10e5 100644 --- a/src/main/java/org/owasp/webgoat/container/WebGoat.java +++ b/src/main/java/org/owasp/webgoat/container/WebGoat.java @@ -34,6 +34,9 @@ package org.owasp.webgoat.container; import java.io.File; import org.owasp.webgoat.container.session.UserSessionData; import org.owasp.webgoat.container.session.WebSession; +import org.owasp.webgoat.container.users.UserRepository; +import org.owasp.webgoat.container.users.WebGoatUser; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.Bean; @@ -42,6 +45,8 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.ScopedProxyMode; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.oauth2.core.user.DefaultOAuth2User; import org.springframework.web.client.RestTemplate; @Configuration @@ -50,6 +55,8 @@ import org.springframework.web.client.RestTemplate; @EnableAutoConfiguration public class WebGoat { + @Autowired private UserRepository userRepository; + @Bean(name = "pluginTargetDirectory") public File pluginTargetDirectory(@Value("${webgoat.user.directory}") final String webgoatHome) { return new File(webgoatHome); @@ -58,7 +65,14 @@ public class WebGoat { @Bean @Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS) public WebSession webSession() { - return new WebSession(); + WebGoatUser webGoatUser = null; + Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + if (principal instanceof WebGoatUser) { + webGoatUser = (WebGoatUser) principal; + } else if (principal instanceof DefaultOAuth2User) { + webGoatUser = userRepository.findByUsername(((DefaultOAuth2User) principal).getName()); + } + return new WebSession(webGoatUser); } @Bean diff --git a/src/main/java/org/owasp/webgoat/container/WebSecurityConfig.java b/src/main/java/org/owasp/webgoat/container/WebSecurityConfig.java index 3621ce707..e40be07b4 100644 --- a/src/main/java/org/owasp/webgoat/container/WebSecurityConfig.java +++ b/src/main/java/org/owasp/webgoat/container/WebSecurityConfig.java @@ -54,32 +54,41 @@ public class WebSecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { - http.authorizeHttpRequests( - auth -> - auth.requestMatchers( - "/css/**", - "/images/**", - "/js/**", - "fonts/**", - "/plugins/**", - "/registration", - "/register.mvc", - "/actuator/**") - .permitAll() - .anyRequest() - .authenticated()); - http.formLogin() - .loginPage("/login") - .defaultSuccessUrl("/welcome.mvc", true) - .usernameParameter("username") - .passwordParameter("password") - .permitAll(); - http.logout().deleteCookies("JSESSIONID").invalidateHttpSession(true); - http.csrf().disable(); - - http.headers().cacheControl().disable(); - http.exceptionHandling().authenticationEntryPoint(new AjaxAuthenticationEntryPoint("/login")); - return http.build(); + return http.authorizeHttpRequests( + auth -> + auth.requestMatchers( + "/", + "/favicon.ico", + "/css/**", + "/images/**", + "/js/**", + "fonts/**", + "/plugins/**", + "/registration", + "/register.mvc") + .permitAll() + .anyRequest() + .authenticated()) + .formLogin( + login -> + login + .loginPage("/login") + .defaultSuccessUrl("/welcome.mvc", true) + .usernameParameter("username") + .passwordParameter("password") + .permitAll()) + .oauth2Login( + oidc -> { + oidc.defaultSuccessUrl("/login-oauth.mvc"); + oidc.loginPage("/login"); + }) + .logout(logout -> logout.deleteCookies("JSESSIONID").invalidateHttpSession(true)) + .csrf(csrf -> csrf.disable()) + .headers(headers -> headers.disable()) + .exceptionHandling( + handling -> + handling.authenticationEntryPoint(new AjaxAuthenticationEntryPoint("/login"))) + .build(); } @Autowired @@ -98,7 +107,6 @@ public class WebSecurityConfig { return authenticationConfiguration.getAuthenticationManager(); } - @SuppressWarnings("deprecation") @Bean public NoOpPasswordEncoder passwordEncoder() { return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance(); diff --git a/src/main/java/org/owasp/webgoat/container/asciidoc/EnvironmentExposure.java b/src/main/java/org/owasp/webgoat/container/asciidoc/EnvironmentExposure.java index 7abaf10c9..072079483 100644 --- a/src/main/java/org/owasp/webgoat/container/asciidoc/EnvironmentExposure.java +++ b/src/main/java/org/owasp/webgoat/container/asciidoc/EnvironmentExposure.java @@ -16,7 +16,7 @@ public class EnvironmentExposure implements ApplicationContextAware { private static ApplicationContext context; public static Environment getEnv() { - return context.getEnvironment(); + return (null != context) ? context.getEnvironment() : null; } @Override diff --git a/src/main/java/org/owasp/webgoat/container/session/WebSession.java b/src/main/java/org/owasp/webgoat/container/session/WebSession.java index 22b339db6..8650ba54b 100644 --- a/src/main/java/org/owasp/webgoat/container/session/WebSession.java +++ b/src/main/java/org/owasp/webgoat/container/session/WebSession.java @@ -3,7 +3,6 @@ package org.owasp.webgoat.container.session; import java.io.Serializable; import org.owasp.webgoat.container.lessons.Lesson; import org.owasp.webgoat.container.users.WebGoatUser; -import org.springframework.security.core.context.SecurityContextHolder; /** * ************************************************************************************************* @@ -40,13 +39,12 @@ import org.springframework.security.core.context.SecurityContextHolder; public class WebSession implements Serializable { private static final long serialVersionUID = -4270066103101711560L; - private final WebGoatUser currentUser; + private WebGoatUser currentUser; private transient Lesson currentLesson; private boolean securityEnabled; - public WebSession() { - this.currentUser = - (WebGoatUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + public WebSession(WebGoatUser webGoatUser) { + this.currentUser = webGoatUser; } /** diff --git a/src/main/java/org/owasp/webgoat/container/users/RegistrationController.java b/src/main/java/org/owasp/webgoat/container/users/RegistrationController.java index 1678385de..9f18c650c 100644 --- a/src/main/java/org/owasp/webgoat/container/users/RegistrationController.java +++ b/src/main/java/org/owasp/webgoat/container/users/RegistrationController.java @@ -3,8 +3,10 @@ package org.owasp.webgoat.container.users; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; +import java.util.UUID; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.security.core.Authentication; import org.springframework.stereotype.Controller; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.GetMapping; @@ -44,4 +46,12 @@ public class RegistrationController { return "redirect:/attack"; } + + @GetMapping("/login-oauth.mvc") + public String registrationOAUTH(Authentication authentication, HttpServletRequest request) + throws ServletException { + log.info("register oauth user in database"); + userService.addUser(authentication.getName(), UUID.randomUUID().toString()); + return "redirect:/welcome.mvc"; + } } diff --git a/src/main/java/org/owasp/webgoat/lessons/passwordreset/ResetLinkAssignmentForgotPassword.java b/src/main/java/org/owasp/webgoat/lessons/passwordreset/ResetLinkAssignmentForgotPassword.java index c53931418..26bdb2e0e 100644 --- a/src/main/java/org/owasp/webgoat/lessons/passwordreset/ResetLinkAssignmentForgotPassword.java +++ b/src/main/java/org/owasp/webgoat/lessons/passwordreset/ResetLinkAssignmentForgotPassword.java @@ -48,16 +48,19 @@ public class ResetLinkAssignmentForgotPassword extends AssignmentEndpoint { private final RestTemplate restTemplate; private String webWolfHost; private String webWolfPort; + private String webWolfURL; private final String webWolfMailURL; public ResetLinkAssignmentForgotPassword( RestTemplate restTemplate, @Value("${webwolf.host}") String webWolfHost, @Value("${webwolf.port}") String webWolfPort, + @Value("${webwolf.url}") String webWolfURL, @Value("${webwolf.mail.url}") String webWolfMailURL) { this.restTemplate = restTemplate; this.webWolfHost = webWolfHost; this.webWolfPort = webWolfPort; + this.webWolfURL = webWolfURL; this.webWolfMailURL = webWolfMailURL; } @@ -67,12 +70,12 @@ public class ResetLinkAssignmentForgotPassword extends AssignmentEndpoint { @RequestParam String email, HttpServletRequest request) { String resetLink = UUID.randomUUID().toString(); ResetLinkAssignment.resetLinks.add(resetLink); - String host = request.getHeader("host"); + String host = request.getHeader(HttpHeaders.HOST); if (ResetLinkAssignment.TOM_EMAIL.equals(email) && (host.contains(webWolfPort) - || host.contains(webWolfHost))) { // User indeed changed the host header. + && host.contains(webWolfHost))) { // User indeed changed the host header. ResetLinkAssignment.userToTomResetLink.put(getWebSession().getUserName(), resetLink); - fakeClickingLinkEmail(host, resetLink); + fakeClickingLinkEmail(webWolfURL, resetLink); } else { try { sendMailToUser(email, host, resetLink); @@ -97,13 +100,13 @@ public class ResetLinkAssignmentForgotPassword extends AssignmentEndpoint { this.restTemplate.postForEntity(webWolfMailURL, mail, Object.class); } - private void fakeClickingLinkEmail(String host, String resetLink) { + private void fakeClickingLinkEmail(String webWolfURL, 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), + String.format("%s/PasswordReset/reset/reset-password/%s", webWolfURL, resetLink), HttpMethod.GET, httpEntity, Void.class); diff --git a/src/main/java/org/owasp/webgoat/lessons/webwolfintroduction/LandingAssignment.java b/src/main/java/org/owasp/webgoat/lessons/webwolfintroduction/LandingAssignment.java index 63764adea..26f8439e8 100644 --- a/src/main/java/org/owasp/webgoat/lessons/webwolfintroduction/LandingAssignment.java +++ b/src/main/java/org/owasp/webgoat/lessons/webwolfintroduction/LandingAssignment.java @@ -58,7 +58,8 @@ public class LandingAssignment extends AssignmentEndpoint { public ModelAndView openPasswordReset(HttpServletRequest request) throws URISyntaxException { URI uri = new URI(request.getRequestURL().toString()); ModelAndView modelAndView = new ModelAndView(); - modelAndView.addObject("webwolfUrl", landingPageUrl); + modelAndView.addObject( + "webwolfLandingPageUrl", landingPageUrl.replace("//landing", "/landing")); modelAndView.addObject("uniqueCode", StringUtils.reverse(getWebSession().getUserName())); modelAndView.setViewName("lessons/webwolfintroduction/templates/webwolfPasswordReset.html"); diff --git a/src/main/java/org/owasp/webgoat/server/StartWebGoat.java b/src/main/java/org/owasp/webgoat/server/StartWebGoat.java index 845a057ac..54c9b8929 100644 --- a/src/main/java/org/owasp/webgoat/server/StartWebGoat.java +++ b/src/main/java/org/owasp/webgoat/server/StartWebGoat.java @@ -25,14 +25,12 @@ package org.owasp.webgoat.server; -import lombok.extern.slf4j.Slf4j; import org.owasp.webgoat.container.WebGoat; import org.owasp.webgoat.webwolf.WebWolf; import org.springframework.boot.Banner; import org.springframework.boot.WebApplicationType; import org.springframework.boot.builder.SpringApplicationBuilder; -@Slf4j public class StartWebGoat { public static void main(String[] args) { diff --git a/src/main/java/org/owasp/webgoat/server/StartupMessage.java b/src/main/java/org/owasp/webgoat/server/StartupMessage.java index 409ffb377..ecc52bc19 100644 --- a/src/main/java/org/owasp/webgoat/server/StartupMessage.java +++ b/src/main/java/org/owasp/webgoat/server/StartupMessage.java @@ -15,16 +15,18 @@ public class StartupMessage { private String port; private String address; + private String contextPath; @EventListener void onStartup(ApplicationReadyEvent event) { + + port = event.getApplicationContext().getEnvironment().getProperty("server.port"); + address = event.getApplicationContext().getEnvironment().getProperty("server.address"); + contextPath = + event.getApplicationContext().getEnvironment().getProperty("server.servlet.context-path"); if (StringUtils.hasText(port) && !StringUtils.hasText(System.getProperty("running.in.docker"))) { - log.info("Please browse to http://{}:{}/WebGoat to get started...", address, port); - } - if (event.getApplicationContext().getApplicationName().contains("WebGoat")) { - port = event.getApplicationContext().getEnvironment().getProperty("server.port"); - address = event.getApplicationContext().getEnvironment().getProperty("server.address"); + log.warn("Please browse to http://{}:{}{} to get started...", address, port, contextPath); } } diff --git a/src/main/java/org/owasp/webgoat/webwolf/FileServer.java b/src/main/java/org/owasp/webgoat/webwolf/FileServer.java index 5eda1ca2b..9a02b4a4c 100644 --- a/src/main/java/org/owasp/webgoat/webwolf/FileServer.java +++ b/src/main/java/org/owasp/webgoat/webwolf/FileServer.java @@ -32,10 +32,9 @@ import lombok.AllArgsConstructor; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.FileUtils; -import org.owasp.webgoat.webwolf.user.WebGoatUser; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.MediaType; -import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.Authentication; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.GetMapping; @@ -58,6 +57,9 @@ public class FileServer { @Value("${server.address}") private String server; + @Value("${server.servlet.context-path}") + private String contextPath; + @Value("${server.port}") private int port; @@ -71,9 +73,11 @@ public class FileServer { } @PostMapping(value = "/fileupload") - public ModelAndView importFile(@RequestParam("file") MultipartFile myFile) throws IOException { - var user = (WebGoatUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); - var destinationDir = new File(fileLocation, user.getUsername()); + public ModelAndView importFile( + @RequestParam("file") MultipartFile myFile, Authentication authentication) + throws IOException { + String username = authentication.getName(); + var destinationDir = new File(fileLocation, username); destinationDir.mkdirs(); myFile.transferTo(new File(destinationDir, myFile.getOriginalFilename())); log.debug("File saved to {}", new File(destinationDir, myFile.getOriginalFilename())); @@ -92,15 +96,13 @@ public class FileServer { } @GetMapping(value = "/files") - public ModelAndView getFiles(HttpServletRequest request) { - WebGoatUser user = - (WebGoatUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); - String username = user.getUsername(); + public ModelAndView getFiles(HttpServletRequest request, Authentication authentication) { + String username = (null != authentication) ? authentication.getName() : "anonymous"; File destinationDir = new File(fileLocation, username); ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("files"); - File changeIndicatorFile = new File(destinationDir, user.getUsername() + "_changed"); + File changeIndicatorFile = new File(destinationDir, username + "_changed"); if (changeIndicatorFile.exists()) { modelAndView.addObject("uploadSuccess", request.getParameter("uploadSuccess")); } @@ -117,7 +119,7 @@ public class FileServer { } modelAndView.addObject("files", uploadedFiles); - modelAndView.addObject("webwolf_url", "http://" + server + ":" + port); + modelAndView.addObject("webwolf_url", "http://" + server + ":" + port + contextPath); return modelAndView; } } diff --git a/src/main/java/org/owasp/webgoat/webwolf/MvcConfiguration.java b/src/main/java/org/owasp/webgoat/webwolf/MvcConfiguration.java index 3c267bd32..c026ae559 100644 --- a/src/main/java/org/owasp/webgoat/webwolf/MvcConfiguration.java +++ b/src/main/java/org/owasp/webgoat/webwolf/MvcConfiguration.java @@ -24,8 +24,10 @@ package org.owasp.webgoat.webwolf; import jakarta.annotation.PostConstruct; import java.io.File; +import org.owasp.webgoat.container.UserInterceptor; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @@ -55,6 +57,12 @@ public class MvcConfiguration implements WebMvcConfigurer { public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/login").setViewName("webwolf-login"); registry.addViewController("/home").setViewName("home"); + registry.addViewController("/").setViewName("home"); + } + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(new UserInterceptor()); } @PostConstruct diff --git a/src/main/java/org/owasp/webgoat/webwolf/WebSecurityConfig.java b/src/main/java/org/owasp/webgoat/webwolf/WebSecurityConfig.java index 64f6758c7..7be7839e5 100644 --- a/src/main/java/org/owasp/webgoat/webwolf/WebSecurityConfig.java +++ b/src/main/java/org/owasp/webgoat/webwolf/WebSecurityConfig.java @@ -22,6 +22,7 @@ package org.owasp.webgoat.webwolf; import lombok.AllArgsConstructor; +import org.owasp.webgoat.container.AjaxAuthenticationEntryPoint; import org.owasp.webgoat.webwolf.user.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; @@ -46,16 +47,39 @@ public class WebSecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { - http.authorizeHttpRequests( - auth -> auth.requestMatchers(HttpMethod.POST, "/fileupload").authenticated()); - http.authorizeHttpRequests( - auth -> - auth.requestMatchers(HttpMethod.GET, "/files", "/mail", "/requests").authenticated()); - http.authorizeHttpRequests().anyRequest().permitAll(); - http.csrf().disable().formLogin().loginPage("/login").failureUrl("/login?error=true"); - http.formLogin().loginPage("/login").defaultSuccessUrl("/home", true).permitAll(); - http.logout().permitAll(); - return http.build(); + return http.authorizeHttpRequests( + auth -> { + auth.requestMatchers("/css/**", "/webjars/**", "/favicon.ico", "/js/**", "/images/**") + .permitAll(); + auth.requestMatchers( + HttpMethod.GET, + "/fileupload/**", + "/files/**", + "/landing/**", + "/PasswordReset/**") + .permitAll(); + auth.requestMatchers(HttpMethod.POST, "/files", "/mail", "/requests").permitAll(); + auth.anyRequest().authenticated(); + }) + .csrf(csrf -> csrf.disable()) + .formLogin( + login -> + login + .loginPage("/login") + .failureUrl("/login?error=true") + .defaultSuccessUrl("/home", true) + .usernameParameter("username") + .passwordParameter("password") + .permitAll()) + .oauth2Login( + oidc -> { + oidc.defaultSuccessUrl("/home"); + }) + .logout(logout -> logout.deleteCookies("WEBWOLFSESSION").invalidateHttpSession(true)) + .exceptionHandling( + handling -> + handling.authenticationEntryPoint(new AjaxAuthenticationEntryPoint("/login"))) + .build(); } @Autowired diff --git a/src/main/java/org/owasp/webgoat/webwolf/mailbox/MailboxController.java b/src/main/java/org/owasp/webgoat/webwolf/mailbox/MailboxController.java index fb1bde0e5..5b4003c38 100644 --- a/src/main/java/org/owasp/webgoat/webwolf/mailbox/MailboxController.java +++ b/src/main/java/org/owasp/webgoat/webwolf/mailbox/MailboxController.java @@ -25,8 +25,8 @@ package org.owasp.webgoat.webwolf.mailbox; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.Authentication; +import org.springframework.ui.Model; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; @@ -42,16 +42,16 @@ public class MailboxController { private final MailboxRepository mailboxRepository; @GetMapping("/mail") - public ModelAndView mail() { - UserDetails user = - (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + public ModelAndView mail(Authentication authentication, Model model) { + String username = (null != authentication) ? authentication.getName() : "anonymous"; ModelAndView modelAndView = new ModelAndView(); - List emails = mailboxRepository.findByRecipientOrderByTimeDesc(user.getUsername()); + List emails = mailboxRepository.findByRecipientOrderByTimeDesc(username); if (emails != null && !emails.isEmpty()) { modelAndView.addObject("total", emails.size()); modelAndView.addObject("emails", emails); } modelAndView.setViewName("mailbox"); + model.addAttribute("username", username); return modelAndView; } diff --git a/src/main/java/org/owasp/webgoat/webwolf/requests/Requests.java b/src/main/java/org/owasp/webgoat/webwolf/requests/Requests.java index 5effa524e..2dda64036 100644 --- a/src/main/java/org/owasp/webgoat/webwolf/requests/Requests.java +++ b/src/main/java/org/owasp/webgoat/webwolf/requests/Requests.java @@ -33,8 +33,7 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.boot.actuate.web.exchanges.HttpExchange; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.Authentication; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -64,12 +63,12 @@ public class Requests { } @GetMapping - public ModelAndView get() { + public ModelAndView get(Authentication authentication) { var model = new ModelAndView("requests"); - var user = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + String username = (null != authentication) ? authentication.getName() : "anonymous"; var traces = traceRepository.findAllTraces().stream() - .filter(t -> allowedTrace(t, user)) + .filter(t -> allowedTrace(t, username)) .map(t -> new Tracert(t.getTimestamp(), path(t), toJsonString(t))) .collect(toList()); model.addObject("traces", traces); @@ -77,17 +76,16 @@ public class Requests { return model; } - private boolean allowedTrace(HttpExchange t, UserDetails user) { + private boolean allowedTrace(HttpExchange t, String username) { HttpExchange.Request req = t.getRequest(); boolean allowed = true; /* do not show certain traces to other users in a classroom setup */ - if (req.getUri().getPath().contains("/files") - && !req.getUri().getPath().contains(user.getUsername())) { + if (req.getUri().getPath().contains("/files") && !req.getUri().getPath().contains(username)) { allowed = false; } else if (req.getUri().getPath().contains("/landing") && req.getUri().getQuery() != null && req.getUri().getQuery().contains("uniqueCode") - && !req.getUri().getQuery().contains(StringUtils.reverse(user.getUsername()))) { + && !req.getUri().getQuery().contains(StringUtils.reverse(username))) { allowed = false; } diff --git a/src/main/java/org/owasp/webgoat/webwolf/requests/WebWolfTraceRepository.java b/src/main/java/org/owasp/webgoat/webwolf/requests/WebWolfTraceRepository.java index ceff13923..0b2ad6f33 100644 --- a/src/main/java/org/owasp/webgoat/webwolf/requests/WebWolfTraceRepository.java +++ b/src/main/java/org/owasp/webgoat/webwolf/requests/WebWolfTraceRepository.java @@ -25,7 +25,6 @@ package org.owasp.webgoat.webwolf.requests; import com.google.common.collect.EvictingQueue; import java.util.ArrayList; import java.util.List; -import lombok.extern.slf4j.Slf4j; import org.springframework.boot.actuate.web.exchanges.HttpExchange; import org.springframework.boot.actuate.web.exchanges.HttpExchangeRepository; @@ -36,7 +35,6 @@ import org.springframework.boot.actuate.web.exchanges.HttpExchangeRepository; * @author nbaars * @since 8/13/17. */ -@Slf4j public class WebWolfTraceRepository implements HttpExchangeRepository { private final EvictingQueue traces = EvictingQueue.create(10000); @@ -46,7 +44,6 @@ public class WebWolfTraceRepository implements HttpExchangeRepository { "/home", "/files", "/images/", - "/favicon.ico", "/js/", "/webjars/", "/requests", diff --git a/src/main/resources/application-webgoat.properties b/src/main/resources/application-webgoat.properties index 186c62690..5d7ecf66f 100644 --- a/src/main/resources/application-webgoat.properties +++ b/src/main/resources/application-webgoat.properties @@ -1,10 +1,12 @@ server.error.include-stacktrace=always server.error.path=/error.html -server.servlet.context-path=/WebGoat +server.servlet.context-path=${webgoat.context} server.servlet.session.persistent=false -server.port=${webgoat.port:8080} +server.port=${webgoat.port} server.address=${webgoat.host} webgoat.host=${WEBGOAT_HOST:127.0.0.1} +webgoat.port=${WEBGOAT_PORT:8080} +webgoat.context=${WEBGOAT_CONTEXT:/WebGoat} spring.application.name=WebGoat server.ssl.key-store-type=${WEBGOAT_KEYSTORE_TYPE:PKCS12} @@ -27,9 +29,10 @@ logging.level.org.thymeleaf.TemplateEngine.cache.TEMPLATE_CACHE=INFO logging.level.org.springframework.web=INFO logging.level.org.springframework=INFO logging.level.org.springframework.boot.devtools=INFO -logging.level.org.owasp=DEBUG -logging.level.org.owasp.webgoat=DEBUG -logging.level.org.hidbernate.SQL=DEBUG +logging.level.org.owasp=INFO +logging.level.org.owasp.webgoat=INFO +logging.level.org.hidbernate.SQL=INFO + webgoat.server.directory=${user.home}/.webgoat-${webgoat.build.version}/ webgoat.user.directory=${user.home}/.webgoat-${webgoat.build.version}/ @@ -43,7 +46,8 @@ webgoat.default.language=en webwolf.host=${WEBWOLF_HOST:127.0.0.1} webwolf.port=${WEBWOLF_PORT:9090} -webwolf.url=http://${webwolf.host}:${webwolf.port} +webwolf.context=${WEBWOLF_CONTEXT:/WebWolf} +webwolf.url=http://${webwolf.host}:${webwolf.port}${webwolf.context} webwolf.landingpage.url=${webwolf.url}/landing webwolf.mail.url=${webwolf.url}/mail @@ -62,3 +66,7 @@ exclude.lessons=${EXCLUDE_LESSONS:none,none} management.health.db.enabled=true management.endpoint.health.show-details=always management.endpoints.web.exposure.include=env, health,configprops + +spring.security.oauth2.client.registration.github.client-id=${WEBGOAT_OAUTH_CLIENTID:dummy} +spring.security.oauth2.client.registration.github.client-secret=${WEBGOAT_OAUTH_CLIENTSECRET:dummy} + diff --git a/src/main/resources/application-webwolf.properties b/src/main/resources/application-webwolf.properties index 7d7bef3d1..4d450fc90 100644 --- a/src/main/resources/application-webwolf.properties +++ b/src/main/resources/application-webwolf.properties @@ -1,10 +1,13 @@ server.error.include-stacktrace=always server.error.path=/error.html -server.port=${webwolf.port:9090} +server.servlet.context-path=${webwolf.context} +server.port=${webwolf.port} server.address=${webwolf.host} spring.application.name=WebWolf webwolf.host=${WEBWOLF_HOST:127.0.0.1} +webwolf.port=${WEBWOLF_PORT:9090} +webwolf.context=${WEBWOLF_CONTEXT:/WebWolf} management.server.port=-1 server.servlet.session.cookie.name=WEBWOLFSESSION @@ -47,3 +50,6 @@ spring.jackson.serialization.write-dates-as-timestamps=false #For static file refresh ... and faster dev :D spring.devtools.restart.additional-paths=webwolf/src/main/resources/static/ + +spring.security.oauth2.client.registration.github.client-id=${WEBWOLF_OAUTH_CLIENTID:dummy} +spring.security.oauth2.client.registration.github.client-secret=${WEBWOLF_OAUTH_CLIENTSECRET:dummy} diff --git a/src/main/resources/lessons/authbypass/html/AuthBypass.html b/src/main/resources/lessons/authbypass/html/AuthBypass.html index 1630a5981..2fdeeb826 100644 --- a/src/main/resources/lessons/authbypass/html/AuthBypass.html +++ b/src/main/resources/lessons/authbypass/html/AuthBypass.html @@ -23,7 +23,7 @@
+ action="auth-bypass/verify-account">

Verify Your Account by answering the questions below:

What is the name of your favorite teacher?

@@ -43,7 +43,7 @@

Please provide a new password for your account

diff --git a/src/main/resources/lessons/authbypass/js/bypass.js b/src/main/resources/lessons/authbypass/js/bypass.js index acbc26899..97af89a67 100644 --- a/src/main/resources/lessons/authbypass/js/bypass.js +++ b/src/main/resources/lessons/authbypass/js/bypass.js @@ -9,7 +9,7 @@ var onViewProfile = function () { console.warn("on view profile activated") webgoat.customjs.jquery.ajax({ method: "GET", - url: "/WebGoat/IDOR/profile", + url: "IDOR/profile", contentType: 'application/json; charset=UTF-8' }).then(webgoat.customjs.idorViewProfile); } diff --git a/src/main/resources/lessons/bypassrestrictions/html/BypassRestrictions.html b/src/main/resources/lessons/bypassrestrictions/html/BypassRestrictions.html index a9d71c772..d1c8d3001 100755 --- a/src/main/resources/lessons/bypassrestrictions/html/BypassRestrictions.html +++ b/src/main/resources/lessons/bypassrestrictions/html/BypassRestrictions.html @@ -18,7 +18,7 @@
+ action="BypassRestrictions/FieldRestrictions">
Select field with two possible value
@@ -66,7 +66,7 @@
Field 1: exactly three lowercase characters(^[a-z]{3}$) diff --git a/src/main/resources/lessons/challenges/documentation/Challenge_introduction.adoc b/src/main/resources/lessons/challenges/documentation/Challenge_introduction.adoc index 990f386b4..d28b46a06 100644 --- a/src/main/resources/lessons/challenges/documentation/Challenge_introduction.adoc +++ b/src/main/resources/lessons/challenges/documentation/Challenge_introduction.adoc @@ -4,7 +4,7 @@ The challenges contain more a CTF like lessons where we do not provide any explanations what you need to do, no hints will be provided. You can use these challenges in a CTF style where you can run WebGoat on one server and all -participants can join and hack the challenges. A scoreboard is available at link:/WebGoat/scoreboard["/WebGoat/scoreboard",window=_blank] +participants can join and hack the challenges. A scoreboard is available at link:scoreboard["scoreboard",window=_blank] :hardbreaks: In this CTF you will need to solve a couple of challenges, each challenge will give you a flag which you will diff --git a/src/main/resources/lessons/challenges/html/Challenge1.html b/src/main/resources/lessons/challenges/html/Challenge1.html index 2d9e95114..544dc4f77 100644 --- a/src/main/resources/lessons/challenges/html/Challenge1.html +++ b/src/main/resources/lessons/challenges/html/Challenge1.html @@ -17,7 +17,7 @@
@@ -37,7 +37,7 @@
- +