Compare commits
36 Commits
v2025.3
...
f2e2616a88
Author | SHA1 | Date | |
---|---|---|---|
f2e2616a88 | |||
f6c2996cd4 | |||
c25bc7d7a6 | |||
953e7fd206 | |||
e4cb868623 | |||
5efbd03d98 | |||
7fabcc7fd5 | |||
27ab9f89fa | |||
06c0be257f | |||
8b324b3954 | |||
cba4ff3d48 | |||
ca68d6bcf4 | |||
f6990690de | |||
634162f279 | |||
9f77d74f3e | |||
55ea361f45 | |||
fc6c61397d | |||
f45bf6171b | |||
b3dec8bdc9 | |||
c3f9158eab | |||
ec3b9e8aaf | |||
9ec75d5a56 | |||
49dc370931 | |||
1e1a8af39e | |||
451f5615d2 | |||
a4305f408e | |||
7dea5a1bde | |||
8cd0b0a8c9 | |||
72c09f7240 | |||
d8c402f0d6 | |||
95136c9930 | |||
23d6fe6f36 | |||
2c5e4c4491 | |||
c89fcb140a | |||
3cfd053c83 | |||
10adb1b05f |
18
.gitea/workflows/datadog-sca.yml
Normal file
18
.gitea/workflows/datadog-sca.yml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
on: [push]
|
||||||
|
|
||||||
|
name: Datadog Software Composition Analysis
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
software-composition-analysis:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Datadog SBOM Generation and Upload
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Check imported libraries are secure and compliant
|
||||||
|
id: datadog-software-composition-analysis
|
||||||
|
uses: DataDog/datadog-sca-github-action@main
|
||||||
|
with:
|
||||||
|
dd_api_key: ${{ secrets.DD_API_KEY }}
|
||||||
|
dd_app_key: ${{ secrets.DD_APP_KEY }}
|
||||||
|
dd_site: datadoghq.com
|
21
.gitea/workflows/datadog-secrets-scanning.yml
Normal file
21
.gitea/workflows/datadog-secrets-scanning.yml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
on: [push]
|
||||||
|
|
||||||
|
name: Datadog Secrets Scanning
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
static-analysis:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Datadog Static Analyzer
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Check code for comitted secrets
|
||||||
|
id: datadog-static-analysis
|
||||||
|
uses: DataDog/datadog-static-analyzer-github-action@v1
|
||||||
|
with:
|
||||||
|
dd_api_key: ${{ secrets.DD_API_KEY }}
|
||||||
|
dd_app_key: ${{ secrets.DD_APP_KEY }}
|
||||||
|
dd_site: datadoghq.com
|
||||||
|
secrets_enabled: true
|
||||||
|
static_analysis_enabled: false
|
||||||
|
cpu_count: 2
|
41
.gitea/workflows/datadog-static-analysis.yml
Normal file
41
.gitea/workflows/datadog-static-analysis.yml
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
on: [push]
|
||||||
|
|
||||||
|
name: Datadog Static Analysis
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
static-analysis:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Datadog Static Analyzer
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Check code meets quality and security standards
|
||||||
|
id: datadog-static-analysis
|
||||||
|
uses: DataDog/datadog-static-analyzer-github-action@v1
|
||||||
|
with:
|
||||||
|
dd_api_key: ${{ secrets.DD_API_KEY }}
|
||||||
|
dd_app_key: ${{ secrets.DD_APP_KEY }}
|
||||||
|
dd_site: datadoghq.com
|
||||||
|
cpu_count: 2
|
||||||
|
- name: Run Semgrep
|
||||||
|
run: |
|
||||||
|
python3 -m pip install --break-system-package semgrep
|
||||||
|
semgrep scan --sarif -o /tmp/semgrep.sarif
|
||||||
|
cat /tmp/semgrep.sarif
|
||||||
|
# Download and install nvm:
|
||||||
|
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.2/install.sh | bash
|
||||||
|
# in lieu of restarting the shell
|
||||||
|
\. "$HOME/.nvm/nvm.sh"
|
||||||
|
# Download and install Node.js:
|
||||||
|
nvm install 22
|
||||||
|
# Verify the Node.js version:
|
||||||
|
node -v # Should print "v22.14.0".
|
||||||
|
nvm current # Should print "v22.14.0".
|
||||||
|
# Verify npm version:
|
||||||
|
npm -v # Should print "10.9.2".
|
||||||
|
npm install -g @datadog/datadog-ci
|
||||||
|
datadog-ci sarif upload /tmp/semgrep.sarif
|
||||||
|
env:
|
||||||
|
DD_API_KEY: ${{ secrets.DD_API_KEY }}
|
||||||
|
DD_APP_KEY: ${{ secrets.DD_APP_KEY }}
|
||||||
|
DD_SITE: datadoghq.com
|
134
.gitea/workflows/release.yml
Normal file
134
.gitea/workflows/release.yml
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
name: Scheduled Fake Commits
|
||||||
|
|
||||||
|
on:
|
||||||
|
# Trigger the workflow on a schedule.
|
||||||
|
schedule:
|
||||||
|
# This expression means "run every 3 minutes". Useful for testing.
|
||||||
|
# To revert to the original 8-hour schedule, change this to '0 */8 * * *'.
|
||||||
|
- cron: "0 */8 * * *"
|
||||||
|
|
||||||
|
# To trigger manually for testing, you can add workflow_dispatch:
|
||||||
|
# workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
create_scheduled_commits:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
# Fetch the full history to ensure pushes work correctly
|
||||||
|
fetch-depth: 0
|
||||||
|
# Use a token with write access. This should be stored as a secret in your Gitea repo settings.
|
||||||
|
# The default GITEA_TOKEN might not have push permissions, so a Personal Access Token is recommended.
|
||||||
|
# Ensure you have a secret named GITEA_TOKEN in your repository settings.
|
||||||
|
token: ${{ secrets.GITEA_TOKEN }} # Replace GITEA_TOKEN with the name of your secret
|
||||||
|
|
||||||
|
- name: Set up Git config
|
||||||
|
# Configure Git user details globally for the runner
|
||||||
|
run: |
|
||||||
|
echo "setting up git config"
|
||||||
|
git config --global user.name "Gitea Actions Bot"
|
||||||
|
git config --global user.email "actions-bot@your-gitea-instance.com" # Replace with a suitable email
|
||||||
|
echo "git config setup complete"
|
||||||
|
|
||||||
|
- name: Create and Push Commits
|
||||||
|
env:
|
||||||
|
# Define your list of authors here. Each author should be on a new line,
|
||||||
|
# formatted as "Author Name <author@email.com>".
|
||||||
|
# For production, this should ideally be stored as a secret named FAKE_COMMIT_AUTHORS.
|
||||||
|
# For debugging, you can define it directly here as you have done.
|
||||||
|
AUTHOR_LIST: |
|
||||||
|
Author One <author1@example.com>
|
||||||
|
Author Two <author2@example.com>
|
||||||
|
Author Three <author3@example.com>
|
||||||
|
Author Four <author4@example.com>
|
||||||
|
Author Five <author5@example.com>
|
||||||
|
Author Six <author6@example.com>
|
||||||
|
Author Seven <author7@example.com>
|
||||||
|
Author Eight <author8@example.com>
|
||||||
|
Author Nine <author9@example.com>
|
||||||
|
Author Ten <author10@example.com>
|
||||||
|
DWSAuthor One <dwsauthor1@example.com>
|
||||||
|
DWSAuthor Two <dwsauthor2@example.com>
|
||||||
|
DWSAuthor Three <dwsauthor3@example.com>
|
||||||
|
DWSAuthor Four <autdwshor4@example.com>
|
||||||
|
DWSAuthor Five <autdwshor5@example.com>
|
||||||
|
DWSAuthor Six <autdwshor6@example.com>
|
||||||
|
DWSAuthor Seven <adwsuthor7@example.com>
|
||||||
|
DWSAuthor Eight <adwsuthor8@example.com>
|
||||||
|
DWSAuthor Nine <autdwshor9@example.com>
|
||||||
|
DWSAuthor Ten <autdwshor10@example.com>
|
||||||
|
COMMIT_COUNT: 12 # Number of commits to create
|
||||||
|
SLEEP_SECONDS: 120 # Delay between commits in seconds
|
||||||
|
TARGET_BRANCH: main # The branch to commit to
|
||||||
|
|
||||||
|
run: |
|
||||||
|
echo "starting Create and Push Commits step"
|
||||||
|
echo "AUTHOR_LIST content:"
|
||||||
|
echo "$AUTHOR_LIST" # Echo the content of the variable for debugging
|
||||||
|
|
||||||
|
echo "reading author's list into array"
|
||||||
|
# Read authors into a Bash array using readarray
|
||||||
|
readarray -t authors <<< "$AUTHOR_LIST"
|
||||||
|
echo "finished reading author's list into array"
|
||||||
|
|
||||||
|
# Check if authors list is empty
|
||||||
|
if [ ${#authors[@]} -eq 0 ]; then
|
||||||
|
echo "Error: AUTHOR_LIST is empty or could not be parsed into an array."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Starting commit creation process..."
|
||||||
|
echo "Authors available: ${#authors[@]}"
|
||||||
|
echo "Commits to create: $COMMIT_COUNT"
|
||||||
|
echo "Delay between commits: $SLEEP_SECONDS seconds"
|
||||||
|
echo "Target branch: $TARGET_BRANCH"
|
||||||
|
|
||||||
|
# Loop to create the specified number of commits
|
||||||
|
for i in $(seq 1 $COMMIT_COUNT); do
|
||||||
|
# Calculate the index for the current author, cycling through the list
|
||||||
|
author_index=$(( (i - 1) % ${#authors[@]} ))
|
||||||
|
current_author="${authors[$author_index]}"
|
||||||
|
|
||||||
|
echo "Processing author: $current_author" # Debug echo
|
||||||
|
|
||||||
|
# Extract name and email from the author string
|
||||||
|
# Assumes format "Name <email>"
|
||||||
|
author_name=$(echo "$current_author" | sed -E 's/^(.*) <.*>$/\1/')
|
||||||
|
author_email=$(echo "$current_author" | sed -E 's/^.* <(.*)>$/\1/')
|
||||||
|
|
||||||
|
echo "Extracted name: $author_name, email: $author_email" # Debug echo
|
||||||
|
|
||||||
|
echo "--- Creating commit $i of $COMMIT_COUNT by $author_name ---"
|
||||||
|
|
||||||
|
# Configure git user for this specific commit
|
||||||
|
git config user.name "$author_name"
|
||||||
|
git config user.email "$author_email"
|
||||||
|
|
||||||
|
# Create a dummy change: append current timestamp and author to a file
|
||||||
|
# This ensures there's always something to commit
|
||||||
|
echo "$(date): Commit $i by $author_name" >> fake_commit_log.txt
|
||||||
|
|
||||||
|
# Stage the changes
|
||||||
|
git add fake_commit_log.txt
|
||||||
|
|
||||||
|
# Commit the changes
|
||||||
|
git commit -m "Automated commit $i by $author_name"
|
||||||
|
|
||||||
|
# Push the commit to the target branch
|
||||||
|
# Use --set-upstream origin $TARGET_BRANCH on the first push if needed
|
||||||
|
echo "Pushing commit..."
|
||||||
|
git push origin HEAD:$TARGET_BRANCH
|
||||||
|
|
||||||
|
echo "Commit $i pushed successfully."
|
||||||
|
|
||||||
|
# Wait for the specified delay before the next commit, unless it's the last one
|
||||||
|
if [ $i -lt $COMMIT_COUNT ]; then
|
||||||
|
echo "Waiting for $SLEEP_SECONDS seconds..."
|
||||||
|
sleep $SLEEP_SECONDS
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "Finished creating $COMMIT_COUNT commits."
|
6
.github/workflows/release.yml
vendored
6
.github/workflows/release.yml
vendored
@ -76,13 +76,13 @@ jobs:
|
|||||||
uses: docker/setup-buildx-action@v3
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
- name: "Login to dockerhub"
|
- name: "Login to dockerhub"
|
||||||
uses: docker/login-action@v3.3.0
|
uses: docker/login-action@v3.4.0
|
||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
|
||||||
- name: "Build and push WebGoat"
|
- name: "Build and push WebGoat"
|
||||||
uses: docker/build-push-action@v6.15.0
|
uses: docker/build-push-action@v6.16.0
|
||||||
with:
|
with:
|
||||||
context: ./
|
context: ./
|
||||||
file: ./Dockerfile
|
file: ./Dockerfile
|
||||||
@ -95,7 +95,7 @@ jobs:
|
|||||||
webgoat_version=${{ env.WEBGOAT_MAVEN_VERSION }}
|
webgoat_version=${{ env.WEBGOAT_MAVEN_VERSION }}
|
||||||
|
|
||||||
- name: "Build and push WebGoat desktop"
|
- name: "Build and push WebGoat desktop"
|
||||||
uses: docker/build-push-action@v6.15.0
|
uses: docker/build-push-action@v6.16.0
|
||||||
with:
|
with:
|
||||||
context: ./
|
context: ./
|
||||||
file: ./Dockerfile_desktop
|
file: ./Dockerfile_desktop
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -39,7 +39,6 @@ UserDatabase.mv.db
|
|||||||
webgoat-container/src/main/webapp/users/guest.org.owasp.webgoat.plugin.*.props
|
webgoat-container/src/main/webapp/users/guest.org.owasp.webgoat.plugin.*.props
|
||||||
webgoat-container/src/main/webapp/plugin_lessons/dist-*.pom
|
webgoat-container/src/main/webapp/plugin_lessons/dist-*.pom
|
||||||
webgoat-lessons/**/target
|
webgoat-lessons/**/target
|
||||||
**/*.jar
|
|
||||||
**/.DS_Store
|
**/.DS_Store
|
||||||
webgoat-server/mongo-data/*
|
webgoat-server/mongo-data/*
|
||||||
webgoat-lessons/vulnerable-components/dependency-reduced-pom.xml
|
webgoat-lessons/vulnerable-components/dependency-reduced-pom.xml
|
||||||
|
BIN
.mvn/wrapper/maven-wrapper.jar
vendored
Normal file
BIN
.mvn/wrapper/maven-wrapper.jar
vendored
Normal file
Binary file not shown.
2
.mvn/wrapper/maven-wrapper.properties
vendored
2
.mvn/wrapper/maven-wrapper.properties
vendored
@ -1,2 +1,2 @@
|
|||||||
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.1/apache-maven-3.8.1-bin.zip
|
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip
|
||||||
wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar
|
wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar
|
||||||
|
@ -99,7 +99,7 @@ For a full overview of all the parameters you can use, please check the [WebGoat
|
|||||||
|
|
||||||
### Prerequisites:
|
### Prerequisites:
|
||||||
|
|
||||||
* Java 17 or 21
|
* Java 23
|
||||||
* Your favorite IDE
|
* Your favorite IDE
|
||||||
* Git, or Git support in your IDE
|
* Git, or Git support in your IDE
|
||||||
|
|
||||||
|
@ -3,12 +3,12 @@
|
|||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta http-equiv="refresh" content="0;url=https://owasp.org/www-project-webgoat/" />
|
<meta http-equiv="refresh" content="0;url=https://webgoat.org" />
|
||||||
<link rel="canonical" href="https://owasp.org/www-project-webgoat/" />
|
<link rel="canonical" href="https://webgoat.org" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>
|
<h1>
|
||||||
The page been moved to <a href="https://owasp.org/www-project-webgoat/">https://owasp.org/www-project-webgoat/</a>
|
The page been moved to <a href="https://webgoat.org">https://webgoat.org</a>
|
||||||
</h1>
|
</h1>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
2
fake_commit_log.txt
Normal file
2
fake_commit_log.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
Sat May 10 12:27:40 UTC 2025: Commit 1 by Author One
|
||||||
|
Sat May 10 12:28:00 UTC 2025: Commit 2 by Author Two
|
33
pom.xml
33
pom.xml
@ -5,12 +5,12 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-parent</artifactId>
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
<version>3.4.3</version>
|
<version>3.4.4</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>org.owasp.webgoat</groupId>
|
<groupId>org.owasp.webgoat</groupId>
|
||||||
<artifactId>webgoat</artifactId>
|
<artifactId>webgoat</artifactId>
|
||||||
<version>2025.3</version>
|
<version>2025.4-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>WebGoat</name>
|
<name>WebGoat</name>
|
||||||
@ -63,29 +63,29 @@
|
|||||||
<properties>
|
<properties>
|
||||||
<!-- Shared properties with plugins and version numbers across submodules-->
|
<!-- Shared properties with plugins and version numbers across submodules-->
|
||||||
<asciidoctorj.version>3.0.0</asciidoctorj.version>
|
<asciidoctorj.version>3.0.0</asciidoctorj.version>
|
||||||
<bootstrap.version>5.3.3</bootstrap.version>
|
<bootstrap.version>5.3.5</bootstrap.version>
|
||||||
<cglib.version>3.3.0</cglib.version>
|
<cglib.version>3.3.0</cglib.version>
|
||||||
<!-- do not update necessary for lesson -->
|
<!-- do not update necessary for lesson -->
|
||||||
<checkstyle.version>3.6.0</checkstyle.version>
|
<checkstyle.version>3.6.0</checkstyle.version>
|
||||||
<commons-collections.version>3.2.1</commons-collections.version>
|
<commons-collections.version>3.2.1</commons-collections.version>
|
||||||
<commons-compress.version>1.27.1</commons-compress.version>
|
<commons-compress.version>1.27.1</commons-compress.version>
|
||||||
<commons-io.version>2.18.0</commons-io.version>
|
<commons-io.version>2.19.0</commons-io.version>
|
||||||
<commons-lang3.version>3.14.0</commons-lang3.version>
|
<commons-lang3.version>3.14.0</commons-lang3.version>
|
||||||
<commons-text.version>1.13.0</commons-text.version>
|
<commons-text.version>1.13.1</commons-text.version>
|
||||||
<guava.version>33.4.0-jre</guava.version>
|
<guava.version>33.4.8-jre</guava.version>
|
||||||
<jacoco.version>0.8.11</jacoco.version>
|
<jacoco.version>0.8.11</jacoco.version>
|
||||||
<java.version>23</java.version>
|
<java.version>23</java.version>
|
||||||
<jaxb.version>2.3.1</jaxb.version>
|
<jaxb.version>2.3.1</jaxb.version>
|
||||||
<jjwt.version>0.9.1</jjwt.version>
|
<jjwt.version>0.9.1</jjwt.version>
|
||||||
<jose4j.version>0.9.3</jose4j.version>
|
<jose4j.version>0.9.3</jose4j.version>
|
||||||
<jquery.version>3.7.1</jquery.version>
|
<jquery.version>3.7.1</jquery.version>
|
||||||
<jsoup.version>1.18.3</jsoup.version>
|
<jsoup.version>1.19.1</jsoup.version>
|
||||||
<maven-compiler-plugin.version>3.13.0</maven-compiler-plugin.version>
|
<maven-compiler-plugin.version>3.14.0</maven-compiler-plugin.version>
|
||||||
<maven-failsafe-plugin.version>3.5.2</maven-failsafe-plugin.version>
|
<maven-failsafe-plugin.version>3.5.2</maven-failsafe-plugin.version>
|
||||||
<maven-jar-plugin.version>3.1.2</maven-jar-plugin.version>
|
<maven-jar-plugin.version>3.1.2</maven-jar-plugin.version>
|
||||||
<maven-javadoc-plugin.version>3.1.1</maven-javadoc-plugin.version>
|
<maven-javadoc-plugin.version>3.1.1</maven-javadoc-plugin.version>
|
||||||
<maven-source-plugin.version>3.1.0</maven-source-plugin.version>
|
<maven-source-plugin.version>3.1.0</maven-source-plugin.version>
|
||||||
<maven-surefire-plugin.version>3.5.2</maven-surefire-plugin.version>
|
<maven-surefire-plugin.version>3.5.3</maven-surefire-plugin.version>
|
||||||
<maven.compiler.proc>full</maven.compiler.proc>
|
<maven.compiler.proc>full</maven.compiler.proc>
|
||||||
<maven.compiler.source>23</maven.compiler.source>
|
<maven.compiler.source>23</maven.compiler.source>
|
||||||
<maven.compiler.target>23</maven.compiler.target>
|
<maven.compiler.target>23</maven.compiler.target>
|
||||||
@ -96,14 +96,14 @@
|
|||||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
<thymeleaf.version>3.1.2.RELEASE</thymeleaf.version>
|
<thymeleaf.version>3.1.2.RELEASE</thymeleaf.version>
|
||||||
<waittimeForServerStart>60</waittimeForServerStart>
|
<waittimeForServerStart>60</waittimeForServerStart>
|
||||||
<webdriver.version>5.9.3</webdriver.version>
|
<webdriver.version>6.0.1</webdriver.version>
|
||||||
<webgoat.context>/WebGoat</webgoat.context>
|
<webgoat.context>/WebGoat</webgoat.context>
|
||||||
<webgoat.port>8080</webgoat.port>
|
<webgoat.port>8080</webgoat.port>
|
||||||
<webgoat.sslenabled>false</webgoat.sslenabled>
|
<webgoat.sslenabled>false</webgoat.sslenabled>
|
||||||
<webjars-locator-core.version>0.59</webjars-locator-core.version>
|
<webjars-locator-core.version>0.59</webjars-locator-core.version>
|
||||||
<webwolf.context>/WebWolf</webwolf.context>
|
<webwolf.context>/WebWolf</webwolf.context>
|
||||||
<webwolf.port>9090</webwolf.port>
|
<webwolf.port>9090</webwolf.port>
|
||||||
<wiremock.version>3.12.0</wiremock.version>
|
<wiremock.version>3.13.0</wiremock.version>
|
||||||
<xml-resolver.version>1.2</xml-resolver.version>
|
<xml-resolver.version>1.2</xml-resolver.version>
|
||||||
<xstream.version>1.4.5</xstream.version>
|
<xstream.version>1.4.5</xstream.version>
|
||||||
<!-- do not update necessary for lesson -->
|
<!-- do not update necessary for lesson -->
|
||||||
@ -217,12 +217,12 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jruby</groupId>
|
<groupId>org.jruby</groupId>
|
||||||
<artifactId>jruby</artifactId>
|
<artifactId>jruby</artifactId>
|
||||||
<version>9.4.12.0</version>
|
<version>10.0.0.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.microsoft.playwright</groupId>
|
<groupId>com.microsoft.playwright</groupId>
|
||||||
<artifactId>playwright</artifactId>
|
<artifactId>playwright</artifactId>
|
||||||
<version>1.50.0</version>
|
<version>1.51.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
@ -238,7 +238,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.projectlombok</groupId>
|
<groupId>org.projectlombok</groupId>
|
||||||
<artifactId>lombok</artifactId>
|
<artifactId>lombok</artifactId>
|
||||||
<version>1.18.36</version>
|
<version>1.18.38</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
@ -510,7 +510,7 @@
|
|||||||
<configuration>
|
<configuration>
|
||||||
<forkedProcessTimeoutInSeconds>600</forkedProcessTimeoutInSeconds>
|
<forkedProcessTimeoutInSeconds>600</forkedProcessTimeoutInSeconds>
|
||||||
<!-- Necessary for vulnerable components lesson -->
|
<!-- Necessary for vulnerable components lesson -->
|
||||||
<argLine>--add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED
|
<argLine>--enable-native-access=ALL-UNNAMED --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/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
|
--add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED
|
||||||
--add-opens java.base/java.text=ALL-UNNAMED --add-opens java.desktop/java.awt.font=ALL-UNNAMED
|
--add-opens java.base/java.text=ALL-UNNAMED --add-opens java.desktop/java.awt.font=ALL-UNNAMED
|
||||||
@ -536,7 +536,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>com.diffplug.spotless</groupId>
|
<groupId>com.diffplug.spotless</groupId>
|
||||||
<artifactId>spotless-maven-plugin</artifactId>
|
<artifactId>spotless-maven-plugin</artifactId>
|
||||||
<version>2.44.3</version>
|
<version>2.44.4</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<formats>
|
<formats>
|
||||||
<format>
|
<format>
|
||||||
@ -694,6 +694,7 @@
|
|||||||
<argument>-Dwebgoat.server.directory=${java.io.tmpdir}/webgoat_${webgoat.port}</argument>
|
<argument>-Dwebgoat.server.directory=${java.io.tmpdir}/webgoat_${webgoat.port}</argument>
|
||||||
<argument>-Dwebgoat.user.directory=${java.io.tmpdir}/webgoat_${webgoat.port}</argument>
|
<argument>-Dwebgoat.user.directory=${java.io.tmpdir}/webgoat_${webgoat.port}</argument>
|
||||||
<argument>-Dspring.main.banner-mode=off</argument>
|
<argument>-Dspring.main.banner-mode=off</argument>
|
||||||
|
<argument>--enable-native-access=ALL-UNNAMED</argument>
|
||||||
<argument>--add-opens</argument>
|
<argument>--add-opens</argument>
|
||||||
<argument>java.base/java.lang=ALL-UNNAMED</argument>
|
<argument>java.base/java.lang=ALL-UNNAMED</argument>
|
||||||
<argument>--add-opens</argument>
|
<argument>--add-opens</argument>
|
||||||
|
@ -4,12 +4,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.owasp.webgoat.integration;
|
package org.owasp.webgoat.integration;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
|
|
||||||
import io.restassured.RestAssured;
|
import io.restassured.RestAssured;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.assertj.core.api.Assertions;
|
import org.assertj.core.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
@ -21,7 +18,7 @@ public class ChallengeIntegrationTest extends IntegrationTest {
|
|||||||
void testChallenge1() {
|
void testChallenge1() {
|
||||||
startLesson("Challenge1");
|
startLesson("Challenge1");
|
||||||
|
|
||||||
byte[] resultBytes =
|
byte[] resultBytes =
|
||||||
RestAssured.given()
|
RestAssured.given()
|
||||||
.when()
|
.when()
|
||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
@ -38,8 +35,8 @@ public class ChallengeIntegrationTest extends IntegrationTest {
|
|||||||
params.put("username", "admin");
|
params.put("username", "admin");
|
||||||
params.put("password", "!!webgoat_admin_1234!!".replace("1234", pincode));
|
params.put("password", "!!webgoat_admin_1234!!".replace("1234", pincode));
|
||||||
|
|
||||||
checkAssignment(webGoatUrlConfig.url("challenge/1"), params, true);
|
checkAssignment(webGoatUrlConfig.url("challenge/1"), params, true);
|
||||||
String result =
|
String result =
|
||||||
RestAssured.given()
|
RestAssured.given()
|
||||||
.when()
|
.when()
|
||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
@ -54,22 +51,9 @@ public class ChallengeIntegrationTest extends IntegrationTest {
|
|||||||
String flag = result.substring(result.indexOf("flag") + 6, result.indexOf("flag") + 42);
|
String flag = result.substring(result.indexOf("flag") + 6, result.indexOf("flag") + 42);
|
||||||
params.clear();
|
params.clear();
|
||||||
params.put("flag", flag);
|
params.put("flag", flag);
|
||||||
checkAssignment(webGoatUrlConfig.url("challenge/flag/1"), params, true);
|
checkAssignment(webGoatUrlConfig.url("challenge/flag/1"), params, true);
|
||||||
|
|
||||||
checkResults("Challenge1");
|
checkResults("Challenge1");
|
||||||
|
|
||||||
List<String> capturefFlags =
|
|
||||||
RestAssured.given()
|
|
||||||
.when()
|
|
||||||
.relaxedHTTPSValidation()
|
|
||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
|
||||||
.get(webGoatUrlConfig.url("scoreboard-data"))
|
|
||||||
.then()
|
|
||||||
.statusCode(200)
|
|
||||||
.extract()
|
|
||||||
.jsonPath()
|
|
||||||
.get("find { it.username == \"" + this.getUser() + "\" }.flagsCaptured");
|
|
||||||
assertTrue(capturefFlags.contains("Admin lost password"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -81,7 +65,7 @@ public class ChallengeIntegrationTest extends IntegrationTest {
|
|||||||
params.put("username_login", "Larry");
|
params.put("username_login", "Larry");
|
||||||
params.put("password_login", "1' or '1'='1");
|
params.put("password_login", "1' or '1'='1");
|
||||||
|
|
||||||
String result =
|
String result =
|
||||||
RestAssured.given()
|
RestAssured.given()
|
||||||
.when()
|
.when()
|
||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
@ -96,22 +80,9 @@ public class ChallengeIntegrationTest extends IntegrationTest {
|
|||||||
String flag = result.substring(result.indexOf("flag") + 6, result.indexOf("flag") + 42);
|
String flag = result.substring(result.indexOf("flag") + 6, result.indexOf("flag") + 42);
|
||||||
params.clear();
|
params.clear();
|
||||||
params.put("flag", flag);
|
params.put("flag", flag);
|
||||||
checkAssignment(webGoatUrlConfig.url("challenge/flag/5"), params, true);
|
checkAssignment(webGoatUrlConfig.url("challenge/flag/5"), params, true);
|
||||||
|
|
||||||
checkResults("Challenge5");
|
checkResults("Challenge5");
|
||||||
|
|
||||||
List<String> capturefFlags =
|
|
||||||
RestAssured.given()
|
|
||||||
.when()
|
|
||||||
.relaxedHTTPSValidation()
|
|
||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
|
||||||
.get(webGoatUrlConfig.url("scoreboard-data"))
|
|
||||||
.then()
|
|
||||||
.statusCode(200)
|
|
||||||
.extract()
|
|
||||||
.jsonPath()
|
|
||||||
.get("find { it.username == \"" + this.getUser() + "\" }.flagsCaptured");
|
|
||||||
assertTrue(capturefFlags.contains("Without password"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -120,7 +91,7 @@ public class ChallengeIntegrationTest extends IntegrationTest {
|
|||||||
cleanMailbox();
|
cleanMailbox();
|
||||||
|
|
||||||
// One should first be able to download git.zip from WebGoat
|
// One should first be able to download git.zip from WebGoat
|
||||||
RestAssured.given()
|
RestAssured.given()
|
||||||
.when()
|
.when()
|
||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
@ -131,7 +102,7 @@ public class ChallengeIntegrationTest extends IntegrationTest {
|
|||||||
.asString();
|
.asString();
|
||||||
|
|
||||||
// Should email WebWolf inbox this should give a hint to the link being static
|
// Should email WebWolf inbox this should give a hint to the link being static
|
||||||
RestAssured.given()
|
RestAssured.given()
|
||||||
.when()
|
.when()
|
||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
@ -157,18 +128,20 @@ public class ChallengeIntegrationTest extends IntegrationTest {
|
|||||||
Assertions.assertThat(responseBody).contains("Hi, you requested a password reset link");
|
Assertions.assertThat(responseBody).contains("Hi, you requested a password reset link");
|
||||||
|
|
||||||
// Call reset link with admin link
|
// Call reset link with admin link
|
||||||
String result =
|
String result =
|
||||||
RestAssured.given()
|
RestAssured.given()
|
||||||
.when()
|
.when()
|
||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
.get(webGoatUrlConfig.url("challenge/7/reset-password/{link}"), "375afe1104f4a487a73823c50a9292a2")
|
.get(
|
||||||
|
webGoatUrlConfig.url("challenge/7/reset-password/{link}"),
|
||||||
|
"375afe1104f4a487a73823c50a9292a2")
|
||||||
.then()
|
.then()
|
||||||
.statusCode(HttpStatus.ACCEPTED.value())
|
.statusCode(HttpStatus.ACCEPTED.value())
|
||||||
.extract()
|
.extract()
|
||||||
.asString();
|
.asString();
|
||||||
|
|
||||||
String flag = result.substring(result.indexOf("flag") + 6, result.indexOf("flag") + 42);
|
String flag = result.substring(result.indexOf("flag") + 6, result.indexOf("flag") + 42);
|
||||||
checkAssignment(webGoatUrlConfig.url("challenge/flag/7"), Map.of("flag", flag), true);
|
checkAssignment(webGoatUrlConfig.url("challenge/flag/7"), Map.of("flag", flag), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,9 +7,6 @@ package org.owasp.webgoat.integration;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Angel Olle Blazquez
|
|
||||||
*/
|
|
||||||
class SessionManagementIT extends IntegrationTest {
|
class SessionManagementIT extends IntegrationTest {
|
||||||
|
|
||||||
private static final String HIJACK_LOGIN_CONTEXT_PATH = "HijackSession/login";
|
private static final String HIJACK_LOGIN_CONTEXT_PATH = "HijackSession/login";
|
||||||
|
@ -19,12 +19,17 @@ public class PlaywrightTest {
|
|||||||
public static class WebGoatOptions implements OptionsFactory {
|
public static class WebGoatOptions implements OptionsFactory {
|
||||||
@Override
|
@Override
|
||||||
public Options getOptions() {
|
public Options getOptions() {
|
||||||
return new Options().setHeadless(true).setContextOptions(getContextOptions());
|
return new Options()
|
||||||
|
.setHeadless(true)
|
||||||
|
.setContextOptions(getContextOptions());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static Browser.NewContextOptions getContextOptions() {
|
protected static Browser.NewContextOptions getContextOptions() {
|
||||||
return new Browser.NewContextOptions().setBaseURL(webGoatUrlConfig.getBaseUrl());
|
return new Browser.NewContextOptions()
|
||||||
|
.setLocale("en-US")
|
||||||
|
.setBaseURL(webGoatUrlConfig.getBaseUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String webGoatUrl(String path) {
|
public static String webGoatUrl(String path) {
|
||||||
|
@ -35,7 +35,7 @@ public class RegistrationUITest extends PlaywrightTest {
|
|||||||
@Test
|
@Test
|
||||||
@DisplayName("Should register a new user")
|
@DisplayName("Should register a new user")
|
||||||
void registerNewUser(Browser browser) {
|
void registerNewUser(Browser browser) {
|
||||||
var page = browser.newContext().newPage();
|
var page = browser.newContext(new Browser.NewContextOptions().setLocale("en-US")).newPage();
|
||||||
var registrationPage = new RegistrationPage(page);
|
var registrationPage = new RegistrationPage(page);
|
||||||
registrationPage.open();
|
registrationPage.open();
|
||||||
|
|
||||||
|
@ -33,19 +33,19 @@ public class Authentication {
|
|||||||
|
|
||||||
public static Page sylvester(Browser browser) {
|
public static Page sylvester(Browser browser) {
|
||||||
User user = login(browser, sylvester);
|
User user = login(browser, sylvester);
|
||||||
return browser.newContext(new Browser.NewContextOptions().setStorageState(user.auth)).newPage();
|
return browser.newContext(new Browser.NewContextOptions().setLocale("en-US").setStorageState(user.auth)).newPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Page tweety(Browser browser) {
|
public static Page tweety(Browser browser) {
|
||||||
User user = login(browser, tweety);
|
User user = login(browser, tweety);
|
||||||
return browser.newContext(new Browser.NewContextOptions().setStorageState(user.auth)).newPage();
|
return browser.newContext(new Browser.NewContextOptions().setLocale("en-US").setStorageState(user.auth)).newPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static User login(Browser browser, User user) {
|
private static User login(Browser browser, User user) {
|
||||||
if (user.loggedIn()) {
|
if (user.loggedIn()) {
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
var page = browser.newContext().newPage();
|
var page = browser.newContext(new Browser.NewContextOptions().setLocale("en-US")).newPage();
|
||||||
RegistrationPage registrationPage = new RegistrationPage(page);
|
RegistrationPage registrationPage = new RegistrationPage(page);
|
||||||
registrationPage.open();
|
registrationPage.open();
|
||||||
registrationPage.register(user.name, user.password);
|
registrationPage.register(user.name, user.password);
|
||||||
|
@ -42,8 +42,6 @@ public class VulnerableTaskHolder implements Serializable {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute a task when de-serializing a saved or received object.
|
* Execute a task when de-serializing a saved or received object.
|
||||||
*
|
|
||||||
* @author stupid develop
|
|
||||||
*/
|
*/
|
||||||
private void readObject(ObjectInputStream stream) throws Exception {
|
private void readObject(ObjectInputStream stream) throws Exception {
|
||||||
// unserialize data so taskName and taskAction are available
|
// unserialize data so taskName and taskAction are available
|
||||||
|
@ -11,11 +11,6 @@ import java.io.IOException;
|
|||||||
import org.springframework.security.core.AuthenticationException;
|
import org.springframework.security.core.AuthenticationException;
|
||||||
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
|
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
|
||||||
|
|
||||||
/**
|
|
||||||
* AjaxAuthenticationEntryPoint class.
|
|
||||||
*
|
|
||||||
* @author zupzup
|
|
||||||
*/
|
|
||||||
public class AjaxAuthenticationEntryPoint extends LoginUrlAuthenticationEntryPoint {
|
public class AjaxAuthenticationEntryPoint extends LoginUrlAuthenticationEntryPoint {
|
||||||
public AjaxAuthenticationEntryPoint(String loginFormUrl) {
|
public AjaxAuthenticationEntryPoint(String loginFormUrl) {
|
||||||
super(loginFormUrl);
|
super(loginFormUrl);
|
||||||
|
@ -47,17 +47,26 @@ public class LessonTemplateResolver extends FileTemplateResolver {
|
|||||||
var templateName = resourceName.substring(PREFIX.length());
|
var templateName = resourceName.substring(PREFIX.length());
|
||||||
byte[] resource = resources.get(templateName);
|
byte[] resource = resources.get(templateName);
|
||||||
if (resource == null) {
|
if (resource == null) {
|
||||||
try {
|
resource = loadAndCache(templateName);
|
||||||
resource =
|
}
|
||||||
resourceLoader
|
|
||||||
.getResource("classpath:/" + templateName)
|
if (resource == null) {
|
||||||
.getInputStream()
|
return new StringTemplateResource("Unable to find lesson HTML: %s".formatted(templateName));
|
||||||
.readAllBytes();
|
|
||||||
} catch (IOException e) {
|
|
||||||
log.error("Unable to find lesson HTML: {}", template);
|
|
||||||
}
|
|
||||||
resources.put(templateName, resource);
|
|
||||||
}
|
}
|
||||||
return new StringTemplateResource(new String(resource, StandardCharsets.UTF_8));
|
return new StringTemplateResource(new String(resource, StandardCharsets.UTF_8));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private byte[] loadAndCache(String templateName) {
|
||||||
|
try {
|
||||||
|
var resource =
|
||||||
|
resourceLoader.getResource("classpath:/" + templateName).getInputStream().readAllBytes();
|
||||||
|
resources.put(templateName, resource);
|
||||||
|
return resource;
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error(
|
||||||
|
"Unable to find lesson HTML: '{}', does the name of HTML file name match the lesson class name?",
|
||||||
|
templateName);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,6 @@ public class MvcConfiguration implements WebMvcConfigurer {
|
|||||||
registry.addViewController("/login").setViewName("login");
|
registry.addViewController("/login").setViewName("login");
|
||||||
registry.addViewController("/lesson_content").setViewName("lesson_content");
|
registry.addViewController("/lesson_content").setViewName("lesson_content");
|
||||||
registry.addViewController("/start.mvc").setViewName("main_new");
|
registry.addViewController("/start.mvc").setViewName("main_new");
|
||||||
registry.addViewController("/scoreboard").setViewName("scoreboard");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
@ -10,12 +10,6 @@ import org.springframework.stereotype.Controller;
|
|||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.servlet.ModelAndView;
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
/**
|
|
||||||
* Welcome class.
|
|
||||||
*
|
|
||||||
* @author rlawson
|
|
||||||
* @version $Id: $Id
|
|
||||||
*/
|
|
||||||
@Controller
|
@Controller
|
||||||
public class Welcome {
|
public class Welcome {
|
||||||
|
|
||||||
|
@ -11,8 +11,6 @@ import org.springframework.context.support.ReloadableResourceBundleMessageSource
|
|||||||
/**
|
/**
|
||||||
* ExposedReloadableResourceMessageBundleSource class. Extends the reloadable message source with a
|
* ExposedReloadableResourceMessageBundleSource class. Extends the reloadable message source with a
|
||||||
* way to get all messages
|
* way to get all messages
|
||||||
*
|
|
||||||
* @author zupzup
|
|
||||||
*/
|
*/
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class Messages extends ReloadableResourceBundleMessageSource {
|
public class Messages extends ReloadableResourceBundleMessageSource {
|
||||||
|
@ -7,12 +7,6 @@ package org.owasp.webgoat.container.lessons;
|
|||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
/**
|
|
||||||
* LessonInfoModel class.
|
|
||||||
*
|
|
||||||
* @author dm
|
|
||||||
* @version $Id: $Id
|
|
||||||
*/
|
|
||||||
@Getter
|
@Getter
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class LessonInfoModel {
|
public class LessonInfoModel {
|
||||||
|
@ -7,12 +7,6 @@ package org.owasp.webgoat.container.lessons;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
|
||||||
* LessonMenuItem class.
|
|
||||||
*
|
|
||||||
* @author rlawson
|
|
||||||
* @version $Id: $Id
|
|
||||||
*/
|
|
||||||
public class LessonMenuItem {
|
public class LessonMenuItem {
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
|
@ -18,11 +18,6 @@ import org.springframework.web.bind.annotation.GetMapping;
|
|||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
|
||||||
/**
|
|
||||||
* LessonProgressService class.
|
|
||||||
*
|
|
||||||
* @author webgoat
|
|
||||||
*/
|
|
||||||
@Controller
|
@Controller
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class LessonProgressService {
|
public class LessonProgressService {
|
||||||
|
@ -6,12 +6,6 @@ package org.owasp.webgoat.container.session;
|
|||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
/**
|
|
||||||
* LabelDebugger class.
|
|
||||||
*
|
|
||||||
* @author dm
|
|
||||||
* @version $Id: $Id
|
|
||||||
*/
|
|
||||||
public class LabelDebugger implements Serializable {
|
public class LabelDebugger implements Serializable {
|
||||||
|
|
||||||
private boolean enabled = false;
|
private boolean enabled = false;
|
||||||
|
@ -84,6 +84,6 @@ public class LessonProgress {
|
|||||||
}
|
}
|
||||||
|
|
||||||
long numberOfSolvedAssignments() {
|
long numberOfSolvedAssignments() {
|
||||||
return assignments.size();
|
return assignments.stream().filter(AssignmentProgress::isSolved).count();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,10 +20,6 @@ import org.springframework.web.bind.annotation.GetMapping;
|
|||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 3/19/17.
|
|
||||||
*/
|
|
||||||
@Controller
|
@Controller
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@ -1,83 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: Copyright © 2017 WebGoat authors
|
|
||||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
*/
|
|
||||||
package org.owasp.webgoat.container.users;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
|
||||||
import org.owasp.webgoat.container.i18n.PluginMessages;
|
|
||||||
import org.owasp.webgoat.container.lessons.Lesson;
|
|
||||||
import org.owasp.webgoat.container.session.Course;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Temp endpoint just for the CTF.
|
|
||||||
*
|
|
||||||
* @author nbaars
|
|
||||||
* @since 3/23/17.
|
|
||||||
*/
|
|
||||||
@RestController
|
|
||||||
@AllArgsConstructor
|
|
||||||
public class Scoreboard {
|
|
||||||
|
|
||||||
private final UserProgressRepository userTrackerRepository;
|
|
||||||
private final UserRepository userRepository;
|
|
||||||
private final Course course;
|
|
||||||
private final PluginMessages pluginMessages;
|
|
||||||
|
|
||||||
@AllArgsConstructor
|
|
||||||
@Getter
|
|
||||||
private class Ranking {
|
|
||||||
private String username;
|
|
||||||
private List<String> flagsCaptured;
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/scoreboard-data")
|
|
||||||
public List<Ranking> getRankings() {
|
|
||||||
return userRepository.findAll().stream()
|
|
||||||
.filter(user -> !user.getUsername().startsWith("csrf-"))
|
|
||||||
.map(
|
|
||||||
user ->
|
|
||||||
new Ranking(
|
|
||||||
user.getUsername(),
|
|
||||||
challengesSolved(userTrackerRepository.findByUser(user.getUsername()))))
|
|
||||||
.sorted((o1, o2) -> o2.getFlagsCaptured().size() - o1.getFlagsCaptured().size())
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<String> challengesSolved(UserProgress userTracker) {
|
|
||||||
List<String> challenges =
|
|
||||||
List.of(
|
|
||||||
"Challenge1",
|
|
||||||
"Challenge2",
|
|
||||||
"Challenge3",
|
|
||||||
"Challenge4",
|
|
||||||
"Challenge5",
|
|
||||||
"Challenge6",
|
|
||||||
"Challenge7",
|
|
||||||
"Challenge8",
|
|
||||||
"Challenge9");
|
|
||||||
return challenges.stream()
|
|
||||||
.map(userTracker::getLessonProgress)
|
|
||||||
.flatMap(Optional::stream)
|
|
||||||
.filter(LessonProgress::isLessonSolved)
|
|
||||||
.map(LessonProgress::getLessonName)
|
|
||||||
.map(this::toLessonTitle)
|
|
||||||
.toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
private String toLessonTitle(String id) {
|
|
||||||
String titleKey =
|
|
||||||
course.getLessons().stream()
|
|
||||||
.filter(l -> l.getId().equals(id))
|
|
||||||
.findFirst()
|
|
||||||
.map(Lesson::getTitle)
|
|
||||||
.orElse("No title");
|
|
||||||
return pluginMessages.getMessage(titleKey, titleKey);
|
|
||||||
}
|
|
||||||
}
|
|
@ -10,10 +10,6 @@ import jakarta.validation.constraints.Size;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 3/19/17.
|
|
||||||
*/
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
public class UserForm {
|
public class UserForm {
|
||||||
|
@ -41,7 +41,7 @@ public class UserProgress {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an existing lesson tracker or create a new one based on the lesson
|
* Returns an existing lesson progress or create a new one based on the lesson
|
||||||
*
|
*
|
||||||
* @param lesson the lesson
|
* @param lesson the lesson
|
||||||
* @return a lesson tracker created if not already present
|
* @return a lesson tracker created if not already present
|
||||||
@ -49,7 +49,7 @@ public class UserProgress {
|
|||||||
public LessonProgress getLessonProgress(Lesson lesson) {
|
public LessonProgress getLessonProgress(Lesson lesson) {
|
||||||
Optional<LessonProgress> progress =
|
Optional<LessonProgress> progress =
|
||||||
lessonProgress.stream().filter(l -> l.getLessonName().equals(lesson.getId())).findFirst();
|
lessonProgress.stream().filter(l -> l.getLessonName().equals(lesson.getId())).findFirst();
|
||||||
if (!progress.isPresent()) {
|
if (progress.isEmpty()) {
|
||||||
LessonProgress newLessonTracker = new LessonProgress(lesson);
|
LessonProgress newLessonTracker = new LessonProgress(lesson);
|
||||||
lessonProgress.add(newLessonTracker);
|
lessonProgress.add(newLessonTracker);
|
||||||
return newLessonTracker;
|
return newLessonTracker;
|
||||||
@ -58,16 +58,6 @@ public class UserProgress {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Query method for finding a specific lesson tracker based on id
|
|
||||||
*
|
|
||||||
* @param id the id of the lesson
|
|
||||||
* @return optional due to the fact we can only create a lesson tracker based on a lesson
|
|
||||||
*/
|
|
||||||
public Optional<LessonProgress> getLessonProgress(String id) {
|
|
||||||
return lessonProgress.stream().filter(l -> l.getLessonName().equals(id)).findFirst();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void assignmentSolved(Lesson lesson, String assignmentName) {
|
public void assignmentSolved(Lesson lesson, String assignmentName) {
|
||||||
LessonProgress progress = getLessonProgress(lesson);
|
LessonProgress progress = getLessonProgress(lesson);
|
||||||
progress.incrementAttempts();
|
progress.incrementAttempts();
|
||||||
|
@ -7,10 +7,6 @@ package org.owasp.webgoat.container.users;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 3/19/17.
|
|
||||||
*/
|
|
||||||
public interface UserRepository extends JpaRepository<WebGoatUser, String> {
|
public interface UserRepository extends JpaRepository<WebGoatUser, String> {
|
||||||
|
|
||||||
WebGoatUser findByUsername(String username);
|
WebGoatUser findByUsername(String username);
|
||||||
|
@ -14,10 +14,6 @@ import org.springframework.security.core.userdetails.UserDetailsService;
|
|||||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 3/19/17.
|
|
||||||
*/
|
|
||||||
@Service
|
@Service
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class UserService implements UserDetailsService {
|
public class UserService implements UserDetailsService {
|
||||||
|
@ -10,10 +10,6 @@ import lombok.Getter;
|
|||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import org.springframework.data.annotation.Id;
|
import org.springframework.data.annotation.Id;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 8/15/17.
|
|
||||||
*/
|
|
||||||
@Getter
|
@Getter
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@NoArgsConstructor(access = AccessLevel.PROTECTED)
|
@NoArgsConstructor(access = AccessLevel.PROTECTED)
|
||||||
|
@ -9,10 +9,6 @@ import org.springframework.stereotype.Component;
|
|||||||
import org.springframework.validation.Errors;
|
import org.springframework.validation.Errors;
|
||||||
import org.springframework.validation.Validator;
|
import org.springframework.validation.Validator;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 3/19/17.
|
|
||||||
*/
|
|
||||||
@Component
|
@Component
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class UserValidator implements Validator {
|
public class UserValidator implements Validator {
|
||||||
|
@ -15,10 +15,6 @@ import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
|||||||
import org.springframework.security.core.userdetails.User;
|
import org.springframework.security.core.userdetails.User;
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 3/19/17.
|
|
||||||
*/
|
|
||||||
@Getter
|
@Getter
|
||||||
@Entity
|
@Entity
|
||||||
public class WebGoatUser implements UserDetails {
|
public class WebGoatUser implements UserDetails {
|
||||||
|
@ -8,10 +8,6 @@ import org.owasp.webgoat.container.lessons.Category;
|
|||||||
import org.owasp.webgoat.container.lessons.Lesson;
|
import org.owasp.webgoat.container.lessons.Lesson;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 3/21/17.
|
|
||||||
*/
|
|
||||||
@Component
|
@Component
|
||||||
public class ChallengeIntro extends Lesson {
|
public class ChallengeIntro extends Lesson {
|
||||||
|
|
||||||
|
@ -9,10 +9,6 @@ import java.time.LocalDateTime;
|
|||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 8/20/17.
|
|
||||||
*/
|
|
||||||
@Builder
|
@Builder
|
||||||
@Data
|
@Data
|
||||||
public class Email implements Serializable {
|
public class Email implements Serializable {
|
||||||
|
@ -8,10 +8,6 @@ import org.owasp.webgoat.container.lessons.Category;
|
|||||||
import org.owasp.webgoat.container.lessons.Lesson;
|
import org.owasp.webgoat.container.lessons.Lesson;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 3/21/17.
|
|
||||||
*/
|
|
||||||
@Component
|
@Component
|
||||||
public class Challenge1 extends Lesson {
|
public class Challenge1 extends Lesson {
|
||||||
|
|
||||||
|
@ -8,10 +8,6 @@ import org.owasp.webgoat.container.lessons.Category;
|
|||||||
import org.owasp.webgoat.container.lessons.Lesson;
|
import org.owasp.webgoat.container.lessons.Lesson;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 3/21/17.
|
|
||||||
*/
|
|
||||||
@Component
|
@Component
|
||||||
public class Challenge5 extends Lesson {
|
public class Challenge5 extends Lesson {
|
||||||
|
|
||||||
|
@ -29,10 +29,6 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
|||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 4/8/17.
|
|
||||||
*/
|
|
||||||
@RestController
|
@RestController
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class Assignment7 implements AssignmentEndpoint {
|
public class Assignment7 implements AssignmentEndpoint {
|
||||||
|
@ -8,10 +8,6 @@ import org.owasp.webgoat.container.lessons.Category;
|
|||||||
import org.owasp.webgoat.container.lessons.Lesson;
|
import org.owasp.webgoat.container.lessons.Lesson;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 3/21/17.
|
|
||||||
*/
|
|
||||||
@Component
|
@Component
|
||||||
public class Challenge7 extends Lesson {
|
public class Challenge7 extends Lesson {
|
||||||
|
|
||||||
|
@ -8,9 +8,6 @@ import java.util.Random;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* WARNING: DO NOT CHANGE FILE WITHOUT CHANGING .git contents
|
* WARNING: DO NOT CHANGE FILE WITHOUT CHANGING .git contents
|
||||||
*
|
|
||||||
* @author nbaars
|
|
||||||
* @since 8/17/17.
|
|
||||||
*/
|
*/
|
||||||
public class PasswordResetLink {
|
public class PasswordResetLink {
|
||||||
|
|
||||||
|
@ -8,10 +8,6 @@ import org.owasp.webgoat.container.lessons.Category;
|
|||||||
import org.owasp.webgoat.container.lessons.Lesson;
|
import org.owasp.webgoat.container.lessons.Lesson;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 3/21/17.
|
|
||||||
*/
|
|
||||||
@Component
|
@Component
|
||||||
public class Challenge8 extends Lesson {
|
public class Challenge8 extends Lesson {
|
||||||
|
|
||||||
|
@ -8,10 +8,6 @@ import org.owasp.webgoat.container.lessons.Category;
|
|||||||
import org.owasp.webgoat.container.lessons.Lesson;
|
import org.owasp.webgoat.container.lessons.Lesson;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author TMelzer
|
|
||||||
* @since 30.11.18
|
|
||||||
*/
|
|
||||||
@Component
|
@Component
|
||||||
public class ChromeDevTools extends Lesson {
|
public class ChromeDevTools extends Lesson {
|
||||||
|
|
||||||
|
@ -15,12 +15,6 @@ import org.springframework.web.bind.annotation.RequestParam;
|
|||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
/**
|
|
||||||
* This is just a class used to make the HTTP request.
|
|
||||||
*
|
|
||||||
* @author TMelzer
|
|
||||||
* @since 30.11.18
|
|
||||||
*/
|
|
||||||
@RestController
|
@RestController
|
||||||
public class NetworkDummy implements AssignmentEndpoint {
|
public class NetworkDummy implements AssignmentEndpoint {
|
||||||
|
|
||||||
|
@ -19,9 +19,6 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
/**
|
/**
|
||||||
* Assignment where the user has to look through an HTTP Request using the Developer Tools and find
|
* Assignment where the user has to look through an HTTP Request using the Developer Tools and find
|
||||||
* a specific number.
|
* a specific number.
|
||||||
*
|
|
||||||
* @author TMelzer
|
|
||||||
* @since 30.11.18
|
|
||||||
*/
|
*/
|
||||||
@RestController
|
@RestController
|
||||||
@AssignmentHints({"networkHint1", "networkHint2"})
|
@AssignmentHints({"networkHint1", "networkHint2"})
|
||||||
|
@ -8,10 +8,6 @@ import org.owasp.webgoat.container.lessons.Category;
|
|||||||
import org.owasp.webgoat.container.lessons.Lesson;
|
import org.owasp.webgoat.container.lessons.Lesson;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author BenediktStuhrmann
|
|
||||||
* @since 11/2/18.
|
|
||||||
*/
|
|
||||||
@Component
|
@Component
|
||||||
public class CIA extends Lesson {
|
public class CIA extends Lesson {
|
||||||
|
|
||||||
|
@ -15,10 +15,6 @@ import org.springframework.web.bind.annotation.RequestParam;
|
|||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 4/6/17.
|
|
||||||
*/
|
|
||||||
@RestController
|
@RestController
|
||||||
@AssignmentHints({
|
@AssignmentHints({
|
||||||
"client.side.filtering.free.hint1",
|
"client.side.filtering.free.hint1",
|
||||||
|
@ -15,10 +15,6 @@ import org.springframework.web.bind.annotation.PathVariable;
|
|||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 4/6/17.
|
|
||||||
*/
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/clientSideFiltering/challenge-store")
|
@RequestMapping("/clientSideFiltering/challenge-store")
|
||||||
public class ShopEndpoint {
|
public class ShopEndpoint {
|
||||||
|
@ -10,10 +10,6 @@ import lombok.Getter;
|
|||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 4/8/17.
|
|
||||||
*/
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
|
@ -8,12 +8,6 @@ import org.owasp.webgoat.container.lessons.Category;
|
|||||||
import org.owasp.webgoat.container.lessons.Lesson;
|
import org.owasp.webgoat.container.lessons.Lesson;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/***
|
|
||||||
*
|
|
||||||
* @author Angel Olle Blazquez
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class HijackSession extends Lesson {
|
public class HijackSession extends Lesson {
|
||||||
|
|
||||||
|
@ -21,12 +21,6 @@ import org.springframework.web.bind.annotation.RequestParam;
|
|||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
/***
|
|
||||||
*
|
|
||||||
* @author Angel Olle Blazquez
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@AssignmentHints({
|
@AssignmentHints({
|
||||||
"hijacksession.hints.1",
|
"hijacksession.hints.1",
|
||||||
|
@ -9,9 +9,6 @@ import lombok.Builder;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Angel Olle Blazquez
|
|
||||||
*/
|
|
||||||
@Getter
|
@Getter
|
||||||
@ToString
|
@ToString
|
||||||
public class Authentication implements Principal {
|
public class Authentication implements Principal {
|
||||||
|
@ -6,9 +6,6 @@ package org.owasp.webgoat.lessons.hijacksession.cas;
|
|||||||
|
|
||||||
import java.security.Principal;
|
import java.security.Principal;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Angel Olle Blazquez
|
|
||||||
*/
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface AuthenticationProvider<T extends Principal> {
|
public interface AuthenticationProvider<T extends Principal> {
|
||||||
|
|
||||||
|
@ -15,10 +15,6 @@ import org.apache.commons.lang3.StringUtils;
|
|||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.web.context.annotation.ApplicationScope;
|
import org.springframework.web.context.annotation.ApplicationScope;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Angel Olle Blazquez
|
|
||||||
*/
|
|
||||||
|
|
||||||
// weak id value and mechanism
|
// weak id value and mechanism
|
||||||
|
|
||||||
@ApplicationScope
|
@ApplicationScope
|
||||||
|
@ -8,10 +8,6 @@ import org.owasp.webgoat.container.lessons.Category;
|
|||||||
import org.owasp.webgoat.container.lessons.Lesson;
|
import org.owasp.webgoat.container.lessons.Lesson;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 3/22/17.
|
|
||||||
*/
|
|
||||||
@Component
|
@Component
|
||||||
public class JWT extends Lesson {
|
public class JWT extends Lesson {
|
||||||
|
|
||||||
|
@ -4,10 +4,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.owasp.webgoat.lessons.jwt.votes;
|
package org.owasp.webgoat.lessons.jwt.votes;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 4/30/17.
|
|
||||||
*/
|
|
||||||
public class Views {
|
public class Views {
|
||||||
public interface GuestView {}
|
public interface GuestView {}
|
||||||
|
|
||||||
|
@ -7,10 +7,6 @@ package org.owasp.webgoat.lessons.jwt.votes;
|
|||||||
import com.fasterxml.jackson.annotation.JsonView;
|
import com.fasterxml.jackson.annotation.JsonView;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 5/2/17.
|
|
||||||
*/
|
|
||||||
@Getter
|
@Getter
|
||||||
public class Vote {
|
public class Vote {
|
||||||
@JsonView(Views.GuestView.class)
|
@JsonView(Views.GuestView.class)
|
||||||
|
@ -17,10 +17,6 @@ import org.springframework.web.bind.annotation.RequestParam;
|
|||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 8/20/17.
|
|
||||||
*/
|
|
||||||
@RestController
|
@RestController
|
||||||
public class QuestionsAssignment implements AssignmentEndpoint {
|
public class QuestionsAssignment implements AssignmentEndpoint {
|
||||||
|
|
||||||
|
@ -29,10 +29,6 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
|||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.servlet.ModelAndView;
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 8/20/17.
|
|
||||||
*/
|
|
||||||
@RestController
|
@RestController
|
||||||
@AssignmentHints({
|
@AssignmentHints({
|
||||||
"password-reset-hint1",
|
"password-reset-hint1",
|
||||||
|
@ -22,12 +22,6 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
|||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
/**
|
|
||||||
* Part of the password reset assignment. Used to send the e-mail.
|
|
||||||
*
|
|
||||||
* @author nbaars
|
|
||||||
* @since 8/20/17.
|
|
||||||
*/
|
|
||||||
@RestController
|
@RestController
|
||||||
public class ResetLinkAssignmentForgotPassword implements AssignmentEndpoint {
|
public class ResetLinkAssignmentForgotPassword implements AssignmentEndpoint {
|
||||||
|
|
||||||
|
@ -17,12 +17,6 @@ import org.springframework.web.bind.annotation.RequestParam;
|
|||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
/**
|
|
||||||
* Assignment for picking a good security question.
|
|
||||||
*
|
|
||||||
* @author Tobias Melzer
|
|
||||||
* @since 11.12.18
|
|
||||||
*/
|
|
||||||
@RestController
|
@RestController
|
||||||
public class SecurityQuestionAssignment implements AssignmentEndpoint {
|
public class SecurityQuestionAssignment implements AssignmentEndpoint {
|
||||||
|
|
||||||
|
@ -23,10 +23,6 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
import org.springframework.web.client.RestClientException;
|
import org.springframework.web.client.RestClientException;
|
||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 8/20/17.
|
|
||||||
*/
|
|
||||||
@RestController
|
@RestController
|
||||||
public class SimpleMailAssignment implements AssignmentEndpoint {
|
public class SimpleMailAssignment implements AssignmentEndpoint {
|
||||||
private final String webWolfURL;
|
private final String webWolfURL;
|
||||||
|
@ -9,10 +9,6 @@ import jakarta.validation.constraints.Size;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 8/18/17.
|
|
||||||
*/
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
public class PasswordChangeForm {
|
public class PasswordChangeForm {
|
||||||
|
@ -8,10 +8,6 @@ import org.owasp.webgoat.container.lessons.Category;
|
|||||||
import org.owasp.webgoat.container.lessons.Lesson;
|
import org.owasp.webgoat.container.lessons.Lesson;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author BenediktStuhrmann
|
|
||||||
* @since 12/2/18.
|
|
||||||
*/
|
|
||||||
@Component
|
@Component
|
||||||
public class SecurePasswords extends Lesson {
|
public class SecurePasswords extends Lesson {
|
||||||
|
|
||||||
|
@ -8,12 +8,6 @@ import org.owasp.webgoat.container.lessons.Category;
|
|||||||
import org.owasp.webgoat.container.lessons.Lesson;
|
import org.owasp.webgoat.container.lessons.Lesson;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/***
|
|
||||||
*
|
|
||||||
* @author Angel Olle Blazquez
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class SpoofCookie extends Lesson {
|
public class SpoofCookie extends Lesson {
|
||||||
|
|
||||||
|
@ -25,12 +25,6 @@ import org.springframework.web.bind.annotation.RequestParam;
|
|||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
/***
|
|
||||||
*
|
|
||||||
* @author Angel Olle Blazquez
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
@AssignmentHints({"spoofcookie.hint1", "spoofcookie.hint2", "spoofcookie.hint3"})
|
@AssignmentHints({"spoofcookie.hint1", "spoofcookie.hint2", "spoofcookie.hint3"})
|
||||||
@RestController
|
@RestController
|
||||||
public class SpoofCookieAssignment implements AssignmentEndpoint {
|
public class SpoofCookieAssignment implements AssignmentEndpoint {
|
||||||
|
@ -9,12 +9,6 @@ import java.util.Base64;
|
|||||||
import org.apache.commons.lang3.RandomStringUtils;
|
import org.apache.commons.lang3.RandomStringUtils;
|
||||||
import org.springframework.security.crypto.codec.Hex;
|
import org.springframework.security.crypto.codec.Hex;
|
||||||
|
|
||||||
/***
|
|
||||||
*
|
|
||||||
* @author Angel Olle Blazquez
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class EncDec {
|
public class EncDec {
|
||||||
|
|
||||||
// PoC: weak encoding method
|
// PoC: weak encoding method
|
||||||
|
@ -17,10 +17,6 @@ import org.springframework.web.bind.annotation.RequestParam;
|
|||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 6/13/17.
|
|
||||||
*/
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("SqlInjectionMitigations/servers")
|
@RequestMapping("SqlInjectionMitigations/servers")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@ -18,10 +18,6 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
|||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.servlet.ModelAndView;
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 8/20/17.
|
|
||||||
*/
|
|
||||||
@RestController
|
@RestController
|
||||||
public class LandingAssignment implements AssignmentEndpoint {
|
public class LandingAssignment implements AssignmentEndpoint {
|
||||||
private final String landingPageUrl;
|
private final String landingPageUrl;
|
||||||
|
@ -20,10 +20,6 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
import org.springframework.web.client.RestClientException;
|
import org.springframework.web.client.RestClientException;
|
||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 8/20/17.
|
|
||||||
*/
|
|
||||||
@RestController
|
@RestController
|
||||||
public class MailAssignment implements AssignmentEndpoint {
|
public class MailAssignment implements AssignmentEndpoint {
|
||||||
|
|
||||||
|
@ -10,10 +10,6 @@ import lombok.Getter;
|
|||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 4/8/17.
|
|
||||||
*/
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
|
@ -12,10 +12,6 @@ import lombok.NoArgsConstructor;
|
|||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 4/8/17.
|
|
||||||
*/
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
|
@ -14,10 +14,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
|||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 5/4/17.
|
|
||||||
*/
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("xxe/comments")
|
@RequestMapping("xxe/comments")
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
|
@ -14,10 +14,6 @@ import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry
|
|||||||
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
||||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 8/13/17.
|
|
||||||
*/
|
|
||||||
@Configuration
|
@Configuration
|
||||||
public class MvcConfiguration implements WebMvcConfigurer {
|
public class MvcConfiguration implements WebMvcConfigurer {
|
||||||
|
|
||||||
|
@ -18,10 +18,6 @@ import lombok.Builder;
|
|||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 8/20/17.
|
|
||||||
*/
|
|
||||||
@Data
|
@Data
|
||||||
@Builder
|
@Builder
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
|
@ -7,10 +7,6 @@ package org.owasp.webgoat.webwolf.mailbox;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 8/17/17.
|
|
||||||
*/
|
|
||||||
public interface MailboxRepository extends JpaRepository<Email, String> {
|
public interface MailboxRepository extends JpaRepository<Email, String> {
|
||||||
|
|
||||||
List<Email> findByRecipientOrderByTimeDesc(String recipient);
|
List<Email> findByRecipientOrderByTimeDesc(String recipient);
|
||||||
|
@ -21,9 +21,6 @@ import org.springframework.web.servlet.ModelAndView;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Controller for fetching all the HTTP requests from WebGoat to WebWolf for a specific user.
|
* Controller for fetching all the HTTP requests from WebGoat to WebWolf for a specific user.
|
||||||
*
|
|
||||||
* @author nbaars
|
|
||||||
* @since 8/13/17.
|
|
||||||
*/
|
*/
|
||||||
@Controller
|
@Controller
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
|
@ -16,9 +16,6 @@ import org.springframework.boot.actuate.web.exchanges.HttpExchangeRepository;
|
|||||||
/**
|
/**
|
||||||
* Keep track of all the incoming requests, we are only keeping track of request originating from
|
* Keep track of all the incoming requests, we are only keeping track of request originating from
|
||||||
* WebGoat.
|
* WebGoat.
|
||||||
*
|
|
||||||
* @author nbaars
|
|
||||||
* @since 8/13/17.
|
|
||||||
*/
|
*/
|
||||||
public class WebWolfTraceRepository implements HttpExchangeRepository {
|
public class WebWolfTraceRepository implements HttpExchangeRepository {
|
||||||
private enum MatchingMode {
|
private enum MatchingMode {
|
||||||
|
@ -7,10 +7,6 @@ package org.owasp.webgoat.webwolf.user;
|
|||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 3/19/17.
|
|
||||||
*/
|
|
||||||
@Repository("webWolfUserRepository")
|
@Repository("webWolfUserRepository")
|
||||||
public interface UserRepository extends JpaRepository<WebWolfUser, String> {
|
public interface UserRepository extends JpaRepository<WebWolfUser, String> {
|
||||||
|
|
||||||
|
@ -8,10 +8,6 @@ import org.springframework.security.core.userdetails.UserDetailsService;
|
|||||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 3/19/17.
|
|
||||||
*/
|
|
||||||
@Service
|
@Service
|
||||||
public class UserService implements UserDetailsService {
|
public class UserService implements UserDetailsService {
|
||||||
|
|
||||||
|
@ -15,10 +15,6 @@ import org.springframework.security.core.GrantedAuthority;
|
|||||||
import org.springframework.security.core.userdetails.User;
|
import org.springframework.security.core.userdetails.User;
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 3/19/17.
|
|
||||||
*/
|
|
||||||
@Getter
|
@Getter
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "WEB_GOAT_USER")
|
@Table(name = "WEB_GOAT_USER")
|
||||||
|
@ -36,10 +36,6 @@ logging.level.org.hidbernate.SQL=INFO
|
|||||||
webgoat.server.directory=${user.home}/.webgoat-${webgoat.build.version}/
|
webgoat.server.directory=${user.home}/.webgoat-${webgoat.build.version}/
|
||||||
webgoat.user.directory=${user.home}/.webgoat-${webgoat.build.version}/
|
webgoat.user.directory=${user.home}/.webgoat-${webgoat.build.version}/
|
||||||
webgoat.build.version=@project.version@
|
webgoat.build.version=@project.version@
|
||||||
webgoat.email=webgoat@owasp.org
|
|
||||||
webgoat.emaillist=owasp-webgoat@lists.owasp.org
|
|
||||||
webgoat.feedback.address=webgoat@owasp.org
|
|
||||||
webgoat.feedback.address.html=<A HREF=mailto:webgoat@owasp.org>webgoat@owasp.org</A>
|
|
||||||
webgoat.database.connection.string=jdbc:hsqldb:mem:{USER}
|
webgoat.database.connection.string=jdbc:hsqldb:mem:{USER}
|
||||||
webgoat.default.language=en
|
webgoat.default.language=en
|
||||||
webgoat.url=http://${server.address}:${server.port}${server.servlet.context-path}
|
webgoat.url=http://${server.address}:${server.port}${server.servlet.context-path}
|
||||||
@ -51,9 +47,9 @@ webwolf.url=http://${webwolf.host}:${webwolf.port}${webwolf.context}
|
|||||||
webwolf.landingpage.url=${webwolf.url}/landing
|
webwolf.landingpage.url=${webwolf.url}/landing
|
||||||
webwolf.mail.url=${webwolf.url}/mail
|
webwolf.mail.url=${webwolf.url}/mail
|
||||||
|
|
||||||
spring.jpa.properties.jakarta.persistence.schema-generation.scripts.action=create
|
#spring.jpa.properties.jakarta.persistence.schema-generation.scripts.action=create
|
||||||
spring.jpa.properties.jakarta.persistence.schema-generation.scripts.create-target=create.sql
|
#spring.jpa.properties.jakarta.persistence.schema-generation.scripts.create-target=create.sql
|
||||||
spring.jpa.properties.jakarta.persistence.schema-generation.scripts.create-source=metadata
|
#spring.jpa.properties.jakarta.persistence.schema-generation.scripts.create-source=metadata
|
||||||
|
|
||||||
spring.jackson.serialization.indent_output=true
|
spring.jackson.serialization.indent_output=true
|
||||||
spring.jackson.serialization.write-dates-as-timestamps=false
|
spring.jackson.serialization.write-dates-as-timestamps=false
|
||||||
|
@ -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
|
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
|
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:scoreboard["scoreboard",window=_blank]
|
participants can join and hack the challenges.
|
||||||
|
|
||||||
:hardbreaks:
|
:hardbreaks:
|
||||||
In this CTF you will need to solve a couple of challenges, each challenge will give you a flag which you will
|
In this CTF you will need to solve a couple of challenges, each challenge will give you a flag which you will
|
||||||
|
@ -2,9 +2,6 @@
|
|||||||
|
|
||||||
<html xmlns:th="http://www.thymeleaf.org">
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
|
|
||||||
<div class="lesson-page-wrapper">
|
|
||||||
<div class="adoc-content" th:replace="~{doc:lessons/challenges/documentation/Challenge_introduction.adoc}"></div>
|
|
||||||
</div>
|
|
||||||
<div class="lesson-page-wrapper">
|
<div class="lesson-page-wrapper">
|
||||||
<div class="attack-container">
|
<div class="attack-container">
|
||||||
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
|
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
|
|
||||||
<html xmlns:th="http://www.thymeleaf.org">
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
|
|
@ -45,7 +45,7 @@
|
|||||||
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
|
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
|
||||||
<form class="attack-form" accept-charset="UNKNOWN"
|
<form class="attack-form" accept-charset="UNKNOWN"
|
||||||
method="POST" name="form"
|
method="POST" name="form"
|
||||||
th:action="@{/chromeDevTools/network}">
|
th:action="@{/ChromeDevTools/network}">
|
||||||
<script>
|
<script>
|
||||||
// sample custom javascript in the recommended way ...
|
// sample custom javascript in the recommended way ...
|
||||||
// a namespace has been assigned for it, but you can roll your own if you prefer
|
// 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"
|
<form class="attack-form" accept-charset="UNKNOWN"
|
||||||
method="POST" name="form"
|
method="POST" name="form"
|
||||||
th:action="@{/chromeDevTools/network}">
|
th:action="@{/ChromeDevTools/network}">
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<td>What is the number you found: </td>
|
<td>What is the number you found: </td>
|
||||||
|
@ -16,9 +16,9 @@ An example JKU would look like this:
|
|||||||
}
|
}
|
||||||
----
|
----
|
||||||
|
|
||||||
=== Vulnerability
|
=== Vulnerability: JWT claim misuse with JKU
|
||||||
|
|
||||||
JWT claim misuse with JKU The vulnerability arises when a JWT is signed with a weak or predictable key and the server provides a JKU that points to an external location hosting the public key.
|
The vulnerability arises when a JWT is signed with a weak or predictable key and the server provides a JKU that points to an external location hosting the public key.
|
||||||
|
|
||||||
Attackers can exploit this vulnerability by crafting a JWT with malicious claims and using the `jku` to trick the server into verifying the JWT using a weak or manipulated key.
|
Attackers can exploit this vulnerability by crafting a JWT with malicious claims and using the `jku` to trick the server into verifying the JWT using a weak or manipulated key.
|
||||||
It all depends on the library being used inside the application.
|
It all depends on the library being used inside the application.
|
||||||
@ -39,6 +39,7 @@ However, filtering on URLs is quite challenging to implement, and this can be by
|
|||||||
|
|
||||||
- **Successful attack**: If the server uses the weak or manipulated key to verify the JWT, the attacker gains unauthorized access or executes their intended exploit.
|
- **Successful attack**: If the server uses the weak or manipulated key to verify the JWT, the attacker gains unauthorized access or executes their intended exploit.
|
||||||
|
|
||||||
|
|
||||||
=== Mitigation
|
=== Mitigation
|
||||||
|
|
||||||
To prevent JWT claim misuse with JKU, developers and security professionals should follow these best practices:
|
To prevent JWT claim misuse with JKU, developers and security professionals should follow these best practices:
|
||||||
|
@ -72,7 +72,7 @@
|
|||||||
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
|
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
|
||||||
<form class="attack-form" accept-charset="UNKNOWN"
|
<form class="attack-form" accept-charset="UNKNOWN"
|
||||||
method="POST" name="form"
|
method="POST" name="form"
|
||||||
th:action="@{/SqlInjectionMitigations/attack}"
|
th:action="@{/SqlOnlyInputValidation/attack}"
|
||||||
enctype="application/json;charset=UTF-8">
|
enctype="application/json;charset=UTF-8">
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
@ -95,7 +95,7 @@
|
|||||||
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
|
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
|
||||||
<form class="attack-form" accept-charset="UNKNOWN"
|
<form class="attack-form" accept-charset="UNKNOWN"
|
||||||
method="POST" name="form"
|
method="POST" name="form"
|
||||||
th:action="@{/SqlInjectionMitigations/attack}"
|
th:action="@{/SqlOnlyInputValidationOnKeywords/attack}"
|
||||||
enctype="application/json;charset=UTF-8">
|
enctype="application/json;charset=UTF-8">
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -1172,46 +1172,10 @@ span.show-next-page, span.show-prev-page {
|
|||||||
width: 95% !important
|
width: 95% !important
|
||||||
}
|
}
|
||||||
|
|
||||||
/* scoreboard */
|
|
||||||
div.scoreboard-title {
|
|
||||||
font-size: xx-large;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scoreboard-table tr {
|
|
||||||
}
|
|
||||||
|
|
||||||
div.scoreboard-username {
|
|
||||||
background-color: #222;
|
|
||||||
color: aliceblue;
|
|
||||||
padding: 4px;
|
|
||||||
padding-left: 8px;
|
|
||||||
font-size: medium;
|
|
||||||
border-radius: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
th.username {
|
th.username {
|
||||||
padding-bottom: 6px;
|
padding-bottom: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
td.user-flags {
|
|
||||||
padding-left: 8px;
|
|
||||||
padding-bottom: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.captured-flag {
|
|
||||||
border-radius: 6px;
|
|
||||||
background-color: #444;
|
|
||||||
color: white;
|
|
||||||
padding: 4px;
|
|
||||||
font-size: medium;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scoreboard-page {
|
|
||||||
background-color: #e0dfdc;
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fa-flag {
|
.fa-flag {
|
||||||
color: red
|
color: red
|
||||||
}
|
}
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
define(['jquery',
|
|
||||||
'underscore',
|
|
||||||
'backbone'],
|
|
||||||
function($,
|
|
||||||
_,
|
|
||||||
Backbone) {
|
|
||||||
return Backbone.Model.extend({
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,13 +0,0 @@
|
|||||||
define(['jquery',
|
|
||||||
'underscore',
|
|
||||||
'backbone',
|
|
||||||
'goatApp/model/FlagModel'],
|
|
||||||
function($,
|
|
||||||
_,
|
|
||||||
Backbone,
|
|
||||||
FlagModel) {
|
|
||||||
return Backbone.Collection.extend({
|
|
||||||
url:'scoreboard-data',
|
|
||||||
model:FlagModel
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,16 +0,0 @@
|
|||||||
define(['underscore',
|
|
||||||
'goatApp/support/goatAsyncErrorHandler',
|
|
||||||
'goatApp/view/ScoreboardView'],
|
|
||||||
function (
|
|
||||||
_,
|
|
||||||
asyncErrorHandler,
|
|
||||||
ScoreboardView) {
|
|
||||||
'use strict'
|
|
||||||
class ScoreboardApp {
|
|
||||||
initApp() {
|
|
||||||
asyncErrorHandler.init();
|
|
||||||
this.scoreboard = new ScoreboardView();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new ScoreboardApp();
|
|
||||||
});
|
|
@ -1,14 +0,0 @@
|
|||||||
<table class="scoreboard-table">
|
|
||||||
<% _.each(rankings, function(userRanking, index) { %>
|
|
||||||
<tr>
|
|
||||||
<th class="username"> <div class="scoreboard-username"><%= index+1%> - <%=userRanking.username %> </div></th>
|
|
||||||
<td class="user-flags"> <% _.each(userRanking.flagsCaptured, function(flag) { %>
|
|
||||||
|
|
||||||
<div class="captured-flag">
|
|
||||||
<i class="fa fa-flag" aria-hidden="true"></i>
|
|
||||||
<%=flag%> </div>
|
|
||||||
<% }); %>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<% }); %>
|
|
||||||
</table>
|
|
@ -1,32 +0,0 @@
|
|||||||
define(['jquery',
|
|
||||||
'underscore',
|
|
||||||
'backbone',
|
|
||||||
'goatApp/model/FlagsCollection',
|
|
||||||
'text!templates/scoreboard.html'],
|
|
||||||
function($,
|
|
||||||
_,
|
|
||||||
Backbone,
|
|
||||||
FlagsCollection,
|
|
||||||
ScoreboardTemplate) {
|
|
||||||
return Backbone.View.extend({
|
|
||||||
el:'#scoreboard',
|
|
||||||
|
|
||||||
initialize: function() {
|
|
||||||
this.template = ScoreboardTemplate,
|
|
||||||
this.collection = new FlagsCollection();
|
|
||||||
this.listenTo(this.collection,'reset',this.render)
|
|
||||||
this.collection.fetch({reset:true});
|
|
||||||
},
|
|
||||||
|
|
||||||
render: function() {
|
|
||||||
//this.$el.html('test');
|
|
||||||
var t = _.template(this.template);
|
|
||||||
this.$el.html(t({'rankings':this.collection.toJSON()}));
|
|
||||||
setTimeout(this.pollData.bind(this), 5000);
|
|
||||||
},
|
|
||||||
|
|
||||||
pollData: function() {
|
|
||||||
this.collection.fetch({reset:true});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,44 +0,0 @@
|
|||||||
//main.js
|
|
||||||
/*
|
|
||||||
/js
|
|
||||||
js/main.js << main file for require.js
|
|
||||||
--/libs/(jquery,backbone,etc.) << base libs
|
|
||||||
--/goatApp/ << base dir for goat application, js-wise
|
|
||||||
--/goatApp/model
|
|
||||||
--/goatApp/view
|
|
||||||
--/goatApp/support
|
|
||||||
--/goatApp/controller
|
|
||||||
*/
|
|
||||||
|
|
||||||
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',
|
|
||||||
backbone: 'libs/backbone-min',
|
|
||||||
text: 'libs/text',
|
|
||||||
templates: 'goatApp/templates',
|
|
||||||
polyglot: 'libs/polyglot.min'
|
|
||||||
},
|
|
||||||
|
|
||||||
shim: {
|
|
||||||
"jqueryui": {
|
|
||||||
exports:"$",
|
|
||||||
deps: ['jquery']
|
|
||||||
},
|
|
||||||
underscore: {
|
|
||||||
exports: "_"
|
|
||||||
},
|
|
||||||
backbone: {
|
|
||||||
deps: ['underscore', 'jquery'],
|
|
||||||
exports: 'Backbone'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
require(['underscore','backbone','goatApp/scoreboardApp'], function(_,Backbone,ScoreboardApp){
|
|
||||||
ScoreboardApp.initApp();
|
|
||||||
});
|
|
@ -25,33 +25,15 @@
|
|||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<p>Contact us:
|
<p>Visit our <a href="https://webgoat.org">homepage</a>
|
||||||
<ul>
|
|
||||||
<li>WebGoat mailing list: <span th:text="${@environment.getProperty('webgoat.emaillist')}"></span></li>
|
|
||||||
<li>Bruce Mayhew: <span th:text="${@environment.getProperty('webgoat.email')}"></span></li>
|
|
||||||
</ul>
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<p>WebGoat Authors
|
<p><b>Active Contributors</b>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Bruce Mayhew (Author & Project Lead)</li>
|
<li>Nanne Baars (Project lead)</li>
|
||||||
<li>Jeff Williams (Author & Original Idea)</li>
|
|
||||||
<li>Jason White (Architect)</li>
|
|
||||||
<li>Nanne Baars (Plugin & Platform Architecture)</li>
|
|
||||||
<li>Richard Lawson (Architect)</li>
|
|
||||||
</ul>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6">
|
|
||||||
<p>Active Contributors
|
|
||||||
<ul>
|
|
||||||
<li>Nanne Baars (Developer)</li>
|
|
||||||
<li>Jason White (Developer)</li>
|
|
||||||
<li>Doug Morato (Developer & CI)</li>
|
|
||||||
<li>Bruce Mayhew (Developer)</li>
|
|
||||||
<li>René Zubcevic (Developer)</li>
|
<li>René Zubcevic (Developer)</li>
|
||||||
<li>Àngel Ollé Blázquez (Developer)</li>
|
<li>Àngel Ollé Blázquez (Developer)</li>
|
||||||
</ul>
|
</ul>
|
||||||
@ -60,15 +42,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<p>WebGoat Design Team (Active)
|
<p><b>Corporate Sponsorship</b> - Companies that have donated significant time to WebGoat development
|
||||||
<ul>
|
|
||||||
<li>Nanne Baars (Plugin & Platform Architecture)</li>
|
|
||||||
<li>Bruce Mayhew (Goat Herder)</li>
|
|
||||||
<li>Jason White (User Interface)</li>
|
|
||||||
</ul>
|
|
||||||
</p><br/>
|
|
||||||
|
|
||||||
<p>Corporate Sponsorship - Companies that have donated significant time to WebGoat development
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>Aspect Security</li>
|
<li>Aspect Security</li>
|
||||||
<li>Ounce Labs</li>
|
<li>Ounce Labs</li>
|
||||||
@ -81,8 +55,11 @@
|
|||||||
get you added with no further sacrifices required.</p>
|
get you added with no further sacrifices required.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<p>Past Contributors
|
<p><b>Past Contributors</b>
|
||||||
<ul>
|
<ul>
|
||||||
|
<li>Bruce Mayhew (Author / Project lead / Goat herder)</li>
|
||||||
|
<li>Jason White (Architect UX)</li>
|
||||||
|
<li>Doug Morato (Developer & CI)</li>
|
||||||
<li>Richard Lawson (Architect)</li>
|
<li>Richard Lawson (Architect)</li>
|
||||||
<li>Michael Dever (Developer)</li>
|
<li>Michael Dever (Developer)</li>
|
||||||
<li>Jeff Wayman (Docs)</li>
|
<li>Jeff Wayman (Docs)</li>
|
||||||
@ -109,6 +86,7 @@
|
|||||||
<li>Alex Smolen (Lessons)</li>
|
<li>Alex Smolen (Lessons)</li>
|
||||||
<li>Chuck Willis (Lessons)</li>
|
<li>Chuck Willis (Lessons)</li>
|
||||||
<li>Marcel Wirth (Lessons)</li>
|
<li>Marcel Wirth (Lessons)</li>
|
||||||
|
<li>Jeff Williams (Author & Original Idea)</li>
|
||||||
</ul>
|
</ul>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -139,16 +139,12 @@
|
|||||||
data-toggle="modal" data-target="#about-modal">
|
data-toggle="modal" data-target="#about-modal">
|
||||||
<i class="fa fa-info"></i>
|
<i class="fa fa-info"></i>
|
||||||
</button>
|
</button>
|
||||||
<!-- mailto menu item -->
|
<!-- GitHub menu item -->
|
||||||
<a th:href="'mailto:' + ${@environment.getProperty('webgoat.email')} + '?Subject=Webgoat%20feedback'" target="_top">
|
<a th:href="@{https://github.com/WebGoat/WebGoat}" target="_blank">
|
||||||
<button type="button" class="btn btn-default right_nav_button" data-toggle="tooltip"
|
<button type="button" class="btn btn-default right_nav_button" data-toggle="tooltip">
|
||||||
th:title="#{contact}">
|
<i class="fa fa-github"></i>
|
||||||
<i class="fa fa-envelope"></i>
|
|
||||||
</button>
|
</button>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user