Password reset link test condition more strict and move all WebWolf links to /WebWolf (#1645)

* better check on host and port for password reset and make context roots more flexible

* spotless applied

* removed hardcoded /WebGoat from js

* removed hardcoded /WebGoat from js

* fix spotless

* fix scoreboard

* upgrade WebWolf bootstrap version and icons and templates - part 1

* fixed more bootstrap 5 style issues and context path issues

* organized WebSecurityConfig based on latest conventions and added basic support for oauth (more work needed)

* spotless applied

* added mock bean

* requires updates to properties - commented for now

* requires updates to properties - commented for now

* oauth secrets through env values

* user creation after oauth login

* integration test against non default context paths

* adjusted StartupMessage

* add global model element username

* conditionally show login oauth links

* fixed WebWolf login

---------

Co-authored-by: René Zubcevic <rene@Mac-mini-van-Rene.local>
This commit is contained in:
René Zubcevic 2023-11-14 10:01:59 +01:00 committed by GitHub
parent 5a4974f3c2
commit d1e44bbc98
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
114 changed files with 2763 additions and 546 deletions

15
pom.xml
View File

@ -110,8 +110,7 @@
<properties>
<!-- Shared properties with plugins and version numbers across submodules-->
<asciidoctorj.version>2.5.10</asciidoctorj.version>
<!-- Upgrading needs UI work in WebWolf Limited to 3.4.1 due to stylesheet refactoring -->
<bootstrap.version>3.4.1</bootstrap.version>
<bootstrap.version>5.3.1</bootstrap.version>
<cglib.version>3.3.0</cglib.version>
<!-- do not update necessary for lesson -->
<checkstyle.version>3.3.1</checkstyle.version>
@ -141,8 +140,10 @@
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<thymeleaf.version>3.1.1.RELEASE</thymeleaf.version>
<webdriver.version>5.3.3</webdriver.version>
<webgoat.context>/</webgoat.context>
<webgoat.port>8080</webgoat.port>
<webjars-locator-core.version>0.53</webjars-locator-core.version>
<webwolf.context>/</webwolf.context>
<webwolf.port>9090</webwolf.port>
<wiremock.version>2.27.2</wiremock.version>
<xml-resolver.version>1.2</xml-resolver.version>
@ -327,6 +328,10 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity6</artifactId>
@ -511,7 +516,7 @@
<systemPropertyVariables>
<logback.configurationFile>${basedir}/src/test/resources/logback-test.xml</logback.configurationFile>
</systemPropertyVariables>
<argLine>-Xmx512m -Dwebgoatport=${webgoat.port} -Dwebwolfport=${webwolf.port}</argLine>
<argLine>-Xmx512m -Dwebgoatport=${webgoat.port} -Dwebwolfport=${webwolf.port} -Dwebwolfcontext=${webwolf.context} -Dwebgoatcontext=${webgoat.context}</argLine>
<includes>org/owasp/webgoat/*Test</includes>
</configuration>
<executions>
@ -534,6 +539,7 @@
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
<configuration>
<forkedProcessTimeoutInSeconds>600</forkedProcessTimeoutInSeconds>
<argLine>--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 @@
<argument>-Dwebgoat.user.directory=${java.io.tmpdir}/webgoat_${webgoat.port}</argument>
<argument>-Dspring.main.banner-mode=off</argument>
<argument>-Dwebgoat.port=${webgoat.port}</argument>
<argument>-Dwebgoat.context=${webgoat.context}</argument>
<argument>-Dwebwolf.port=${webwolf.port}</argument>
<argument>-Dwebwolf.context=${webwolf.context}</argument>
<argument>--add-opens</argument>
<argument>java.base/java.lang=ALL-UNNAMED</argument>
<argument>--add-opens</argument>
@ -733,6 +741,7 @@
<argument>${project.build.directory}/webgoat-${project.version}.jar</argument>
</arguments>
<waitForInterrupt>false</waitForInterrupt>
<waitAfterLaunch>120</waitAfterLaunch>
<healthcheckUrl>http://localhost:${webgoat.port}/WebGoat/actuator/health</healthcheckUrl>
</configuration>
</execution>

View File

@ -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

View File

@ -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);
}
}

View File

@ -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<String, Object> 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()

View File

@ -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);
}
}

View File

@ -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<String, Object> 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);
}
}

View File

@ -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/");
}

View File

@ -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<String, Object> 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<String, Object> 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/");
}
}

View File

@ -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<DynamicTest> 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<String, Object> 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<String, Object> 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()

View File

@ -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());
}

View File

@ -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);
}
}

View File

@ -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)

View File

@ -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"),

View File

@ -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<? extends Callable<Response>> flagCalls =

View File

@ -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/");
}

View File

@ -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() {

View File

@ -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/");
}

View File

@ -34,44 +34,44 @@ public class SqlInjectionLessonIntegrationTest extends IntegrationTest {
Map<String, Object> 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/");
}

View File

@ -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();
}

View File

@ -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<String, Object> 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");
}

View File

@ -14,7 +14,7 @@ public class XSSIntegrationTest extends IntegrationTest {
Map<String, Object> 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", "<script>alert('XSS+Test')</script>");
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 {
+ "</table>"
+ "</body>"
+ "</html>");
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");
}

View File

@ -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,
"<comment><text>" + getSecret() + "</text></comment>",
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,
"<comment><text>" + getSecret() + "</text></comment>",
true);

View File

@ -242,6 +242,7 @@ public class MvcConfiguration implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeChangeInterceptor());
registry.addInterceptor(new UserInterceptor());
}
@Bean

View File

@ -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
}
}

View File

@ -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

View File

@ -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();

View File

@ -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

View File

@ -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;
}
/**

View File

@ -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";
}
}

View File

@ -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);

View File

@ -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");

View File

@ -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) {

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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

View File

@ -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

View File

@ -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<Email> emails = mailboxRepository.findByRecipientOrderByTimeDesc(user.getUsername());
List<Email> 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;
}

View File

@ -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;
}

View File

@ -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<HttpExchange> traces = EvictingQueue.create(10000);
@ -46,7 +44,6 @@ public class WebWolfTraceRepository implements HttpExchangeRepository {
"/home",
"/files",
"/images/",
"/favicon.ico",
"/js/",
"/webjars/",
"/requests",

View File

@ -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}

View File

@ -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}

View File

@ -23,7 +23,7 @@
<form class="attack-form" accept-charset="UNKNOWN" id="verify-account-form"
method="POST" name="form"
successCallback="onBypassResponse"
action="/WebGoat/auth-bypass/verify-account">
action="auth-bypass/verify-account">
<p>Verify Your Account by answering the questions below:</p>
<p>What is the name of your favorite teacher?</p>
@ -43,7 +43,7 @@
<form class="attack-form" accept-charset="UNKNOWN" id="change-password-form"
method="POST" name="form"
successCallback="onBypassResponse"
action="/WebGoat/auth-bypass/verify-account"
action="auth-bypass/verify-account"
style="display:none"><!-- start off hidden -->
<p>Please provide a new password for your account</p>

View File

@ -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);
}

View File

@ -18,7 +18,7 @@
<div class="container-fluid">
<form class="attack-form" accept-charset="UNKNOWN" name="fieldRestrictions"
method="POST"
action="/WebGoat/BypassRestrictions/FieldRestrictions">
action="BypassRestrictions/FieldRestrictions">
<div class="bypass-input-container"><b>Select field with two possible value</b>
<div class="input-group">
@ -66,7 +66,7 @@
<form class="attack-form" accept-charset="UNKNOWN" name="frontendValidation"
id="frontendValidation"
method="POST"
action="/WebGoat/BypassRestrictions/frontendValidation"
action="BypassRestrictions/frontendValidation"
onsubmit="return validate()">
<div>
<strong>Field 1:</strong> exactly three lowercase characters(^[a-z]{3}$)

View File

@ -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

View File

@ -17,7 +17,7 @@
<div class="panel-body">
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/challenge/1"
action="challenge/1"
style="width: 200px;">
<div class="form-group">
@ -37,7 +37,7 @@
</div>
</div>
<form class="attack-form" method="POST" name="form" action="/WebGoat/challenge/flag">
<form class="attack-form" method="POST" name="form" action="challenge/flag">
<div class="form-group">
<div class="input-group">
<div class="input-group-addon"><i class="fa fa-flag-checkered" aria-hidden="true"

View File

@ -25,7 +25,7 @@
<div class="col-lg-12">
<form id="login-form" class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/challenge/5" role="form">
action="challenge/5" role="form">
<div class="form-group">
<input type="text" name="username_login" id="username4" tabindex="1"
class="form-control" placeholder="Username" value=""/>
@ -66,7 +66,7 @@
</div>
</div>
<br/>
<form class="attack-form" method="POST" name="form" action="/WebGoat/challenge/flag">
<form class="attack-form" method="POST" name="form" action="challenge/flag">
<div class="form-group">
<div class="input-group">
<div class="input-group-addon"><i class="fa fa-flag-checkered" aria-hidden="true"

View File

@ -29,7 +29,7 @@
<div class="col-lg-12">
<form id="login-form" class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/challenge/6" role="form">
action="challenge/6" role="form">
<div class="form-group">
<input type="text" name="username_login" id="username4" tabindex="1"
class="form-control" placeholder="Username" value=""/>
@ -64,7 +64,7 @@
</form>
<form id="register-form" class="attack-form" accept-charset="UNKNOWN"
method="PUT" name="form"
action="/WebGoat/challenge/6" style="display: none;" role="form">
action="challenge/6" style="display: none;" role="form">
<div class="form-group">
<input type="text" name="username_reg" id="username" tabindex="1"
class="form-control" placeholder="Username" value=""/>
@ -99,7 +99,7 @@
</div>
</div>
<br/>
<form class="attack-form" method="POST" name="form" action="/WebGoat/challenge/flag">
<form class="attack-form" method="POST" name="form" action="challenge/flag">
<div class="form-group">
<div class="input-group">
<div class="input-group-addon"><i class="fa fa-flag-checkered" aria-hidden="true"

View File

@ -28,7 +28,7 @@ f94008f801fceb8833a30fe56a8b26976347edcf First version of WebGoat Cloud website
<form id="login-form" class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/challenge/7" role="form">
action="challenge/7" role="form">
<div class="form-group">
<div class="input-group">
@ -43,7 +43,7 @@ f94008f801fceb8833a30fe56a8b26976347edcf First version of WebGoat Cloud website
value="Reset Password" type="submit"/>
</div>
<div class="form-group">
<p>(c) 2017 WebGoat Cloud Platform</p>
<p>(c) 2023 WebGoat Cloud Platform</p>
</div>
<input type="hidden" class="hide" name="token" id="token" value=""/>
@ -57,7 +57,7 @@ f94008f801fceb8833a30fe56a8b26976347edcf First version of WebGoat Cloud website
</div>
</div>
<br/>
<form class="attack-form" method="POST" name="form" action="/WebGoat/challenge/flag">
<form class="attack-form" method="POST" name="form" action="challenge/flag">
<div class="form-group">
<div class="input-group">
<div class="input-group-addon"><i class="fa fa-flag-checkered" aria-hidden="true"

View File

@ -231,7 +231,7 @@
</div>
<br/>
<form class="attack-form" method="POST" name="form" action="/WebGoat/challenge/flag">
<form class="attack-form" method="POST" name="form" action="challenge/flag">
<div class="form-group">
<div class="input-group">
<div class="input-group-addon"><i class="fa fa-flag-checkered" aria-hidden="true"

View File

@ -24,7 +24,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="DOMFollowUp"
action="/WebGoat/ChromeDevTools/dummy">
action="ChromeDevTools/dummy">
<input name="successMessage" value="" type="TEXT" />
<input name="submitMessage" value="Submit" type="SUBMIT"/>
</form>
@ -45,7 +45,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/ChromeDevTools/network">
action="ChromeDevTools/network">
<script>
// sample custom javascript in the recommended way ...
// a namespace has been assigned for it, but you can roll your own if you prefer
@ -66,7 +66,7 @@
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/ChromeDevTools/network">
action="ChromeDevTools/network">
<table>
<tr>
<td>What is the number you found: </td>

View File

@ -14,7 +14,7 @@
<input type="hidden" id="user_id" value="102"/>
<!-- using attack-form class on your form, will allow your request to be ajaxified and stay within the display framework for webgoat -->
<form class="attack-form" accept-charset="UNKNOWN" method="POST" name="form"
action="/WebGoat/clientSideFiltering/attack1">
action="clientSideFiltering/attack1">
<link rel="stylesheet" type="text/css"
th:href="@{/lesson_css/clientSideFiltering-stage1.css}"/>
<script th:src="@{/lesson_js/clientSideFiltering.js}"
@ -83,7 +83,7 @@
<div class="container-fluid">
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/clientSideFiltering/getItForFree">
action="clientSideFiltering/getItForFree">
<input id="discount" type="hidden" value="0"/>
<div class="row">

View File

@ -7,10 +7,10 @@
* JavaScript to load initial assignment tokens
*/
function initialise() {
$("#sha256token").load('/WebGoat/crypto/hashing/sha256');
$("#md5token").load('/WebGoat/crypto/hashing/md5');
$("#basicauthtoken").load('/WebGoat/crypto/encoding/basic');
$("#privatekey").load('/WebGoat/crypto/signing/getprivate');
$("#sha256token").load('crypto/hashing/sha256');
$("#md5token").load('crypto/hashing/md5');
$("#basicauthtoken").load('crypto/encoding/basic');
$("#privatekey").load('crypto/signing/getprivate');
}
$(document).ready(initialise);
</script>
@ -28,7 +28,7 @@ $(document).ready(initialise);
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
Now suppose you have intercepted the following header:<br/>
<div id="basicauthtoken" ></div><br/>
<form class="attack-form" method="POST" name="form" action="/WebGoat/crypto/encoding/basic-auth">
<form class="attack-form" method="POST" name="form" action="crypto/encoding/basic-auth">
Then what was the username
<input name="answer_user" value="" type="TEXT"/>
and what was the password:
@ -45,7 +45,7 @@ $(document).ready(initialise);
<!-- 3. assignment xor -->
<div class="attack-container">
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" method="POST" name="form" action="/WebGoat/crypto/encoding/xor">
<form class="attack-form" method="POST" name="form" action="crypto/encoding/xor">
Suppose you found the database password encoded as {xor}Oz4rPj0+LDovPiwsKDAtOw==<br/>
What would be the actual password
<input name="answer_pwd1" value="" type="TEXT"/><br/>
@ -62,7 +62,7 @@ $(document).ready(initialise);
<!-- 4. weak hashing exercise -->
<div class="attack-container">
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" method="POST" name="form" action="/WebGoat/crypto/hashing">
<form class="attack-form" method="POST" name="form" action="crypto/hashing">
Which password belongs to this hash: <div id="md5token" ></div>
<input name="answer_pwd1" value="" type="TEXT"/><br/>
Which password belongs to this hash: <div id="sha256token" ></div>
@ -87,7 +87,7 @@ $(document).ready(initialise);
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
Now suppose you have the following private key:<br/>
<pre><div id="privatekey" ></div></pre><br/>
<form class="attack-form" method="POST" name="form" action="/WebGoat/crypto/signing/verify">
<form class="attack-form" method="POST" name="form" action="crypto/signing/verify">
Then what was the modulus of the public key
<input name="modulus" value="" type="TEXT"/>
and now provide a signature for us based on that modulus
@ -110,7 +110,7 @@ $(document).ready(initialise);
<!-- 8. assignment -->
<div class="attack-container">
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" method="POST" name="form" action="/WebGoat/crypto/secure/defaults">
<form class="attack-form" method="POST" name="form" action="crypto/secure/defaults">
What is the unencrypted message<br/>
<input name="secretText" value="" type="TEXT"/><br/>
and what is the name of the file that stored the password <br/>

View File

@ -17,7 +17,7 @@
method="POST" name="form1"
target="_blank"
successCallback=""
action="/WebGoat/csrf/basic-get-flag">
action="csrf/basic-get-flag">
<input name="csrf" type="hidden" value="false"/>
<input type="submit" name="submit"/>
@ -35,7 +35,7 @@
<form class="attack-form" accept-charset="UNKNOWN" id="confirm-flag-1"
method="POST" name="form2"
successCallback=""
action="/WebGoat/csrf/confirm-flag-1">
action="csrf/confirm-flag-1">
Confirm Flag Value:
<input type="text" length="6" name="confirmFlagVal" value=""/>
@ -93,7 +93,7 @@
<form class="attack-form" accept-charset="UNKNOWN" id="csrf-review"
method="POST" name="review-form"
successCallback=""
action="/WebGoat/csrf/review">
action="csrf/review">
<input class="form-control" id="reviewText" name="reviewText" placeholder="Add a Review"
type="text"/>
<input class="form-control" id="reviewStars" name="stars" type="text"/>
@ -146,7 +146,7 @@
<form class="attack-form" accept-charset="UNKNOWN" id="csrf-feedback"
method="POST"
prepareData="feedback"
action="/WebGoat/csrf/feedback/message"
action="csrf/feedback/message"
contentType="application/json">
<div class="row">
<div class="col-md-6">
@ -212,7 +212,7 @@
</div>
<form class="attack-form" accept-charset="UNKNOWN" id="confirm-flag-feedback"
method="POST" name="form2"
action="/WebGoat/csrf/feedback">
action="csrf/feedback">
Confirm Flag Value:
<input type="text" length="6" name="confirmFlagVal" value=""/>
@ -236,7 +236,7 @@
</div>
<form class="attack-form" accept-charset="UNKNOWN" id="confirm-flag-login"
method="POST" name="form2"
action="/WebGoat/csrf/login">
action="csrf/login">
Press the button below when your are logged in as the other user<br/>

View File

@ -25,7 +25,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN" name="task"
method="POST"
action="/WebGoat/InsecureDeserialization/task">
action="InsecureDeserialization/task">
<input type="textarea" rows="4" cols="40" value="" name="token" placeholder="token"/>
<input type="submit" value="Submit" />

View File

@ -1,7 +1,7 @@
<div class="row">
<div class="col-md-4">
<form class="attack-form" accept-charset="UNKNOWN" method="POST"
action="/WebGoat/HijackSession/login">
action="HijackSession/login">
<div style="padding: 20px;" id="password-login">
<h4 style="border-bottom: 1px solid #c5c5c5;">Account Access</h4>
<fieldset>

View File

@ -13,7 +13,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN" id="task" name="task"
method="POST"
action="/WebGoat/HtmlTampering/task">
action="HtmlTampering/task">
<script>
var regex = /^2999.99$/;
var price = 2999.99;

View File

@ -21,7 +21,7 @@
<!-- of course, you can write your own ajax submission /handling in your own javascript if you like -->
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/HttpBasics/attack1">
action="HttpBasics/attack1">
<div id="lessonContent">
<form accept-charset="UNKNOWN" method="POST" name="form"
action="#attack/307/100">
@ -51,7 +51,7 @@
<!-- of course, you can write your own ajax submission /handling in your own javascript if you like -->
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/HttpBasics/attack2">
action="HttpBasics/attack2">
<script>
// sample custom javascript in the recommended way ...
// a namespace has been assigned for it, but you can roll your own if you prefer

View File

@ -24,7 +24,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN" name="intercept-request"
method="POST"
action="/WebGoat/HttpProxies/intercept-request">
action="HttpProxies/intercept-request">
<input type="text" value="doesn't matter really" name="changeMe" />
<input type="submit" value="Submit" />

View File

@ -22,7 +22,7 @@
<!-- modify the action to point to the intended endpoint -->
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/IDOR/login">
action="IDOR/login">
<table>
<tr>
<td>user/pass</td>
@ -57,7 +57,7 @@
<!-- modify the action to point to the intended endpoint -->
<form class="attack-form" accept-charset="UNKNOWN"
method="GET" name="form"
action="/WebGoat/IDOR/profile">
action="IDOR/profile">
<script th:src="@{/lesson_js/idor.js}" />
<input name="View Profile" value="View Profile" type="button" onclick="onViewProfile();" />
@ -107,7 +107,7 @@
<!-- modify the action to point to the intended endpoint -->
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/IDOR/profile/alt-path">
action="IDOR/profile/alt-path">
<div class="adoc-content" th:replace="~{doc:lessons/idor/documentation/IDOR_inputAltPath.adoc}"></div>
<input name="url" value="WebGoat/" type="text"/>
<input name="submit" value="Submit" type="SUBMIT"/>
@ -134,7 +134,7 @@
<!-- modify the action to point to the intended endpoint -->
<form class="attack-form" accept-charset="UNKNOWN" id="view-other"
method="GET" name="view-other-profile"
action="/WebGoat/IDOR/profile/{userId}">
action="IDOR/profile/{userId}">
<script th:src="@{/lesson_js/idor.js}" />
<input name="View Profile" value="View Profile" type="submit" />
@ -158,7 +158,7 @@
<!-- modify the action to point to the intended endpoint -->
<form class="attack-form" accept-charset="UNKNOWN" id="edit-other"
method="GET" name="edit-other-profile"
action="/WebGoat/IDOR/profile/{userId}">
action="IDOR/profile/{userId}">
<script th:src="@{/lesson_js/idor.js}" />
<input name="View Profile" value="View Profile" type="submit" />

View File

@ -12,7 +12,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);
}

