diff --git a/Dockerfile b/Dockerfile
index 5d530644c..ff465d403 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM docker.io/eclipse-temurin:19-jre-focal
+FROM docker.io/eclipse-temurin:21-jdk-ubi9-minimal
LABEL NAME = "WebGoat: A deliberately insecure Web Application"
MAINTAINER "WebGoat team"
@@ -14,6 +14,8 @@ COPY --chown=webgoat target/webgoat-*.jar /home/webgoat/webgoat.jar
EXPOSE 8080
EXPOSE 9090
+ENV TZ=Europe/Amsterdam
+
WORKDIR /home/webgoat
ENTRYPOINT [ "java", \
"-Duser.home=/home/webgoat", \
@@ -30,8 +32,4 @@ ENTRYPOINT [ "java", \
"--add-opens", "java.base/sun.nio.ch=ALL-UNNAMED", \
"--add-opens", "java.base/java.io=ALL-UNNAMED", \
"-Drunning.in.docker=true", \
- "-Dwebgoat.host=0.0.0.0", \
- "-Dwebwolf.host=0.0.0.0", \
- "-Dwebgoat.port=8080", \
- "-Dwebwolf.port=9090", \
- "-jar", "webgoat.jar" ]
+ "-jar", "webgoat.jar", "--server.address", "0.0.0.0" ]
diff --git a/README.md b/README.md
index a1cadeae9..b8203e0bd 100644
--- a/README.md
+++ b/README.md
@@ -44,19 +44,27 @@ Every release is also published on [DockerHub](https://hub.docker.com/r/webgoat/
docker run -it -p 127.0.0.1:8080:8080 -p 127.0.0.1:9090:9090 webgoat/webgoat
```
-If you want to reuse the container, give it a name:
+For some lessons you need the container run in the same timezone. For this you can set the TZ environment variable.
+E.g.
```shell
-docker run --name webgoat -it -p 127.0.0.1:8080:8080 -p 127.0.0.1:9090:9090 webgoat/webgoat
+docker run -it -p 127.0.0.1:8080:8080 -p 127.0.0.1:9090:9090 -e TZ=America/Boise webgoat/webgoat
```
-As long as you don't remove the container you can use:
+If you want to use OWASP ZAP or another proxy, you can no longer use 127.0.0.1 or localhost. but
+you can use custom host entries. For example:
```shell
-docker start webgoat
+127.0.0.1 www.webgoat.local www.webwolf.local
```
-This way, you can start where you left off. If you remove the container, you need to use `docker run` again.
+Then you can run the container with:
+
+```shell
+docker run -it -p 127.0.0.1:8080:8080 -p 127.0.0.1:9090:9090 -e WEBGOAT_HOST=www.webgoat.local -e WEBWOLF_HOST=www.webwolf.local -e TZ=America/Boise webgoat/webgoat
+```
+
+Then visit http://www.webgoat.local:8080/WebGoat/ and http://www.webwolf.local:9090/WebWolf/
## 2. Run using Docker with complete Linux Desktop
@@ -71,7 +79,8 @@ docker run -p 127.0.0.1:3000:3000 webgoat/webgoat-desktop
Download the latest WebGoat release from [https://github.com/WebGoat/WebGoat/releases](https://github.com/WebGoat/WebGoat/releases)
```shell
-java -Dfile.encoding=UTF-8 -Dwebgoat.port=8080 -Dwebwolf.port=9090 -jar webgoat-2023.5.jar
+export TZ=Europe/Amsterdam # or your timezone
+java -Dfile.encoding=UTF-8 -jar webgoat-2023.5.jar
```
Click the link in the log to start WebGoat.
@@ -80,7 +89,7 @@ Click the link in the log to start WebGoat.
### Prerequisites:
-* Java 17
+* Java 17 or 21
* Your favorite IDE
* Git, or Git support in your IDE
@@ -132,9 +141,10 @@ For specialist only. There is a way to set up WebGoat with a personalized menu.
For instance running as a jar on a Linux/macOS it will look like this:
```Shell
+export TZ=Europe/Amsterdam # or your timezone
export EXCLUDE_CATEGORIES="CLIENT_SIDE,GENERAL,CHALLENGE"
export EXCLUDE_LESSONS="SqlInjectionAdvanced,SqlInjectionMitigations"
-java -jar target/webgoat-2023.4-SNAPSHOT.jar
+java -jar target/webgoat-2023.6-SNAPSHOT.jar
```
Or in a docker run it would (once this version is pushed into docker hub) look like this:
diff --git a/pom.xml b/pom.xml
index 6a6094419..86db9d546 100644
--- a/pom.xml
+++ b/pom.xml
@@ -141,10 +141,9 @@
3.1.1.RELEASE
5.3.3
/
- 8080
+ false
0.53
/
- 9090
2.27.2
1.2
1.4.5
@@ -513,10 +512,19 @@
org.apache.maven.plugins
maven-failsafe-plugin
+
+ ${webgoat.sslenabled}
+ 127.0.0.1
+ ${webgoat.port}
+ ${webgoat.context}
+ 127.0.0.1
+ ${webwolf.port}
+ ${webwolf.context}
+
${basedir}/src/test/resources/logback-test.xml
- -Xmx512m -Dwebgoatport=${webgoat.port} -Dwebwolfport=${webwolf.port} -Dwebwolfcontext=${webwolf.context} -Dwebgoatcontext=${webgoat.context}
+ -Xmx512m
org/owasp/webgoat/*Test
@@ -557,7 +565,6 @@
maven-checkstyle-plugin
${checkstyle.version}
- UTF-8
true
true
config/checkstyle/checkstyle.xml
@@ -686,16 +693,15 @@
webgoat.port
webwolf.port
- jmxPort
- com.bazaarvoice.maven.plugins
+ org.honton.chas
process-exec-maven-plugin
- 0.9
+ 0.9.2
start-jar
@@ -703,8 +709,18 @@
start
pre-integration-test
+
${project.build.directory}
+
+ ${webgoat.sslenabled}
+ 127.0.0.1
+ ${webgoat.port}
+ ${webgoat.context}
+ 127.0.0.1
+ ${webwolf.port}
+ ${webwolf.context}
+
java
-jar
@@ -712,10 +728,6 @@
-Dwebgoat.server.directory=${java.io.tmpdir}/webgoat_${webgoat.port}
-Dwebgoat.user.directory=${java.io.tmpdir}/webgoat_${webgoat.port}
-Dspring.main.banner-mode=off
- -Dwebgoat.port=${webgoat.port}
- -Dwebgoat.context=${webgoat.context}
- -Dwebwolf.port=${webwolf.port}
- -Dwebwolf.context=${webwolf.context}
--add-opens
java.base/java.lang=ALL-UNNAMED
--add-opens
@@ -741,8 +753,6 @@
${project.build.directory}/webgoat-${project.version}.jar
false
- 120
- http://localhost:${webgoat.port}/WebGoat/actuator/health
@@ -767,7 +777,6 @@
org.owasp
dependency-check-maven
- 8.4.3
7
false
@@ -816,7 +825,6 @@
org.jacoco
jacoco-maven-plugin
- ${jacoco.version}
before-unit-test
diff --git a/src/it/java/org/owasp/webgoat/CSRFIntegrationTest.java b/src/it/java/org/owasp/webgoat/CSRFIntegrationTest.java
index 54d9dc5a3..54231e893 100644
--- a/src/it/java/org/owasp/webgoat/CSRFIntegrationTest.java
+++ b/src/it/java/org/owasp/webgoat/CSRFIntegrationTest.java
@@ -253,6 +253,7 @@ public class CSRFIntegrationTest extends IntegrationTest {
Overview[] assignments =
RestAssured.given()
.cookie("JSESSIONID", getWebGoatCookie())
+ .relaxedHTTPSValidation()
.get(url("service/lessonoverview.mvc"))
.then()
.extract()
diff --git a/src/it/java/org/owasp/webgoat/IntegrationTest.java b/src/it/java/org/owasp/webgoat/IntegrationTest.java
index 2694b56a7..06a626047 100644
--- a/src/it/java/org/owasp/webgoat/IntegrationTest.java
+++ b/src/it/java/org/owasp/webgoat/IntegrationTest.java
@@ -5,7 +5,6 @@ import static io.restassured.RestAssured.given;
import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import java.util.Map;
-import java.util.Objects;
import lombok.Getter;
import org.hamcrest.CoreMatchers;
import org.hamcrest.MatcherAssert;
@@ -15,23 +14,26 @@ import org.springframework.http.HttpStatus;
public abstract class IntegrationTest {
- private static String webGoatPort =
- Objects.requireNonNull(System.getProperty("webgoatport", "8080"));
+ private static String webGoatPort = System.getenv().getOrDefault("WEBGOAT_PORT", "8080");
private static String webGoatContext =
- Objects.requireNonNull(System.getProperty("webgoatcontext", "/WebGoat/"));
+ System.getenv().getOrDefault("WEBGOAT_CONTEXT", "/WebGoat/");
+
+ @Getter private static String webWolfPort = System.getenv().getOrDefault("WEBWOLF_PORT", "9090");
@Getter
- private static String webWolfPort =
- Objects.requireNonNull(System.getProperty("webwolfport", "9090"));
+ private static String webWolfHost = System.getenv().getOrDefault("WEBWOLF_HOST", "127.0.0.1");
+
+ @Getter
+ private static String webGoatHost = System.getenv().getOrDefault("WEBGOAT_HOST", "127.0.0.1");
private static String webWolfContext =
- Objects.requireNonNull(System.getProperty("webwolfcontext", "/WebWolf/"));
+ System.getenv().getOrDefault("WEBWOLF_CONTEXT", "/WebWolf/");
- private static boolean useSSL = false;
+ private static boolean useSSL =
+ Boolean.valueOf(System.getenv().getOrDefault("WEBGOAT_SSLENABLED", "false"));
private static String webgoatUrl =
- (useSSL ? "https:" : "http:") + "//localhost:" + webGoatPort + webGoatContext;
- private static String webWolfUrl =
- (useSSL ? "https:" : "http:") + "//localhost:" + webWolfPort + webWolfContext;
+ (useSSL ? "https://" : "http://") + webGoatHost + ":" + webGoatPort + webGoatContext;
+ private static String webWolfUrl = "http://" + webWolfHost + ":" + webWolfPort + webWolfContext;
@Getter private String webGoatCookie;
@Getter private String webWolfCookie;
@Getter private final String user = "webgoat";
diff --git a/src/it/java/org/owasp/webgoat/PasswordResetLessonIntegrationTest.java b/src/it/java/org/owasp/webgoat/PasswordResetLessonIntegrationTest.java
index 8c7018c59..f3b700b9a 100644
--- a/src/it/java/org/owasp/webgoat/PasswordResetLessonIntegrationTest.java
+++ b/src/it/java/org/owasp/webgoat/PasswordResetLessonIntegrationTest.java
@@ -69,7 +69,6 @@ public class PasswordResetLessonIntegrationTest extends IntegrationTest {
// WebWolf
var link = getPasswordResetLinkFromLandingPage();
-
// WebGoat
changePassword(link);
checkAssignment(
@@ -137,7 +136,7 @@ public class PasswordResetLessonIntegrationTest extends IntegrationTest {
private void clickForgotEmailLink(String user) {
RestAssured.given()
.when()
- .header(HttpHeaders.HOST, String.format("%s:%s", "127.0.0.1", getWebWolfPort()))
+ .header(HttpHeaders.HOST, String.format("%s:%s", getWebWolfHost(), getWebWolfPort()))
.relaxedHTTPSValidation()
.cookie("JSESSIONID", getWebGoatCookie())
.formParams("email", user)
diff --git a/src/main/java/org/owasp/webgoat/container/asciidoc/WebWolfMacro.java b/src/main/java/org/owasp/webgoat/container/asciidoc/WebWolfMacro.java
index 8456d6dbe..119fd9269 100644
--- a/src/main/java/org/owasp/webgoat/container/asciidoc/WebWolfMacro.java
+++ b/src/main/java/org/owasp/webgoat/container/asciidoc/WebWolfMacro.java
@@ -1,12 +1,9 @@
package org.owasp.webgoat.container.asciidoc;
-import jakarta.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import org.asciidoctor.ast.ContentNode;
import org.asciidoctor.extension.InlineMacroProcessor;
-import org.springframework.web.context.request.RequestContextHolder;
-import org.springframework.web.context.request.ServletRequestAttributes;
/**
* Usage in asciidoc:
@@ -26,7 +23,7 @@ public class WebWolfMacro extends InlineMacroProcessor {
@Override
public Object process(ContentNode contentNode, String linkText, Map attributes) {
var env = EnvironmentExposure.getEnv();
- var hostname = determineHost(env.getProperty("webwolf.port"));
+ var hostname = env.getProperty("webwolf.url");
var target = (String) attributes.getOrDefault("target", "home");
var href = hostname + "/" + target;
@@ -45,29 +42,4 @@ public class WebWolfMacro extends InlineMacroProcessor {
private boolean displayCompleteLinkNoFormatting(Map attributes) {
return attributes.values().stream().anyMatch(a -> a.equals("noLink"));
}
-
- /**
- * Determine the host from the hostname and ports that were used. The purpose is to make it
- * possible to use the application behind a reverse proxy. For instance in the docker
- * compose/stack version with webgoat webwolf and nginx proxy. You do not have to use the
- * indicated hostname, but if you do, you should define two hosts aliases 127.0.0.1
- * www.webgoat.local www.webwolf.local
- */
- private String determineHost(String port) {
- HttpServletRequest request =
- ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
- String host = request.getHeader("Host");
- int semicolonIndex = host.indexOf(":");
- if (semicolonIndex == -1 || host.endsWith(":80")) {
- host = host.replace(":80", "").replace("www.webgoat.local", "www.webwolf.local");
- } else {
- host = host.substring(0, semicolonIndex);
- host = host.concat(":").concat(port);
- }
- return "http://" + host + (includeWebWolfContext() ? "/WebWolf" : "");
- }
-
- protected boolean includeWebWolfContext() {
- return true;
- }
}
diff --git a/src/main/java/org/owasp/webgoat/container/asciidoc/WebWolfRootMacro.java b/src/main/java/org/owasp/webgoat/container/asciidoc/WebWolfRootMacro.java
index 58b12e547..7044e125c 100644
--- a/src/main/java/org/owasp/webgoat/container/asciidoc/WebWolfRootMacro.java
+++ b/src/main/java/org/owasp/webgoat/container/asciidoc/WebWolfRootMacro.java
@@ -17,9 +17,4 @@ public class WebWolfRootMacro extends WebWolfMacro {
public WebWolfRootMacro(String macroName, Map config) {
super(macroName, config);
}
-
- @Override
- protected boolean includeWebWolfContext() {
- return false;
- }
}
diff --git a/src/main/java/org/owasp/webgoat/server/StartupMessage.java b/src/main/java/org/owasp/webgoat/server/StartupMessage.java
index ecc52bc19..7273ed77b 100644
--- a/src/main/java/org/owasp/webgoat/server/StartupMessage.java
+++ b/src/main/java/org/owasp/webgoat/server/StartupMessage.java
@@ -17,6 +17,11 @@ public class StartupMessage {
private String address;
private String contextPath;
+ private String applicationName;
+
+ private static boolean useSSL =
+ Boolean.valueOf(System.getenv().getOrDefault("WEBGOAT_SSLENABLED", "true"));
+
@EventListener
void onStartup(ApplicationReadyEvent event) {
@@ -24,9 +29,24 @@ public class StartupMessage {
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.warn("Please browse to http://{}:{}{} to get started...", address, port, contextPath);
+ applicationName =
+ event.getApplicationContext().getEnvironment().getProperty("spring.application.name");
+ if (StringUtils.hasText(applicationName)) {
+ if (applicationName.equals("WebGoat")) {
+ log.warn(
+ "Please browse to "
+ + (useSSL ? "https://" : "http://")
+ + "{}:{}{} to start using WebGoat...",
+ event.getApplicationContext().getEnvironment().getProperty("webgoat.host"),
+ port,
+ contextPath);
+ } else {
+ log.warn(
+ "Please browse to http://{}:{}{} to start using WebWolf...",
+ event.getApplicationContext().getEnvironment().getProperty("webwolf.host"),
+ port,
+ contextPath);
+ }
}
}
diff --git a/src/main/resources/application-webgoat.properties b/src/main/resources/application-webgoat.properties
index 5d7ecf66f..aefde2765 100644
--- a/src/main/resources/application-webgoat.properties
+++ b/src/main/resources/application-webgoat.properties
@@ -1,9 +1,9 @@
server.error.include-stacktrace=always
server.error.path=/error.html
-server.servlet.context-path=${webgoat.context}
+server.servlet.context-path=${WEBGOAT_CONTEXT:/WebGoat}
server.servlet.session.persistent=false
-server.port=${webgoat.port}
-server.address=${webgoat.host}
+server.port=${WEBGOAT_PORT:8080}
+server.address=0.0.0.0
webgoat.host=${WEBGOAT_HOST:127.0.0.1}
webgoat.port=${WEBGOAT_PORT:8080}
webgoat.context=${WEBGOAT_CONTEXT:/WebGoat}
@@ -47,7 +47,7 @@ webgoat.default.language=en
webwolf.host=${WEBWOLF_HOST:127.0.0.1}
webwolf.port=${WEBWOLF_PORT:9090}
webwolf.context=${WEBWOLF_CONTEXT:/WebWolf}
-webwolf.url=http://${webwolf.host}:${webwolf.port}${webwolf.context}
+webwolf.url=http://${WEBWOLF_HOST:127.0.0.1}:${WEBWOLF_PORT:9090}${WEBWOLF_CONTEXT:/WebWolf}
webwolf.landingpage.url=${webwolf.url}/landing
webwolf.mail.url=${webwolf.url}/mail
diff --git a/src/main/resources/application-webwolf.properties b/src/main/resources/application-webwolf.properties
index 4d450fc90..986a70b80 100644
--- a/src/main/resources/application-webwolf.properties
+++ b/src/main/resources/application-webwolf.properties
@@ -1,8 +1,8 @@
server.error.include-stacktrace=always
server.error.path=/error.html
server.servlet.context-path=${webwolf.context}
-server.port=${webwolf.port}
-server.address=${webwolf.host}
+server.port=${WEBWOLF_PORT:9090}
+server.address=0.0.0.0
spring.application.name=WebWolf
webwolf.host=${WEBWOLF_HOST:127.0.0.1}