View File

@ -17,7 +17,7 @@
<script th:src="@{/lesson_js/credentials.js}"></script>
<form class="attack-form" accept-charset="UNKNOWN" name="task"
method="POST"
action="/WebGoat/InsecureLogin/task">
action="InsecureLogin/task">
<button onclick="javascript:submit_secret_credentials();return false;">Log in</button>
@ -25,7 +25,7 @@
<br></br>
<form class="attack-form" accept-charset="UNKNOWN" name="task"
method="POST"
action="/WebGoat/InsecureLogin/task">
action="InsecureLogin/task">
<input type="text" value="" name="username" placeholder="username"/>
<input type="password" value="" name="password" placeholder="password" />

View File

@ -17,7 +17,7 @@
<div class="adoc-content" th:replace="~{doc:lessons/jwt/documentation/JWT_decode.adoc}"></div>
<div class="attack-container">
<img th:src="@{/images/wolf-enabled.png}" class="webwolf-enabled"/>
<form id="decode" class="attack-form" method="POST" name="form" action="/WebGoat/JWT/decode">
<form id="decode" class="attack-form" method="POST" name="form" action="JWT/decode">
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<br>
<div class="row">
@ -53,7 +53,7 @@
<form class="attack-form" accept-charset="UNKNOWN"
method="POST"
successCallback="jwtSigningCallback"
action="/WebGoat/JWT/votings">
action="JWT/votings">
<div class="container-fluid">
<div class="row">
@ -124,7 +124,7 @@
<div class="container-fluid">
<form id="quiz-form" class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/JWT/quiz"
action="JWT/quiz"
role="form">
<div id="q_container"></div>
<br/>
@ -155,7 +155,7 @@
<div class="attack-container">
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" method="POST" name="form" action="/WebGoat/JWT/secret">
<form class="attack-form" method="POST" name="form" action="JWT/secret">
<div class="form-group">
<div class="input-group">
<div class="input-group-addon"><i class="fa fa-flag-checkered" aria-hidden="true"
@ -192,7 +192,7 @@
<form class="attack-form" accept-charset="UNKNOWN"
method="POST"
additionalHeaders="addBearerToken"
action="/WebGoat/JWT/refresh/checkout">
action="JWT/refresh/checkout">
<div class="container-fluid">
<div class="row">
<div class="col-sm-12 col-md-10 col-md-offset-1">
@ -319,7 +319,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST"
action="/WebGoat/JWT/final/delete?token=eyJ0eXAiOiJKV1QiLCJqa3UiOiJodHRwczovL2NvZ25pdG8taWRwLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tL3dlYmdvYXQvLndlbGwta25vd24vandrcy5qc29uIiwiYWxnIjoiUlMyNTYifQ.eyJpc3MiOiJXZWJHb2F0IFRva2VuIEJ1aWxkZXIiLCJpYXQiOjE1MjQyMTA5MDQsImV4cCI6MTYxODkwNTMwNCwiYXVkIjoid2ViZ29hdC5vcmciLCJzdWIiOiJqZXJyeUB3ZWJnb2F0LmNvbSIsInVzZXJuYW1lIjoiSmVycnkiLCJFbWFpbCI6ImplcnJ5QHdlYmdvYXQuY29tIiwiUm9sZSI6WyJDYXQiXX0.SabvRaYSCW7xI0ueca19TL1e66cJIJaxRiydK2G5lgFMIbL5gQQjE6022HEha9HcprqFXyHbtXrQWRXAp6Gjaf5zs8LUMBMARWjEr8TS43ihguarmLLmvBCoqjiZY39o4EcEjEH9xAoyIYR_Trh7kXn6JVU-8MM76l9IOcYIJ9c8LqT1ERNmbCqtI4PP0tdqCy99nHhqlxSCVXaGDF0jMHV5kjCDSHNYib9riy9xZ63Sztify-bwPqRvxmaShPYtG4BBM_wOGlg-BYTTuws-6yISMfTB5U1WBDwLr6dLU123TGO26wCVBgTKbA0KKG94-ToOcneWLOTEacEfQQOlIQ">
action="JWT/final/delete?token=eyJ0eXAiOiJKV1QiLCJqa3UiOiJodHRwczovL2NvZ25pdG8taWRwLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tL3dlYmdvYXQvLndlbGwta25vd24vandrcy5qc29uIiwiYWxnIjoiUlMyNTYifQ.eyJpc3MiOiJXZWJHb2F0IFRva2VuIEJ1aWxkZXIiLCJpYXQiOjE1MjQyMTA5MDQsImV4cCI6MTYxODkwNTMwNCwiYXVkIjoid2ViZ29hdC5vcmciLCJzdWIiOiJqZXJyeUB3ZWJnb2F0LmNvbSIsInVzZXJuYW1lIjoiSmVycnkiLCJFbWFpbCI6ImplcnJ5QHdlYmdvYXQuY29tIiwiUm9sZSI6WyJDYXQiXX0.SabvRaYSCW7xI0ueca19TL1e66cJIJaxRiydK2G5lgFMIbL5gQQjE6022HEha9HcprqFXyHbtXrQWRXAp6Gjaf5zs8LUMBMARWjEr8TS43ihguarmLLmvBCoqjiZY39o4EcEjEH9xAoyIYR_Trh7kXn6JVU-8MM76l9IOcYIJ9c8LqT1ERNmbCqtI4PP0tdqCy99nHhqlxSCVXaGDF0jMHV5kjCDSHNYib9riy9xZ63Sztify-bwPqRvxmaShPYtG4BBM_wOGlg-BYTTuws-6yISMfTB5U1WBDwLr6dLU123TGO26wCVBgTKbA0KKG94-ToOcneWLOTEacEfQQOlIQ">
<div class="container-fluid">
<div id="toast"></div>
<div class="col-sm-6 col-md-4 col-lg-3 mt-4">
@ -385,7 +385,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST"
action="/WebGoat/JWT/kid/delete?token=eyJ0eXAiOiJKV1QiLCJraWQiOiJ3ZWJnb2F0X2tleSIsImFsZyI6IkhTMjU2In0.eyJpc3MiOiJXZWJHb2F0IFRva2VuIEJ1aWxkZXIiLCJpYXQiOjE1MjQyMTA5MDQsImV4cCI6MTYxODkwNTMwNCwiYXVkIjoid2ViZ29hdC5vcmciLCJzdWIiOiJqZXJyeUB3ZWJnb2F0LmNvbSIsInVzZXJuYW1lIjoiSmVycnkiLCJFbWFpbCI6ImplcnJ5QHdlYmdvYXQuY29tIiwiUm9sZSI6WyJDYXQiXX0.CgZ27DzgVW8gzc0n6izOU638uUCi6UhiOJKYzoEZGE8">
action="JWT/kid/delete?token=eyJ0eXAiOiJKV1QiLCJraWQiOiJ3ZWJnb2F0X2tleSIsImFsZyI6IkhTMjU2In0.eyJpc3MiOiJXZWJHb2F0IFRva2VuIEJ1aWxkZXIiLCJpYXQiOjE1MjQyMTA5MDQsImV4cCI6MTYxODkwNTMwNCwiYXVkIjoid2ViZ29hdC5vcmciLCJzdWIiOiJqZXJyeUB3ZWJnb2F0LmNvbSIsInVzZXJuYW1lIjoiSmVycnkiLCJFbWFpbCI6ImplcnJ5QHdlYmdvYXQuY29tIiwiUm9sZSI6WyJDYXQiXX0.CgZ27DzgVW8gzc0n6izOU638uUCi6UhiOJKYzoEZGE8">
<div class="container-fluid">
<div id="toast"></div>
<div class="col-sm-6 col-md-4 col-lg-3 mt-4">

View File

@ -1,5 +1,5 @@
$(document).ready(
function(){
$("#secrettoken").load('/WebGoat/JWT/secret/gettoken');
$("#secrettoken").load('JWT/secret/gettoken');
}
);

View File

@ -87,7 +87,7 @@ green when the user solves the assignment. To make this work we need to add to t
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/lesson-template/sample-attack">
action="lesson-template/sample-attack">
<table>
<tr>
<td>two random params</td>

View File

@ -47,7 +47,7 @@
<!-- modify the action to point to the intended endpoint and set other attributes as desired -->
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/lesson-template/sample-attack">
action="lesson-template/sample-attack">
<table>
<tr>
<td>two random params</td>

View File

@ -12,7 +12,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);
}

View File

@ -16,7 +16,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN" name="task"
method="POST"
action="/WebGoat/LogSpoofing/log-spoofing">
action="LogSpoofing/log-spoofing">
<input type="text" value="" name="username" placeholder="username"/>
<input type="password" value="" name="password" placeholder="password"/>
@ -38,7 +38,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN" name="task"
method="POST"
action="/WebGoat/LogSpoofing/log-bleeding">
action="LogSpoofing/log-bleeding">
<input type="text" value="" name="username" placeholder="username"/>
<input type="password" value="" name="password" placeholder="password"/>

View File

@ -53,7 +53,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/access-control/hidden-menu">
action="access-control/hidden-menu">
<p>Hidden item 1 <input name="hiddenMenu1" value="" type="TEXT"/></p>
<p>Hidden item 2 <input name="hiddenMenu2" value="" type="TEXT"/></p>
@ -76,7 +76,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/access-control/user-hash">
action="access-control/user-hash">
<p>Your Hash: <input name="userHash" value="" type="TEXT"/></p>
<br/>
@ -98,7 +98,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/access-control/user-hash-fix">
action="access-control/user-hash-fix">
<p>Your Hash: <input name="userHash" value="" type="TEXT"/></p>
<br/>

View File

@ -23,7 +23,7 @@
<form class="attack-form" accept-charset="UNKNOWN" novalidate="novalidate"
method="POST"
action="/WebGoat/PasswordReset/simple-mail/reset">
action="PasswordReset/simple-mail/reset">
<div style="display: none;" id="password-reset-2">
<h4 class="">Forgot your password?</h4>
@ -31,7 +31,7 @@
<span class="help-block">Please type your e-mail address</span>
<div class="form-group input-group">
<span class="input-group-addon">@</span>
<input class="form-control" placeholder="test1233@webgoat.org" name="emailReset"
<input class="form-control" th:attr="placeholder=${username + '@webgoat.org'}" name="emailReset"
type="email"/>
</div>
<button type="submit" class="btn btn-primary btn-block" id="btn-olvidado">Continue
@ -47,7 +47,7 @@
</form>
<form class="attack-form" accept-charset="UNKNOWN" novalidate="novalidate"
method="POST"
action="/WebGoat/PasswordReset/simple-mail">
action="PasswordReset/simple-mail">
<div style="padding: 20px;" id="password-login-2">
<h4 style="border-bottom: 1px solid #c5c5c5;"><i class="glyphicon glyphicon-user"></i>
Account
@ -103,7 +103,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST"
action="/WebGoat/PasswordReset/questions">
action="PasswordReset/questions">
<div class="container-fluid">
<div class="col-md-4">
<article class="card-body">
@ -143,7 +143,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/PasswordReset/SecurityQuestions">
action="PasswordReset/SecurityQuestions">
<select name="question">
<option>What is your favorite animal?</option>
<option>In what year was your mother born?</option>
@ -175,7 +175,7 @@
<form class="attack-form" accept-charset="UNKNOWN"
method="POST"
action="/WebGoat/PasswordReset/reset/login">
action="PasswordReset/reset/login">
<div class="container-fluid">
<div class="row">
<div class="col-md-4">
@ -186,7 +186,7 @@
<div style="padding: 20px;" id="password-login">
<form id="login-form" class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/PasswordReset/reset/login"
action="PasswordReset/reset/login"
role="form">
<fieldset>
<div class="form-group input-group">
@ -222,7 +222,7 @@
</h4>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/PasswordReset/ForgotPassword/create-password-reset-link"
action="PasswordReset/ForgotPassword/create-password-reset-link"
role="form">
<fieldset>
<span class="help-block">

View File

@ -9,7 +9,7 @@
<div class="container">
<div class="row">
<div class="col-xs-12 col-sm-8 col-md-6 col-sm-offset-2 col-md-offset-3">
<form role="form" method="POST" action="/WebGoat/PasswordReset/reset/change-password" th:object="${form}" novalidate="novalidate">
<form role="form" method="POST" action="PasswordReset/reset/change-password" th:object="${form}" novalidate="novalidate">
<h2 class="sign_up_title">Reset your password</h2>
<div class="form-group" th:classappend="${#fields.hasErrors('password')}? 'has-error'">
<input type="hidden" name="resetLink" th:field="*{resetLink}" />

View File

@ -22,7 +22,7 @@
informationalCallback="profileUploadCallback"
prepareData="profileUpload"
enctype="multipart/form-data"
action="/WebGoat/PathTraversal/profile-upload">
action="PathTraversal/profile-upload">
<div class="preview text-center">
<img class="preview-img" th:src="@{/images/account.png}" alt="Preview Image" width="200"
height="200" id="preview"/>
@ -76,7 +76,7 @@
informationalCallback="profileUploadCallbackFix"
prepareData="profileUploadFix"
enctype="multipart/form-data"
action="/WebGoat/PathTraversal/profile-upload-fix">
action="PathTraversal/profile-upload-fix">
<div class="preview text-center">
<img class="preview-img" th:src="@{/images/account.png}" alt="Preview Image" width="200"
height="200" id="previewFix"/>
@ -131,7 +131,7 @@
informationalCallback="profileUploadCallbackRemoveUserInput"
prepareData="profileUploadRemoveUserInput"
enctype="multipart/form-data"
action="/WebGoat/PathTraversal/profile-upload-remove-user-input">
action="PathTraversal/profile-upload-remove-user-input">
<div class="preview text-center">
<img class="preview-img" th:src="@{/images/account.png}" alt="Preview Image" width="200"
height="200" id="previewRemoveUserInput"/>
@ -189,7 +189,7 @@
<br/>
<form class="attack-form" method="POST" name="form" action="/WebGoat/PathTraversal/random">
<form class="attack-form" method="POST" name="form" action="PathTraversal/random">
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<div class="form-group">
<div class="input-group">
@ -227,7 +227,7 @@
prepareData="profileZipSlip"
enctype="multipart/form-data"
action="/WebGoat/PathTraversal/zip-slip">
action="PathTraversal/zip-slip">
<div class="preview text-center">
<img class="preview-img" th:src="@{/images/account.png}" alt="Preview Image" width="200"
height="200" id="previewZipSlip"/>

View File

@ -20,7 +20,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/SecurePasswords/assignment"
action="SecurePasswords/assignment"
autocomplete="off">
<div class="input-group input-group">

View File

@ -1,7 +1,7 @@
<div class="row">
<div class="col-md-4">
<form class="attack-form" accept-charset="UNKNOWN" method="POST"
action="/WebGoat/SpoofCookie/login">
action="SpoofCookie/login">
<div style="padding: 20px;" id="password-login">
<h4 style="border-bottom: 1px solid #c5c5c5;">Account Access</h4>
<fieldset>

View File

@ -15,7 +15,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/SqlInjection/attack2"
action="SqlInjection/attack2"
autocomplete="off">
<table>
<tr>
@ -39,7 +39,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/SqlInjection/attack3"
action="SqlInjection/attack3"
autocomplete="off">
<table>
<tr>
@ -63,7 +63,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/SqlInjection/attack4"
action="SqlInjection/attack4"
autocomplete="off">
<table>
<tr>
@ -87,7 +87,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/SqlInjection/attack5"
action="SqlInjection/attack5"
autocomplete="off">
<table>
<tr>
@ -143,7 +143,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/SqlInjection/assignment5a">
action="SqlInjection/assignment5a">
<table>
<tr>
<td>SELECT * FROM user_data WHERE first_name = 'John' AND last_name = '</td>
@ -188,7 +188,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/SqlInjection/assignment5b">
action="SqlInjection/assignment5b">
<table>
<tr>
<td>Login_Count:</td>
@ -216,7 +216,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/SqlInjection/attack8"
action="SqlInjection/attack8"
autocomplete="off">
<table>
<tr>
@ -244,7 +244,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/SqlInjection/attack9"
action="SqlInjection/attack9"
autocomplete="off">
<table>
<tr>
@ -273,7 +273,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/SqlInjection/attack10"
action="SqlInjection/attack10"
autocomplete="off">
<table>
<tr>

View File

@ -20,7 +20,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/SqlInjectionAdvanced/attack6a">
action="SqlInjectionAdvanced/attack6a">
<table>
<tr>
<td>Name:</td>
@ -33,7 +33,7 @@
</form>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/SqlInjectionAdvanced/attack6b">
action="SqlInjectionAdvanced/attack6b">
<table>
<tr>
<td>Password:</td>
@ -79,7 +79,7 @@
<div class="col-lg-12">
<form id="login-form" class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/SqlInjectionAdvanced/challenge_Login"
action="SqlInjectionAdvanced/challenge_Login"
role="form">
<div class="form-group">
<input type="text" name="username_login" id="username4" tabindex="1"
@ -115,7 +115,7 @@
</form>
<form id="register-form" class="attack-form" accept-charset="UNKNOWN"
method="PUT" name="form"
action="/WebGoat/SqlInjectionAdvanced/challenge"
action="SqlInjectionAdvanced/challenge"
style="display: none;" role="form">
<div class="form-group">
<input type="text" name="username_reg" id="username" tabindex="1"
@ -168,7 +168,7 @@
<div class="container-fluid">
<form id="quiz-form" class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/SqlInjectionAdvanced/quiz"
action="SqlInjectionAdvanced/quiz"
role="form">
<div id="q_container"></div>
<br />

View File

@ -23,7 +23,7 @@
<div class="adoc-content" th:replace="~{doc:lessons/sqlinjection/documentation/SqlInjection_jdbc_completion.adoc}"></div>
<div class="attack-container">
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN" method="POST" name="form" action="/WebGoat/SqlInjectionMitigations/attack10a">
<form class="attack-form" accept-charset="UNKNOWN" method="POST" name="form" action="SqlInjectionMitigations/attack10a">
<div>
<p>Connection conn = DriverManager.<input type="text" name="field1" id="field1" />(DBURL, DBUSER, DBPW);</p>
<p><input type="text" name="field2" id="field2" /> = conn.<input type="text" name="field3" id="field3" />("SELECT status FROM users WHERE name=<input type="text" name="field4" id="field4" /> AND mail=<input type="text" name="field5" id="field5" />");</p>
@ -42,7 +42,7 @@
<div class="lesson-page-wrapper">
<div class="adoc-content" th:replace="~{doc:lessons/sqlinjection/documentation/SqlInjection_jdbc_newcode.adoc}"></div>
<div class="attack-container" style="border: none !important; height: 100%; min-height: 300px;">
<form id="codesubmit" style="height: 100%; min-height: 300px;" class="attack-form" accept-charset="UNKNOWN" method="POST" name="form" action="/WebGoat/SqlInjectionMitigations/attack10b">
<form id="codesubmit" style="height: 100%; min-height: 300px;" class="attack-form" accept-charset="UNKNOWN" method="POST" name="form" action="SqlInjectionMitigations/attack10b">
<div>
<div id="editor" style="position: absolute; top: 0; right: 0; bottom: 0; left: 0; height: 300px;" name="editor"></div>
<script th:src="@{/js/libs/ace.js}" type="text/javascript" charset="utf-8"></script>
@ -72,7 +72,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/SqlOnlyInputValidation/attack"
action="SqlOnlyInputValidation/attack"
enctype="application/json;charset=UTF-8">
<table>
<tr>
@ -95,7 +95,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/SqlOnlyInputValidationOnKeywords/attack"
action="SqlOnlyInputValidationOnKeywords/attack"
enctype="application/json;charset=UTF-8">
<table>
<tr>
@ -124,7 +124,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/SqlInjectionMitigations/attack12a">
action="SqlInjectionMitigations/attack12a">
<div class="container-fluid">
<div class="row">
<div class="panel panel-primary">
@ -173,7 +173,7 @@
<br/>
</div>
</form>
<form class="attack-form" method="POST" name="form" action="/WebGoat/SqlInjectionMitigations/attack12a">
<form class="attack-form" method="POST" name="form" action="SqlInjectionMitigations/attack12a">
<div class="form-group">
<div class="input-group">
<div class="input-group-addon">IP address webgoat-prd server:</div>

View File

@ -12,7 +12,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/SSRF/task1">
action="SSRF/task1">
<table>
<tr>
<td><input type="hidden" id="url1" name="url" value="images/tom.png"/></td>
@ -34,7 +34,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/SSRF/task2">
action="SSRF/task2">
<table>
<tr>
<td><input type="hidden" id="url2" name="url" value="images/cat.png"/></td>

View File

@ -99,7 +99,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/VulnerableComponents/attack1">
action="VulnerableComponents/attack1">
<div id="lessonContent">
<form accept-charset="UNKNOWN" method="POST" name="form"
action="#attack/307/100">

View File

@ -18,7 +18,7 @@
<form class="attack-form" accept-charset="UNKNOWN" style="position:relative;top:150px"
method="POST" name="form"
action="/WebGoat/WebWolf/mail">
action="WebWolf/mail">
<div class="container-fluid">
<div class="row">
<div class="col-md-4">
@ -39,7 +39,7 @@
<!-- <div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>-->
<form class="attack-form" accept-charset="UNKNOWN" style="position:relative;top:-50px"
method="POST" name="secondform"
action="/WebGoat/WebWolf/mail/send">
action="WebWolf/mail/send">
<div class="container-fluid">
<div class="row">
<div class="col-md-4">
@ -47,7 +47,7 @@
<span class="input-group-addon">
@
</span>
<input class="form-control" placeholder="test1233@webgoat.org" name="email" type="email"
<input class="form-control" th:attr="placeholder=${username + '@webgoat.org'}" name="email" type="email"
required=""/>
</div>
<button type="submit" class="btn btn-primary btn-block" id="btn-login">
@ -70,13 +70,13 @@
<div class="attack-container">
<img th:src="@{/images/wolf-enabled.png}" class="webwolf-enabled"/>
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<a href="/WebGoat/WebWolf/landing/password-reset" target="_blank">Click here to reset your password</a>
<a href="WebWolf/landing/password-reset" target="_blank">Click here to reset your password</a>
<br/>
<br/>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/WebWolf/landing">
action="WebWolf/landing">
<div class="container-fluid">
<div class="row">
<div class="col-md-4">

View File

@ -9,7 +9,7 @@
<div class="container">
<div class="row">
<div class="col-xs-12 col-sm-8 col-md-6 col-sm-offset-2 col-md-offset-3">
<form role="form" method="GET" th:action="${webwolfUrl}">
<form role="form" method="GET" th:action="${webwolfLandingPageUrl}">
<h2 class="sign_up_title">Reset your password</h2>
<input type="hidden" name="uniqueCode" th:value="${uniqueCode}"/>
<div class="form-group">
@ -23,7 +23,7 @@
</div>
</div>
<div>
<a href="https://github.com/WebGoat">(c) 2017 WebGoat Company</a>
<a href="https://github.com/WebGoat">(c) 2023 WebGoat Company</a>
</div>
</form>
</div>

View File

@ -12,7 +12,7 @@
<div id="lessonContent">
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/CrossSiteScripting/attack1">
action="CrossSiteScripting/attack1">
<table>
<tr>
<td><input type="checkbox" name="checkboxAttack1"> The cookies are the same on each tab </td>
@ -46,7 +46,7 @@
<div id="lessonContent">
<form class="attack-form" accept-charset="UNKNOWN"
method="GET" name="xss-5a"
action="/WebGoat/CrossSiteScripting/attack5a">
action="CrossSiteScripting/attack5a">
<center>
<h4>Shopping Cart</h4>
</center>
@ -133,7 +133,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="DOMTestRoute"
action="/WebGoat/CrossSiteScripting/attack6a">
action="CrossSiteScripting/attack6a">
<input name="DOMTestRoute" value="" type="TEXT" />
<input name="SubmitTestRoute" value="Submit" type="SUBMIT"/>
</form>
@ -148,7 +148,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="DOMFollowUp"
action="/WebGoat/CrossSiteScripting/dom-follow-up">
action="CrossSiteScripting/dom-follow-up">
<input name="successMessage" value="" type="TEXT" />
<input name="submitMessage" value="Submit" type="SUBMIT"/>
</form>
@ -168,7 +168,7 @@
<div class="container-fluid">
<form id="quiz-form" class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/CrossSiteScripting/quiz" role="form">
action="CrossSiteScripting/quiz" role="form">
<div id="q_container"></div>
<br />
<input name="Quiz_solutions" value="Submit answers" type="SUBMIT"/>

View File

@ -21,7 +21,7 @@
<div class="lesson-page-wrapper">
<div class="adoc-content" th:replace="~{doc:lessons/xss/documentation/CrossSiteScripting_content8b.adoc}"></div>
<div class="attack-container" style="height: 100%; border: none !important;min-height: 450px;">
<form id="codesubmit" style="height: 100%; min-height: 350px;" class="attack-form" accept-charset="UNKNOWN" method="POST" name="form" action="/WebGoat/CrossSiteScripting/attack3">
<form id="codesubmit" style="height: 100%; min-height: 350px;" class="attack-form" accept-charset="UNKNOWN" method="POST" name="form" action="CrossSiteScripting/attack3">
<div>
<div id="editor" style="position: absolute; top: 0; right: 0; bottom: 0; left: 0; height: 350px;" name="editor"></div>
<script th:src="@{/js/libs/ace.js}" type="text/javascript" charset="utf-8"></script>
@ -41,7 +41,7 @@
<div class="lesson-page-wrapper">
<div class="adoc-content" th:replace="~{doc:lessons/xss/documentation/CrossSiteScripting_content8c.adoc}"></div>
<div class="attack-container" style="height: 100%; border: none !important;min-height: 450px;">
<form id="codesubmit2" style="height: 100%; min-height: 350px;" class="attack-form" accept-charset="UNKNOWN" method="POST" name="form" action="/WebGoat/CrossSiteScripting/attack4">
<form id="codesubmit2" style="height: 100%; min-height: 350px;" class="attack-form" accept-charset="UNKNOWN" method="POST" name="form" action="CrossSiteScripting/attack4">
<div>
<div id="editor2" style="position: absolute; top: 0; right: 0; bottom: 0; left: 0; height: 350px;" name="editor2"></div>
<script th:src="@{/js/libs/ace.js}" type="text/javascript" charset="utf-8"></script>

View File

@ -67,7 +67,7 @@
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="DOMFollowUp"
action="/WebGoat/CrossSiteScriptingStored/stored-xss-follow-up">
action="CrossSiteScriptingStored/stored-xss-follow-up">
<input name="successMessage" value="" type="TEXT" />
<input name="submitMessage" value="Submit" type="SUBMIT"/>
</form>

View File

@ -17,7 +17,7 @@ xss-reflected-6a-failure=Sorry that is not correct. Look at the example again to
xss-reflected-6a-hint-1=To search through the client side code, use the developer tools of your browser. (If you don't know how to use them, check the <i>Developer Tools</i> Lesson in the general category.)
xss-reflected-6a-hint-2=Since you are looking for application code, check the WebGoat/js/goatApp folder for a file that could handle the routes.
xss-reflected-6a-hint-3=Make sure you add the base route at the start, when submitting your solution.
xss-reflected-6a-hint-4=Still did not find it? Check the <a href="/WebGoat/js/goatApp/view/GoatRouter.js" target="_blank">GoatRouter.js</a> file. It should be pretty easy to determine.
xss-reflected-6a-hint-4=Still did not find it? Check the <a href="js/goatApp/view/GoatRouter.js" target="_blank">GoatRouter.js</a> file. It should be pretty easy to determine.
xss.lesson1.failure=The cookies should be the same on both tabs. Ensure that the tabs are from the same site.
xss-dom-message-success=Correct, I hope you did not cheat, using the console!
xss-dom-message-failure=Incorrect, keep trying. It should be obvious in the log when you are successful.

View File

@ -3,7 +3,7 @@ $(document).ready(function () {
var commentInput = $("#commentInput").val();
$.ajax({
type: 'POST',
url: '/WebGoat/CrossSiteScriptingStored/stored-xss',
url: 'CrossSiteScriptingStored/stored-xss',
data: JSON.stringify({text: commentInput}),
contentType: "application/json",
dataType: 'json'
@ -32,7 +32,7 @@ $(document).ready(function () {
function getChallenges() {
$("#list").empty();
$.get('/WebGoat/CrossSiteScriptingStored/stored-xss', function (result, status) {
$.get('CrossSiteScriptingStored/stored-xss', function (result, status) {
for (var i = 0; i < result.length; i++) {
var comment = html.replace('USER', result[i].user);
comment = comment.replace('DATETIME', result[i].dateTime);

View File

@ -28,7 +28,7 @@
successCallback="simpleXXECallback"
failureCallback="simpleXXECallback"
contentType="application/xml"
action="/WebGoat/xxe/simple">
action="xxe/simple">
<div class="container-fluid">
<div class="panel post">
<div class="post-heading">
@ -166,7 +166,7 @@
prepareData="blindXXE"
successCallback="blindXXECallback"
failureCallback="blindXXECallback"
action="/WebGoat/xxe/blind"
action="xxe/blind"
contentType="application/xml">
<div class="container-fluid">
<div class="panel post">
@ -221,7 +221,7 @@
<div class="lesson-page-wrapper">
<div class="adoc-content" th:replace="~{doc:lessons/xxe/documentation/XXE_static_code_analysis.adoc}"></div>
<br/>
<a id="submitlink" class="btn btn-primary" href="" onclick="javascript:$('#patchbutton').load('/WebGoat/service/enable-security.mvc');return false;"><span id="patchbutton">Apply XXE security patch</span></a>
<a id="submitlink" class="btn btn-primary" href="" onclick="javascript:$('#patchbutton').load('service/enable-security.mvc');return false;"><span id="patchbutton">Apply XXE security patch</span></a>
</div>
</body>

View File

@ -7,7 +7,7 @@ define(['jquery',
Backbone,
FlagModel) {
return Backbone.Collection.extend({
url:'/WebGoat/scoreboard-data',
url:'scoreboard-data',
model:FlagModel
});
});

View File

@ -3,7 +3,7 @@
define(['jquery','underscore','backbone'], function($,_,Backbone) {
var menuData = Backbone.Model.extend({
urlRoot:'/webgoat/service/lessonmenu.mvc',
urlRoot:'service/lessonmenu.mvc',
defaults: {
items:null,
selectedItem:null

View File

@ -1,17 +1,16 @@
define(['jquery',
'underscore',
'backbone',
define(['underscore',
'goatApp/support/goatAsyncErrorHandler',
'goatApp/view/ScoreboardView'],
function ($,
function (
_,
Backbone,
asyncErrorHandler,
ScoreboardView) {
'use strict'
return {
initApp: function () {
scoreboard = new ScoreboardView();
class ScoreboardApp {
initApp() {
asyncErrorHandler.init();
this.scoreboard = new ScoreboardView();
}
};
}
return new ScoreboardApp();
});

View File

@ -5,7 +5,7 @@
*/
define(['jquery',
'libs/jquery-vuln',
'jqueryvuln',
'jqueryuivuln',
'underscore',
'backbone',
@ -66,7 +66,7 @@ define(['jquery',
console.log('phoneHome invoked');
webgoat.customjs.jquery.ajax({
method: "POST",
url: "/WebGoat/CrossSiteScripting/phone-home-xss",
url: "CrossSiteScripting/phone-home-xss",
data: {param1: 42, param2: 24},
headers: {
"webgoat-requested-by": "dom-xss-vuln"

View File

@ -53,7 +53,7 @@ function($,
},
/**
* Select the hints, we get '/WebGoat/HttpBasics/attack1' in the json (nav) we need to select all the hints
* Select the hints, we get 'HttpBasics/attack1' in the json (nav) we need to select all the hints
* from the model where the assignment name is contained in the assignmentPath. We do this not to mess
* with contextRoots etc and try to select the name from the url.
*

View File

@ -57,8 +57,8 @@ define(['jquery',
isAttackSolved = function (path) {
//strip
var newPath = path.replace(/^\/WebGoat/,'');
var newPath = newPath.replace(/\//g,'');
//var newPath = path.replace(/^\/WebGoat/,'');
var newPath = path.replace(/\//g,'');
if (typeof solvedMap[newPath] !== 'undefined') {
return true;
}
@ -82,9 +82,9 @@ define(['jquery',
for (var i=0; i< $assignmentForms.length; i++) {
//normalize path
var action = $assignmentForms.attr('action');
if (action.endsWith("/WebGoat/WebWolf/mail/")) {
if (action.endsWith("WebWolf/mail/")) {
//fix for now. the find does not seem to work properly and gets confused with two /mail
action = "/WebGoat/WebWolf/mail/send";
action = "WebWolf/mail/send";
}
if (action.indexOf("?")>-1) {
//used to also mark forms like JWT assignment 8 complete

View File

@ -1,9 +0,0 @@
// AMD (Asynchronous Module Definition) wrapper for jQuery 1.8
define([
// Load the jQuery source file
'/WebGoat/js/libs/jquery.min.js'
],
function(){
// Tell Require.js that this module returns a reference to jQuery
return $; // Return the global scope object
});

View File

@ -1,4 +1,4 @@
var jQuery = require('libs/jquery-vuln');
var jQuery = require('jqueryvuln');
/*! jQuery UI - v1.10.3 - 2013-05-03
* http://jqueryui.com

View File

@ -1,9 +0,0 @@
// AMD (Asynchronous Module Definition) wrapper for jQuery 1.8
define([
// Load the jQuery source file
'/WebGoat/js/libs/jquery-2.1.4.min.js'
],
function(){
// Tell Require.js that this module returns a reference to jQuery
return $.noConflict(true); // Return the global scope object
});

View File

@ -25,6 +25,7 @@ require.config({
baseUrl: "js/",
paths: {
jquery: 'libs/jquery.min',
jqueryvuln: 'libs/jquery-2.1.4.min',
jqueryuivuln: 'libs/jquery-ui-1.10.4',
jqueryui: 'libs/jquery-ui.min',
underscore: 'libs/underscore-min',
@ -35,16 +36,10 @@ require.config({
polyglot: 'libs/polyglot.min'
},
map: {
'libs/jquery-base' : {'jquery':'libs/jquery.min'},
'libs/jquery-vuln' : {'jquery':'libs/jquery-2.1.4.min'}
},
shim: {
"jqueryui": {
exports:"$",
deps: ['libs/jquery-base']
deps: ['jquery']
},
underscore: {
exports: "_"
@ -65,12 +60,11 @@ require.config({
*/
require([
'jquery',
'libs/jquery-base',
'libs/jquery-vuln',
'jqueryvuln',
'jqueryui',
'underscore',
'backbone',
'bootstrap',
'goatApp/goatApp'], function($,jqueryBase,jqueryVuln,jqueryui,_,Backbone,Bootstrap,Goat){
'goatApp/goatApp'], function($,jqueryVuln,jqueryui,_,Backbone,Bootstrap,Goat){
Goat.initApp();
});

View File

@ -12,7 +12,7 @@ $(function () {
var json = "";
var client = new XMLHttpRequest();
var quiz_id = document.getElementById("quiz_id").getAttribute("data-quiz_id");
client.open('GET', '/WebGoat/lesson_js/questions_' + quiz_id + '.json');
client.open('GET', 'lesson_js/questions_' + quiz_id + '.json');
client.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
json += client.responseText;

View File

@ -14,6 +14,7 @@ require.config({
baseUrl: "js/",
paths: {
jquery: 'libs/jquery.min',
jqueryvuln: 'libs/jquery-2.1.4.min',
jqueryuivuln: 'libs/jquery-ui-1.10.4',
jqueryui: 'libs/jquery-ui.min',
underscore: 'libs/underscore-min',
@ -23,11 +24,6 @@ require.config({
polyglot: 'libs/polyglot.min'
},
map: {
'libs/jquery-base' : {'jquery':'libs/jquery.min'},
'libs/jquery-vuln' : {'jquery':'libs/jquery-2.1.4.min'}
},
shim: {
"jqueryui": {
exports:"$",
@ -43,6 +39,6 @@ require.config({
}
});
require(['jquery','libs/jquery-base','libs/jquery-vuln','jqueryui', 'underscore','backbone','goatApp/scoreboardApp'], function($,jqueryBase,jqueryVuln,jqueryui,_,Backbone,ScoreboardApp){
require(['underscore','backbone','goatApp/scoreboardApp'], function(_,Backbone,ScoreboardApp){
ScoreboardApp.initApp();
});

View File

@ -43,6 +43,12 @@
<div class="text-center"><a th:href="@{/registration}" th:text="#{register.new}"></a></div>
</form>
<br/><br/>
<div th:if="${oauth}">
<h3 class="form-signin-heading">Login with OAuth 2.0</h3>
<table class="table table-striped">
<tr><td></tr><a href="oauth2/authorization/github">GitHub</a></td></tr>
</table>
</div>
</section>
</section>
</section>

Some files were not shown because too many files have changed in this diff Show More