Compare commits
130 Commits
Author | SHA1 | Date | |
---|---|---|---|
27f23fea19 | |||
9bd7a81435 | |||
08ccb069df | |||
2357651570 | |||
b25caa5c2f | |||
9c354d5699 | |||
84029345b4 | |||
a0ca199cdc | |||
2058298e2d | |||
17acef57b4 | |||
d913967ec5 | |||
87edc7d1db | |||
ac7a9c7863 | |||
2803ef45e4 | |||
5357a65e05 | |||
d343c60781 | |||
98acc1f55a | |||
f99888e61b | |||
29dda49190 | |||
369be6f688 | |||
d5f869c006 | |||
a9caaabb47 | |||
fb2ff01775 | |||
89ecf1d2ad | |||
1b66a742da | |||
a831da5886 | |||
fd5189c102 | |||
ae261f201a | |||
3d651526be | |||
c7c2a61f65 | |||
b7f657ad2c | |||
7fea42afe9 | |||
826887cc83 | |||
62db86246e | |||
f7a9995fe0 | |||
d6c4e8e454 | |||
26628a39e1 | |||
2d26a318d1 | |||
dc16e9a0fb | |||
88a321c268 | |||
8450c5a5be | |||
ba75e10efd | |||
d1e44bbc98 | |||
5a4974f3c2 | |||
4fc1d1fb22 | |||
084a105c69 | |||
7485cb8b9a | |||
c312ae989f | |||
5fde7fbf29 | |||
a32c56bfc7 | |||
6fd3eb57eb | |||
1743d017ff | |||
2b2638943b | |||
45c26d8aaf | |||
be30551850 | |||
49862f6b90 | |||
4009785bb8 | |||
d8341c86a1 | |||
055578893d | |||
b89ebd70ad | |||
7b81247dd1 | |||
3bc2e57c9c | |||
c3ec168d59 | |||
a67fbf5a5a | |||
3365c8d447 | |||
368c046779 | |||
8749137d1e | |||
786cabd251 | |||
dda8b10f55 | |||
d6ca083529 | |||
7c92d625dd | |||
4ba818533c | |||
a9b1fd66b8 | |||
8f6e47e6d4 | |||
61de52840f | |||
fd3eb2451c | |||
32fa1ec0a6 | |||
ad00119b0d | |||
25f49537e7 | |||
8cb735e623 | |||
155a40aab4 | |||
6c4ddbbaad | |||
d704f69879 | |||
3b2b613aa5 | |||
934ba3e496 | |||
8ec718c1ef | |||
1df7ca61a3 | |||
75398feca0 | |||
76a2365abf | |||
015216df5f | |||
60fc807d36 | |||
636a2bdaf5 | |||
816a694c84 | |||
06a55ab278 | |||
0136c1070f | |||
dce5eeb797 | |||
ca886b4818 | |||
ff3a2983e2 | |||
6f0b88f9b6 | |||
9d9fb092be | |||
4bc53a6666 | |||
61d5fb9ece | |||
6eafa45e4c | |||
ac6de9d788 | |||
f6855bf6a5 | |||
f7b4af5023 | |||
e720eec5f9 | |||
a43a6125e8 | |||
d3e2164716 | |||
cbf2e153d9 | |||
0795ff0fc5 | |||
d7cdfeec2a | |||
491fe2d84d | |||
a509e8e24e | |||
e50986a098 | |||
61dac201f0 | |||
c5629be618 | |||
df8c83fe74 | |||
6d3813c2ce | |||
ecfa0197af | |||
8467ae8a0b | |||
5243fa2bf2 | |||
36f99dede8 | |||
5dbe2eaf19 | |||
1b49b2fd3b | |||
b49c61636b | |||
8269207d6b | |||
de2f568229 | |||
9f6cf39ff2 | |||
19d54dbe95 |
11
.github/dependabot.yml
vendored
11
.github/dependabot.yml
vendored
@ -1,7 +1,14 @@
|
|||||||
version: 2
|
version: 2
|
||||||
updates:
|
updates:
|
||||||
# Maintain dependencies for GitHub Actions
|
|
||||||
- package-ecosystem: "github-actions"
|
- package-ecosystem: "github-actions"
|
||||||
directory: "/"
|
directory: "/"
|
||||||
schedule:
|
schedule:
|
||||||
interval: "daily"
|
interval: "weekly"
|
||||||
|
- package-ecosystem: "maven"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: "weekly"
|
||||||
|
- package-ecosystem: "docker"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: "weekly"
|
||||||
|
54
.github/workflows/branchbuild.txt
vendored
Normal file
54
.github/workflows/branchbuild.txt
vendored
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
name: "Branch build"
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- "*"
|
||||||
|
- "!main"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
branch-build:
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [ ubuntu-latest, windows-latest, macos-latest ]
|
||||||
|
java-version: [ 17, 21 ]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- name: Set up JDK ${{ matrix.java-version }}
|
||||||
|
uses: actions/setup-java@v4
|
||||||
|
with:
|
||||||
|
distribution: 'temurin'
|
||||||
|
java-version: ${{ matrix.java-version }}
|
||||||
|
architecture: x64
|
||||||
|
- name: Cache Maven packages
|
||||||
|
uses: actions/cache@v3.3.1
|
||||||
|
with:
|
||||||
|
path: ~/.m2
|
||||||
|
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
|
||||||
|
restore-keys: ${{ runner.os }}-m2-
|
||||||
|
- name: Build with Maven
|
||||||
|
run: mvn --no-transfer-progress verify
|
||||||
|
- name: "Set up QEMU"
|
||||||
|
if: runner.os == 'Linux'
|
||||||
|
uses: docker/setup-qemu-action@v2.2.0
|
||||||
|
- name: "Set up Docker Buildx"
|
||||||
|
if: runner.os == 'Linux'
|
||||||
|
uses: docker/setup-buildx-action@v2
|
||||||
|
- name: "Verify Docker WebGoat build"
|
||||||
|
if: runner.os == 'Linux'
|
||||||
|
uses: docker/build-push-action@v5.1.0
|
||||||
|
with:
|
||||||
|
context: ./
|
||||||
|
file: ./Dockerfile
|
||||||
|
push: false
|
||||||
|
build-args: |
|
||||||
|
webgoat_version=${{ env.WEBGOAT_MAVEN_VERSION }}
|
||||||
|
- name: "Verify Docker WebGoat desktop build"
|
||||||
|
uses: docker/build-push-action@v5.1.0
|
||||||
|
if: runner.os == 'Linux'
|
||||||
|
with:
|
||||||
|
context: ./
|
||||||
|
file: ./Dockerfile_desktop
|
||||||
|
push: false
|
||||||
|
build-args: |
|
||||||
|
webgoat_version=${{ env.WEBGOAT_MAVEN_VERSION }}
|
42
.github/workflows/build.yml
vendored
42
.github/workflows/build.yml
vendored
@ -1,19 +1,17 @@
|
|||||||
name: "Pull requests build"
|
name: "Main / Pull requests build"
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- '.txt'
|
- '.txt'
|
||||||
- 'LICENSE'
|
- 'LICENSE'
|
||||||
- 'docs/**'
|
- 'docs/**'
|
||||||
|
branches: [main]
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
pr-build:
|
build:
|
||||||
if: >
|
|
||||||
github.event_name == 'pull_request' && !github.event.pull_request.draft && (
|
|
||||||
github.event.action == 'opened' ||
|
|
||||||
github.event.action == 'reopened' ||
|
|
||||||
github.event.action == 'synchronize'
|
|
||||||
)
|
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
@ -21,40 +19,16 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- name: Set up JDK 17
|
- name: Set up JDK 17
|
||||||
uses: actions/setup-java@v3
|
uses: actions/setup-java@v4
|
||||||
with:
|
with:
|
||||||
distribution: 'temurin'
|
distribution: 'temurin'
|
||||||
java-version: 17
|
java-version: 17
|
||||||
architecture: x64
|
architecture: x64
|
||||||
- name: Cache Maven packages
|
- name: Cache Maven packages
|
||||||
uses: actions/cache@v3.2.5
|
uses: actions/cache@v3.3.1
|
||||||
with:
|
with:
|
||||||
path: ~/.m2
|
path: ~/.m2
|
||||||
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
|
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
|
||||||
restore-keys: ${{ runner.os }}-m2-
|
restore-keys: ${{ runner.os }}-m2-
|
||||||
- name: Build with Maven
|
- name: Build with Maven
|
||||||
run: mvn --no-transfer-progress verify
|
run: mvn --no-transfer-progress verify
|
||||||
- name: "Set up QEMU"
|
|
||||||
if: runner.os == 'Linux'
|
|
||||||
uses: docker/setup-qemu-action@v2.1.0
|
|
||||||
- name: "Set up Docker Buildx"
|
|
||||||
if: runner.os == 'Linux'
|
|
||||||
uses: docker/setup-buildx-action@v2
|
|
||||||
- name: "Verify Docker WebGoat build"
|
|
||||||
if: runner.os == 'Linux'
|
|
||||||
uses: docker/build-push-action@v4.0.0
|
|
||||||
with:
|
|
||||||
context: ./
|
|
||||||
file: ./Dockerfile
|
|
||||||
push: false
|
|
||||||
build-args: |
|
|
||||||
webgoat_version=${{ env.WEBGOAT_MAVEN_VERSION }}
|
|
||||||
- name: "Verify Docker WebGoat desktop build"
|
|
||||||
uses: docker/build-push-action@v4.0.0
|
|
||||||
if: runner.os == 'Linux'
|
|
||||||
with:
|
|
||||||
context: ./
|
|
||||||
file: ./Dockerfile_desktop
|
|
||||||
push: false
|
|
||||||
build-args: |
|
|
||||||
webgoat_version=${{ env.WEBGOAT_MAVEN_VERSION }}
|
|
||||||
|
29
.github/workflows/pre-commit.yaml
vendored
Normal file
29
.github/workflows/pre-commit.yaml
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
name: Pre-commit check
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
branches: [main]
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
jobs:
|
||||||
|
pre-commit:
|
||||||
|
name: Pre-commit check
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout git repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: Setup python
|
||||||
|
uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: "3.9"
|
||||||
|
- uses: actions/setup-java@v4
|
||||||
|
with:
|
||||||
|
distribution: 'temurin'
|
||||||
|
java-version: '17'
|
||||||
|
- name: Pre-commit checks
|
||||||
|
uses: pre-commit/action@v3.0.0
|
||||||
|
- name: pre-commit-ci-lite
|
||||||
|
uses: pre-commit-ci/lite-action@v1.0.1
|
||||||
|
if: always()
|
28
.github/workflows/release.yml
vendored
28
.github/workflows/release.yml
vendored
@ -8,20 +8,22 @@ jobs:
|
|||||||
if: github.repository == 'WebGoat/WebGoat'
|
if: github.repository == 'WebGoat/WebGoat'
|
||||||
name: Release WebGoat
|
name: Release WebGoat
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
environment:
|
environment:
|
||||||
name: release
|
name: release
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Set up JDK 17
|
- name: Set up JDK 17
|
||||||
uses: actions/setup-java@v3
|
uses: actions/setup-java@v4
|
||||||
with:
|
with:
|
||||||
distribution: 'temurin'
|
distribution: 'temurin'
|
||||||
java-version: 17
|
java-version: 17
|
||||||
architecture: x64
|
architecture: x64
|
||||||
|
|
||||||
- name: Cache Maven packages
|
- name: Cache Maven packages
|
||||||
uses: actions/cache@v3.2.5
|
uses: actions/cache@v3.3.1
|
||||||
with:
|
with:
|
||||||
path: ~/.m2
|
path: ~/.m2
|
||||||
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
|
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
|
||||||
@ -44,7 +46,7 @@ jobs:
|
|||||||
files: |
|
files: |
|
||||||
target/webgoat-${{ env.WEBGOAT_MAVEN_VERSION }}.jar
|
target/webgoat-${{ env.WEBGOAT_MAVEN_VERSION }}.jar
|
||||||
body: |
|
body: |
|
||||||
## Version ${{ steps.tag.outputs.tag }}
|
## Version ${{ github.ref_name }}
|
||||||
|
|
||||||
### New functionality
|
### New functionality
|
||||||
|
|
||||||
@ -54,7 +56,7 @@ jobs:
|
|||||||
|
|
||||||
- [#743 - Character encoding errors](https://github.com/WebGoat/WebGoat/issues/743)
|
- [#743 - Character encoding errors](https://github.com/WebGoat/WebGoat/issues/743)
|
||||||
|
|
||||||
Full change log: https://github.com/WebGoat/WebGoat/compare/${{ steps.tag.outputs.tag }}...${{ steps.tag.outputs.tag }}
|
Full change log: https://github.com/WebGoat/WebGoat/compare/${{ github.ref_name }}...${{ github.ref_name }}
|
||||||
|
|
||||||
|
|
||||||
## Contributors
|
## Contributors
|
||||||
@ -72,26 +74,26 @@ jobs:
|
|||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: "Set up QEMU"
|
- name: "Set up QEMU"
|
||||||
uses: docker/setup-qemu-action@v2.1.0
|
uses: docker/setup-qemu-action@v2.2.0
|
||||||
with:
|
with:
|
||||||
platforms: all
|
platforms: all
|
||||||
|
|
||||||
- name: "Set up Docker Buildx"
|
- name: "Set up Docker Buildx"
|
||||||
uses: docker/setup-buildx-action@v2
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
- name: "Login to dockerhub"
|
- name: "Login to dockerhub"
|
||||||
uses: docker/login-action@v2.1.0
|
uses: docker/login-action@v3.0.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@v4.0.0
|
uses: docker/build-push-action@v5.1.0
|
||||||
with:
|
with:
|
||||||
context: ./
|
context: ./
|
||||||
file: ./Dockerfile
|
file: ./Dockerfile
|
||||||
push: true
|
push: true
|
||||||
platforms: linux/amd64, linux/arm64, linux/arm/v7
|
platforms: linux/amd64, linux/arm64
|
||||||
tags: |
|
tags: |
|
||||||
webgoat/webgoat:${{ env.WEBGOAT_TAG_VERSION }}
|
webgoat/webgoat:${{ env.WEBGOAT_TAG_VERSION }}
|
||||||
webgoat/webgoat:latest
|
webgoat/webgoat:latest
|
||||||
@ -99,12 +101,12 @@ 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@v4.0.0
|
uses: docker/build-push-action@v5.1.0
|
||||||
with:
|
with:
|
||||||
context: ./
|
context: ./
|
||||||
file: ./Dockerfile_desktop
|
file: ./Dockerfile_desktop
|
||||||
push: true
|
push: true
|
||||||
platforms: linux/amd64, linux/arm64, linux/arm/v7
|
platforms: linux/amd64, linux/arm64
|
||||||
tags: |
|
tags: |
|
||||||
webgoat/webgoat-desktop:${{ env.WEBGOAT_TAG_VERSION }}
|
webgoat/webgoat-desktop:${{ env.WEBGOAT_TAG_VERSION }}
|
||||||
webgoat/webgoat-desktop:latest
|
webgoat/webgoat-desktop:latest
|
||||||
@ -121,8 +123,9 @@ jobs:
|
|||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Set up JDK 17
|
- name: Set up JDK 17
|
||||||
uses: actions/setup-java@v3
|
uses: actions/setup-java@v4
|
||||||
with:
|
with:
|
||||||
|
distribution: 'temurin'
|
||||||
java-version: 17
|
java-version: 17
|
||||||
architecture: x64
|
architecture: x64
|
||||||
|
|
||||||
@ -144,4 +147,3 @@ jobs:
|
|||||||
github_token: "${{ secrets.GITHUB_TOKEN }}"
|
github_token: "${{ secrets.GITHUB_TOKEN }}"
|
||||||
title: ${{ github.event.commits[0].message }}
|
title: ${{ github.event.commits[0].message }}
|
||||||
target_branch: main
|
target_branch: main
|
||||||
|
|
||||||
|
12
.github/workflows/test.yml
vendored
12
.github/workflows/test.yml
vendored
@ -23,21 +23,21 @@ jobs:
|
|||||||
# Uses an default action to checkout the code
|
# Uses an default action to checkout the code
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
# Uses an action to add Python to the VM
|
# Uses an action to add Python to the VM
|
||||||
- name: Setup Pyton
|
- name: Setup Python
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: '3.7'
|
python-version: '3.7'
|
||||||
architecture: x64
|
architecture: x64
|
||||||
# Uses an action to add JDK 17 to the VM (and mvn?)
|
# Uses an action to add JDK 17 to the VM (and mvn?)
|
||||||
- name: set up JDK 17
|
- name: set up JDK 17
|
||||||
uses: actions/setup-java@v3
|
uses: actions/setup-java@v4
|
||||||
with:
|
with:
|
||||||
distribution: 'temurin'
|
distribution: 'temurin'
|
||||||
java-version: 17
|
java-version: 17
|
||||||
architecture: x64
|
architecture: x64
|
||||||
#Uses an action to set up a cache using a certain key based on the hash of the dependencies
|
#Uses an action to set up a cache using a certain key based on the hash of the dependencies
|
||||||
- name: Cache Maven packages
|
- name: Cache Maven packages
|
||||||
uses: actions/cache@v3.2.5
|
uses: actions/cache@v3.3.1
|
||||||
with:
|
with:
|
||||||
path: ~/.m2
|
path: ~/.m2
|
||||||
key: ubuntu-latest-m2-${{ hashFiles('**/pom.xml') }}
|
key: ubuntu-latest-m2-${{ hashFiles('**/pom.xml') }}
|
||||||
@ -48,6 +48,8 @@ jobs:
|
|||||||
robotframework
|
robotframework
|
||||||
robotframework-SeleniumLibrary
|
robotframework-SeleniumLibrary
|
||||||
webdriver-manager
|
webdriver-manager
|
||||||
|
selenium==4.9.1
|
||||||
|
# TODO https://github.com/robotframework/SeleniumLibrary/issues/1835
|
||||||
- name: Run with Maven
|
- name: Run with Maven
|
||||||
run: mvn --no-transfer-progress spring-boot:run &
|
run: mvn --no-transfer-progress spring-boot:run &
|
||||||
- name: Wait to start
|
- name: Wait to start
|
||||||
@ -59,7 +61,7 @@ jobs:
|
|||||||
# send report to forks only due to limits on permission tokens
|
# send report to forks only due to limits on permission tokens
|
||||||
- name: Send report to commit
|
- name: Send report to commit
|
||||||
if: github.repository != 'WebGoat/WebGoat' && github.event_name == 'push'
|
if: github.repository != 'WebGoat/WebGoat' && github.event_name == 'push'
|
||||||
uses: joonvena/robotframework-reporter-action@v2.1
|
uses: joonvena/robotframework-reporter-action@v2.2
|
||||||
with:
|
with:
|
||||||
gh_access_token: ${{ secrets.GITHUB_TOKEN }}
|
gh_access_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
report_path: 'robotreport'
|
report_path: 'robotreport'
|
||||||
|
2
.github/workflows/welcome.yml
vendored
2
.github/workflows/welcome.yml
vendored
@ -10,7 +10,7 @@ jobs:
|
|||||||
if: github.repository == 'WebGoat/WebGoat'
|
if: github.repository == 'WebGoat/WebGoat'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/first-interaction@v1.1.1
|
- uses: actions/first-interaction@v1.3.0
|
||||||
with:
|
with:
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
issue-message: 'Thanks for submitting your first issue, we will have a look as quickly as possible.'
|
issue-message: 'Thanks for submitting your first issue, we will have a look as quickly as possible.'
|
||||||
|
28
.pre-commit-config.yaml
Normal file
28
.pre-commit-config.yaml
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
ci:
|
||||||
|
autofix_commit_msg: |
|
||||||
|
[pre-commit.ci] auto fixes from pre-commit.com hooks
|
||||||
|
autofix_prs: false # managed in the action step
|
||||||
|
autoupdate_branch: ""
|
||||||
|
autoupdate_commit_msg: "[pre-commit.ci] pre-commit autoupdate"
|
||||||
|
autoupdate_schedule: weekly
|
||||||
|
skip: []
|
||||||
|
submodules: false
|
||||||
|
repos:
|
||||||
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
|
rev: v4.4.0
|
||||||
|
hooks:
|
||||||
|
- id: check-yaml
|
||||||
|
- id: end-of-file-fixer
|
||||||
|
exclude: ^(README.md|CREATE_RELEASE.md)
|
||||||
|
- id: trailing-whitespace
|
||||||
|
- repo: https://github.com/alessandrojcm/commitlint-pre-commit-hook
|
||||||
|
rev: v9.5.0
|
||||||
|
hooks:
|
||||||
|
- id: commitlint
|
||||||
|
stages: [commit-msg]
|
||||||
|
- repo: https://github.com/ejba/pre-commit-maven
|
||||||
|
rev: v0.3.4
|
||||||
|
hooks:
|
||||||
|
- id: maven
|
||||||
|
args: [ 'clean compile' ]
|
||||||
|
- id: maven-spotless-apply
|
@ -3,6 +3,7 @@
|
|||||||
[](https://github.com/WebGoat/WebGoat/graphs/contributors)
|
[](https://github.com/WebGoat/WebGoat/graphs/contributors)
|
||||||

|

|
||||||

|

|
||||||
|
[](https://conventionalcommits.org)
|
||||||
|
|
||||||
This document describes how you can contribute to WebGoat. Please read it carefully.
|
This document describes how you can contribute to WebGoat. Please read it carefully.
|
||||||
|
|
||||||
@ -41,6 +42,19 @@ Pull requests should be as small/atomic as possible. Large, wide-sweeping change
|
|||||||
|
|
||||||
### Write a good commit message
|
### Write a good commit message
|
||||||
|
|
||||||
|
* We use [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) and use the following types:
|
||||||
|
|
||||||
|
- fix:
|
||||||
|
- feat:
|
||||||
|
- build:
|
||||||
|
- chore:
|
||||||
|
- ci:
|
||||||
|
- docs:
|
||||||
|
- refactor:
|
||||||
|
- test:
|
||||||
|
|
||||||
|
Using this style of commits makes it possible to create our release notes automatically.
|
||||||
|
|
||||||
* Explain why you make the changes. [More infos about a good commit message.](https://betterprogramming.pub/stop-writing-bad-commit-messages-8df79517177d)
|
* Explain why you make the changes. [More infos about a good commit message.](https://betterprogramming.pub/stop-writing-bad-commit-messages-8df79517177d)
|
||||||
|
|
||||||
* If you fix an issue with your commit, please close the issue by [adding one of the keywords and the issue number](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue) to your commit message.
|
* If you fix an issue with your commit, please close the issue by [adding one of the keywords and the issue number](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue) to your commit message.
|
||||||
|
@ -8,11 +8,12 @@ and 2023.01 in the `pom.xml`.
|
|||||||
### Release notes:
|
### Release notes:
|
||||||
|
|
||||||
Update the release notes with the correct version. Use `git shortlog -s -n --since "JAN 06 2023"` for the list of
|
Update the release notes with the correct version. Use `git shortlog -s -n --since "JAN 06 2023"` for the list of
|
||||||
committers.
|
committers. In order to fetch the list of issues included use: `git log --graph --pretty='%C(auto)%d%Creset%s' v2023.4..origin/main`
|
||||||
|
|
||||||
```
|
```
|
||||||
mvn versions:set
|
mvn versions:set
|
||||||
<< update release notes >>
|
<< update release notes >>
|
||||||
|
mvn verify
|
||||||
git commit ....
|
git commit ....
|
||||||
git tag v2023.01
|
git tag v2023.01
|
||||||
git push --tags
|
git push --tags
|
||||||
|
12
Dockerfile
12
Dockerfile
@ -1,4 +1,4 @@
|
|||||||
FROM docker.io/eclipse-temurin:17-jre-focal
|
FROM docker.io/eclipse-temurin:21.0.1_12-jre
|
||||||
LABEL NAME = "WebGoat: A deliberately insecure Web Application"
|
LABEL NAME = "WebGoat: A deliberately insecure Web Application"
|
||||||
MAINTAINER "WebGoat team"
|
MAINTAINER "WebGoat team"
|
||||||
|
|
||||||
@ -14,6 +14,8 @@ COPY --chown=webgoat target/webgoat-*.jar /home/webgoat/webgoat.jar
|
|||||||
EXPOSE 8080
|
EXPOSE 8080
|
||||||
EXPOSE 9090
|
EXPOSE 9090
|
||||||
|
|
||||||
|
ENV TZ=Europe/Amsterdam
|
||||||
|
|
||||||
WORKDIR /home/webgoat
|
WORKDIR /home/webgoat
|
||||||
ENTRYPOINT [ "java", \
|
ENTRYPOINT [ "java", \
|
||||||
"-Duser.home=/home/webgoat", \
|
"-Duser.home=/home/webgoat", \
|
||||||
@ -27,9 +29,7 @@ ENTRYPOINT [ "java", \
|
|||||||
"--add-opens", "java.base/sun.nio.ch=ALL-UNNAMED", \
|
"--add-opens", "java.base/sun.nio.ch=ALL-UNNAMED", \
|
||||||
"--add-opens", "java.base/java.io=ALL-UNNAMED", \
|
"--add-opens", "java.base/java.io=ALL-UNNAMED", \
|
||||||
"--add-opens", "java.base/java.util=ALL-UNNAMED", \
|
"--add-opens", "java.base/java.util=ALL-UNNAMED", \
|
||||||
|
"--add-opens", "java.base/sun.nio.ch=ALL-UNNAMED", \
|
||||||
|
"--add-opens", "java.base/java.io=ALL-UNNAMED", \
|
||||||
"-Drunning.in.docker=true", \
|
"-Drunning.in.docker=true", \
|
||||||
"-Dwebgoat.host=0.0.0.0", \
|
"-jar", "webgoat.jar", "--server.address", "0.0.0.0" ]
|
||||||
"-Dwebwolf.host=0.0.0.0", \
|
|
||||||
"-Dwebgoat.port=8080", \
|
|
||||||
"-Dwebwolf.port=9090", \
|
|
||||||
"-jar", "webgoat.jar" ]
|
|
||||||
|
@ -10,12 +10,17 @@ COPY config/desktop/start_zap.sh /config/start_zap.sh
|
|||||||
COPY config/desktop/WebGoat.txt /config/Desktop/
|
COPY config/desktop/WebGoat.txt /config/Desktop/
|
||||||
|
|
||||||
RUN \
|
RUN \
|
||||||
|
case $(uname -m) in \
|
||||||
|
x86_64) ARCH=x64;; \
|
||||||
|
aarch64) ARCH=aarch64;; \
|
||||||
|
*) ARCH=unknown;; \
|
||||||
|
esac && \
|
||||||
curl -LO https://github.com/zaproxy/zaproxy/releases/download/v2.12.0/ZAP_2.12.0_Linux.tar.gz && \
|
curl -LO https://github.com/zaproxy/zaproxy/releases/download/v2.12.0/ZAP_2.12.0_Linux.tar.gz && \
|
||||||
tar zfxv ZAP_2.12.0_Linux.tar.gz && \
|
tar zfxv ZAP_2.12.0_Linux.tar.gz && \
|
||||||
rm -rf ZAP_2.12.0_Linux.tar.gz && \
|
rm -rf ZAP_2.12.0_Linux.tar.gz && \
|
||||||
curl -LO https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.6%2B10/OpenJDK17U-jre_aarch64_linux_hotspot_17.0.6_10.tar.gz && \
|
curl -LO https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.6%2B10/OpenJDK17U-jre_${ARCH}_linux_hotspot_17.0.6_10.tar.gz && \
|
||||||
tar zfxv OpenJDK17U-jre_aarch64_linux_hotspot_17.0.6_10.tar.gz && \
|
tar zfxv OpenJDK17U-jre_${ARCH}_linux_hotspot_17.0.6_10.tar.gz && \
|
||||||
rm -rf OpenJDK17U-jre_aarch64_linux_hotspot_17.0.6_10.tar.gz && \
|
rm -rf OpenJDK17U-jre_${ARCH}_linux_hotspot_17.0.6_10.tar.gz && \
|
||||||
chmod +x /config/start_webgoat.sh && \
|
chmod +x /config/start_webgoat.sh && \
|
||||||
chmod +x /config/start_zap.sh && \
|
chmod +x /config/start_zap.sh && \
|
||||||
apt-get update && \
|
apt-get update && \
|
||||||
|
7
FAQ.md
Normal file
7
FAQ.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# FAQ for development
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
### Integration tests fail
|
||||||
|
|
||||||
|
Try to run the command in the console `java -jar ...` and remove `-Dlogging.pattern.console=` from the command line.
|
29
README.md
29
README.md
@ -1,4 +1,4 @@
|
|||||||
# WebGoat 8: A deliberately insecure Web Application
|
# WebGoat: A deliberately insecure Web Application
|
||||||
|
|
||||||
[](https://github.com/WebGoat/WebGoat/actions/workflows/build.yml)
|
[](https://github.com/WebGoat/WebGoat/actions/workflows/build.yml)
|
||||||
[](https://jdk.java.net/)
|
[](https://jdk.java.net/)
|
||||||
@ -6,6 +6,7 @@
|
|||||||
[](https://github.com/WebGoat/WebGoat/releases/latest)
|
[](https://github.com/WebGoat/WebGoat/releases/latest)
|
||||||
[](https://gitter.im/OWASPWebGoat/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
[](https://gitter.im/OWASPWebGoat/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||||
[](https://github.com/WebGoat/WebGoat/discussions)
|
[](https://github.com/WebGoat/WebGoat/discussions)
|
||||||
|
[](https://conventionalcommits.org)
|
||||||
|
|
||||||
# Introduction
|
# Introduction
|
||||||
|
|
||||||
@ -43,19 +44,27 @@ Every release is also published on [DockerHub](https://hub.docker.com/r/webgoat/
|
|||||||
docker run -it -p 127.0.0.1:8080:8080 -p 127.0.0.1:9090:9090 webgoat/webgoat
|
docker run -it -p 127.0.0.1:8080:8080 -p 127.0.0.1:9090:9090 webgoat/webgoat
|
||||||
```
|
```
|
||||||
|
|
||||||
If you want to reuse the container, give it a name:
|
For some lessons you need the container run in the same timezone. For this you can set the TZ environment variable.
|
||||||
|
E.g.
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
docker run --name webgoat -it -p 127.0.0.1:8080:8080 -p 127.0.0.1:9090:9090 webgoat/webgoat
|
docker run -it -p 127.0.0.1:8080:8080 -p 127.0.0.1:9090:9090 -e TZ=America/Boise webgoat/webgoat
|
||||||
```
|
```
|
||||||
|
|
||||||
As long as you don't remove the container you can use:
|
If you want to use OWASP ZAP or another proxy, you can no longer use 127.0.0.1 or localhost. but
|
||||||
|
you can use custom host entries. For example:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
docker start webgoat
|
127.0.0.1 www.webgoat.local www.webwolf.local
|
||||||
```
|
```
|
||||||
|
|
||||||
This way, you can start where you left off. If you remove the container, you need to use `docker run` again.
|
Then you can run the container with:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
docker run -it -p 127.0.0.1:8080:8080 -p 127.0.0.1:9090:9090 -e WEBGOAT_HOST=www.webgoat.local -e WEBWOLF_HOST=www.webwolf.local -e TZ=America/Boise webgoat/webgoat
|
||||||
|
```
|
||||||
|
|
||||||
|
Then visit http://www.webgoat.local:8080/WebGoat/ and http://www.webwolf.local:9090/WebWolf/
|
||||||
|
|
||||||
## 2. Run using Docker with complete Linux Desktop
|
## 2. Run using Docker with complete Linux Desktop
|
||||||
|
|
||||||
@ -70,7 +79,8 @@ docker run -p 127.0.0.1:3000:3000 webgoat/webgoat-desktop
|
|||||||
Download the latest WebGoat release from [https://github.com/WebGoat/WebGoat/releases](https://github.com/WebGoat/WebGoat/releases)
|
Download the latest WebGoat release from [https://github.com/WebGoat/WebGoat/releases](https://github.com/WebGoat/WebGoat/releases)
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
java -Dfile.encoding=UTF-8 -Dwebgoat.port=8080 -Dwebwolf.port=9090 -jar webgoat-2023.3.jar
|
export TZ=Europe/Amsterdam # or your timezone
|
||||||
|
java -Dfile.encoding=UTF-8 -jar webgoat-2023.5.jar
|
||||||
```
|
```
|
||||||
|
|
||||||
Click the link in the log to start WebGoat.
|
Click the link in the log to start WebGoat.
|
||||||
@ -79,7 +89,7 @@ Click the link in the log to start WebGoat.
|
|||||||
|
|
||||||
### Prerequisites:
|
### Prerequisites:
|
||||||
|
|
||||||
* Java 17
|
* Java 17 or 21
|
||||||
* Your favorite IDE
|
* Your favorite IDE
|
||||||
* Git, or Git support in your IDE
|
* Git, or Git support in your IDE
|
||||||
|
|
||||||
@ -131,9 +141,10 @@ For specialist only. There is a way to set up WebGoat with a personalized menu.
|
|||||||
For instance running as a jar on a Linux/macOS it will look like this:
|
For instance running as a jar on a Linux/macOS it will look like this:
|
||||||
|
|
||||||
```Shell
|
```Shell
|
||||||
|
export TZ=Europe/Amsterdam # or your timezone
|
||||||
export EXCLUDE_CATEGORIES="CLIENT_SIDE,GENERAL,CHALLENGE"
|
export EXCLUDE_CATEGORIES="CLIENT_SIDE,GENERAL,CHALLENGE"
|
||||||
export EXCLUDE_LESSONS="SqlInjectionAdvanced,SqlInjectionMitigations"
|
export EXCLUDE_LESSONS="SqlInjectionAdvanced,SqlInjectionMitigations"
|
||||||
java -jar target/webgoat-2023.3-SNAPSHOT.jar
|
java -jar target/webgoat-2023.6-SNAPSHOT.jar
|
||||||
```
|
```
|
||||||
|
|
||||||
Or in a docker run it would (once this version is pushed into docker hub) look like this:
|
Or in a docker run it would (once this version is pushed into docker hub) look like this:
|
||||||
|
@ -17,18 +17,18 @@ The following steps are required when you want to add a new language
|
|||||||
1. Update [main_new.html](src/main/resources/webgoat/static/main_new.html)
|
1. Update [main_new.html](src/main/resources/webgoat/static/main_new.html)
|
||||||
1. Add the parts for showing the flag and providing the correct value for the flag= parameter
|
1. Add the parts for showing the flag and providing the correct value for the flag= parameter
|
||||||
2.
|
2.
|
||||||
3. Add a flag image to src/main/resources/webgoat/static/css/img
|
2. Add a flag image to src/main/resources/webgoat/static/css/img
|
||||||
1. See the main_new.html for a link to download flag resources
|
1. See the main_new.html for a link to download flag resources
|
||||||
4. Add a welcome page to the introduction lesson
|
3. Add a welcome page to the introduction lesson
|
||||||
1. Copy Introduction_.adoc to Introduction_es.adoc (if in this case you want to add Spanish)
|
1. Copy Introduction_.adoc to Introduction_es.adoc (if in this case you want to add Spanish)
|
||||||
2. Add a highlighted section that explains that most parts of WebGoat will still be in English and invite people to translate parts where it would be valuable
|
2. Add a highlighted section that explains that most parts of WebGoat will still be in English and invite people to translate parts where it would be valuable
|
||||||
5. Translate the main labels
|
4. Translate the main labels
|
||||||
1. Copy messages.properties to messages_es.properties (if in this case you want to add Spanish)
|
1. Copy messages.properties to messages_es.properties (if in this case you want to add Spanish)
|
||||||
2. Translate the label values
|
2. Translate the label values
|
||||||
6. Optionally translate lessons by
|
5. Optionally translate lessons by
|
||||||
1. Adding lang specifc adoc files in documentation folder of the lesson
|
1. Adding lang specifc adoc files in documentation folder of the lesson
|
||||||
2. Adding WebGoatLabels.properties of a specific language if you want to
|
2. Adding WebGoatLabels.properties of a specific language if you want to
|
||||||
7. Run mvn clean to see if the LabelAndHintIntegration test passes
|
6. Run mvn clean to see if the LabelAndHintIntegration test passes
|
||||||
8. Run WebGoat and verify that your own language and the other languages work as expected
|
7. Run WebGoat and verify that your own language and the other languages work as expected
|
||||||
|
|
||||||
If you only want to translate more for a certain language, you only need to do step 4-8
|
If you only want to translate more for a certain language, you only need to do step 4-8
|
||||||
|
@ -1,5 +1,73 @@
|
|||||||
# WebGoat release notes
|
# WebGoat release notes
|
||||||
|
|
||||||
|
## Version 2023.8
|
||||||
|
|
||||||
|
### 🚀 New functionality
|
||||||
|
|
||||||
|
- Consistent environment values and url references (#1677)
|
||||||
|
- Show directly requested file in requests overview
|
||||||
|
- Show creating time in file upload overview
|
||||||
|
|
||||||
|
### 🐞 Bug fixes
|
||||||
|
|
||||||
|
- Fix startup message (#1687)
|
||||||
|
- Fix/state of software supply chain links (#1683)
|
||||||
|
- Fix WebWolf UI (#1686)
|
||||||
|
|
||||||
|
### 🔄 Technical tasks
|
||||||
|
|
||||||
|
- bump actions/setup-java from 3 to 4 (#1690)
|
||||||
|
- bump commons-io:commons-io from 2.14.0 to 2.15.1 (#1689)
|
||||||
|
- bump com.diffplug.spotless:spotless-maven-plugin (#1688)
|
||||||
|
|
||||||
|
## Version 2023.5
|
||||||
|
|
||||||
|
### New functionality
|
||||||
|
|
||||||
|
- Implement JWT jku example (#1552)
|
||||||
|
- Java 21 initial support (#1622)
|
||||||
|
- improve MFAC lesson hint texts for a better user experience (#1424)
|
||||||
|
- upgrade to Spring Boot version 3 (#1477)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
- typo in WebGoad.txt (#1667)
|
||||||
|
- search box moved and jwt encode/decode with little delay (#1664)
|
||||||
|
- skip validation for JWT (#1663)
|
||||||
|
- fixed issue in JWT test tool and added robot test (#1658)
|
||||||
|
- Password reset link test condition more strict and move all WebWolf links to /WebWolf (#1645)
|
||||||
|
- fix servers id (#1619)
|
||||||
|
- potential NPE in the stored XSS assignment
|
||||||
|
- crypto basics broken links
|
||||||
|
- fixes the default change in trailing slash matching and address the affected assignments
|
||||||
|
- hint that was breaking the template, causing hints from different assignments to mix (#1424)
|
||||||
|
- HijackSession lesson template deprecated Tymeleaf attribute
|
||||||
|
- Fix NPE in IDOR lesson
|
||||||
|
- Add new assignment IT tests
|
||||||
|
- XSS mitigation
|
||||||
|
- Stored Cross-Site Scripting Lesson
|
||||||
|
- Add Assignment7 Tests
|
||||||
|
- Fix IDOR lesson
|
||||||
|
- remove steps from release script (#1509)
|
||||||
|
- robotframework fails due to updated dependencies (#1508)
|
||||||
|
- fix Java image inside Docker file The image now downloads the correct Java version based on the architecture.
|
||||||
|
- Fix typo of HijackSession_content0.adoc
|
||||||
|
- Restrict SSRF Regexes
|
||||||
|
- update challenge code - Flags are now wired through a Spring config - Introduced Flag class - Removed Flags from the FlagController
|
||||||
|
|
||||||
|
## Version 2023.4
|
||||||
|
|
||||||
|
### New functionality
|
||||||
|
|
||||||
|
- [#1422 Add Docker Linux Desktop variant with all tools installed](https://github.com/WebGoat/WebGoat/issues/1422). Thanks to the [OWASP WrongSecrets project](https://owasp.org/www-project-wrongsecrets/) we now have a Docker Linux desktop image with all the tools installed. No need to install any tools locally only run the new Docker image. See README.md for details on how to start it.
|
||||||
|
- [#1411 JWT: looks that buy as Tom also works with alg:none](https://github.com/WebGoat/WebGoat/issues/1411).
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
- [#1410 WebWolf: JWT decode is broken](https://github.com/WebGoat/WebGoat/issues/1410).
|
||||||
|
- [#1396 password_reset return 500 Error](https://github.com/WebGoat/WebGoat/issues/1396).
|
||||||
|
- [#1379 Move XXE to A05:2021-Security Misconfiguration](https://github.com/WebGoat/WebGoat/issues/1379).
|
||||||
|
|
||||||
## Version 2023.3
|
## Version 2023.3
|
||||||
|
|
||||||
With great pleasure, we present you with a new release of WebGoat **2023.3**. Finally, it has been a while. This year starts with a new release of WebGoat. This year we will undoubtedly release more often. From this release on, we began to use a new versioning scheme (https://calver.org/#scheme).
|
With great pleasure, we present you with a new release of WebGoat **2023.3**. Finally, it has been a while. This year starts with a new release of WebGoat. This year we will undoubtedly release more often. From this release on, we began to use a new versioning scheme (https://calver.org/#scheme).
|
||||||
@ -147,4 +215,3 @@ Special thanks to the following contributors providing us with a pull request:
|
|||||||
And everyone who provided feedback through Github.
|
And everyone who provided feedback through Github.
|
||||||
|
|
||||||
Team WebGoat
|
Team WebGoat
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
With this image you have WebGoat and ZAP and a browser available to you in a browser running on Ubuntu.
|
With this image you have WebGoat and ZAP and a browser available to you in a browser running on Ubuntu.
|
||||||
You can start WebGoat and ZAP by opening a terminal and type:
|
You can start WebGoat and ZAP by opening a terminal and type:
|
||||||
|
|
||||||
./start-webgoat.sh
|
./start_webgoat.sh
|
||||||
./start_zap.sh
|
./start_zap.sh
|
||||||
|
|
||||||
Happy hacking,
|
Happy hacking,
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
# WebGoat landing page
|
# WebGoat landing page
|
||||||
|
|
||||||
Old GitHub page which now redirects to OWASP website.
|
Old GitHub page which now redirects to OWASP website.
|
||||||
|
|
||||||
|
229
pom.xml
229
pom.xml
@ -1,16 +1,16 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<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>2.7.1</version>
|
<version>3.1.5</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>org.owasp.webgoat</groupId>
|
<groupId>org.owasp.webgoat</groupId>
|
||||||
<artifactId>webgoat</artifactId>
|
<artifactId>webgoat</artifactId>
|
||||||
<version>2023.4-SNAPSHOT</version>
|
<version>2023.9-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>WebGoat</name>
|
<name>WebGoat</name>
|
||||||
@ -27,6 +27,7 @@
|
|||||||
<url>https://www.gnu.org/licenses/gpl-2.0.txt</url>
|
<url>https://www.gnu.org/licenses/gpl-2.0.txt</url>
|
||||||
</license>
|
</license>
|
||||||
</licenses>
|
</licenses>
|
||||||
|
|
||||||
<developers>
|
<developers>
|
||||||
<developer>
|
<developer>
|
||||||
<id>mayhew64</id>
|
<id>mayhew64</id>
|
||||||
@ -94,7 +95,6 @@
|
|||||||
<archive>http://lists.owasp.org/pipermail/owasp-webgoat/</archive>
|
<archive>http://lists.owasp.org/pipermail/owasp-webgoat/</archive>
|
||||||
</mailingList>
|
</mailingList>
|
||||||
</mailingLists>
|
</mailingLists>
|
||||||
|
|
||||||
<scm>
|
<scm>
|
||||||
<connection>scm:git:git@github.com:WebGoat/WebGoat.git</connection>
|
<connection>scm:git:git@github.com:WebGoat/WebGoat.git</connection>
|
||||||
<developerConnection>scm:git:git@github.com:WebGoat/WebGoat.git</developerConnection>
|
<developerConnection>scm:git:git@github.com:WebGoat/WebGoat.git</developerConnection>
|
||||||
@ -108,44 +108,47 @@
|
|||||||
</issueManagement>
|
</issueManagement>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
|
||||||
<!-- Shared properties with plugins and version numbers across submodules-->
|
<!-- Shared properties with plugins and version numbers across submodules-->
|
||||||
<asciidoctorj.version>2.5.3</asciidoctorj.version>
|
<asciidoctorj.version>2.5.10</asciidoctorj.version>
|
||||||
<bootstrap.version>3.3.7</bootstrap.version>
|
<bootstrap.version>5.3.2</bootstrap.version>
|
||||||
<cglib.version>2.2</cglib.version>
|
<cglib.version>3.3.0</cglib.version>
|
||||||
<!-- do not update necessary for lesson -->
|
<!-- do not update necessary for lesson -->
|
||||||
<checkstyle.version>3.1.2</checkstyle.version>
|
<checkstyle.version>3.3.1</checkstyle.version>
|
||||||
<commons-collections.version>3.2.1</commons-collections.version>
|
<commons-collections.version>3.2.1</commons-collections.version>
|
||||||
<commons-io.version>2.6</commons-io.version>
|
<commons-io.version>2.15.1</commons-io.version>
|
||||||
<commons-lang3.version>3.12.0</commons-lang3.version>
|
<commons-lang3.version>3.12.0</commons-lang3.version>
|
||||||
<commons-text.version>1.9</commons-text.version>
|
<commons-text.version>1.10.0</commons-text.version>
|
||||||
<guava.version>30.1-jre</guava.version>
|
<guava.version>32.1.3-jre</guava.version>
|
||||||
|
<jacoco.version>0.8.11</jacoco.version>
|
||||||
<java.version>17</java.version>
|
<java.version>17</java.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.7.6</jose4j.version>
|
<jose4j.version>0.9.3</jose4j.version>
|
||||||
<jquery.version>3.5.1</jquery.version>
|
<jquery.version>3.7.0</jquery.version>
|
||||||
<jsoup.version>1.14.3</jsoup.version>
|
<jsoup.version>1.16.1</jsoup.version>
|
||||||
<maven-compiler-plugin.version>3.8.0</maven-compiler-plugin.version>
|
<maven-compiler-plugin.version>3.8.0</maven-compiler-plugin.version>
|
||||||
<maven-failsafe-plugin.version>2.22.0</maven-failsafe-plugin.version>
|
<maven-failsafe-plugin.version>2.22.0</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.0.0-M5</maven-surefire-plugin.version>
|
<maven-surefire-plugin.version>3.2.1</maven-surefire-plugin.version>
|
||||||
<maven.compiler.source>17</maven.compiler.source>
|
<maven.compiler.source>17</maven.compiler.source>
|
||||||
<maven.compiler.target>17</maven.compiler.target>
|
<maven.compiler.target>17</maven.compiler.target>
|
||||||
<pmd.version>3.15.0</pmd.version>
|
<pmd.version>3.15.0</pmd.version>
|
||||||
<!-- Use UTF-8 Encoding -->
|
<!-- Use UTF-8 Encoding -->
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
<thymeleaf.version>3.0.15.RELEASE</thymeleaf.version>
|
<thymeleaf.version>3.1.1.RELEASE</thymeleaf.version>
|
||||||
<webdriver.version>4.3.1</webdriver.version>
|
<webdriver.version>5.3.3</webdriver.version>
|
||||||
<webgoat.port>8080</webgoat.port>
|
<webgoat.context>/</webgoat.context>
|
||||||
<webwolf.port>9090</webwolf.port>
|
<webgoat.sslenabled>false</webgoat.sslenabled>
|
||||||
|
<webjars-locator-core.version>0.53</webjars-locator-core.version>
|
||||||
|
<webwolf.context>/</webwolf.context>
|
||||||
<wiremock.version>2.27.2</wiremock.version>
|
<wiremock.version>2.27.2</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 -->
|
||||||
<zxcvbn.version>1.5.2</zxcvbn.version>
|
<zxcvbn.version>1.8.0</zxcvbn.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencyManagement>
|
<dependencyManagement>
|
||||||
@ -154,7 +157,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.ow2.asm</groupId>
|
<groupId>org.ow2.asm</groupId>
|
||||||
<artifactId>asm</artifactId>
|
<artifactId>asm</artifactId>
|
||||||
<version>9.1</version>
|
<version>9.5</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -198,6 +201,17 @@
|
|||||||
<artifactId>jjwt</artifactId>
|
<artifactId>jjwt</artifactId>
|
||||||
<version>${jjwt.version}</version>
|
<version>${jjwt.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.auth0</groupId>
|
||||||
|
<artifactId>jwks-rsa</artifactId>
|
||||||
|
<version>0.22.1</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- https://mvnrepository.com/artifact/com.auth0/java-jwt -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.auth0</groupId>
|
||||||
|
<artifactId>java-jwt</artifactId>
|
||||||
|
<version>4.4.0</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.guava</groupId>
|
<groupId>com.google.guava</groupId>
|
||||||
<artifactId>guava</artifactId>
|
<artifactId>guava</artifactId>
|
||||||
@ -228,6 +242,11 @@
|
|||||||
<artifactId>jquery</artifactId>
|
<artifactId>jquery</artifactId>
|
||||||
<version>${jquery.version}</version>
|
<version>${jquery.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.webjars</groupId>
|
||||||
|
<artifactId>webjars-locator-core</artifactId>
|
||||||
|
<version>${webjars-locator-core.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.tomakehurst</groupId>
|
<groupId>com.github.tomakehurst</groupId>
|
||||||
<artifactId>wiremock</artifactId>
|
<artifactId>wiremock</artifactId>
|
||||||
@ -241,16 +260,15 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>commons-compress</artifactId>
|
<artifactId>commons-compress</artifactId>
|
||||||
<version>1.21</version>
|
<version>1.25.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jruby</groupId>
|
<groupId>org.jruby</groupId>
|
||||||
<artifactId>jruby</artifactId>
|
<artifactId>jruby</artifactId>
|
||||||
<version>9.3.6.0</version>
|
<version>9.4.3.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
@ -269,6 +287,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javax.xml.bind</groupId>
|
<groupId>javax.xml.bind</groupId>
|
||||||
<artifactId>jaxb-api</artifactId>
|
<artifactId>jaxb-api</artifactId>
|
||||||
|
<version>${jaxb.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
@ -308,9 +327,17 @@
|
|||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-oauth2-client</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.thymeleaf.extras</groupId>
|
<groupId>org.thymeleaf.extras</groupId>
|
||||||
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
|
<artifactId>thymeleaf-extras-springsecurity6</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>jakarta.servlet</groupId>
|
||||||
|
<artifactId>jakarta.servlet-api</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.hsqldb</groupId>
|
<groupId>org.hsqldb</groupId>
|
||||||
@ -340,6 +367,15 @@
|
|||||||
<groupId>io.jsonwebtoken</groupId>
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
<artifactId>jjwt</artifactId>
|
<artifactId>jjwt</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.auth0</groupId>
|
||||||
|
<artifactId>jwks-rsa</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- https://mvnrepository.com/artifact/com.auth0/java-jwt -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.auth0</groupId>
|
||||||
|
<artifactId>java-jwt</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.guava</groupId>
|
<groupId>com.google.guava</groupId>
|
||||||
<artifactId>guava</artifactId>
|
<artifactId>guava</artifactId>
|
||||||
@ -369,8 +405,17 @@
|
|||||||
<artifactId>jquery</artifactId>
|
<artifactId>jquery</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.glassfish.jaxb</groupId>
|
<groupId>org.webjars</groupId>
|
||||||
<artifactId>jaxb-runtime</artifactId>
|
<artifactId>webjars-locator-core</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>jakarta.xml.bind</groupId>
|
||||||
|
<artifactId>jakarta.xml.bind-api</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.sun.xml.bind</groupId>
|
||||||
|
<artifactId>jaxb-impl</artifactId>
|
||||||
|
<scope>runtime</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -386,6 +431,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.tomakehurst</groupId>
|
<groupId>com.github.tomakehurst</groupId>
|
||||||
<artifactId>wiremock</artifactId>
|
<artifactId>wiremock</artifactId>
|
||||||
|
<version>3.0.0-beta-2</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -393,6 +439,11 @@
|
|||||||
<artifactId>rest-assured</artifactId>
|
<artifactId>rest-assured</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-properties-migrator</artifactId>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<repositories>
|
<repositories>
|
||||||
@ -461,10 +512,19 @@
|
|||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-failsafe-plugin</artifactId>
|
<artifactId>maven-failsafe-plugin</artifactId>
|
||||||
<configuration>
|
<configuration>
|
||||||
|
<environmentVariables>
|
||||||
|
<WEBGOAT_SSLENABLED>${webgoat.sslenabled}</WEBGOAT_SSLENABLED>
|
||||||
|
<WEBGOAT_HOST>127.0.0.1</WEBGOAT_HOST>
|
||||||
|
<WEBGOAT_PORT>${webgoat.port}</WEBGOAT_PORT>
|
||||||
|
<WEBGOAT_CONTEXT>${webgoat.context}</WEBGOAT_CONTEXT>
|
||||||
|
<WEBWOLF_HOST>127.0.0.1</WEBWOLF_HOST>
|
||||||
|
<WEBWOLF_PORT>${webwolf.port}</WEBWOLF_PORT>
|
||||||
|
<WEBWOLF_CONTEXT>${webwolf.context}</WEBWOLF_CONTEXT>
|
||||||
|
</environmentVariables>
|
||||||
<systemPropertyVariables>
|
<systemPropertyVariables>
|
||||||
<logback.configurationFile>${basedir}/src/test/resources/logback-test.xml</logback.configurationFile>
|
<logback.configurationFile>${basedir}/src/test/resources/logback-test.xml</logback.configurationFile>
|
||||||
</systemPropertyVariables>
|
</systemPropertyVariables>
|
||||||
<argLine>-Xmx512m -Dwebgoatport=${webgoat.port} -Dwebwolfport=${webwolf.port}</argLine>
|
<argLine>-Xmx512m</argLine>
|
||||||
<includes>org/owasp/webgoat/*Test</includes>
|
<includes>org/owasp/webgoat/*Test</includes>
|
||||||
</configuration>
|
</configuration>
|
||||||
<executions>
|
<executions>
|
||||||
@ -487,10 +547,12 @@
|
|||||||
<artifactId>maven-surefire-plugin</artifactId>
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
<version>${maven-surefire-plugin.version}</version>
|
<version>${maven-surefire-plugin.version}</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
|
<forkedProcessTimeoutInSeconds>600</forkedProcessTimeoutInSeconds>
|
||||||
<argLine>--add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED
|
<argLine>--add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED
|
||||||
--add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED
|
--add-opens java.base/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</argLine>
|
--add-opens java.base/java.text=ALL-UNNAMED --add-opens java.desktop/java.awt.font=ALL-UNNAMED
|
||||||
|
--add-opens=java.base/sun.nio.ch=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED</argLine>
|
||||||
<excludes>
|
<excludes>
|
||||||
<exclude>**/*IntegrationTest.java</exclude>
|
<exclude>**/*IntegrationTest.java</exclude>
|
||||||
<exclude>src/it/java</exclude>
|
<exclude>src/it/java</exclude>
|
||||||
@ -503,7 +565,6 @@
|
|||||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||||
<version>${checkstyle.version}</version>
|
<version>${checkstyle.version}</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<encoding>UTF-8</encoding>
|
|
||||||
<consoleOutput>true</consoleOutput>
|
<consoleOutput>true</consoleOutput>
|
||||||
<failsOnError>true</failsOnError>
|
<failsOnError>true</failsOnError>
|
||||||
<configLocation>config/checkstyle/checkstyle.xml</configLocation>
|
<configLocation>config/checkstyle/checkstyle.xml</configLocation>
|
||||||
@ -514,7 +575,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.29.0</version>
|
<version>2.41.1</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<formats>
|
<formats>
|
||||||
<format>
|
<format>
|
||||||
@ -575,7 +636,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-enforcer-plugin</artifactId>
|
<artifactId>maven-enforcer-plugin</artifactId>
|
||||||
<version>3.0.0</version>
|
<version>3.3.0</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>restrict-log4j-versions</id>
|
<id>restrict-log4j-versions</id>
|
||||||
@ -632,16 +693,15 @@
|
|||||||
<portNames>
|
<portNames>
|
||||||
<portName>webgoat.port</portName>
|
<portName>webgoat.port</portName>
|
||||||
<portName>webwolf.port</portName>
|
<portName>webwolf.port</portName>
|
||||||
<portName>jmxPort</portName>
|
|
||||||
</portNames>
|
</portNames>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>com.bazaarvoice.maven.plugins</groupId>
|
<groupId>org.honton.chas</groupId>
|
||||||
<artifactId>process-exec-maven-plugin</artifactId>
|
<artifactId>process-exec-maven-plugin</artifactId>
|
||||||
<version>0.9</version>
|
<version>0.9.2</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>start-jar</id>
|
<id>start-jar</id>
|
||||||
@ -649,8 +709,18 @@
|
|||||||
<goal>start</goal>
|
<goal>start</goal>
|
||||||
</goals>
|
</goals>
|
||||||
<phase>pre-integration-test</phase>
|
<phase>pre-integration-test</phase>
|
||||||
|
|
||||||
<configuration>
|
<configuration>
|
||||||
<workingDir>${project.build.directory}</workingDir>
|
<workingDir>${project.build.directory}</workingDir>
|
||||||
|
<environment>
|
||||||
|
<WEBGOAT_SSLENABLED>${webgoat.sslenabled}</WEBGOAT_SSLENABLED>
|
||||||
|
<WEBGOAT_HOST>127.0.0.1</WEBGOAT_HOST>
|
||||||
|
<WEBGOAT_PORT>${webgoat.port}</WEBGOAT_PORT>
|
||||||
|
<WEBGOAT_CONTEXT>${webgoat.context}</WEBGOAT_CONTEXT>
|
||||||
|
<WEBWOLF_HOST>127.0.0.1</WEBWOLF_HOST>
|
||||||
|
<WEBWOLF_PORT>${webwolf.port}</WEBWOLF_PORT>
|
||||||
|
<WEBWOLF_CONTEXT>${webwolf.context}</WEBWOLF_CONTEXT>
|
||||||
|
</environment>
|
||||||
<arguments>
|
<arguments>
|
||||||
<argument>java</argument>
|
<argument>java</argument>
|
||||||
<argument>-jar</argument>
|
<argument>-jar</argument>
|
||||||
@ -658,8 +728,6 @@
|
|||||||
<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>-Dwebgoat.port=${webgoat.port}</argument>
|
|
||||||
<argument>-Dwebwolf.port=${webwolf.port}</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>
|
||||||
@ -678,10 +746,13 @@
|
|||||||
<argument>java.base/java.io=ALL-UNNAMED</argument>
|
<argument>java.base/java.io=ALL-UNNAMED</argument>
|
||||||
<argument>--add-opens</argument>
|
<argument>--add-opens</argument>
|
||||||
<argument>java.base/java.util=ALL-UNNAMED</argument>
|
<argument>java.base/java.util=ALL-UNNAMED</argument>
|
||||||
|
<argument>--add-opens</argument>
|
||||||
|
<argument>java.base/sun.nio.ch=ALL-UNNAMED</argument>
|
||||||
|
<argument>--add-opens</argument>
|
||||||
|
<argument>java.base/java.io=ALL-UNNAMED</argument>
|
||||||
<argument>${project.build.directory}/webgoat-${project.version}.jar</argument>
|
<argument>${project.build.directory}/webgoat-${project.version}.jar</argument>
|
||||||
</arguments>
|
</arguments>
|
||||||
<waitForInterrupt>false</waitForInterrupt>
|
<waitForInterrupt>false</waitForInterrupt>
|
||||||
<healthcheckUrl>http://localhost:${webgoat.port}/WebGoat/actuator/health</healthcheckUrl>
|
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
<execution>
|
<execution>
|
||||||
@ -706,7 +777,6 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.owasp</groupId>
|
<groupId>org.owasp</groupId>
|
||||||
<artifactId>dependency-check-maven</artifactId>
|
<artifactId>dependency-check-maven</artifactId>
|
||||||
<version>6.5.1</version>
|
|
||||||
<configuration>
|
<configuration>
|
||||||
<failBuildOnCVSS>7</failBuildOnCVSS>
|
<failBuildOnCVSS>7</failBuildOnCVSS>
|
||||||
<skipProvidedScope>false</skipProvidedScope>
|
<skipProvidedScope>false</skipProvidedScope>
|
||||||
@ -727,6 +797,81 @@
|
|||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
</profile>
|
</profile>
|
||||||
|
<profile>
|
||||||
|
<!-- run with: mvn test -Pcoverage -->
|
||||||
|
<id>coverage</id>
|
||||||
|
<activation>
|
||||||
|
<activeByDefault>false</activeByDefault>
|
||||||
|
</activation>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>${maven-surefire-plugin.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<argLine>--add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED
|
||||||
|
--add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED
|
||||||
|
--add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED
|
||||||
|
--add-opens java.base/java.text=ALL-UNNAMED --add-opens java.desktop/java.awt.font=ALL-UNNAMED
|
||||||
|
${surefire.jacoco.args}</argLine>
|
||||||
|
<excludes>
|
||||||
|
<exclude>**/*IntegrationTest.java</exclude>
|
||||||
|
<exclude>src/it/java</exclude>
|
||||||
|
<exclude>org/owasp/webgoat/*Test</exclude>
|
||||||
|
</excludes>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.jacoco</groupId>
|
||||||
|
<artifactId>jacoco-maven-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>before-unit-test</id>
|
||||||
|
<goals>
|
||||||
|
<goal>prepare-agent</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<destFile>${project.build.directory}/jacoco/jacoco-ut.exec</destFile>
|
||||||
|
<propertyName>surefire.jacoco.args</propertyName>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>check</id>
|
||||||
|
<goals>
|
||||||
|
<goal>check</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<rules>
|
||||||
|
<rule>
|
||||||
|
<element>BUNDLE</element>
|
||||||
|
<limits>
|
||||||
|
<limit>
|
||||||
|
<counter>CLASS</counter>
|
||||||
|
<value>COVEREDCOUNT</value>
|
||||||
|
<minimum>0.6</minimum>
|
||||||
|
</limit>
|
||||||
|
</limits>
|
||||||
|
</rule>
|
||||||
|
</rules>
|
||||||
|
<dataFile>${project.build.directory}/jacoco/jacoco-ut.exec</dataFile>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>after-unit-test</id>
|
||||||
|
<goals>
|
||||||
|
<goal>report</goal>
|
||||||
|
</goals>
|
||||||
|
<phase>test</phase>
|
||||||
|
<configuration>
|
||||||
|
<dataFile>${project.build.directory}/jacoco/jacoco-ut.exec</dataFile>
|
||||||
|
<outputDirectory>${project.reporting.outputDirectory}/jacoco-unit-test-coverage-report</outputDirectory>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
</profiles>
|
</profiles>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@ -12,8 +12,10 @@ Then see security settings and allow the file to run
|
|||||||
pip3 install virtualenv --user
|
pip3 install virtualenv --user
|
||||||
python3 -m virtualenv .venv
|
python3 -m virtualenv .venv
|
||||||
source .venv/bin/activate
|
source .venv/bin/activate
|
||||||
pip install robotframework
|
pip install --upgrade robotframework
|
||||||
pip install robotframework-SeleniumLibrary
|
pip install --upgrade robotframework-SeleniumLibrary
|
||||||
pip install webdriver-manager
|
pip install --upgrade webdriver-manager
|
||||||
|
brew upgrade
|
||||||
robot --variable HEADLESS:"0" --variable ENDPOINT:"http://127.0.0.1:8080/WebGoat" goat.robot
|
robot --variable HEADLESS:"0" --variable ENDPOINT:"http://127.0.0.1:8080/WebGoat" goat.robot
|
||||||
|
|
||||||
|
Make sure that the Chrome version, the webdriver version and all related components are up-to-date and compatible!
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
Documentation Setup WebGoat Robotframework tests
|
Documentation Setup WebGoat Robotframework tests
|
||||||
Library SeleniumLibrary timeout=100 run_on_failure=Capture Page Screenshot
|
Library SeleniumLibrary timeout=100 run_on_failure=Capture Page Screenshot
|
||||||
Library String
|
Library String
|
||||||
|
Library OperatingSystem
|
||||||
|
|
||||||
Suite Setup Initial_Page ${ENDPOINT} ${BROWSER}
|
Suite Setup Initial_Page ${ENDPOINT} ${BROWSER}
|
||||||
Suite Teardown Close_Page
|
Suite Teardown Close_Page
|
||||||
@ -11,7 +12,7 @@ ${BROWSER} chrome
|
|||||||
${SLEEP} 100
|
${SLEEP} 100
|
||||||
${DELAY} 0.25
|
${DELAY} 0.25
|
||||||
${ENDPOINT} http://127.0.0.1:8080/WebGoat
|
${ENDPOINT} http://127.0.0.1:8080/WebGoat
|
||||||
${ENDPOINT_WOLF} http://127.0.0.1:9090
|
${ENDPOINT_WOLF} http://127.0.0.1:9090/WebWolf
|
||||||
${USERNAME} robotuser
|
${USERNAME} robotuser
|
||||||
${PASSWORD} password
|
${PASSWORD} password
|
||||||
${HEADLESS} ${FALSE}
|
${HEADLESS} ${FALSE}
|
||||||
@ -22,22 +23,25 @@ Initial_Page
|
|||||||
[Arguments] ${ENDPOINT} ${BROWSER}
|
[Arguments] ${ENDPOINT} ${BROWSER}
|
||||||
Log To Console Start WebGoat UI Testing
|
Log To Console Start WebGoat UI Testing
|
||||||
IF ${HEADLESS}
|
IF ${HEADLESS}
|
||||||
Open Browser ${ENDPOINT} ${BROWSER} options=add_argument("-headless");add_argument("--start-maximized");add_experimental_option('prefs', {'intl.accept_languages': 'en,en_US'}) alias=webgoat
|
Open Browser ${ENDPOINT} ${BROWSER} options=add_experimental_option('prefs', {'intl.accept_languages': 'en,en_US'});add_argument("-headless");add_argument("--start-maximized") alias=webgoat
|
||||||
ELSE
|
ELSE
|
||||||
Open Browser ${ENDPOINT} ${BROWSER} options=add_experimental_option('prefs', {'intl.accept_languages': 'en,en_US'}) alias=webgoat
|
Open Browser ${ENDPOINT} ${BROWSER} options=add_experimental_option('prefs', {'intl.accept_languages': 'en,en_US'}) alias=webgoat
|
||||||
END
|
END
|
||||||
IF ${HEADLESS}
|
|
||||||
Open Browser ${ENDPOINT_WOLF}/WebWolf ${BROWSER} options=add_argument("-headless");add_argument("--start-maximized");add_experimental_option('prefs', {'intl.accept_languages': 'en,en_US'}) alias=webwolf
|
|
||||||
ELSE
|
|
||||||
Open Browser ${ENDPOINT_WOLF}/WebWolf ${BROWSER} options=add_experimental_option('prefs', {'intl.accept_languages': 'en,en_US'}) alias=webwolf
|
|
||||||
END
|
|
||||||
Switch Browser webgoat
|
Switch Browser webgoat
|
||||||
Maximize Browser Window
|
Maximize Browser Window
|
||||||
Set Window Size ${1400} ${1000}
|
Set Window Size ${1400} ${1000}
|
||||||
|
Set Window Position ${0} ${0}
|
||||||
|
Set Selenium Speed ${DELAY}
|
||||||
|
Log To Console Start WebWolf UI Testing
|
||||||
|
IF ${HEADLESS}
|
||||||
|
Open Browser ${ENDPOINT_WOLF} ${BROWSER} options=add_experimental_option('prefs', {'intl.accept_languages': 'en,en_US'});add_argument("-headless");add_argument("--start-maximized") alias=webwolf
|
||||||
|
ELSE
|
||||||
|
Open Browser ${ENDPOINT_WOLF} ${BROWSER} options=add_experimental_option('prefs', {'intl.accept_languages': 'en,en_US'}) alias=webwolf
|
||||||
|
END
|
||||||
Switch Browser webwolf
|
Switch Browser webwolf
|
||||||
Maximize Browser Window
|
Maximize Browser Window
|
||||||
Set Window Size ${1400} ${1000}
|
Set Window Size ${1400} ${1000}
|
||||||
Set Window Position ${400} ${200}
|
Set Window Position ${500} ${0}
|
||||||
Set Selenium Speed ${DELAY}
|
Set Selenium Speed ${DELAY}
|
||||||
|
|
||||||
Close_Page
|
Close_Page
|
||||||
@ -53,6 +57,7 @@ Close_Page
|
|||||||
*** Test Cases ***
|
*** Test Cases ***
|
||||||
|
|
||||||
Check_Initial_Page
|
Check_Initial_Page
|
||||||
|
[Tags] WebGoatTests
|
||||||
Switch Browser webgoat
|
Switch Browser webgoat
|
||||||
Page Should Contain Username
|
Page Should Contain Username
|
||||||
Click Button Sign in
|
Click Button Sign in
|
||||||
@ -60,6 +65,7 @@ Check_Initial_Page
|
|||||||
Click Link /WebGoat/registration
|
Click Link /WebGoat/registration
|
||||||
|
|
||||||
Check_Registration_Page
|
Check_Registration_Page
|
||||||
|
[Tags] WebGoatTests
|
||||||
Page Should Contain Username
|
Page Should Contain Username
|
||||||
Input Text username ${USERNAME}
|
Input Text username ${USERNAME}
|
||||||
Input Text password ${PASSWORD}
|
Input Text password ${PASSWORD}
|
||||||
@ -68,6 +74,7 @@ Check_Registration_Page
|
|||||||
Click Button Sign up
|
Click Button Sign up
|
||||||
|
|
||||||
Check_Welcome_Page
|
Check_Welcome_Page
|
||||||
|
[Tags] WebGoatTests
|
||||||
Page Should Contain WebGoat
|
Page Should Contain WebGoat
|
||||||
Go To ${ENDPOINT}/login
|
Go To ${ENDPOINT}/login
|
||||||
Page Should Contain Username
|
Page Should Contain Username
|
||||||
@ -77,6 +84,7 @@ Check_Welcome_Page
|
|||||||
Page Should Contain WebGoat
|
Page Should Contain WebGoat
|
||||||
|
|
||||||
Check_Menu_Page
|
Check_Menu_Page
|
||||||
|
[Tags] WebGoatTests
|
||||||
Click Element css=a[category='Introduction']
|
Click Element css=a[category='Introduction']
|
||||||
Click Element Introduction-WebGoat
|
Click Element Introduction-WebGoat
|
||||||
CLick Element Introduction-WebWolf
|
CLick Element Introduction-WebWolf
|
||||||
@ -93,9 +101,29 @@ Check_Menu_Page
|
|||||||
|
|
||||||
Check_WebWolf
|
Check_WebWolf
|
||||||
Switch Browser webwolf
|
Switch Browser webwolf
|
||||||
location should be ${ENDPOINT_WOLF}/WebWolf
|
location should be ${ENDPOINT_WOLF}/login
|
||||||
Go To ${ENDPOINT_WOLF}/mail
|
|
||||||
Input Text username ${USERNAME}
|
Input Text username ${USERNAME}
|
||||||
Input Text password ${PASSWORD}
|
Input Text password ${PASSWORD}
|
||||||
Click Button Sign In
|
Click Button Sign In
|
||||||
|
Go To ${ENDPOINT_WOLF}/mail
|
||||||
|
Go To ${ENDPOINT_WOLF}/requests
|
||||||
|
Go To ${ENDPOINT_WOLF}/files
|
||||||
|
|
||||||
|
Check_JWT_Page
|
||||||
|
Go To ${ENDPOINT_WOLF}/jwt
|
||||||
|
Click Element token
|
||||||
|
Wait Until Element Is Enabled token 5s
|
||||||
|
Input Text token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
|
||||||
|
Click Element secretKey
|
||||||
|
Input Text secretKey none
|
||||||
|
Sleep 2s # Pause before reading the result
|
||||||
|
${OUT_VALUE} Get Value xpath=//textarea[@id='token']
|
||||||
|
Log To Console Found token ${OUT_VALUE}
|
||||||
|
${OUT_RESULT} Evaluate "ImuPnHvLdU7ULKfbD4aJU" in """${OUT_VALUE}"""
|
||||||
|
Log To Console Found token ${OUT_RESULT}
|
||||||
|
Capture Page Screenshot
|
||||||
|
|
||||||
|
Check_Files_Page
|
||||||
|
Go To ${ENDPOINT_WOLF}/files
|
||||||
|
Choose File css:input[type="file"] ${CURDIR}/goat.robot
|
||||||
|
Click Button Upload files
|
||||||
|
@ -25,7 +25,7 @@ class AccessControlIntegrationTest extends IntegrationTest {
|
|||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.get(url("/WebGoat/access-control/users-admin-fix"))
|
.get(url("access-control/users-admin-fix"))
|
||||||
.then()
|
.then()
|
||||||
.statusCode(HttpStatus.SC_FORBIDDEN);
|
.statusCode(HttpStatus.SC_FORBIDDEN);
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ class AccessControlIntegrationTest extends IntegrationTest {
|
|||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body(String.format(userTemplate, this.getUser(), this.getUser()))
|
.body(String.format(userTemplate, this.getUser(), this.getUser()))
|
||||||
.post(url("/WebGoat/access-control/users"))
|
.post(url("access-control/users"))
|
||||||
.then()
|
.then()
|
||||||
.statusCode(HttpStatus.SC_OK);
|
.statusCode(HttpStatus.SC_OK);
|
||||||
|
|
||||||
@ -51,15 +51,14 @@ class AccessControlIntegrationTest extends IntegrationTest {
|
|||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.get(url("/WebGoat/access-control/users-admin-fix"))
|
.get(url("access-control/users-admin-fix"))
|
||||||
.then()
|
.then()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.extract()
|
.extract()
|
||||||
.jsonPath()
|
.jsonPath()
|
||||||
.get("find { it.username == \"Jerry\" }.userHash");
|
.get("find { it.username == \"Jerry\" }.userHash");
|
||||||
|
|
||||||
checkAssignment(
|
checkAssignment(url("access-control/user-hash-fix"), Map.of("userHash", userHash), true);
|
||||||
url("/WebGoat/access-control/user-hash-fix"), Map.of("userHash", userHash), true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assignment2() {
|
private void assignment2() {
|
||||||
@ -69,18 +68,18 @@ class AccessControlIntegrationTest extends IntegrationTest {
|
|||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.get(url("/WebGoat/access-control/users"))
|
.get(url("access-control/users"))
|
||||||
.then()
|
.then()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.extract()
|
.extract()
|
||||||
.jsonPath()
|
.jsonPath()
|
||||||
.get("find { it.username == \"Jerry\" }.userHash");
|
.get("find { it.username == \"Jerry\" }.userHash");
|
||||||
|
|
||||||
checkAssignment(url("/WebGoat/access-control/user-hash"), Map.of("userHash", userHash), true);
|
checkAssignment(url("access-control/user-hash"), Map.of("userHash", userHash), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assignment1() {
|
private void assignment1() {
|
||||||
var params = Map.of("hiddenMenu1", "Users", "hiddenMenu2", "Config");
|
var params = Map.of("hiddenMenu1", "Users", "hiddenMenu2", "Config");
|
||||||
checkAssignment(url("/WebGoat/access-control/hidden-menu"), params, true);
|
checkAssignment(url("access-control/hidden-menu"), params, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,12 +64,12 @@ public class CSRFIntegrationTest extends IntegrationTest {
|
|||||||
public void init() {
|
public void init() {
|
||||||
startLesson("CSRF");
|
startLesson("CSRF");
|
||||||
webwolfFileDir = getWebWolfFileServerLocation();
|
webwolfFileDir = getWebWolfFileServerLocation();
|
||||||
uploadTrickHtml("csrf3.html", trickHTML3.replace("WEBGOATURL", url("/csrf/basic-get-flag")));
|
uploadTrickHtml("csrf3.html", trickHTML3.replace("WEBGOATURL", url("csrf/basic-get-flag")));
|
||||||
uploadTrickHtml("csrf4.html", trickHTML4.replace("WEBGOATURL", url("/csrf/review")));
|
uploadTrickHtml("csrf4.html", trickHTML4.replace("WEBGOATURL", url("csrf/review")));
|
||||||
uploadTrickHtml("csrf7.html", trickHTML7.replace("WEBGOATURL", url("/csrf/feedback/message")));
|
uploadTrickHtml("csrf7.html", trickHTML7.replace("WEBGOATURL", url("csrf/feedback/message")));
|
||||||
uploadTrickHtml(
|
uploadTrickHtml(
|
||||||
"csrf8.html",
|
"csrf8.html",
|
||||||
trickHTML8.replace("WEBGOATURL", url("/login")).replace("USERNAME", this.getUser()));
|
trickHTML8.replace("WEBGOATURL", url("login")).replace("USERNAME", this.getUser()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestFactory
|
@TestFactory
|
||||||
@ -103,7 +103,7 @@ public class CSRFIntegrationTest extends IntegrationTest {
|
|||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("WEBWOLFSESSION", getWebWolfCookie())
|
.cookie("WEBWOLFSESSION", getWebWolfCookie())
|
||||||
.multiPart("file", htmlName, htmlContent.getBytes())
|
.multiPart("file", htmlName, htmlContent.getBytes())
|
||||||
.post(webWolfUrl("/WebWolf/fileupload"))
|
.post(webWolfUrl("fileupload"))
|
||||||
.then()
|
.then()
|
||||||
.extract()
|
.extract()
|
||||||
.response()
|
.response()
|
||||||
@ -118,7 +118,7 @@ public class CSRFIntegrationTest extends IntegrationTest {
|
|||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
.cookie("WEBWOLFSESSION", getWebWolfCookie())
|
.cookie("WEBWOLFSESSION", getWebWolfCookie())
|
||||||
.get(webWolfUrl("/files/" + this.getUser() + "/" + htmlName))
|
.get(webWolfUrl("files/" + this.getUser() + "/" + htmlName))
|
||||||
.then()
|
.then()
|
||||||
.extract()
|
.extract()
|
||||||
.response()
|
.response()
|
||||||
@ -136,7 +136,7 @@ public class CSRFIntegrationTest extends IntegrationTest {
|
|||||||
.when()
|
.when()
|
||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
.header("Referer", webWolfUrl("/files/fake.html"))
|
.header("Referer", webWolfUrl("files/fake.html"))
|
||||||
.post(goatURL)
|
.post(goatURL)
|
||||||
.then()
|
.then()
|
||||||
.extract()
|
.extract()
|
||||||
@ -146,7 +146,7 @@ public class CSRFIntegrationTest extends IntegrationTest {
|
|||||||
Map<String, Object> params = new HashMap<>();
|
Map<String, Object> params = new HashMap<>();
|
||||||
params.clear();
|
params.clear();
|
||||||
params.put("confirmFlagVal", flag);
|
params.put("confirmFlagVal", flag);
|
||||||
checkAssignment(url("/WebGoat/csrf/confirm-flag-1"), params, true);
|
checkAssignment(url("csrf/confirm-flag-1"), params, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkAssignment4(String goatURL) {
|
private void checkAssignment4(String goatURL) {
|
||||||
@ -163,7 +163,7 @@ public class CSRFIntegrationTest extends IntegrationTest {
|
|||||||
.when()
|
.when()
|
||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
.header("Referer", webWolfUrl("/files/fake.html"))
|
.header("Referer", webWolfUrl("files/fake.html"))
|
||||||
.formParams(params)
|
.formParams(params)
|
||||||
.post(goatURL)
|
.post(goatURL)
|
||||||
.then()
|
.then()
|
||||||
@ -184,7 +184,7 @@ public class CSRFIntegrationTest extends IntegrationTest {
|
|||||||
.when()
|
.when()
|
||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
.header("Referer", webWolfUrl("/files/fake.html"))
|
.header("Referer", webWolfUrl("files/fake.html"))
|
||||||
.contentType(ContentType.TEXT)
|
.contentType(ContentType.TEXT)
|
||||||
.body(
|
.body(
|
||||||
"{\"name\":\"WebGoat\",\"email\":\"webgoat@webgoat.org\",\"content\":\"WebGoat is"
|
"{\"name\":\"WebGoat\",\"email\":\"webgoat@webgoat.org\",\"content\":\"WebGoat is"
|
||||||
@ -198,7 +198,7 @@ public class CSRFIntegrationTest extends IntegrationTest {
|
|||||||
|
|
||||||
params.clear();
|
params.clear();
|
||||||
params.put("confirmFlagVal", flag);
|
params.put("confirmFlagVal", flag);
|
||||||
checkAssignment(url("/WebGoat/csrf/feedback"), params, true);
|
checkAssignment(url("csrf/feedback"), params, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkAssignment8(String goatURL) {
|
private void checkAssignment8(String goatURL) {
|
||||||
@ -217,7 +217,7 @@ public class CSRFIntegrationTest extends IntegrationTest {
|
|||||||
.when()
|
.when()
|
||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
.header("Referer", webWolfUrl("/files/fake.html"))
|
.header("Referer", webWolfUrl("files/fake.html"))
|
||||||
.params(params)
|
.params(params)
|
||||||
.post(goatURL)
|
.post(goatURL)
|
||||||
.then()
|
.then()
|
||||||
@ -239,7 +239,7 @@ public class CSRFIntegrationTest extends IntegrationTest {
|
|||||||
.when()
|
.when()
|
||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("JSESSIONID", newCookie)
|
.cookie("JSESSIONID", newCookie)
|
||||||
.post(url("/csrf/login"))
|
.post(url("csrf/login"))
|
||||||
.then()
|
.then()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.extract()
|
.extract()
|
||||||
@ -253,7 +253,8 @@ public class CSRFIntegrationTest extends IntegrationTest {
|
|||||||
Overview[] assignments =
|
Overview[] assignments =
|
||||||
RestAssured.given()
|
RestAssured.given()
|
||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
.get(url("/service/lessonoverview.mvc"))
|
.relaxedHTTPSValidation()
|
||||||
|
.get(url("service/lessonoverview.mvc"))
|
||||||
.then()
|
.then()
|
||||||
.extract()
|
.extract()
|
||||||
.jsonPath()
|
.jsonPath()
|
||||||
|
@ -7,12 +7,14 @@ import java.util.Arrays;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import org.assertj.core.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
|
||||||
public class ChallengeIntegrationTest extends IntegrationTest {
|
public class ChallengeIntegrationTest extends IntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testChallenge1() {
|
void testChallenge1() {
|
||||||
startLesson("Challenge1");
|
startLesson("Challenge1");
|
||||||
|
|
||||||
byte[] resultBytes =
|
byte[] resultBytes =
|
||||||
@ -20,7 +22,7 @@ public class ChallengeIntegrationTest extends IntegrationTest {
|
|||||||
.when()
|
.when()
|
||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
.get(url("/WebGoat/challenge/logo"))
|
.get(url("challenge/logo"))
|
||||||
.then()
|
.then()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.extract()
|
.extract()
|
||||||
@ -32,14 +34,14 @@ 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(url("/WebGoat/challenge/1"), params, true);
|
checkAssignment(url("challenge/1"), params, true);
|
||||||
String result =
|
String result =
|
||||||
RestAssured.given()
|
RestAssured.given()
|
||||||
.when()
|
.when()
|
||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
.formParams(params)
|
.formParams(params)
|
||||||
.post(url("/WebGoat/challenge/1"))
|
.post(url("challenge/1"))
|
||||||
.then()
|
.then()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.extract()
|
.extract()
|
||||||
@ -48,7 +50,7 @@ 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(url("/WebGoat/challenge/flag"), params, true);
|
checkAssignment(url("challenge/flag"), params, true);
|
||||||
|
|
||||||
checkResults("/challenge/1");
|
checkResults("/challenge/1");
|
||||||
|
|
||||||
@ -57,7 +59,7 @@ public class ChallengeIntegrationTest extends IntegrationTest {
|
|||||||
.when()
|
.when()
|
||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
.get(url("/WebGoat/scoreboard-data"))
|
.get(url("scoreboard-data"))
|
||||||
.then()
|
.then()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.extract()
|
.extract()
|
||||||
@ -67,7 +69,7 @@ public class ChallengeIntegrationTest extends IntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testChallenge5() {
|
void testChallenge5() {
|
||||||
startLesson("Challenge5");
|
startLesson("Challenge5");
|
||||||
|
|
||||||
Map<String, Object> params = new HashMap<>();
|
Map<String, Object> params = new HashMap<>();
|
||||||
@ -81,7 +83,7 @@ public class ChallengeIntegrationTest extends IntegrationTest {
|
|||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
.formParams(params)
|
.formParams(params)
|
||||||
.post(url("/WebGoat/challenge/5"))
|
.post(url("challenge/5"))
|
||||||
.then()
|
.then()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.extract()
|
.extract()
|
||||||
@ -90,7 +92,7 @@ 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(url("/WebGoat/challenge/flag"), params, true);
|
checkAssignment(url("challenge/flag"), params, true);
|
||||||
|
|
||||||
checkResults("/challenge/5");
|
checkResults("/challenge/5");
|
||||||
|
|
||||||
@ -99,7 +101,7 @@ public class ChallengeIntegrationTest extends IntegrationTest {
|
|||||||
.when()
|
.when()
|
||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
.get(url("/WebGoat/scoreboard-data"))
|
.get(url("scoreboard-data"))
|
||||||
.then()
|
.then()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.extract()
|
.extract()
|
||||||
@ -107,4 +109,62 @@ public class ChallengeIntegrationTest extends IntegrationTest {
|
|||||||
.get("find { it.username == \"" + this.getUser() + "\" }.flagsCaptured");
|
.get("find { it.username == \"" + this.getUser() + "\" }.flagsCaptured");
|
||||||
assertTrue(capturefFlags.contains("Without password"));
|
assertTrue(capturefFlags.contains("Without password"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testChallenge7() {
|
||||||
|
startLesson("Challenge7");
|
||||||
|
cleanMailbox();
|
||||||
|
|
||||||
|
// One should first be able to download git.zip from WebGoat
|
||||||
|
RestAssured.given()
|
||||||
|
.when()
|
||||||
|
.relaxedHTTPSValidation()
|
||||||
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
|
.get(url("challenge/7/.git"))
|
||||||
|
.then()
|
||||||
|
.statusCode(200)
|
||||||
|
.extract()
|
||||||
|
.asString();
|
||||||
|
|
||||||
|
// Should send an email to WebWolf inbox this should give a hint to the link being static
|
||||||
|
RestAssured.given()
|
||||||
|
.when()
|
||||||
|
.relaxedHTTPSValidation()
|
||||||
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
|
.formParams("email", getUser() + "@webgoat.org")
|
||||||
|
.post(url("challenge/7"))
|
||||||
|
.then()
|
||||||
|
.statusCode(200)
|
||||||
|
.extract()
|
||||||
|
.asString();
|
||||||
|
|
||||||
|
// Check whether email has been received
|
||||||
|
var responseBody =
|
||||||
|
RestAssured.given()
|
||||||
|
.when()
|
||||||
|
.relaxedHTTPSValidation()
|
||||||
|
.cookie("WEBWOLFSESSION", getWebWolfCookie())
|
||||||
|
.get(webWolfUrl("mail"))
|
||||||
|
.then()
|
||||||
|
.extract()
|
||||||
|
.response()
|
||||||
|
.getBody()
|
||||||
|
.asString();
|
||||||
|
Assertions.assertThat(responseBody).contains("Hi, you requested a password reset link");
|
||||||
|
|
||||||
|
// Call reset link with admin link
|
||||||
|
String result =
|
||||||
|
RestAssured.given()
|
||||||
|
.when()
|
||||||
|
.relaxedHTTPSValidation()
|
||||||
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
|
.get(url("challenge/7/reset-password/{link}"), "375afe1104f4a487a73823c50a9292a2")
|
||||||
|
.then()
|
||||||
|
.statusCode(HttpStatus.ACCEPTED.value())
|
||||||
|
.extract()
|
||||||
|
.asString();
|
||||||
|
|
||||||
|
String flag = result.substring(result.indexOf("flag") + 6, result.indexOf("flag") + 42);
|
||||||
|
checkAssignment(url("challenge/flag"), Map.of("flag", flag), true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ public class CryptoIntegrationTest extends IntegrationTest {
|
|||||||
.when()
|
.when()
|
||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
.get(url("/crypto/encoding/basic"))
|
.get(url("crypto/encoding/basic"))
|
||||||
.then()
|
.then()
|
||||||
.extract()
|
.extract()
|
||||||
.asString();
|
.asString();
|
||||||
@ -64,7 +64,7 @@ public class CryptoIntegrationTest extends IntegrationTest {
|
|||||||
params.clear();
|
params.clear();
|
||||||
params.put("answer_user", answer_user);
|
params.put("answer_user", answer_user);
|
||||||
params.put("answer_pwd", answer_pwd);
|
params.put("answer_pwd", answer_pwd);
|
||||||
checkAssignment(url("/crypto/encoding/basic-auth"), params, true);
|
checkAssignment(url("crypto/encoding/basic-auth"), params, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkAssignment3() {
|
private void checkAssignment3() {
|
||||||
@ -72,7 +72,7 @@ public class CryptoIntegrationTest extends IntegrationTest {
|
|||||||
Map<String, Object> params = new HashMap<>();
|
Map<String, Object> params = new HashMap<>();
|
||||||
params.clear();
|
params.clear();
|
||||||
params.put("answer_pwd1", answer_1);
|
params.put("answer_pwd1", answer_1);
|
||||||
checkAssignment(url("/crypto/encoding/xor"), params, true);
|
checkAssignment(url("crypto/encoding/xor"), params, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkAssignment4() throws NoSuchAlgorithmException {
|
private void checkAssignment4() throws NoSuchAlgorithmException {
|
||||||
@ -82,7 +82,7 @@ public class CryptoIntegrationTest extends IntegrationTest {
|
|||||||
.when()
|
.when()
|
||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
.get(url("/crypto/hashing/md5"))
|
.get(url("crypto/hashing/md5"))
|
||||||
.then()
|
.then()
|
||||||
.extract()
|
.extract()
|
||||||
.asString();
|
.asString();
|
||||||
@ -92,7 +92,7 @@ public class CryptoIntegrationTest extends IntegrationTest {
|
|||||||
.when()
|
.when()
|
||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
.get(url("/crypto/hashing/sha256"))
|
.get(url("crypto/hashing/sha256"))
|
||||||
.then()
|
.then()
|
||||||
.extract()
|
.extract()
|
||||||
.asString();
|
.asString();
|
||||||
@ -112,7 +112,7 @@ public class CryptoIntegrationTest extends IntegrationTest {
|
|||||||
params.clear();
|
params.clear();
|
||||||
params.put("answer_pwd1", answer_1);
|
params.put("answer_pwd1", answer_1);
|
||||||
params.put("answer_pwd2", answer_2);
|
params.put("answer_pwd2", answer_2);
|
||||||
checkAssignment(url("/WebGoat/crypto/hashing"), params, true);
|
checkAssignment(url("crypto/hashing"), params, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkAssignmentSigning() throws NoSuchAlgorithmException, InvalidKeySpecException {
|
private void checkAssignmentSigning() throws NoSuchAlgorithmException, InvalidKeySpecException {
|
||||||
@ -122,7 +122,7 @@ public class CryptoIntegrationTest extends IntegrationTest {
|
|||||||
.when()
|
.when()
|
||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
.get(url("/crypto/signing/getprivate"))
|
.get(url("crypto/signing/getprivate"))
|
||||||
.then()
|
.then()
|
||||||
.extract()
|
.extract()
|
||||||
.asString();
|
.asString();
|
||||||
@ -135,7 +135,7 @@ public class CryptoIntegrationTest extends IntegrationTest {
|
|||||||
params.clear();
|
params.clear();
|
||||||
params.put("modulus", modulus);
|
params.put("modulus", modulus);
|
||||||
params.put("signature", signature);
|
params.put("signature", signature);
|
||||||
checkAssignment(url("/crypto/signing/verify"), params, true);
|
checkAssignment(url("crypto/signing/verify"), params, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkAssignmentDefaults() {
|
private void checkAssignmentDefaults() {
|
||||||
@ -151,6 +151,6 @@ public class CryptoIntegrationTest extends IntegrationTest {
|
|||||||
params.clear();
|
params.clear();
|
||||||
params.put("secretText", text);
|
params.put("secretText", text);
|
||||||
params.put("secretFileName", "default_secret");
|
params.put("secretFileName", "default_secret");
|
||||||
checkAssignment(url("/crypto/secure/defaults"), params, true);
|
checkAssignment(url("crypto/secure/defaults"), params, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ public class DeserializationIntegrationTest extends IntegrationTest {
|
|||||||
params.put(
|
params.put(
|
||||||
"token", SerializationHelper.toString(new VulnerableTaskHolder("wait", "sleep 5")));
|
"token", SerializationHelper.toString(new VulnerableTaskHolder("wait", "sleep 5")));
|
||||||
}
|
}
|
||||||
checkAssignment(url("/WebGoat/InsecureDeserialization/task"), params, true);
|
checkAssignment(url("InsecureDeserialization/task"), params, true);
|
||||||
|
|
||||||
checkResults("/InsecureDeserialization/");
|
checkResults("/InsecureDeserialization/");
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,7 @@ public class GeneralLessonIntegrationTest extends IntegrationTest {
|
|||||||
params.put(
|
params.put(
|
||||||
"question_3_solution",
|
"question_3_solution",
|
||||||
"Solution 2: The systems security is compromised even if only one goal is harmed.");
|
"Solution 2: The systems security is compromised even if only one goal is harmed.");
|
||||||
checkAssignment(url("/WebGoat/cia/quiz"), params, true);
|
checkAssignment(url("cia/quiz"), params, true);
|
||||||
checkResults("/cia/");
|
checkResults("/cia/");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,7 +95,7 @@ public class GeneralLessonIntegrationTest extends IntegrationTest {
|
|||||||
Map<String, Object> params = new HashMap<>();
|
Map<String, Object> params = new HashMap<>();
|
||||||
params.clear();
|
params.clear();
|
||||||
params.put("payload", solution);
|
params.put("payload", solution);
|
||||||
checkAssignment(url("/WebGoat/VulnerableComponents/attack1"), params, true);
|
checkAssignment(url("VulnerableComponents/attack1"), params, true);
|
||||||
checkResults("/VulnerableComponents/");
|
checkResults("/VulnerableComponents/");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -107,7 +107,7 @@ public class GeneralLessonIntegrationTest extends IntegrationTest {
|
|||||||
params.clear();
|
params.clear();
|
||||||
params.put("username", "CaptainJack");
|
params.put("username", "CaptainJack");
|
||||||
params.put("password", "BlackPearl");
|
params.put("password", "BlackPearl");
|
||||||
checkAssignment(url("/WebGoat/InsecureLogin/task"), params, true);
|
checkAssignment(url("InsecureLogin/task"), params, true);
|
||||||
checkResults("/InsecureLogin/");
|
checkResults("/InsecureLogin/");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,7 +117,7 @@ public class GeneralLessonIntegrationTest extends IntegrationTest {
|
|||||||
Map<String, Object> params = new HashMap<>();
|
Map<String, Object> params = new HashMap<>();
|
||||||
params.clear();
|
params.clear();
|
||||||
params.put("password", "ajnaeliclm^&&@kjn.");
|
params.put("password", "ajnaeliclm^&&@kjn.");
|
||||||
checkAssignment(url("/WebGoat/SecurePasswords/assignment"), params, true);
|
checkAssignment(url("SecurePasswords/assignment"), params, true);
|
||||||
checkResults("SecurePasswords/");
|
checkResults("SecurePasswords/");
|
||||||
|
|
||||||
startLesson("AuthBypass");
|
startLesson("AuthBypass");
|
||||||
@ -127,7 +127,7 @@ public class GeneralLessonIntegrationTest extends IntegrationTest {
|
|||||||
params.put("jsEnabled", "1");
|
params.put("jsEnabled", "1");
|
||||||
params.put("verifyMethod", "SEC_QUESTIONS");
|
params.put("verifyMethod", "SEC_QUESTIONS");
|
||||||
params.put("userId", "12309746");
|
params.put("userId", "12309746");
|
||||||
checkAssignment(url("/WebGoat/auth-bypass/verify-account"), params, true);
|
checkAssignment(url("auth-bypass/verify-account"), params, true);
|
||||||
checkResults("/auth-bypass/");
|
checkResults("/auth-bypass/");
|
||||||
|
|
||||||
startLesson("HttpProxies");
|
startLesson("HttpProxies");
|
||||||
@ -138,8 +138,7 @@ public class GeneralLessonIntegrationTest extends IntegrationTest {
|
|||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
.header("x-request-intercepted", "true")
|
.header("x-request-intercepted", "true")
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.get(
|
.get(url("HttpProxies/intercept-request?changeMe=Requests are tampered easily"))
|
||||||
url("/WebGoat/HttpProxies/intercept-request?changeMe=Requests are tampered easily"))
|
|
||||||
.then()
|
.then()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.extract()
|
.extract()
|
||||||
@ -165,7 +164,7 @@ public class GeneralLessonIntegrationTest extends IntegrationTest {
|
|||||||
.header("webgoat-requested-by", "dom-xss-vuln")
|
.header("webgoat-requested-by", "dom-xss-vuln")
|
||||||
.header("X-Requested-With", "XMLHttpRequest")
|
.header("X-Requested-With", "XMLHttpRequest")
|
||||||
.formParams(params)
|
.formParams(params)
|
||||||
.post(url("/WebGoat/CrossSiteScripting/phone-home-xss"))
|
.post(url("CrossSiteScripting/phone-home-xss"))
|
||||||
.then()
|
.then()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.extract()
|
.extract()
|
||||||
@ -174,12 +173,12 @@ public class GeneralLessonIntegrationTest extends IntegrationTest {
|
|||||||
|
|
||||||
params.clear();
|
params.clear();
|
||||||
params.put("successMessage", secretNumber);
|
params.put("successMessage", secretNumber);
|
||||||
checkAssignment(url("/WebGoat/ChromeDevTools/dummy"), params, true);
|
checkAssignment(url("ChromeDevTools/dummy"), params, true);
|
||||||
|
|
||||||
params.clear();
|
params.clear();
|
||||||
params.put("number", "24");
|
params.put("number", "24");
|
||||||
params.put("network_num", "24");
|
params.put("network_num", "24");
|
||||||
checkAssignment(url("/WebGoat/ChromeDevTools/network"), params, true);
|
checkAssignment(url("ChromeDevTools/network"), params, true);
|
||||||
|
|
||||||
checkResults("/ChromeDevTools/");
|
checkResults("/ChromeDevTools/");
|
||||||
}
|
}
|
||||||
@ -194,7 +193,7 @@ public class GeneralLessonIntegrationTest extends IntegrationTest {
|
|||||||
params.put("jsEnabled", "1");
|
params.put("jsEnabled", "1");
|
||||||
params.put("verifyMethod", "SEC_QUESTIONS");
|
params.put("verifyMethod", "SEC_QUESTIONS");
|
||||||
params.put("userId", "12309746");
|
params.put("userId", "12309746");
|
||||||
checkAssignment(url("/auth-bypass/verify-account"), params, true);
|
checkAssignment(url("auth-bypass/verify-account"), params, true);
|
||||||
checkResults("/auth-bypass/");
|
checkResults("/auth-bypass/");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,7 +204,7 @@ public class GeneralLessonIntegrationTest extends IntegrationTest {
|
|||||||
params.clear();
|
params.clear();
|
||||||
params.put("param1", "secr37Value");
|
params.put("param1", "secr37Value");
|
||||||
params.put("param2", "Main");
|
params.put("param2", "Main");
|
||||||
checkAssignment(url("/lesson-template/sample-attack"), params, true);
|
checkAssignment(url("lesson-template/sample-attack"), params, true);
|
||||||
checkResults("/lesson-template/");
|
checkResults("/lesson-template/");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,9 @@ import static org.junit.jupiter.api.DynamicTest.dynamicTest;
|
|||||||
|
|
||||||
import io.restassured.RestAssured;
|
import io.restassured.RestAssured;
|
||||||
import io.restassured.http.ContentType;
|
import io.restassured.http.ContentType;
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import lombok.SneakyThrows;
|
|
||||||
import org.hamcrest.CoreMatchers;
|
import org.hamcrest.CoreMatchers;
|
||||||
import org.hamcrest.MatcherAssert;
|
import org.hamcrest.MatcherAssert;
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
@ -19,7 +17,6 @@ import org.junit.jupiter.api.TestFactory;
|
|||||||
public class IDORIntegrationTest extends IntegrationTest {
|
public class IDORIntegrationTest extends IntegrationTest {
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
@SneakyThrows
|
|
||||||
public void init() {
|
public void init() {
|
||||||
startLesson("IDOR");
|
startLesson("IDOR");
|
||||||
}
|
}
|
||||||
@ -27,56 +24,63 @@ public class IDORIntegrationTest extends IntegrationTest {
|
|||||||
@TestFactory
|
@TestFactory
|
||||||
Iterable<DynamicTest> testIDORLesson() {
|
Iterable<DynamicTest> testIDORLesson() {
|
||||||
return Arrays.asList(
|
return Arrays.asList(
|
||||||
dynamicTest("login", () -> loginIDOR()), dynamicTest("profile", () -> profile()));
|
dynamicTest("assignment 2 - login", this::loginIDOR),
|
||||||
|
dynamicTest("profile", this::profile));
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterEach
|
@AfterEach
|
||||||
public void shutdown() throws IOException {
|
public void shutdown() {
|
||||||
checkResults("/IDOR");
|
checkResults("/IDOR");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loginIDOR() throws IOException {
|
private void loginIDOR() {
|
||||||
|
|
||||||
Map<String, Object> params = new HashMap<>();
|
Map<String, Object> params = new HashMap<>();
|
||||||
params.clear();
|
|
||||||
params.put("username", "tom");
|
params.put("username", "tom");
|
||||||
params.put("password", "cat");
|
params.put("password", "cat");
|
||||||
|
|
||||||
checkAssignment(url("/WebGoat/IDOR/login"), params, true);
|
checkAssignment(url("IDOR/login"), params, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void profile() {
|
private void profile() {
|
||||||
|
|
||||||
|
// View profile - assignment 3a
|
||||||
MatcherAssert.assertThat(
|
MatcherAssert.assertThat(
|
||||||
RestAssured.given()
|
RestAssured.given()
|
||||||
.when()
|
.when()
|
||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
.get(url("/WebGoat/IDOR/profile"))
|
.get(url("IDOR/profile"))
|
||||||
.then()
|
.then()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.extract()
|
.extract()
|
||||||
.path("userId"),
|
.path("userId"),
|
||||||
CoreMatchers.is("2342384"));
|
CoreMatchers.is("2342384"));
|
||||||
|
|
||||||
|
// Show difference - assignment 3b
|
||||||
Map<String, Object> params = new HashMap<>();
|
Map<String, Object> params = new HashMap<>();
|
||||||
params.clear();
|
|
||||||
params.put("attributes", "userId,role");
|
params.put("attributes", "userId,role");
|
||||||
checkAssignment(url("/WebGoat/IDOR/diff-attributes"), params, true);
|
checkAssignment(url("IDOR/diff-attributes"), params, true);
|
||||||
|
|
||||||
|
// View profile another way - assignment 4
|
||||||
params.clear();
|
params.clear();
|
||||||
params.put("url", "WebGoat/IDOR/profile/2342384");
|
params.put("url", "WebGoat/IDOR/profile/2342384");
|
||||||
checkAssignment(url("/WebGoat/IDOR/profile/alt-path"), params, true);
|
checkAssignment(url("IDOR/profile/alt-path"), params, true);
|
||||||
|
|
||||||
|
// assignment 5a
|
||||||
MatcherAssert.assertThat(
|
MatcherAssert.assertThat(
|
||||||
RestAssured.given()
|
RestAssured.given()
|
||||||
.when()
|
.when()
|
||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
.get(url("/WebGoat/IDOR/profile/2342388"))
|
.get(url("IDOR/profile/2342388"))
|
||||||
.then()
|
.then()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.extract()
|
.extract()
|
||||||
.path("lessonCompleted"),
|
.path("lessonCompleted"),
|
||||||
CoreMatchers.is(true));
|
CoreMatchers.is(true));
|
||||||
|
|
||||||
|
// assignment 5b
|
||||||
MatcherAssert.assertThat(
|
MatcherAssert.assertThat(
|
||||||
RestAssured.given()
|
RestAssured.given()
|
||||||
.when()
|
.when()
|
||||||
@ -86,7 +90,7 @@ public class IDORIntegrationTest extends IntegrationTest {
|
|||||||
.body(
|
.body(
|
||||||
"{\"role\":\"1\", \"color\":\"red\", \"size\":\"large\", \"name\":\"Buffalo Bill\","
|
"{\"role\":\"1\", \"color\":\"red\", \"size\":\"large\", \"name\":\"Buffalo Bill\","
|
||||||
+ " \"userId\":\"2342388\"}")
|
+ " \"userId\":\"2342388\"}")
|
||||||
.put(url("/WebGoat/IDOR/profile/2342388"))
|
.put(url("IDOR/profile/2342388"))
|
||||||
.then()
|
.then()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.extract()
|
.extract()
|
||||||
|
@ -5,43 +5,51 @@ import static io.restassured.RestAssured.given;
|
|||||||
import io.restassured.RestAssured;
|
import io.restassured.RestAssured;
|
||||||
import io.restassured.http.ContentType;
|
import io.restassured.http.ContentType;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.hamcrest.CoreMatchers;
|
import org.hamcrest.CoreMatchers;
|
||||||
import org.hamcrest.MatcherAssert;
|
import org.hamcrest.MatcherAssert;
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
|
||||||
public abstract class IntegrationTest {
|
public abstract class IntegrationTest {
|
||||||
|
|
||||||
private static String webGoatPort = Objects.requireNonNull(System.getProperty("webgoatport"));
|
private static String webGoatPort = System.getenv().getOrDefault("WEBGOAT_PORT", "8080");
|
||||||
|
private static String webGoatContext =
|
||||||
|
System.getenv().getOrDefault("WEBGOAT_CONTEXT", "/WebGoat/");
|
||||||
|
|
||||||
|
@Getter private static String webWolfPort = System.getenv().getOrDefault("WEBWOLF_PORT", "9090");
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private static String webWolfPort = Objects.requireNonNull(System.getProperty("webwolfport"));
|
private static String webWolfHost = System.getenv().getOrDefault("WEBWOLF_HOST", "127.0.0.1");
|
||||||
|
|
||||||
private static boolean useSSL = false;
|
@Getter
|
||||||
|
private static String webGoatHost = System.getenv().getOrDefault("WEBGOAT_HOST", "127.0.0.1");
|
||||||
|
|
||||||
|
private static String webWolfContext =
|
||||||
|
System.getenv().getOrDefault("WEBWOLF_CONTEXT", "/WebWolf/");
|
||||||
|
|
||||||
|
private static boolean useSSL =
|
||||||
|
Boolean.valueOf(System.getenv().getOrDefault("WEBGOAT_SSLENABLED", "false"));
|
||||||
private static String webgoatUrl =
|
private static String webgoatUrl =
|
||||||
(useSSL ? "https:" : "http:") + "//localhost:" + webGoatPort + "/WebGoat/";
|
(useSSL ? "https://" : "http://") + webGoatHost + ":" + webGoatPort + webGoatContext;
|
||||||
private static String webWolfUrl =
|
private static String webWolfUrl = "http://" + webWolfHost + ":" + webWolfPort + webWolfContext;
|
||||||
(useSSL ? "https:" : "http:") + "//localhost:" + webWolfPort + "/";
|
|
||||||
@Getter private String webGoatCookie;
|
@Getter private String webGoatCookie;
|
||||||
@Getter private String webWolfCookie;
|
@Getter private String webWolfCookie;
|
||||||
@Getter private final String user = "webgoat";
|
@Getter private final String user = "webgoat";
|
||||||
|
|
||||||
protected String url(String url) {
|
protected String url(String url) {
|
||||||
url = url.replaceFirst("/WebGoat/", "");
|
|
||||||
url = url.replaceFirst("/WebGoat", "");
|
|
||||||
url = url.startsWith("/") ? url.replaceFirst("/", "") : url;
|
|
||||||
return webgoatUrl + url;
|
return webgoatUrl + url;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String webWolfUrl(String url) {
|
protected String webWolfUrl(String url) {
|
||||||
url = url.replaceFirst("/WebWolf/", "");
|
|
||||||
url = url.replaceFirst("/WebWolf", "");
|
|
||||||
url = url.startsWith("/") ? url.replaceFirst("/", "") : url;
|
|
||||||
return webWolfUrl + url;
|
return webWolfUrl + url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected String webWolfFileUrl(String fileName) {
|
||||||
|
return webWolfUrl("files") + "/" + getUser() + "/" + fileName;
|
||||||
|
}
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void login() {
|
public void login() {
|
||||||
String location =
|
String location =
|
||||||
@ -230,7 +238,7 @@ public abstract class IntegrationTest {
|
|||||||
.when()
|
.when()
|
||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("WEBWOLFSESSION", getWebWolfCookie())
|
.cookie("WEBWOLFSESSION", getWebWolfCookie())
|
||||||
.get(webWolfUrl("/file-server-location"))
|
.get(webWolfUrl("file-server-location"))
|
||||||
.then()
|
.then()
|
||||||
.extract()
|
.extract()
|
||||||
.response()
|
.response()
|
||||||
@ -245,11 +253,21 @@ public abstract class IntegrationTest {
|
|||||||
.when()
|
.when()
|
||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
.get(url("/server-directory"))
|
.get(url("server-directory"))
|
||||||
.then()
|
.then()
|
||||||
.extract()
|
.extract()
|
||||||
.response()
|
.response()
|
||||||
.getBody()
|
.getBody()
|
||||||
.asString();
|
.asString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void cleanMailbox() {
|
||||||
|
RestAssured.given()
|
||||||
|
.when()
|
||||||
|
.relaxedHTTPSValidation()
|
||||||
|
.cookie("WEBWOLFSESSION", getWebWolfCookie())
|
||||||
|
.delete(webWolfUrl("mail"))
|
||||||
|
.then()
|
||||||
|
.statusCode(HttpStatus.ACCEPTED.value());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,10 @@ import io.restassured.RestAssured;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.security.InvalidKeyException;
|
import java.security.InvalidKeyException;
|
||||||
|
import java.security.KeyPair;
|
||||||
|
import java.security.KeyPairGenerator;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.interfaces.RSAPublicKey;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
@ -23,6 +26,8 @@ import java.util.HashMap;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.hamcrest.CoreMatchers;
|
import org.hamcrest.CoreMatchers;
|
||||||
import org.hamcrest.MatcherAssert;
|
import org.hamcrest.MatcherAssert;
|
||||||
|
import org.jose4j.jwk.JsonWebKeySet;
|
||||||
|
import org.jose4j.jwk.RsaJsonWebKey;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.owasp.webgoat.lessons.jwt.JWTSecretKeyEndpoint;
|
import org.owasp.webgoat.lessons.jwt.JWTSecretKeyEndpoint;
|
||||||
|
|
||||||
@ -40,7 +45,9 @@ public class JWTLessonIntegrationTest extends IntegrationTest {
|
|||||||
|
|
||||||
buyAsTom();
|
buyAsTom();
|
||||||
|
|
||||||
deleteTom();
|
deleteTomThroughKidClaim();
|
||||||
|
|
||||||
|
deleteTomThroughJkuClaim();
|
||||||
|
|
||||||
quiz();
|
quiz();
|
||||||
|
|
||||||
@ -81,7 +88,7 @@ public class JWTLessonIntegrationTest extends IntegrationTest {
|
|||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
.formParam("jwt-encode-user", "user")
|
.formParam("jwt-encode-user", "user")
|
||||||
.post(url("/WebGoat/JWT/decode"))
|
.post(url("JWT/decode"))
|
||||||
.then()
|
.then()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.extract()
|
.extract()
|
||||||
@ -96,7 +103,7 @@ public class JWTLessonIntegrationTest extends IntegrationTest {
|
|||||||
.when()
|
.when()
|
||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
.get(url("/WebGoat/JWT/secret/gettoken"))
|
.get(url("JWT/secret/gettoken"))
|
||||||
.then()
|
.then()
|
||||||
.extract()
|
.extract()
|
||||||
.response()
|
.response()
|
||||||
@ -110,7 +117,7 @@ public class JWTLessonIntegrationTest extends IntegrationTest {
|
|||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
.formParam("token", generateToken(secret))
|
.formParam("token", generateToken(secret))
|
||||||
.post(url("/WebGoat/JWT/secret"))
|
.post(url("JWT/secret"))
|
||||||
.then()
|
.then()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.extract()
|
.extract()
|
||||||
@ -124,7 +131,7 @@ public class JWTLessonIntegrationTest extends IntegrationTest {
|
|||||||
.when()
|
.when()
|
||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
.get(url("/WebGoat/JWT/votings/login?user=Tom"))
|
.get(url("JWT/votings/login?user=Tom"))
|
||||||
.then()
|
.then()
|
||||||
.extract()
|
.extract()
|
||||||
.cookie("access_token");
|
.cookie("access_token");
|
||||||
@ -157,7 +164,7 @@ public class JWTLessonIntegrationTest extends IntegrationTest {
|
|||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
.cookie("access_token", replacedToken)
|
.cookie("access_token", replacedToken)
|
||||||
.post(url("/WebGoat/JWT/votings"))
|
.post(url("JWT/votings"))
|
||||||
.then()
|
.then()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.extract()
|
.extract()
|
||||||
@ -198,7 +205,7 @@ public class JWTLessonIntegrationTest extends IntegrationTest {
|
|||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
.header("Authorization", "Bearer " + replacedToken)
|
.header("Authorization", "Bearer " + replacedToken)
|
||||||
.post(url("/WebGoat/JWT/refresh/checkout"))
|
.post(url("JWT/refresh/checkout"))
|
||||||
.then()
|
.then()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.extract()
|
.extract()
|
||||||
@ -206,8 +213,7 @@ public class JWTLessonIntegrationTest extends IntegrationTest {
|
|||||||
CoreMatchers.is(true));
|
CoreMatchers.is(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void deleteTom() {
|
private void deleteTomThroughKidClaim() {
|
||||||
|
|
||||||
Map<String, Object> header = new HashMap();
|
Map<String, Object> header = new HashMap();
|
||||||
header.put(Header.TYPE, Header.JWT_TYPE);
|
header.put(Header.TYPE, Header.JWT_TYPE);
|
||||||
header.put(
|
header.put(
|
||||||
@ -232,7 +238,54 @@ public class JWTLessonIntegrationTest extends IntegrationTest {
|
|||||||
.when()
|
.when()
|
||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
.post(url("/WebGoat/JWT/final/delete?token=" + token))
|
.post(url("JWT/kid/delete?token=" + token))
|
||||||
|
.then()
|
||||||
|
.statusCode(200)
|
||||||
|
.extract()
|
||||||
|
.path("lessonCompleted"),
|
||||||
|
CoreMatchers.is(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteTomThroughJkuClaim() throws NoSuchAlgorithmException {
|
||||||
|
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
|
||||||
|
keyPairGenerator.initialize(2048);
|
||||||
|
KeyPair keyPair = keyPairGenerator.generateKeyPair();
|
||||||
|
var jwks = new JsonWebKeySet(new RsaJsonWebKey((RSAPublicKey) keyPair.getPublic()));
|
||||||
|
RestAssured.given()
|
||||||
|
.when()
|
||||||
|
.relaxedHTTPSValidation()
|
||||||
|
.cookie("WEBWOLFSESSION", getWebWolfCookie())
|
||||||
|
.multiPart("file", "jwks.json", jwks.toJson().getBytes())
|
||||||
|
.post(webWolfUrl("fileupload"))
|
||||||
|
.then()
|
||||||
|
.extract()
|
||||||
|
.response()
|
||||||
|
.getBody()
|
||||||
|
.asString();
|
||||||
|
|
||||||
|
Map<String, Object> header = new HashMap();
|
||||||
|
header.put(Header.TYPE, Header.JWT_TYPE);
|
||||||
|
header.put(JwsHeader.JWK_SET_URL, webWolfFileUrl("jwks.json"));
|
||||||
|
String token =
|
||||||
|
Jwts.builder()
|
||||||
|
.setHeader(header)
|
||||||
|
.setIssuer("WebGoat Token Builder")
|
||||||
|
.setAudience("webgoat.org")
|
||||||
|
.setIssuedAt(Calendar.getInstance().getTime())
|
||||||
|
.setExpiration(Date.from(Instant.now().plusSeconds(60)))
|
||||||
|
.setSubject("tom@webgoat.org")
|
||||||
|
.claim("username", "Tom")
|
||||||
|
.claim("Email", "tom@webgoat.org")
|
||||||
|
.claim("Role", new String[] {"Manager", "Project Administrator"})
|
||||||
|
.signWith(SignatureAlgorithm.RS256, keyPair.getPrivate())
|
||||||
|
.compact();
|
||||||
|
|
||||||
|
MatcherAssert.assertThat(
|
||||||
|
RestAssured.given()
|
||||||
|
.when()
|
||||||
|
.relaxedHTTPSValidation()
|
||||||
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
|
.post(url("JWT/jku/delete?token=" + token))
|
||||||
.then()
|
.then()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.extract()
|
.extract()
|
||||||
@ -245,6 +298,6 @@ public class JWTLessonIntegrationTest extends IntegrationTest {
|
|||||||
params.put("question_0_solution", "Solution 1");
|
params.put("question_0_solution", "Solution 1");
|
||||||
params.put("question_1_solution", "Solution 2");
|
params.put("question_1_solution", "Solution 2");
|
||||||
|
|
||||||
checkAssignment(url("/WebGoat/JWT/quiz"), params, true);
|
checkAssignment(url("JWT/quiz"), params, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,20 +5,19 @@ import static org.junit.jupiter.api.DynamicTest.dynamicTest;
|
|||||||
import io.restassured.RestAssured;
|
import io.restassured.RestAssured;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import lombok.SneakyThrows;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.assertj.core.api.Assertions;
|
import org.assertj.core.api.Assertions;
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.DynamicTest;
|
import org.junit.jupiter.api.DynamicTest;
|
||||||
import org.junit.jupiter.api.TestFactory;
|
import org.junit.jupiter.api.TestFactory;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
|
||||||
public class PasswordResetLessonIntegrationTest extends IntegrationTest {
|
public class PasswordResetLessonIntegrationTest extends IntegrationTest {
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
@SneakyThrows
|
|
||||||
public void init() {
|
public void init() {
|
||||||
startLesson("/PasswordReset");
|
startLesson("PasswordReset");
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestFactory
|
@TestFactory
|
||||||
@ -70,7 +69,6 @@ public class PasswordResetLessonIntegrationTest extends IntegrationTest {
|
|||||||
|
|
||||||
// WebWolf
|
// WebWolf
|
||||||
var link = getPasswordResetLinkFromLandingPage();
|
var link = getPasswordResetLinkFromLandingPage();
|
||||||
|
|
||||||
// WebGoat
|
// WebGoat
|
||||||
changePassword(link);
|
changePassword(link);
|
||||||
checkAssignment(
|
checkAssignment(
|
||||||
@ -87,7 +85,7 @@ public class PasswordResetLessonIntegrationTest extends IntegrationTest {
|
|||||||
.when()
|
.when()
|
||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("WEBWOLFSESSION", getWebWolfCookie())
|
.cookie("WEBWOLFSESSION", getWebWolfCookie())
|
||||||
.get(webWolfUrl("/WebWolf/mail"))
|
.get(webWolfUrl("mail"))
|
||||||
.then()
|
.then()
|
||||||
.extract()
|
.extract()
|
||||||
.response()
|
.response()
|
||||||
@ -121,7 +119,7 @@ public class PasswordResetLessonIntegrationTest extends IntegrationTest {
|
|||||||
.when()
|
.when()
|
||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("WEBWOLFSESSION", getWebWolfCookie())
|
.cookie("WEBWOLFSESSION", getWebWolfCookie())
|
||||||
.get(webWolfUrl("/WebWolf/requests"))
|
.get(webWolfUrl("requests"))
|
||||||
.then()
|
.then()
|
||||||
.extract()
|
.extract()
|
||||||
.response()
|
.response()
|
||||||
@ -138,7 +136,7 @@ public class PasswordResetLessonIntegrationTest extends IntegrationTest {
|
|||||||
private void clickForgotEmailLink(String user) {
|
private void clickForgotEmailLink(String user) {
|
||||||
RestAssured.given()
|
RestAssured.given()
|
||||||
.when()
|
.when()
|
||||||
.header("host", String.format("%s:%s", "localhost", getWebWolfPort()))
|
.header(HttpHeaders.HOST, String.format("%s:%s", getWebWolfHost(), getWebWolfPort()))
|
||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
.formParams("email", user)
|
.formParams("email", user)
|
||||||
|
@ -55,7 +55,7 @@ class PathTraversalIT extends IntegrationTest {
|
|||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
.multiPart("uploadedFile", "test.jpg", Files.readAllBytes(fileToUpload.toPath()))
|
.multiPart("uploadedFile", "test.jpg", Files.readAllBytes(fileToUpload.toPath()))
|
||||||
.param("fullName", "../John Doe")
|
.param("fullName", "../John Doe")
|
||||||
.post(url("/WebGoat/PathTraversal/profile-upload"))
|
.post(url("PathTraversal/profile-upload"))
|
||||||
.then()
|
.then()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.extract()
|
.extract()
|
||||||
@ -71,7 +71,7 @@ class PathTraversalIT extends IntegrationTest {
|
|||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
.multiPart("uploadedFileFix", "test.jpg", Files.readAllBytes(fileToUpload.toPath()))
|
.multiPart("uploadedFileFix", "test.jpg", Files.readAllBytes(fileToUpload.toPath()))
|
||||||
.param("fullNameFix", "..././John Doe")
|
.param("fullNameFix", "..././John Doe")
|
||||||
.post(url("/WebGoat/PathTraversal/profile-upload-fix"))
|
.post(url("PathTraversal/profile-upload-fix"))
|
||||||
.then()
|
.then()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.extract()
|
.extract()
|
||||||
@ -89,7 +89,7 @@ class PathTraversalIT extends IntegrationTest {
|
|||||||
"uploadedFileRemoveUserInput",
|
"uploadedFileRemoveUserInput",
|
||||||
"../test.jpg",
|
"../test.jpg",
|
||||||
Files.readAllBytes(fileToUpload.toPath()))
|
Files.readAllBytes(fileToUpload.toPath()))
|
||||||
.post(url("/WebGoat/PathTraversal/profile-upload-remove-user-input"))
|
.post(url("PathTraversal/profile-upload-remove-user-input"))
|
||||||
.then()
|
.then()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.extract()
|
.extract()
|
||||||
@ -98,7 +98,7 @@ class PathTraversalIT extends IntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void assignment4() throws IOException {
|
private void assignment4() throws IOException {
|
||||||
var uri = "/WebGoat/PathTraversal/random-picture?id=%2E%2E%2F%2E%2E%2Fpath-traversal-secret";
|
var uri = "PathTraversal/random-picture?id=%2E%2E%2F%2E%2E%2Fpath-traversal-secret";
|
||||||
RestAssured.given()
|
RestAssured.given()
|
||||||
.urlEncodingEnabled(false)
|
.urlEncodingEnabled(false)
|
||||||
.when()
|
.when()
|
||||||
@ -110,7 +110,7 @@ class PathTraversalIT extends IntegrationTest {
|
|||||||
.body(CoreMatchers.is("You found it submit the SHA-512 hash of your username as answer"));
|
.body(CoreMatchers.is("You found it submit the SHA-512 hash of your username as answer"));
|
||||||
|
|
||||||
checkAssignment(
|
checkAssignment(
|
||||||
url("/WebGoat/PathTraversal/random"),
|
url("PathTraversal/random"),
|
||||||
Map.of("secret", Sha512DigestUtils.shaHex(this.getUser())),
|
Map.of("secret", Sha512DigestUtils.shaHex(this.getUser())),
|
||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
@ -133,8 +133,10 @@ class PathTraversalIT extends IntegrationTest {
|
|||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
.multiPart("uploadedFileZipSlip", "upload.zip", Files.readAllBytes(zipFile.toPath()))
|
.multiPart("uploadedFileZipSlip", "upload.zip", Files.readAllBytes(zipFile.toPath()))
|
||||||
.post(url("/WebGoat/PathTraversal/zip-slip"))
|
.post(url("PathTraversal/zip-slip"))
|
||||||
.then()
|
.then()
|
||||||
|
.log()
|
||||||
|
.all()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.extract()
|
.extract()
|
||||||
.path("lessonCompleted"),
|
.path("lessonCompleted"),
|
||||||
|
@ -29,9 +29,9 @@ public class ProgressRaceConditionIntegrationTest extends IntegrationTest {
|
|||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
.formParams(Map.of("flag", "test"))
|
.formParams(Map.of("flag", "test"))
|
||||||
.post(url("/challenge/flag/"));
|
.post(url("challenge/flag"));
|
||||||
};
|
};
|
||||||
ExecutorService executorService = Executors.newWorkStealingPool(NUMBER_OF_PARALLEL_THREADS);
|
ExecutorService executorService = Executors.newFixedThreadPool(NUMBER_OF_PARALLEL_THREADS);
|
||||||
List<? extends Callable<Response>> flagCalls =
|
List<? extends Callable<Response>> flagCalls =
|
||||||
IntStream.range(0, NUMBER_OF_CALLS).mapToObj(i -> call).collect(Collectors.toList());
|
IntStream.range(0, NUMBER_OF_CALLS).mapToObj(i -> call).collect(Collectors.toList());
|
||||||
var responses = executorService.invokeAll(flagCalls);
|
var responses = executorService.invokeAll(flagCalls);
|
||||||
|
@ -15,11 +15,11 @@ public class SSRFIntegrationTest extends IntegrationTest {
|
|||||||
params.clear();
|
params.clear();
|
||||||
params.put("url", "images/jerry.png");
|
params.put("url", "images/jerry.png");
|
||||||
|
|
||||||
checkAssignment(url("/WebGoat/SSRF/task1"), params, true);
|
checkAssignment(url("SSRF/task1"), params, true);
|
||||||
params.clear();
|
params.clear();
|
||||||
params.put("url", "http://ifconfig.pro");
|
params.put("url", "http://ifconfig.pro");
|
||||||
|
|
||||||
checkAssignment(url("/WebGoat/SSRF/task2"), params, true);
|
checkAssignment(url("SSRF/task2"), params, true);
|
||||||
|
|
||||||
checkResults("/SSRF/");
|
checkResults("/SSRF/");
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ import org.junit.jupiter.api.Test;
|
|||||||
*/
|
*/
|
||||||
class SessionManagementIT extends IntegrationTest {
|
class SessionManagementIT extends IntegrationTest {
|
||||||
|
|
||||||
private static final String HIJACK_LOGIN_CONTEXT_PATH = "/WebGoat/HijackSession/login";
|
private static final String HIJACK_LOGIN_CONTEXT_PATH = "HijackSession/login";
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void hijackSessionTest() {
|
void hijackSessionTest() {
|
||||||
|
@ -16,27 +16,27 @@ public class SqlInjectionAdvancedIntegrationTest extends IntegrationTest {
|
|||||||
params.put("password_reg", "password");
|
params.put("password_reg", "password");
|
||||||
params.put("email_reg", "someone@microsoft.com");
|
params.put("email_reg", "someone@microsoft.com");
|
||||||
params.put("confirm_password", "password");
|
params.put("confirm_password", "password");
|
||||||
checkAssignmentWithPUT(url("/WebGoat/SqlInjectionAdvanced/challenge"), params, true);
|
checkAssignmentWithPUT(url("SqlInjectionAdvanced/challenge"), params, true);
|
||||||
|
|
||||||
params.clear();
|
params.clear();
|
||||||
params.put("username_login", "tom");
|
params.put("username_login", "tom");
|
||||||
params.put("password_login", "thisisasecretfortomonly");
|
params.put("password_login", "thisisasecretfortomonly");
|
||||||
checkAssignment(url("/WebGoat/SqlInjectionAdvanced/challenge_Login"), params, true);
|
checkAssignment(url("SqlInjectionAdvanced/challenge_Login"), params, true);
|
||||||
|
|
||||||
params.clear();
|
params.clear();
|
||||||
params.put("userid_6a", "'; SELECT * FROM user_system_data;--");
|
params.put("userid_6a", "'; SELECT * FROM user_system_data;--");
|
||||||
checkAssignment(url("/WebGoat/SqlInjectionAdvanced/attack6a"), params, true);
|
checkAssignment(url("SqlInjectionAdvanced/attack6a"), params, true);
|
||||||
|
|
||||||
params.clear();
|
params.clear();
|
||||||
params.put(
|
params.put(
|
||||||
"userid_6a",
|
"userid_6a",
|
||||||
"Smith' union select userid,user_name, user_name,user_name,password,cookie,userid from"
|
"Smith' union select userid,user_name, user_name,user_name,password,cookie,userid from"
|
||||||
+ " user_system_data --");
|
+ " user_system_data --");
|
||||||
checkAssignment(url("/WebGoat/SqlInjectionAdvanced/attack6a"), params, true);
|
checkAssignment(url("SqlInjectionAdvanced/attack6a"), params, true);
|
||||||
|
|
||||||
params.clear();
|
params.clear();
|
||||||
params.put("userid_6b", "passW0rD");
|
params.put("userid_6b", "passW0rD");
|
||||||
checkAssignment(url("/WebGoat/SqlInjectionAdvanced/attack6b"), params, true);
|
checkAssignment(url("SqlInjectionAdvanced/attack6b"), params, true);
|
||||||
|
|
||||||
params.clear();
|
params.clear();
|
||||||
params.put(
|
params.put(
|
||||||
@ -54,7 +54,7 @@ public class SqlInjectionAdvancedIntegrationTest extends IntegrationTest {
|
|||||||
params.put(
|
params.put(
|
||||||
"question_4_solution",
|
"question_4_solution",
|
||||||
"Solution 4: The database registers 'Robert' ); DROP TABLE Students;--'.");
|
"Solution 4: The database registers 'Robert' ); DROP TABLE Students;--'.");
|
||||||
checkAssignment(url("/WebGoat/SqlInjectionAdvanced/quiz"), params, true);
|
checkAssignment(url("SqlInjectionAdvanced/quiz"), params, true);
|
||||||
|
|
||||||
checkResults("/SqlInjectionAdvanced/");
|
checkResults("/SqlInjectionAdvanced/");
|
||||||
}
|
}
|
||||||
|
@ -34,44 +34,44 @@ public class SqlInjectionLessonIntegrationTest extends IntegrationTest {
|
|||||||
Map<String, Object> params = new HashMap<>();
|
Map<String, Object> params = new HashMap<>();
|
||||||
params.clear();
|
params.clear();
|
||||||
params.put("query", sql_2);
|
params.put("query", sql_2);
|
||||||
checkAssignment(url("/WebGoat/SqlInjection/attack2"), params, true);
|
checkAssignment(url("SqlInjection/attack2"), params, true);
|
||||||
|
|
||||||
params.clear();
|
params.clear();
|
||||||
params.put("query", sql_3);
|
params.put("query", sql_3);
|
||||||
checkAssignment(url("/WebGoat/SqlInjection/attack3"), params, true);
|
checkAssignment(url("SqlInjection/attack3"), params, true);
|
||||||
|
|
||||||
params.clear();
|
params.clear();
|
||||||
params.put("query", sql_4_add);
|
params.put("query", sql_4_add);
|
||||||
checkAssignment(url("/WebGoat/SqlInjection/attack4"), params, true);
|
checkAssignment(url("SqlInjection/attack4"), params, true);
|
||||||
|
|
||||||
params.clear();
|
params.clear();
|
||||||
params.put("query", sql_5);
|
params.put("query", sql_5);
|
||||||
checkAssignment(url("/WebGoat/SqlInjection/attack5"), params, true);
|
checkAssignment(url("SqlInjection/attack5"), params, true);
|
||||||
|
|
||||||
params.clear();
|
params.clear();
|
||||||
params.put("operator", sql_9_operator);
|
params.put("operator", sql_9_operator);
|
||||||
params.put("account", sql_9_account);
|
params.put("account", sql_9_account);
|
||||||
params.put("injection", sql_9_injection);
|
params.put("injection", sql_9_injection);
|
||||||
checkAssignment(url("/WebGoat/SqlInjection/assignment5a"), params, true);
|
checkAssignment(url("SqlInjection/assignment5a"), params, true);
|
||||||
|
|
||||||
params.clear();
|
params.clear();
|
||||||
params.put("login_count", sql_10_login_count);
|
params.put("login_count", sql_10_login_count);
|
||||||
params.put("userid", sql_10_userid);
|
params.put("userid", sql_10_userid);
|
||||||
checkAssignment(url("/WebGoat/SqlInjection/assignment5b"), params, true);
|
checkAssignment(url("SqlInjection/assignment5b"), params, true);
|
||||||
|
|
||||||
params.clear();
|
params.clear();
|
||||||
params.put("name", sql_11_a);
|
params.put("name", sql_11_a);
|
||||||
params.put("auth_tan", sql_11_b);
|
params.put("auth_tan", sql_11_b);
|
||||||
checkAssignment(url("/WebGoat/SqlInjection/attack8"), params, true);
|
checkAssignment(url("SqlInjection/attack8"), params, true);
|
||||||
|
|
||||||
params.clear();
|
params.clear();
|
||||||
params.put("name", sql_12_a);
|
params.put("name", sql_12_a);
|
||||||
params.put("auth_tan", sql_12_b);
|
params.put("auth_tan", sql_12_b);
|
||||||
checkAssignment(url("/WebGoat/SqlInjection/attack9"), params, true);
|
checkAssignment(url("SqlInjection/attack9"), params, true);
|
||||||
|
|
||||||
params.clear();
|
params.clear();
|
||||||
params.put("action_string", sql_13);
|
params.put("action_string", sql_13);
|
||||||
checkAssignment(url("/WebGoat/SqlInjection/attack10"), params, true);
|
checkAssignment(url("SqlInjection/attack10"), params, true);
|
||||||
|
|
||||||
checkResults("/SqlInjection/");
|
checkResults("/SqlInjection/");
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ public class SqlInjectionMitigationIntegrationTest extends IntegrationTest {
|
|||||||
params.put("field5", "?");
|
params.put("field5", "?");
|
||||||
params.put("field6", "prep.setString(1,\"\")");
|
params.put("field6", "prep.setString(1,\"\")");
|
||||||
params.put("field7", "prep.setString(2,\\\"\\\")");
|
params.put("field7", "prep.setString(2,\\\"\\\")");
|
||||||
checkAssignment(url("/WebGoat/SqlInjectionMitigations/attack10a"), params, true);
|
checkAssignment(url("SqlInjectionMitigations/attack10a"), params, true);
|
||||||
|
|
||||||
params.put(
|
params.put(
|
||||||
"editor",
|
"editor",
|
||||||
@ -37,18 +37,18 @@ public class SqlInjectionMitigationIntegrationTest extends IntegrationTest {
|
|||||||
+ "} catch (Exception e) {\r\n"
|
+ "} catch (Exception e) {\r\n"
|
||||||
+ " System.out.println(\"Oops. Something went wrong!\");\r\n"
|
+ " System.out.println(\"Oops. Something went wrong!\");\r\n"
|
||||||
+ "}");
|
+ "}");
|
||||||
checkAssignment(url("/WebGoat/SqlInjectionMitigations/attack10b"), params, true);
|
checkAssignment(url("SqlInjectionMitigations/attack10b"), params, true);
|
||||||
|
|
||||||
params.clear();
|
params.clear();
|
||||||
params.put(
|
params.put(
|
||||||
"userid_sql_only_input_validation", "Smith';SELECT/**/*/**/from/**/user_system_data;--");
|
"userid_sql_only_input_validation", "Smith';SELECT/**/*/**/from/**/user_system_data;--");
|
||||||
checkAssignment(url("/WebGoat/SqlOnlyInputValidation/attack"), params, true);
|
checkAssignment(url("SqlOnlyInputValidation/attack"), params, true);
|
||||||
|
|
||||||
params.clear();
|
params.clear();
|
||||||
params.put(
|
params.put(
|
||||||
"userid_sql_only_input_validation_on_keywords",
|
"userid_sql_only_input_validation_on_keywords",
|
||||||
"Smith';SESELECTLECT/**/*/**/FRFROMOM/**/user_system_data;--");
|
"Smith';SESELECTLECT/**/*/**/FRFROMOM/**/user_system_data;--");
|
||||||
checkAssignment(url("/WebGoat/SqlOnlyInputValidationOnKeywords/attack"), params, true);
|
checkAssignment(url("SqlOnlyInputValidationOnKeywords/attack"), params, true);
|
||||||
|
|
||||||
RestAssured.given()
|
RestAssured.given()
|
||||||
.when()
|
.when()
|
||||||
@ -57,7 +57,7 @@ public class SqlInjectionMitigationIntegrationTest extends IntegrationTest {
|
|||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.get(
|
.get(
|
||||||
url(
|
url(
|
||||||
"/WebGoat/SqlInjectionMitigations/servers?column=(case when (true) then hostname"
|
"SqlInjectionMitigations/servers?column=(case when (true) then hostname"
|
||||||
+ " else id end)"))
|
+ " else id end)"))
|
||||||
.then()
|
.then()
|
||||||
.statusCode(200);
|
.statusCode(200);
|
||||||
@ -67,7 +67,7 @@ public class SqlInjectionMitigationIntegrationTest extends IntegrationTest {
|
|||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.get(url("/WebGoat/SqlInjectionMitigations/servers?column=unknown"))
|
.get(url("SqlInjectionMitigations/servers?column=unknown"))
|
||||||
.then()
|
.then()
|
||||||
.statusCode(500)
|
.statusCode(500)
|
||||||
.body(
|
.body(
|
||||||
@ -78,7 +78,7 @@ public class SqlInjectionMitigationIntegrationTest extends IntegrationTest {
|
|||||||
|
|
||||||
params.clear();
|
params.clear();
|
||||||
params.put("ip", "104.130.219.202");
|
params.put("ip", "104.130.219.202");
|
||||||
checkAssignment(url("/WebGoat/SqlInjectionMitigations/attack12a"), params, true);
|
checkAssignment(url("SqlInjectionMitigations/attack12a"), params, true);
|
||||||
|
|
||||||
checkResults();
|
checkResults();
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@ package org.owasp.webgoat;
|
|||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
import io.restassured.RestAssured;
|
import io.restassured.RestAssured;
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
@ -11,21 +10,20 @@ import org.junit.jupiter.api.Test;
|
|||||||
public class WebWolfIntegrationTest extends IntegrationTest {
|
public class WebWolfIntegrationTest extends IntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void runTests() throws IOException {
|
public void runTests() {
|
||||||
startLesson("WebWolfIntroduction");
|
startLesson("WebWolfIntroduction");
|
||||||
|
|
||||||
// Assignment 3
|
// Assignment 3
|
||||||
Map<String, Object> params = new HashMap<>();
|
Map<String, Object> params = new HashMap<>();
|
||||||
params.clear();
|
|
||||||
params.put("email", this.getUser() + "@webgoat.org");
|
params.put("email", this.getUser() + "@webgoat.org");
|
||||||
checkAssignment(url("/WebGoat/WebWolf/mail/send"), params, false);
|
checkAssignment(url("WebWolf/mail/send"), params, false);
|
||||||
|
|
||||||
String responseBody =
|
String responseBody =
|
||||||
RestAssured.given()
|
RestAssured.given()
|
||||||
.when()
|
.when()
|
||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("WEBWOLFSESSION", getWebWolfCookie())
|
.cookie("WEBWOLFSESSION", getWebWolfCookie())
|
||||||
.get(webWolfUrl("/WebWolf/mail"))
|
.get(webWolfUrl("mail"))
|
||||||
.then()
|
.then()
|
||||||
.extract()
|
.extract()
|
||||||
.response()
|
.response()
|
||||||
@ -39,7 +37,7 @@ public class WebWolfIntegrationTest extends IntegrationTest {
|
|||||||
uniqueCode.lastIndexOf("your unique code is: ") + (21 + this.getUser().length()));
|
uniqueCode.lastIndexOf("your unique code is: ") + (21 + this.getUser().length()));
|
||||||
params.clear();
|
params.clear();
|
||||||
params.put("uniqueCode", uniqueCode);
|
params.put("uniqueCode", uniqueCode);
|
||||||
checkAssignment(url("/WebGoat/WebWolf/mail"), params, true);
|
checkAssignment(url("WebWolf/mail"), params, true);
|
||||||
|
|
||||||
// Assignment 4
|
// Assignment 4
|
||||||
RestAssured.given()
|
RestAssured.given()
|
||||||
@ -47,7 +45,7 @@ public class WebWolfIntegrationTest extends IntegrationTest {
|
|||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
.queryParams(params)
|
.queryParams(params)
|
||||||
.get(url("/WebGoat/WebWolf/landing/password-reset"))
|
.get(url("WebWolf/landing/password-reset"))
|
||||||
.then()
|
.then()
|
||||||
.statusCode(200);
|
.statusCode(200);
|
||||||
RestAssured.given()
|
RestAssured.given()
|
||||||
@ -55,7 +53,7 @@ public class WebWolfIntegrationTest extends IntegrationTest {
|
|||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("WEBWOLFSESSION", getWebWolfCookie())
|
.cookie("WEBWOLFSESSION", getWebWolfCookie())
|
||||||
.queryParams(params)
|
.queryParams(params)
|
||||||
.get(webWolfUrl("/landing"))
|
.get(webWolfUrl("landing"))
|
||||||
.then()
|
.then()
|
||||||
.statusCode(200);
|
.statusCode(200);
|
||||||
responseBody =
|
responseBody =
|
||||||
@ -63,7 +61,7 @@ public class WebWolfIntegrationTest extends IntegrationTest {
|
|||||||
.when()
|
.when()
|
||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("WEBWOLFSESSION", getWebWolfCookie())
|
.cookie("WEBWOLFSESSION", getWebWolfCookie())
|
||||||
.get(webWolfUrl("/WebWolf/requests"))
|
.get(webWolfUrl("requests"))
|
||||||
.then()
|
.then()
|
||||||
.extract()
|
.extract()
|
||||||
.response()
|
.response()
|
||||||
@ -72,7 +70,7 @@ public class WebWolfIntegrationTest extends IntegrationTest {
|
|||||||
assertTrue(responseBody.contains(uniqueCode));
|
assertTrue(responseBody.contains(uniqueCode));
|
||||||
params.clear();
|
params.clear();
|
||||||
params.put("uniqueCode", uniqueCode);
|
params.put("uniqueCode", uniqueCode);
|
||||||
checkAssignment(url("/WebGoat/WebWolf/landing"), params, true);
|
checkAssignment(url("WebWolf/landing"), params, true);
|
||||||
|
|
||||||
checkResults("/WebWolf");
|
checkResults("/WebWolf");
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ public class XSSIntegrationTest extends IntegrationTest {
|
|||||||
Map<String, Object> params = new HashMap<>();
|
Map<String, Object> params = new HashMap<>();
|
||||||
params.clear();
|
params.clear();
|
||||||
params.put("checkboxAttack1", "value");
|
params.put("checkboxAttack1", "value");
|
||||||
checkAssignment(url("/CrossSiteScripting/attack1"), params, true);
|
checkAssignment(url("CrossSiteScripting/attack1"), params, true);
|
||||||
|
|
||||||
params.clear();
|
params.clear();
|
||||||
params.put("QTY1", "1");
|
params.put("QTY1", "1");
|
||||||
@ -23,11 +23,11 @@ public class XSSIntegrationTest extends IntegrationTest {
|
|||||||
params.put("QTY4", "1");
|
params.put("QTY4", "1");
|
||||||
params.put("field1", "<script>alert('XSS+Test')</script>");
|
params.put("field1", "<script>alert('XSS+Test')</script>");
|
||||||
params.put("field2", "111");
|
params.put("field2", "111");
|
||||||
checkAssignmentWithGet(url("/CrossSiteScripting/attack5a"), params, true);
|
checkAssignmentWithGet(url("CrossSiteScripting/attack5a"), params, true);
|
||||||
|
|
||||||
params.clear();
|
params.clear();
|
||||||
params.put("DOMTestRoute", "start.mvc#test");
|
params.put("DOMTestRoute", "start.mvc#test");
|
||||||
checkAssignment(url("/CrossSiteScripting/attack6a"), params, true);
|
checkAssignment(url("CrossSiteScripting/attack6a"), params, true);
|
||||||
|
|
||||||
params.clear();
|
params.clear();
|
||||||
params.put("param1", "42");
|
params.put("param1", "42");
|
||||||
@ -41,7 +41,7 @@ public class XSSIntegrationTest extends IntegrationTest {
|
|||||||
.header("webgoat-requested-by", "dom-xss-vuln")
|
.header("webgoat-requested-by", "dom-xss-vuln")
|
||||||
.header("X-Requested-With", "XMLHttpRequest")
|
.header("X-Requested-With", "XMLHttpRequest")
|
||||||
.formParams(params)
|
.formParams(params)
|
||||||
.post(url("/CrossSiteScripting/phone-home-xss"))
|
.post(url("CrossSiteScripting/phone-home-xss"))
|
||||||
.then()
|
.then()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.extract()
|
.extract()
|
||||||
@ -50,7 +50,7 @@ public class XSSIntegrationTest extends IntegrationTest {
|
|||||||
|
|
||||||
params.clear();
|
params.clear();
|
||||||
params.put("successMessage", secretNumber);
|
params.put("successMessage", secretNumber);
|
||||||
checkAssignment(url("/CrossSiteScripting/dom-follow-up"), params, true);
|
checkAssignment(url("CrossSiteScripting/dom-follow-up"), params, true);
|
||||||
|
|
||||||
params.clear();
|
params.clear();
|
||||||
params.put(
|
params.put(
|
||||||
@ -73,8 +73,44 @@ public class XSSIntegrationTest extends IntegrationTest {
|
|||||||
"question_4_solution",
|
"question_4_solution",
|
||||||
"Solution 4: No there are many other ways. Like HTML, Flash or any other type of code that"
|
"Solution 4: No there are many other ways. Like HTML, Flash or any other type of code that"
|
||||||
+ " the browser executes.");
|
+ " the browser executes.");
|
||||||
checkAssignment(url("/CrossSiteScripting/quiz"), params, true);
|
checkAssignment(url("CrossSiteScripting/quiz"), params, true);
|
||||||
|
|
||||||
checkResults("/CrossSiteScripting/");
|
params.clear();
|
||||||
|
params.put(
|
||||||
|
"editor",
|
||||||
|
"<%@ taglib uri=\"https://www.owasp.org/index.php/OWASP_Java_Encoder_Project\" %>"
|
||||||
|
+ "<html>"
|
||||||
|
+ "<head>"
|
||||||
|
+ "<title>Using GET and POST Method to Read Form Data</title>"
|
||||||
|
+ "</head>"
|
||||||
|
+ "<body>"
|
||||||
|
+ "<h1>Using POST Method to Read Form Data</h1>"
|
||||||
|
+ "<table>"
|
||||||
|
+ "<tbody>"
|
||||||
|
+ "<tr>"
|
||||||
|
+ "<td><b>First Name:</b></td>"
|
||||||
|
+ "<td>${e:forHtml(param.first_name)}</td>"
|
||||||
|
+ "</tr>"
|
||||||
|
+ "<tr>"
|
||||||
|
+ "<td><b>Last Name:</b></td>"
|
||||||
|
+ "<td>${e:forHtml(param.last_name)}</td>"
|
||||||
|
+ "</tr>"
|
||||||
|
+ "</tbody>"
|
||||||
|
+ "</table>"
|
||||||
|
+ "</body>"
|
||||||
|
+ "</html>");
|
||||||
|
checkAssignment(url("CrossSiteScripting/attack3"), params, true);
|
||||||
|
|
||||||
|
params.clear();
|
||||||
|
params.put(
|
||||||
|
"editor2",
|
||||||
|
"Policy.getInstance(\"antisamy-slashdot.xml\");"
|
||||||
|
+ "Sammy s = new AntiSamy();"
|
||||||
|
+ "s.scan(newComment,\"\");"
|
||||||
|
+ "CleanResults();"
|
||||||
|
+ "MyCommentDAO.addComment(threadID, userID).getCleanHTML());");
|
||||||
|
checkAssignment(url("CrossSiteScripting/attack4"), params, true);
|
||||||
|
|
||||||
|
checkResults("/CrossSiteScripting");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,10 +45,10 @@ public class XXEIntegrationTest extends IntegrationTest {
|
|||||||
.get(url("service/enable-security.mvc"))
|
.get(url("service/enable-security.mvc"))
|
||||||
.then()
|
.then()
|
||||||
.statusCode(200);
|
.statusCode(200);
|
||||||
checkAssignment(url("/WebGoat/xxe/simple"), ContentType.XML, xxe3, false);
|
checkAssignment(url("xxe/simple"), ContentType.XML, xxe3, false);
|
||||||
checkAssignment(url("/WebGoat/xxe/content-type"), ContentType.XML, xxe4, false);
|
checkAssignment(url("xxe/content-type"), ContentType.XML, xxe4, false);
|
||||||
checkAssignment(
|
checkAssignment(
|
||||||
url("/WebGoat/xxe/blind"),
|
url("xxe/blind"),
|
||||||
ContentType.XML,
|
ContentType.XML,
|
||||||
"<comment><text>" + getSecret() + "</text></comment>",
|
"<comment><text>" + getSecret() + "</text></comment>",
|
||||||
false);
|
false);
|
||||||
@ -68,7 +68,7 @@ public class XXEIntegrationTest extends IntegrationTest {
|
|||||||
}
|
}
|
||||||
String secretFile = webGoatHomeDirectory.concat("/XXE/" + getUser() + "/secret.txt");
|
String secretFile = webGoatHomeDirectory.concat("/XXE/" + getUser() + "/secret.txt");
|
||||||
String dtd7String =
|
String dtd7String =
|
||||||
dtd7.replace("WEBWOLFURL", webWolfUrl("/landing")).replace("SECRET", secretFile);
|
dtd7.replace("WEBWOLFURL", webWolfUrl("landing")).replace("SECRET", secretFile);
|
||||||
|
|
||||||
// upload DTD
|
// upload DTD
|
||||||
RestAssured.given()
|
RestAssured.given()
|
||||||
@ -76,7 +76,7 @@ public class XXEIntegrationTest extends IntegrationTest {
|
|||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("WEBWOLFSESSION", getWebWolfCookie())
|
.cookie("WEBWOLFSESSION", getWebWolfCookie())
|
||||||
.multiPart("file", "blind.dtd", dtd7String.getBytes())
|
.multiPart("file", "blind.dtd", dtd7String.getBytes())
|
||||||
.post(webWolfUrl("/fileupload"))
|
.post(webWolfUrl("fileupload"))
|
||||||
.then()
|
.then()
|
||||||
.extract()
|
.extract()
|
||||||
.response()
|
.response()
|
||||||
@ -84,8 +84,8 @@ public class XXEIntegrationTest extends IntegrationTest {
|
|||||||
.asString();
|
.asString();
|
||||||
// upload attack
|
// upload attack
|
||||||
String xxe7String =
|
String xxe7String =
|
||||||
xxe7.replace("WEBWOLFURL", webWolfUrl("/files")).replace("USERNAME", this.getUser());
|
xxe7.replace("WEBWOLFURL", webWolfUrl("files")).replace("USERNAME", this.getUser());
|
||||||
checkAssignment(url("/WebGoat/xxe/blind"), ContentType.XML, xxe7String, false);
|
checkAssignment(url("xxe/blind"), ContentType.XML, xxe7String, false);
|
||||||
|
|
||||||
// read results from WebWolf
|
// read results from WebWolf
|
||||||
String result =
|
String result =
|
||||||
@ -93,7 +93,7 @@ public class XXEIntegrationTest extends IntegrationTest {
|
|||||||
.when()
|
.when()
|
||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("WEBWOLFSESSION", getWebWolfCookie())
|
.cookie("WEBWOLFSESSION", getWebWolfCookie())
|
||||||
.get(webWolfUrl("/WebWolf/requests"))
|
.get(webWolfUrl("requests"))
|
||||||
.then()
|
.then()
|
||||||
.extract()
|
.extract()
|
||||||
.response()
|
.response()
|
||||||
@ -114,10 +114,10 @@ public class XXEIntegrationTest extends IntegrationTest {
|
|||||||
startLesson("XXE", true);
|
startLesson("XXE", true);
|
||||||
webGoatHomeDirectory = webGoatServerDirectory();
|
webGoatHomeDirectory = webGoatServerDirectory();
|
||||||
webWolfFileServerLocation = getWebWolfFileServerLocation();
|
webWolfFileServerLocation = getWebWolfFileServerLocation();
|
||||||
checkAssignment(url("/WebGoat/xxe/simple"), ContentType.XML, xxe3, true);
|
checkAssignment(url("xxe/simple"), ContentType.XML, xxe3, true);
|
||||||
checkAssignment(url("/WebGoat/xxe/content-type"), ContentType.XML, xxe4, true);
|
checkAssignment(url("xxe/content-type"), ContentType.XML, xxe4, true);
|
||||||
checkAssignment(
|
checkAssignment(
|
||||||
url("/WebGoat/xxe/blind"),
|
url("xxe/blind"),
|
||||||
ContentType.XML,
|
ContentType.XML,
|
||||||
"<comment><text>" + getSecret() + "</text></comment>",
|
"<comment><text>" + getSecret() + "</text></comment>",
|
||||||
true);
|
true);
|
||||||
|
@ -27,10 +27,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.owasp.webgoat.container;
|
package org.owasp.webgoat.container;
|
||||||
|
|
||||||
|
import jakarta.servlet.ServletException;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import javax.servlet.ServletException;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
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;
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ package org.owasp.webgoat.container;
|
|||||||
import static org.asciidoctor.Asciidoctor.Factory.create;
|
import static org.asciidoctor.Asciidoctor.Factory.create;
|
||||||
|
|
||||||
import io.undertow.util.Headers;
|
import io.undertow.util.Headers;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
@ -41,7 +42,6 @@ import java.util.HashMap;
|
|||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.asciidoctor.Asciidoctor;
|
import org.asciidoctor.Asciidoctor;
|
||||||
import org.asciidoctor.extension.JavaExtensionRegistry;
|
import org.asciidoctor.extension.JavaExtensionRegistry;
|
||||||
@ -60,7 +60,7 @@ import org.thymeleaf.templateresource.StringTemplateResource;
|
|||||||
* Thymeleaf resolver for AsciiDoc used in the lesson, can be used as follows inside a lesson file:
|
* Thymeleaf resolver for AsciiDoc used in the lesson, can be used as follows inside a lesson file:
|
||||||
*
|
*
|
||||||
* <p><code>
|
* <p><code>
|
||||||
* <div th:replace="doc:AccessControlMatrix_plan.adoc"></div>
|
* <div th:replace="~{doc:AccessControlMatrix_plan.adoc}"></div>
|
||||||
* </code>
|
* </code>
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@ -6,7 +6,6 @@ import javax.sql.DataSource;
|
|||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.flywaydb.core.Flyway;
|
import org.flywaydb.core.Flyway;
|
||||||
import org.owasp.webgoat.container.lessons.LessonScanner;
|
|
||||||
import org.owasp.webgoat.container.service.RestartLessonService;
|
import org.owasp.webgoat.container.service.RestartLessonService;
|
||||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
@ -20,7 +19,6 @@ import org.springframework.jdbc.datasource.DriverManagerDataSource;
|
|||||||
public class DatabaseConfiguration {
|
public class DatabaseConfiguration {
|
||||||
|
|
||||||
private final DataSourceProperties properties;
|
private final DataSourceProperties properties;
|
||||||
private final LessonScanner lessonScanner;
|
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@Primary
|
@Primary
|
||||||
@ -50,12 +48,13 @@ public class DatabaseConfiguration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public Function<String, Flyway> flywayLessons(LessonDataSource lessonDataSource) {
|
public Function<String, Flyway> flywayLessons() {
|
||||||
return schema ->
|
return schema ->
|
||||||
Flyway.configure()
|
Flyway.configure()
|
||||||
.configuration(Map.of("driver", properties.getDriverClassName()))
|
.configuration(Map.of("driver", properties.getDriverClassName()))
|
||||||
.schemas(schema)
|
.schemas(schema)
|
||||||
.dataSource(lessonDataSource)
|
.cleanDisabled(false)
|
||||||
|
.dataSource(dataSource())
|
||||||
.locations("lessons")
|
.locations("lessons")
|
||||||
.load();
|
.load();
|
||||||
}
|
}
|
||||||
|
@ -56,10 +56,10 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
|||||||
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
|
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
|
||||||
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
|
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
|
||||||
import org.thymeleaf.IEngineConfiguration;
|
import org.thymeleaf.IEngineConfiguration;
|
||||||
import org.thymeleaf.extras.springsecurity5.dialect.SpringSecurityDialect;
|
import org.thymeleaf.extras.springsecurity6.dialect.SpringSecurityDialect;
|
||||||
import org.thymeleaf.spring5.SpringTemplateEngine;
|
import org.thymeleaf.spring6.SpringTemplateEngine;
|
||||||
import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver;
|
import org.thymeleaf.spring6.templateresolver.SpringResourceTemplateResolver;
|
||||||
import org.thymeleaf.spring5.view.ThymeleafViewResolver;
|
import org.thymeleaf.spring6.view.ThymeleafViewResolver;
|
||||||
import org.thymeleaf.templatemode.TemplateMode;
|
import org.thymeleaf.templatemode.TemplateMode;
|
||||||
import org.thymeleaf.templateresolver.FileTemplateResolver;
|
import org.thymeleaf.templateresolver.FileTemplateResolver;
|
||||||
import org.thymeleaf.templateresolver.ITemplateResolver;
|
import org.thymeleaf.templateresolver.ITemplateResolver;
|
||||||
@ -242,6 +242,7 @@ public class MvcConfiguration implements WebMvcConfigurer {
|
|||||||
@Override
|
@Override
|
||||||
public void addInterceptors(InterceptorRegistry registry) {
|
public void addInterceptors(InterceptorRegistry registry) {
|
||||||
registry.addInterceptor(localeChangeInterceptor());
|
registry.addInterceptor(localeChangeInterceptor());
|
||||||
|
registry.addInterceptor(new UserInterceptor());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
@ -0,0 +1,53 @@
|
|||||||
|
package org.owasp.webgoat.container;
|
||||||
|
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import org.owasp.webgoat.container.asciidoc.EnvironmentExposure;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.web.servlet.HandlerInterceptor;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
|
public class UserInterceptor implements HandlerInterceptor {
|
||||||
|
|
||||||
|
private Environment env = EnvironmentExposure.getEnv();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
|
||||||
|
throws Exception {
|
||||||
|
// Do nothing
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postHandle(
|
||||||
|
HttpServletRequest request,
|
||||||
|
HttpServletResponse response,
|
||||||
|
Object handler,
|
||||||
|
ModelAndView modelAndView)
|
||||||
|
throws Exception {
|
||||||
|
if (null != modelAndView) {
|
||||||
|
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||||
|
if (null != authentication) {
|
||||||
|
modelAndView.getModel().put("username", authentication.getName());
|
||||||
|
}
|
||||||
|
if (null != env) {
|
||||||
|
String githubClientId =
|
||||||
|
env.getProperty("spring.security.oauth2.client.registration.github.client-id");
|
||||||
|
if (null != githubClientId && !githubClientId.equals("dummy")) {
|
||||||
|
modelAndView.getModel().put("oauth", Boolean.TRUE);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
modelAndView.getModel().put("oauth", Boolean.FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterCompletion(
|
||||||
|
HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
|
||||||
|
throws Exception {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
}
|
@ -34,6 +34,9 @@ package org.owasp.webgoat.container;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import org.owasp.webgoat.container.session.UserSessionData;
|
import org.owasp.webgoat.container.session.UserSessionData;
|
||||||
import org.owasp.webgoat.container.session.WebSession;
|
import org.owasp.webgoat.container.session.WebSession;
|
||||||
|
import org.owasp.webgoat.container.users.UserRepository;
|
||||||
|
import org.owasp.webgoat.container.users.WebGoatUser;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
@ -42,6 +45,8 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
import org.springframework.context.annotation.PropertySource;
|
import org.springframework.context.annotation.PropertySource;
|
||||||
import org.springframework.context.annotation.Scope;
|
import org.springframework.context.annotation.Scope;
|
||||||
import org.springframework.context.annotation.ScopedProxyMode;
|
import org.springframework.context.annotation.ScopedProxyMode;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.security.oauth2.core.user.DefaultOAuth2User;
|
||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@ -50,6 +55,8 @@ import org.springframework.web.client.RestTemplate;
|
|||||||
@EnableAutoConfiguration
|
@EnableAutoConfiguration
|
||||||
public class WebGoat {
|
public class WebGoat {
|
||||||
|
|
||||||
|
@Autowired private UserRepository userRepository;
|
||||||
|
|
||||||
@Bean(name = "pluginTargetDirectory")
|
@Bean(name = "pluginTargetDirectory")
|
||||||
public File pluginTargetDirectory(@Value("${webgoat.user.directory}") final String webgoatHome) {
|
public File pluginTargetDirectory(@Value("${webgoat.user.directory}") final String webgoatHome) {
|
||||||
return new File(webgoatHome);
|
return new File(webgoatHome);
|
||||||
@ -58,7 +65,14 @@ public class WebGoat {
|
|||||||
@Bean
|
@Bean
|
||||||
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
|
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
|
||||||
public WebSession webSession() {
|
public WebSession webSession() {
|
||||||
return new WebSession();
|
WebGoatUser webGoatUser = null;
|
||||||
|
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
|
||||||
|
if (principal instanceof WebGoatUser) {
|
||||||
|
webGoatUser = (WebGoatUser) principal;
|
||||||
|
} else if (principal instanceof DefaultOAuth2User) {
|
||||||
|
webGoatUser = userRepository.findByUsername(((DefaultOAuth2User) principal).getName());
|
||||||
|
}
|
||||||
|
return new WebSession(webGoatUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
@ -37,50 +37,58 @@ import org.springframework.context.annotation.Bean;
|
|||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.security.authentication.AuthenticationManager;
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||||
|
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
|
||||||
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
|
|
||||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
|
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
|
||||||
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
|
|
||||||
/** Security configuration for WebGoat. */
|
/** Security configuration for WebGoat. */
|
||||||
@Configuration
|
@Configuration
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@EnableWebSecurity
|
@EnableWebSecurity
|
||||||
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
public class WebSecurityConfig {
|
||||||
|
|
||||||
private final UserService userDetailsService;
|
private final UserService userDetailsService;
|
||||||
|
|
||||||
@Override
|
@Bean
|
||||||
protected void configure(HttpSecurity http) throws Exception {
|
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||||
ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry security =
|
return http.authorizeHttpRequests(
|
||||||
http.authorizeRequests()
|
auth ->
|
||||||
.antMatchers(
|
auth.requestMatchers(
|
||||||
|
"/",
|
||||||
|
"/favicon.ico",
|
||||||
"/css/**",
|
"/css/**",
|
||||||
"/images/**",
|
"/images/**",
|
||||||
"/js/**",
|
"/js/**",
|
||||||
"fonts/**",
|
"fonts/**",
|
||||||
"/plugins/**",
|
"/plugins/**",
|
||||||
"/registration",
|
"/registration",
|
||||||
"/register.mvc",
|
"/register.mvc")
|
||||||
"/actuator/**")
|
|
||||||
.permitAll()
|
.permitAll()
|
||||||
.anyRequest()
|
.anyRequest()
|
||||||
.authenticated();
|
.authenticated())
|
||||||
security
|
.formLogin(
|
||||||
.and()
|
login ->
|
||||||
.formLogin()
|
login
|
||||||
.loginPage("/login")
|
.loginPage("/login")
|
||||||
.defaultSuccessUrl("/welcome.mvc", true)
|
.defaultSuccessUrl("/welcome.mvc", true)
|
||||||
.usernameParameter("username")
|
.usernameParameter("username")
|
||||||
.passwordParameter("password")
|
.passwordParameter("password")
|
||||||
.permitAll();
|
.permitAll())
|
||||||
security.and().logout().deleteCookies("JSESSIONID").invalidateHttpSession(true);
|
.oauth2Login(
|
||||||
security.and().csrf().disable();
|
oidc -> {
|
||||||
|
oidc.defaultSuccessUrl("/login-oauth.mvc");
|
||||||
http.headers().cacheControl().disable();
|
oidc.loginPage("/login");
|
||||||
http.exceptionHandling().authenticationEntryPoint(new AjaxAuthenticationEntryPoint("/login"));
|
})
|
||||||
|
.logout(logout -> logout.deleteCookies("JSESSIONID").invalidateHttpSession(true))
|
||||||
|
.csrf(csrf -> csrf.disable())
|
||||||
|
.headers(headers -> headers.disable())
|
||||||
|
.exceptionHandling(
|
||||||
|
handling ->
|
||||||
|
handling.authenticationEntryPoint(new AjaxAuthenticationEntryPoint("/login")))
|
||||||
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@ -89,18 +97,16 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@Override
|
public UserDetailsService userDetailsServiceBean() {
|
||||||
public UserDetailsService userDetailsServiceBean() throws Exception {
|
|
||||||
return userDetailsService;
|
return userDetailsService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
@Bean
|
@Bean
|
||||||
protected AuthenticationManager authenticationManager() throws Exception {
|
public AuthenticationManager authenticationManager(
|
||||||
return super.authenticationManager();
|
AuthenticationConfiguration authenticationConfiguration) throws Exception {
|
||||||
|
return authenticationConfiguration.getAuthenticationManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
@Bean
|
@Bean
|
||||||
public NoOpPasswordEncoder passwordEncoder() {
|
public NoOpPasswordEncoder passwordEncoder() {
|
||||||
return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
|
return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
|
||||||
|
@ -16,7 +16,7 @@ public class EnvironmentExposure implements ApplicationContextAware {
|
|||||||
private static ApplicationContext context;
|
private static ApplicationContext context;
|
||||||
|
|
||||||
public static Environment getEnv() {
|
public static Environment getEnv() {
|
||||||
return context.getEnvironment();
|
return (null != context) ? context.getEnvironment() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -2,11 +2,8 @@ package org.owasp.webgoat.container.asciidoc;
|
|||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import org.asciidoctor.ast.ContentNode;
|
import org.asciidoctor.ast.ContentNode;
|
||||||
import org.asciidoctor.extension.InlineMacroProcessor;
|
import org.asciidoctor.extension.InlineMacroProcessor;
|
||||||
import org.springframework.web.context.request.RequestContextHolder;
|
|
||||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Usage in asciidoc:
|
* Usage in asciidoc:
|
||||||
@ -26,7 +23,7 @@ public class WebWolfMacro extends InlineMacroProcessor {
|
|||||||
@Override
|
@Override
|
||||||
public Object process(ContentNode contentNode, String linkText, Map<String, Object> attributes) {
|
public Object process(ContentNode contentNode, String linkText, Map<String, Object> attributes) {
|
||||||
var env = EnvironmentExposure.getEnv();
|
var env = EnvironmentExposure.getEnv();
|
||||||
var hostname = determineHost(env.getProperty("webwolf.port"));
|
var hostname = env.getProperty("webwolf.url");
|
||||||
var target = (String) attributes.getOrDefault("target", "home");
|
var target = (String) attributes.getOrDefault("target", "home");
|
||||||
var href = hostname + "/" + target;
|
var href = hostname + "/" + target;
|
||||||
|
|
||||||
@ -45,29 +42,4 @@ public class WebWolfMacro extends InlineMacroProcessor {
|
|||||||
private boolean displayCompleteLinkNoFormatting(Map<String, Object> attributes) {
|
private boolean displayCompleteLinkNoFormatting(Map<String, Object> attributes) {
|
||||||
return attributes.values().stream().anyMatch(a -> a.equals("noLink"));
|
return attributes.values().stream().anyMatch(a -> a.equals("noLink"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine the host from the hostname and ports that were used. The purpose is to make it
|
|
||||||
* possible to use the application behind a reverse proxy. For instance in the docker
|
|
||||||
* compose/stack version with webgoat webwolf and nginx proxy. You do not have to use the
|
|
||||||
* indicated hostname, but if you do, you should define two hosts aliases 127.0.0.1
|
|
||||||
* www.webgoat.local www.webwolf.local
|
|
||||||
*/
|
|
||||||
private String determineHost(String port) {
|
|
||||||
HttpServletRequest request =
|
|
||||||
((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
|
|
||||||
String host = request.getHeader("Host");
|
|
||||||
int semicolonIndex = host.indexOf(":");
|
|
||||||
if (semicolonIndex == -1 || host.endsWith(":80")) {
|
|
||||||
host = host.replace(":80", "").replace("www.webgoat.local", "www.webwolf.local");
|
|
||||||
} else {
|
|
||||||
host = host.substring(0, semicolonIndex);
|
|
||||||
host = host.concat(":").concat(port);
|
|
||||||
}
|
|
||||||
return "http://" + host + (includeWebWolfContext() ? "/WebWolf" : "");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean includeWebWolfContext() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -17,9 +17,4 @@ public class WebWolfRootMacro extends WebWolfMacro {
|
|||||||
public WebWolfRootMacro(String macroName, Map<String, Object> config) {
|
public WebWolfRootMacro(String macroName, Map<String, Object> config) {
|
||||||
super(macroName, config);
|
super(macroName, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean includeWebWolfContext() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,8 @@ public class LessonTrackerInterceptor implements ResponseBodyAdvice<Object> {
|
|||||||
} else {
|
} else {
|
||||||
userTracker.assignmentFailed(webSession.getCurrentLesson());
|
userTracker.assignmentFailed(webSession.getCurrentLesson());
|
||||||
}
|
}
|
||||||
userTrackerRepository.saveAndFlush(userTracker);
|
userTrackerRepository.save(userTracker);
|
||||||
|
|
||||||
return attackResult;
|
return attackResult;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.owasp.webgoat.container.controller;
|
package org.owasp.webgoat.container.controller;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import org.owasp.webgoat.container.session.Course;
|
import org.owasp.webgoat.container.session.Course;
|
||||||
import org.owasp.webgoat.container.session.WebSession;
|
import org.owasp.webgoat.container.session.WebSession;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
|
@ -29,8 +29,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.owasp.webgoat.container.controller;
|
package org.owasp.webgoat.container.controller;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpSession;
|
import jakarta.servlet.http.HttpSession;
|
||||||
import org.springframework.stereotype.Controller;
|
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;
|
||||||
@ -49,7 +49,7 @@ public class Welcome {
|
|||||||
/**
|
/**
|
||||||
* welcome.
|
* welcome.
|
||||||
*
|
*
|
||||||
* @param request a {@link javax.servlet.http.HttpServletRequest} object.
|
* @param request a {@link jakarta.servlet.http.HttpServletRequest} object.
|
||||||
* @return a {@link org.springframework.web.servlet.ModelAndView} object.
|
* @return a {@link org.springframework.web.servlet.ModelAndView} object.
|
||||||
*/
|
*/
|
||||||
@GetMapping(path = {"welcome.mvc"})
|
@GetMapping(path = {"welcome.mvc"})
|
||||||
|
@ -1,9 +1,14 @@
|
|||||||
package org.owasp.webgoat.container.lessons;
|
package org.owasp.webgoat.container.lessons;
|
||||||
|
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.GenerationType;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.Transient;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.persistence.*;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.*;
|
import lombok.Getter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ************************************************************************************************
|
* ************************************************************************************************
|
||||||
@ -41,7 +46,7 @@ import lombok.*;
|
|||||||
public class Assignment {
|
public class Assignment {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
|
@ -4,15 +4,13 @@ import java.lang.reflect.InvocationHandler;
|
|||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.owasp.webgoat.container.users.WebGoatUser;
|
import org.owasp.webgoat.container.users.WebGoatUser;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handler which sets the correct schema for the currently bounded user. This way users are not
|
* Handler which sets the correct schema for the currently bounded user. This way users are not
|
||||||
* seeing each other data and we can reset data for just one particular user.
|
* seeing each other data, and we can reset data for just one particular user.
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
|
||||||
public class LessonConnectionInvocationHandler implements InvocationHandler {
|
public class LessonConnectionInvocationHandler implements InvocationHandler {
|
||||||
|
|
||||||
private final Connection targetConnection;
|
private final Connection targetConnection;
|
||||||
|
@ -3,7 +3,6 @@ package org.owasp.webgoat.container.session;
|
|||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import org.owasp.webgoat.container.lessons.Lesson;
|
import org.owasp.webgoat.container.lessons.Lesson;
|
||||||
import org.owasp.webgoat.container.users.WebGoatUser;
|
import org.owasp.webgoat.container.users.WebGoatUser;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* *************************************************************************************************
|
* *************************************************************************************************
|
||||||
@ -40,13 +39,12 @@ import org.springframework.security.core.context.SecurityContextHolder;
|
|||||||
public class WebSession implements Serializable {
|
public class WebSession implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = -4270066103101711560L;
|
private static final long serialVersionUID = -4270066103101711560L;
|
||||||
private final WebGoatUser currentUser;
|
private WebGoatUser currentUser;
|
||||||
private transient Lesson currentLesson;
|
private transient Lesson currentLesson;
|
||||||
private boolean securityEnabled;
|
private boolean securityEnabled;
|
||||||
|
|
||||||
public WebSession() {
|
public WebSession(WebGoatUser webGoatUser) {
|
||||||
this.currentUser =
|
this.currentUser = webGoatUser;
|
||||||
(WebGoatUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,8 +1,20 @@
|
|||||||
package org.owasp.webgoat.container.users;
|
package org.owasp.webgoat.container.users;
|
||||||
|
|
||||||
import java.util.*;
|
import jakarta.persistence.CascadeType;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.FetchType;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.GenerationType;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.OneToMany;
|
||||||
|
import jakarta.persistence.Version;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import javax.persistence.*;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.owasp.webgoat.container.lessons.Assignment;
|
import org.owasp.webgoat.container.lessons.Assignment;
|
||||||
import org.owasp.webgoat.container.lessons.Lesson;
|
import org.owasp.webgoat.container.lessons.Lesson;
|
||||||
@ -39,10 +51,11 @@ import org.owasp.webgoat.container.lessons.Lesson;
|
|||||||
* @since October 29, 2003
|
* @since October 29, 2003
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
|
@EqualsAndHashCode
|
||||||
public class LessonTracker {
|
public class LessonTracker {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
@Getter private String lessonName;
|
@Getter private String lessonName;
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
package org.owasp.webgoat.container.users;
|
package org.owasp.webgoat.container.users;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import jakarta.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import javax.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
|
import java.util.UUID;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.security.authentication.AuthenticationManager;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.validation.BindingResult;
|
import org.springframework.validation.BindingResult;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
@ -23,7 +24,6 @@ public class RegistrationController {
|
|||||||
|
|
||||||
private UserValidator userValidator;
|
private UserValidator userValidator;
|
||||||
private UserService userService;
|
private UserService userService;
|
||||||
private AuthenticationManager authenticationManager;
|
|
||||||
|
|
||||||
@GetMapping("/registration")
|
@GetMapping("/registration")
|
||||||
public String showForm(UserForm userForm) {
|
public String showForm(UserForm userForm) {
|
||||||
@ -46,4 +46,12 @@ public class RegistrationController {
|
|||||||
|
|
||||||
return "redirect:/attack";
|
return "redirect:/attack";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/login-oauth.mvc")
|
||||||
|
public String registrationOAUTH(Authentication authentication, HttpServletRequest request)
|
||||||
|
throws ServletException {
|
||||||
|
log.info("register oauth user in database");
|
||||||
|
userService.addUser(authentication.getName(), UUID.randomUUID().toString());
|
||||||
|
return "redirect:/welcome.mvc";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package org.owasp.webgoat.container.users;
|
package org.owasp.webgoat.container.users;
|
||||||
|
|
||||||
import javax.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
import javax.validation.constraints.Pattern;
|
import jakarta.validation.constraints.Pattern;
|
||||||
import javax.validation.constraints.Size;
|
import jakarta.validation.constraints.Size;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@ -1,11 +1,19 @@
|
|||||||
package org.owasp.webgoat.container.users;
|
package org.owasp.webgoat.container.users;
|
||||||
|
|
||||||
|
import jakarta.persistence.CascadeType;
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.FetchType;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.GenerationType;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.OneToMany;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import javax.persistence.*;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.owasp.webgoat.container.lessons.Assignment;
|
import org.owasp.webgoat.container.lessons.Assignment;
|
||||||
import org.owasp.webgoat.container.lessons.Lesson;
|
import org.owasp.webgoat.container.lessons.Lesson;
|
||||||
@ -43,10 +51,11 @@ import org.owasp.webgoat.container.lessons.Lesson;
|
|||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Entity
|
@Entity
|
||||||
|
@EqualsAndHashCode
|
||||||
public class UserTracker {
|
public class UserTracker {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
@Column(name = "username")
|
@Column(name = "username")
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package org.owasp.webgoat.container.users;
|
package org.owasp.webgoat.container.users;
|
||||||
|
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.Transient;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.Id;
|
|
||||||
import javax.persistence.Transient;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.springframework.security.core.GrantedAuthority;
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||||
|
@ -42,6 +42,7 @@ public class AccountVerificationHelper {
|
|||||||
static {
|
static {
|
||||||
secQuestionStore.put(verifyUserId, userSecQuestions);
|
secQuestionStore.put(verifyUserId, userSecQuestions);
|
||||||
}
|
}
|
||||||
|
|
||||||
// end 'data store set up'
|
// end 'data store set up'
|
||||||
|
|
||||||
// this is to aid feedback in the attack process and is not intended to be part of the
|
// this is to aid feedback in the attack process and is not intended to be part of the
|
||||||
@ -68,6 +69,7 @@ public class AccountVerificationHelper {
|
|||||||
|
|
||||||
return likely;
|
return likely;
|
||||||
}
|
}
|
||||||
|
|
||||||
// end of cheating check ... the method below is the one of real interest. Can you find the flaw?
|
// end of cheating check ... the method below is the one of real interest. Can you find the flaw?
|
||||||
|
|
||||||
public boolean verifyAccount(Integer userId, HashMap<String, String> submittedQuestions) {
|
public boolean verifyAccount(Integer userId, HashMap<String, String> submittedQuestions) {
|
||||||
|
@ -22,13 +22,13 @@
|
|||||||
|
|
||||||
package org.owasp.webgoat.lessons.authbypass;
|
package org.owasp.webgoat.lessons.authbypass;
|
||||||
|
|
||||||
|
import jakarta.servlet.ServletException;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.servlet.ServletException;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
|
||||||
import org.owasp.webgoat.container.assignments.AssignmentHints;
|
import org.owasp.webgoat.container.assignments.AssignmentHints;
|
||||||
import org.owasp.webgoat.container.assignments.AttackResult;
|
import org.owasp.webgoat.container.assignments.AttackResult;
|
||||||
|
@ -1,89 +1,13 @@
|
|||||||
/*
|
|
||||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
|
||||||
*
|
|
||||||
* Copyright (c) 2002 - 2019 Bruce Mayhew
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
|
||||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
|
||||||
* License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
|
||||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along with this program; if
|
|
||||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
||||||
* 02111-1307, USA.
|
|
||||||
*
|
|
||||||
* Getting Source ==============
|
|
||||||
*
|
|
||||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.owasp.webgoat.lessons.challenges;
|
package org.owasp.webgoat.lessons.challenges;
|
||||||
|
|
||||||
import java.util.HashMap;
|
public record Flag(int number, String answer) {
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.stream.IntStream;
|
|
||||||
import javax.annotation.PostConstruct;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
|
||||||
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
|
|
||||||
import org.owasp.webgoat.container.assignments.AttackResult;
|
|
||||||
import org.owasp.webgoat.container.session.WebSession;
|
|
||||||
import org.owasp.webgoat.container.users.UserTracker;
|
|
||||||
import org.owasp.webgoat.container.users.UserTrackerRepository;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.http.MediaType;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
/**
|
public boolean isCorrect(String flag) {
|
||||||
* @author nbaars
|
return answer.equals(flag);
|
||||||
* @since 3/23/17.
|
|
||||||
*/
|
|
||||||
@RestController
|
|
||||||
public class Flag extends AssignmentEndpoint {
|
|
||||||
|
|
||||||
public static final Map<Integer, String> FLAGS = new HashMap<>();
|
|
||||||
@Autowired private UserTrackerRepository userTrackerRepository;
|
|
||||||
@Autowired private WebSession webSession;
|
|
||||||
|
|
||||||
@AllArgsConstructor
|
|
||||||
private class FlagPosted {
|
|
||||||
@Getter private boolean lessonCompleted;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostConstruct
|
@Override
|
||||||
public void initFlags() {
|
public String toString() {
|
||||||
IntStream.range(1, 10).forEach(i -> FLAGS.put(i, UUID.randomUUID().toString()));
|
return answer;
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping(
|
|
||||||
path = "/challenge/flag",
|
|
||||||
method = RequestMethod.POST,
|
|
||||||
produces = MediaType.APPLICATION_JSON_VALUE)
|
|
||||||
@ResponseBody
|
|
||||||
public AttackResult postFlag(@RequestParam String flag) {
|
|
||||||
UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName());
|
|
||||||
String currentChallenge = webSession.getCurrentLesson().getName();
|
|
||||||
int challengeNumber =
|
|
||||||
Integer.valueOf(
|
|
||||||
currentChallenge.substring(currentChallenge.length() - 1, currentChallenge.length()));
|
|
||||||
String expectedFlag = FLAGS.get(challengeNumber);
|
|
||||||
final AttackResult attackResult;
|
|
||||||
if (expectedFlag.equals(flag)) {
|
|
||||||
userTracker.assignmentSolved(webSession.getCurrentLesson(), "Assignment" + challengeNumber);
|
|
||||||
attackResult = success(this).feedback("challenge.flag.correct").build();
|
|
||||||
} else {
|
|
||||||
userTracker.assignmentFailed(webSession.getCurrentLesson());
|
|
||||||
attackResult = failed(this).feedback("challenge.flag.incorrect").build();
|
|
||||||
}
|
|
||||||
userTrackerRepository.save(userTracker);
|
|
||||||
return attackResult;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2002 - 2019 Bruce Mayhew
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||||
|
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||||
|
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program; if
|
||||||
|
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
* 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Getting Source ==============
|
||||||
|
*
|
||||||
|
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.owasp.webgoat.lessons.challenges;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
|
||||||
|
import org.owasp.webgoat.container.assignments.AttackResult;
|
||||||
|
import org.owasp.webgoat.container.session.WebSession;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class FlagController extends AssignmentEndpoint {
|
||||||
|
|
||||||
|
private final WebSession webSession;
|
||||||
|
private final Flags flags;
|
||||||
|
|
||||||
|
@PostMapping(path = "/challenge/flag", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||||
|
@ResponseBody
|
||||||
|
public AttackResult postFlag(@RequestParam String flag) {
|
||||||
|
Flag expectedFlag = flags.getFlag(webSession.getCurrentLesson());
|
||||||
|
if (expectedFlag.isCorrect(flag)) {
|
||||||
|
return success(this).feedback("challenge.flag.correct").build();
|
||||||
|
} else {
|
||||||
|
return failed(this).feedback("challenge.flag.incorrect").build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
package org.owasp.webgoat.lessons.challenges;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
import org.owasp.webgoat.container.lessons.Lesson;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class Flags {
|
||||||
|
private final Map<Integer, Flag> FLAGS = new HashMap<>();
|
||||||
|
|
||||||
|
public Flags() {
|
||||||
|
IntStream.range(1, 10).forEach(i -> FLAGS.put(i, new Flag(i, UUID.randomUUID().toString())));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Flag getFlag(Lesson forLesson) {
|
||||||
|
String lessonName = forLesson.getName();
|
||||||
|
int challengeNumber = Integer.valueOf(lessonName.substring(lessonName.length() - 1));
|
||||||
|
return FLAGS.get(challengeNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Flag getFlag(int flagNumber) {
|
||||||
|
return FLAGS.get(flagNumber);
|
||||||
|
}
|
||||||
|
}
|
@ -32,6 +32,4 @@ public interface SolutionConstants {
|
|||||||
|
|
||||||
// TODO should be random generated when starting the server
|
// TODO should be random generated when starting the server
|
||||||
String PASSWORD = "!!webgoat_admin_1234!!";
|
String PASSWORD = "!!webgoat_admin_1234!!";
|
||||||
String PASSWORD_TOM = "thisisasecretfortomonly";
|
|
||||||
String ADMIN_PASSWORD_LINK = "375afe1104f4a487a73823c50a9292a2";
|
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,10 @@ package org.owasp.webgoat.lessons.challenges.challenge1;
|
|||||||
|
|
||||||
import static org.owasp.webgoat.lessons.challenges.SolutionConstants.PASSWORD;
|
import static org.owasp.webgoat.lessons.challenges.SolutionConstants.PASSWORD;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
|
||||||
import org.owasp.webgoat.container.assignments.AttackResult;
|
import org.owasp.webgoat.container.assignments.AttackResult;
|
||||||
import org.owasp.webgoat.lessons.challenges.Flag;
|
import org.owasp.webgoat.lessons.challenges.Flags;
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
@ -43,12 +42,14 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
* @since August 11, 2016
|
* @since August 11, 2016
|
||||||
*/
|
*/
|
||||||
@RestController
|
@RestController
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class Assignment1 extends AssignmentEndpoint {
|
public class Assignment1 extends AssignmentEndpoint {
|
||||||
|
|
||||||
|
private final Flags flags;
|
||||||
|
|
||||||
@PostMapping("/challenge/1")
|
@PostMapping("/challenge/1")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AttackResult completed(
|
public AttackResult completed(@RequestParam String username, @RequestParam String password) {
|
||||||
@RequestParam String username, @RequestParam String password, HttpServletRequest request) {
|
|
||||||
boolean ipAddressKnown = true;
|
boolean ipAddressKnown = true;
|
||||||
boolean passwordCorrect =
|
boolean passwordCorrect =
|
||||||
"admin".equals(username)
|
"admin".equals(username)
|
||||||
@ -56,14 +57,10 @@ public class Assignment1 extends AssignmentEndpoint {
|
|||||||
.replace("1234", String.format("%04d", ImageServlet.PINCODE))
|
.replace("1234", String.format("%04d", ImageServlet.PINCODE))
|
||||||
.equals(password);
|
.equals(password);
|
||||||
if (passwordCorrect && ipAddressKnown) {
|
if (passwordCorrect && ipAddressKnown) {
|
||||||
return success(this).feedback("challenge.solved").feedbackArgs(Flag.FLAGS.get(1)).build();
|
return success(this).feedback("challenge.solved").feedbackArgs(flags.getFlag(1)).build();
|
||||||
} else if (passwordCorrect) {
|
} else if (passwordCorrect) {
|
||||||
return failed(this).feedback("ip.address.unknown").build();
|
return failed(this).feedback("ip.address.unknown").build();
|
||||||
}
|
}
|
||||||
return failed(this).build();
|
return failed(this).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean containsHeader(HttpServletRequest request) {
|
|
||||||
return StringUtils.hasText(request.getHeader("X-Forwarded-For"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,7 @@ import static org.springframework.web.bind.annotation.RequestMethod.GET;
|
|||||||
import static org.springframework.web.bind.annotation.RequestMethod.POST;
|
import static org.springframework.web.bind.annotation.RequestMethod.POST;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.SecureRandom;
|
import java.util.Random;
|
||||||
import javax.servlet.http.HttpServlet;
|
|
||||||
import org.springframework.core.io.ClassPathResource;
|
import org.springframework.core.io.ClassPathResource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
@ -13,10 +12,9 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
|||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
public class ImageServlet extends HttpServlet {
|
public class ImageServlet {
|
||||||
|
|
||||||
private static final long serialVersionUID = 9132775506936676850L;
|
public static final int PINCODE = new Random().nextInt(10000);
|
||||||
public static final int PINCODE = new SecureRandom().nextInt(10000);
|
|
||||||
|
|
||||||
@RequestMapping(
|
@RequestMapping(
|
||||||
method = {GET, POST},
|
method = {GET, POST},
|
||||||
|
@ -24,11 +24,12 @@ package org.owasp.webgoat.lessons.challenges.challenge5;
|
|||||||
|
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.owasp.webgoat.container.LessonDataSource;
|
import org.owasp.webgoat.container.LessonDataSource;
|
||||||
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
|
||||||
import org.owasp.webgoat.container.assignments.AttackResult;
|
import org.owasp.webgoat.container.assignments.AttackResult;
|
||||||
import org.owasp.webgoat.lessons.challenges.Flag;
|
import org.owasp.webgoat.lessons.challenges.Flags;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
@ -37,13 +38,11 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class Assignment5 extends AssignmentEndpoint {
|
public class Assignment5 extends AssignmentEndpoint {
|
||||||
|
|
||||||
private final LessonDataSource dataSource;
|
private final LessonDataSource dataSource;
|
||||||
|
private final Flags flags;
|
||||||
public Assignment5(LessonDataSource dataSource) {
|
|
||||||
this.dataSource = dataSource;
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping("/challenge/5")
|
@PostMapping("/challenge/5")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
@ -66,7 +65,7 @@ public class Assignment5 extends AssignmentEndpoint {
|
|||||||
ResultSet resultSet = statement.executeQuery();
|
ResultSet resultSet = statement.executeQuery();
|
||||||
|
|
||||||
if (resultSet.next()) {
|
if (resultSet.next()) {
|
||||||
return success(this).feedback("challenge.solved").feedbackArgs(Flag.FLAGS.get(5)).build();
|
return success(this).feedback("challenge.solved").feedbackArgs(flags.getFlag(5)).build();
|
||||||
} else {
|
} else {
|
||||||
return failed(this).feedback("challenge.close").build();
|
return failed(this).feedback("challenge.close").build();
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,14 @@
|
|||||||
package org.owasp.webgoat.lessons.challenges.challenge7;
|
package org.owasp.webgoat.lessons.challenges.challenge7;
|
||||||
|
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
|
||||||
import org.owasp.webgoat.container.assignments.AttackResult;
|
import org.owasp.webgoat.container.assignments.AttackResult;
|
||||||
import org.owasp.webgoat.lessons.challenges.Email;
|
import org.owasp.webgoat.lessons.challenges.Email;
|
||||||
import org.owasp.webgoat.lessons.challenges.Flag;
|
import org.owasp.webgoat.lessons.challenges.Flags;
|
||||||
import org.owasp.webgoat.lessons.challenges.SolutionConstants;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.core.io.ClassPathResource;
|
import org.springframework.core.io.ClassPathResource;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
@ -33,6 +31,8 @@ import org.springframework.web.client.RestTemplate;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class Assignment7 extends AssignmentEndpoint {
|
public class Assignment7 extends AssignmentEndpoint {
|
||||||
|
|
||||||
|
public static final String ADMIN_PASSWORD_LINK = "375afe1104f4a487a73823c50a9292a2";
|
||||||
|
|
||||||
private static final String TEMPLATE =
|
private static final String TEMPLATE =
|
||||||
"Hi, you requested a password reset link, please use this <a target='_blank'"
|
"Hi, you requested a password reset link, please use this <a target='_blank'"
|
||||||
+ " href='%s:8080/WebGoat/challenge/7/reset-password/%s'>link</a> to reset your"
|
+ " href='%s:8080/WebGoat/challenge/7/reset-password/%s'>link</a> to reset your"
|
||||||
@ -44,22 +44,26 @@ public class Assignment7 extends AssignmentEndpoint {
|
|||||||
+ "Kind regards, \n"
|
+ "Kind regards, \n"
|
||||||
+ "Team WebGoat";
|
+ "Team WebGoat";
|
||||||
|
|
||||||
@Autowired private RestTemplate restTemplate;
|
private final Flags flags;
|
||||||
|
private final RestTemplate restTemplate;
|
||||||
|
private final String webWolfMailURL;
|
||||||
|
|
||||||
@Value("${webwolf.mail.url}")
|
public Assignment7(
|
||||||
private String webWolfMailURL;
|
Flags flags, RestTemplate restTemplate, @Value("${webwolf.mail.url}") String webWolfMailURL) {
|
||||||
|
this.flags = flags;
|
||||||
|
this.restTemplate = restTemplate;
|
||||||
|
this.webWolfMailURL = webWolfMailURL;
|
||||||
|
}
|
||||||
|
|
||||||
@GetMapping("/challenge/7/reset-password/{link}")
|
@GetMapping("/challenge/7/reset-password/{link}")
|
||||||
public ResponseEntity<String> resetPassword(@PathVariable(value = "link") String link) {
|
public ResponseEntity<String> resetPassword(@PathVariable(value = "link") String link) {
|
||||||
if (link.equals(SolutionConstants.ADMIN_PASSWORD_LINK)) {
|
if (link.equals(ADMIN_PASSWORD_LINK)) {
|
||||||
return ResponseEntity.accepted()
|
return ResponseEntity.accepted()
|
||||||
.body(
|
.body(
|
||||||
"<h1>Success!!</h1>"
|
"<h1>Success!!</h1>"
|
||||||
+ "<img src='/WebGoat/images/hi-five-cat.jpg'>"
|
+ "<img src='/WebGoat/images/hi-five-cat.jpg'>"
|
||||||
+ "<br/><br/>Here is your flag: "
|
+ "<br/><br/>Here is your flag: "
|
||||||
+ "<b>"
|
+ flags.getFlag(7));
|
||||||
+ Flag.FLAGS.get(7)
|
|
||||||
+ "</b>");
|
|
||||||
}
|
}
|
||||||
return ResponseEntity.status(HttpStatus.I_AM_A_TEAPOT)
|
return ResponseEntity.status(HttpStatus.I_AM_A_TEAPOT)
|
||||||
.body("That is not the reset link for admin");
|
.body("That is not the reset link for admin");
|
||||||
@ -94,6 +98,6 @@ public class Assignment7 extends AssignmentEndpoint {
|
|||||||
@GetMapping(value = "/challenge/7/.git", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
|
@GetMapping(value = "/challenge/7/.git", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ClassPathResource git() {
|
public ClassPathResource git() {
|
||||||
return new ClassPathResource("challenge7/git.zip");
|
return new ClassPathResource("lessons/challenges/challenge7/git.zip");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
package org.owasp.webgoat.lessons.challenges.challenge8;
|
package org.owasp.webgoat.lessons.challenges.challenge8;
|
||||||
|
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
|
||||||
import org.owasp.webgoat.container.assignments.AttackResult;
|
import org.owasp.webgoat.container.assignments.AttackResult;
|
||||||
import org.owasp.webgoat.lessons.challenges.Flag;
|
import org.owasp.webgoat.lessons.challenges.Flags;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
@ -15,12 +16,9 @@ import org.springframework.web.bind.annotation.PathVariable;
|
|||||||
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/8/17.
|
|
||||||
*/
|
|
||||||
@RestController
|
@RestController
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class Assignment8 extends AssignmentEndpoint {
|
public class Assignment8 extends AssignmentEndpoint {
|
||||||
|
|
||||||
private static final Map<Integer, Integer> votes = new HashMap<>();
|
private static final Map<Integer, Integer> votes = new HashMap<>();
|
||||||
@ -33,6 +31,8 @@ public class Assignment8 extends AssignmentEndpoint {
|
|||||||
votes.put(5, 300);
|
votes.put(5, 300);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final Flags flags;
|
||||||
|
|
||||||
@GetMapping(value = "/challenge/8/vote/{stars}", produces = MediaType.APPLICATION_JSON_VALUE)
|
@GetMapping(value = "/challenge/8/vote/{stars}", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ResponseEntity<?> vote(
|
public ResponseEntity<?> vote(
|
||||||
@ -47,7 +47,7 @@ public class Assignment8 extends AssignmentEndpoint {
|
|||||||
Integer allVotesForStar = votes.getOrDefault(nrOfStars, 0);
|
Integer allVotesForStar = votes.getOrDefault(nrOfStars, 0);
|
||||||
votes.put(nrOfStars, allVotesForStar + 1);
|
votes.put(nrOfStars, allVotesForStar + 1);
|
||||||
return ResponseEntity.ok()
|
return ResponseEntity.ok()
|
||||||
.header("X-Flag", "Thanks for voting, your flag is: " + Flag.FLAGS.get(8))
|
.header("X-FlagController", "Thanks for voting, your flag is: " + flags.getFlag(8))
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
package org.owasp.webgoat.lessons.clientsidefiltering;
|
package org.owasp.webgoat.lessons.clientsidefiltering;
|
||||||
|
|
||||||
|
import jakarta.annotation.PostConstruct;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
@ -31,7 +32,6 @@ import java.util.ArrayList;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.annotation.PostConstruct;
|
|
||||||
import javax.xml.xpath.XPath;
|
import javax.xml.xpath.XPath;
|
||||||
import javax.xml.xpath.XPathConstants;
|
import javax.xml.xpath.XPathConstants;
|
||||||
import javax.xml.xpath.XPathExpressionException;
|
import javax.xml.xpath.XPathExpressionException;
|
||||||
|
@ -22,9 +22,9 @@
|
|||||||
|
|
||||||
package org.owasp.webgoat.lessons.cryptography;
|
package org.owasp.webgoat.lessons.cryptography;
|
||||||
|
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
|
||||||
import org.owasp.webgoat.container.assignments.AttackResult;
|
import org.owasp.webgoat.container.assignments.AttackResult;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
|
@ -22,10 +22,10 @@
|
|||||||
|
|
||||||
package org.owasp.webgoat.lessons.cryptography;
|
package org.owasp.webgoat.lessons.cryptography;
|
||||||
|
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.xml.bind.DatatypeConverter;
|
import javax.xml.bind.DatatypeConverter;
|
||||||
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
|
||||||
import org.owasp.webgoat.container.assignments.AssignmentHints;
|
import org.owasp.webgoat.container.assignments.AssignmentHints;
|
||||||
|
@ -22,11 +22,11 @@
|
|||||||
|
|
||||||
package org.owasp.webgoat.lessons.cryptography;
|
package org.owasp.webgoat.lessons.cryptography;
|
||||||
|
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import java.security.InvalidAlgorithmParameterException;
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
import java.security.KeyPair;
|
import java.security.KeyPair;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.interfaces.RSAPublicKey;
|
import java.security.interfaces.RSAPublicKey;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.xml.bind.DatatypeConverter;
|
import javax.xml.bind.DatatypeConverter;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
|
||||||
|
@ -24,11 +24,11 @@ package org.owasp.webgoat.lessons.csrf;
|
|||||||
|
|
||||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import jakarta.servlet.http.Cookie;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import javax.servlet.http.Cookie;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||||
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
|
||||||
import org.owasp.webgoat.container.assignments.AssignmentHints;
|
import org.owasp.webgoat.container.assignments.AssignmentHints;
|
||||||
|
@ -22,15 +22,14 @@
|
|||||||
|
|
||||||
package org.owasp.webgoat.lessons.csrf;
|
package org.owasp.webgoat.lessons.csrf;
|
||||||
|
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import org.owasp.webgoat.container.i18n.PluginMessages;
|
import org.owasp.webgoat.container.i18n.PluginMessages;
|
||||||
import org.owasp.webgoat.container.session.UserSessionData;
|
import org.owasp.webgoat.container.session.UserSessionData;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
|
||||||
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;
|
||||||
|
|
||||||
@ -41,10 +40,9 @@ public class CSRFGetFlag {
|
|||||||
@Autowired UserSessionData userSessionData;
|
@Autowired UserSessionData userSessionData;
|
||||||
@Autowired private PluginMessages pluginMessages;
|
@Autowired private PluginMessages pluginMessages;
|
||||||
|
|
||||||
@RequestMapping(
|
@PostMapping(
|
||||||
path = "/csrf/basic-get-flag",
|
path = "/csrf/basic-get-flag",
|
||||||
produces = {"application/json"},
|
produces = {"application/json"})
|
||||||
method = RequestMethod.POST)
|
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public Map<String, Object> invoke(HttpServletRequest req) {
|
public Map<String, Object> invoke(HttpServletRequest req) {
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
package org.owasp.webgoat.lessons.csrf;
|
package org.owasp.webgoat.lessons.csrf;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
|
||||||
import org.owasp.webgoat.container.assignments.AssignmentHints;
|
import org.owasp.webgoat.container.assignments.AssignmentHints;
|
||||||
import org.owasp.webgoat.container.assignments.AttackResult;
|
import org.owasp.webgoat.container.assignments.AttackResult;
|
||||||
|
@ -25,6 +25,7 @@ package org.owasp.webgoat.lessons.csrf;
|
|||||||
import static org.springframework.http.MediaType.ALL_VALUE;
|
import static org.springframework.http.MediaType.ALL_VALUE;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -32,7 +33,6 @@ import java.util.Collection;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
|
||||||
import org.owasp.webgoat.container.assignments.AssignmentHints;
|
import org.owasp.webgoat.container.assignments.AssignmentHints;
|
||||||
import org.owasp.webgoat.container.assignments.AttackResult;
|
import org.owasp.webgoat.container.assignments.AttackResult;
|
||||||
|
@ -22,8 +22,8 @@
|
|||||||
|
|
||||||
package org.owasp.webgoat.lessons.hijacksession;
|
package org.owasp.webgoat.lessons.hijacksession;
|
||||||
|
|
||||||
import javax.servlet.http.Cookie;
|
import jakarta.servlet.http.Cookie;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
|
||||||
import org.owasp.webgoat.container.assignments.AssignmentHints;
|
import org.owasp.webgoat.container.assignments.AssignmentHints;
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
package org.owasp.webgoat.lessons.httpproxies;
|
package org.owasp.webgoat.lessons.httpproxies;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
|
||||||
import org.owasp.webgoat.container.assignments.AttackResult;
|
import org.owasp.webgoat.container.assignments.AttackResult;
|
||||||
import org.springframework.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
|
@ -15,7 +15,8 @@
|
|||||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
* 02111-1307, USA.
|
* 02111-1307, USA.
|
||||||
*
|
*
|
||||||
* Getting Source ==============
|
* Getting Source
|
||||||
|
* ==============
|
||||||
*
|
*
|
||||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||||
*/
|
*/
|
||||||
|
@ -15,7 +15,8 @@
|
|||||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
* 02111-1307, USA.
|
* 02111-1307, USA.
|
||||||
*
|
*
|
||||||
* Getting Source ==============
|
* Getting Source
|
||||||
|
* ==============
|
||||||
*
|
*
|
||||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||||
*/
|
*/
|
||||||
@ -45,7 +46,7 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
"idor.hints.otherProfile8",
|
"idor.hints.otherProfile8",
|
||||||
"idor.hints.otherProfile9"
|
"idor.hints.otherProfile9"
|
||||||
})
|
})
|
||||||
public class IDOREditOtherProfiile extends AssignmentEndpoint {
|
public class IDOREditOtherProfile extends AssignmentEndpoint {
|
||||||
|
|
||||||
@Autowired private UserSessionData userSessionData;
|
@Autowired private UserSessionData userSessionData;
|
||||||
|
|
||||||
@ -69,7 +70,7 @@ public class IDOREditOtherProfiile extends AssignmentEndpoint {
|
|||||||
// we will persist in the session object for now in case we want to refer back or use it later
|
// we will persist in the session object for now in case we want to refer back or use it later
|
||||||
userSessionData.setValue("idor-updated-other-profile", currentUserProfile);
|
userSessionData.setValue("idor-updated-other-profile", currentUserProfile);
|
||||||
if (currentUserProfile.getRole() <= 1
|
if (currentUserProfile.getRole() <= 1
|
||||||
&& currentUserProfile.getColor().toLowerCase().equals("red")) {
|
&& currentUserProfile.getColor().equalsIgnoreCase("red")) {
|
||||||
return success(this)
|
return success(this)
|
||||||
.feedback("idor.edit.profile.success1")
|
.feedback("idor.edit.profile.success1")
|
||||||
.output(currentUserProfile.profileToMap().toString())
|
.output(currentUserProfile.profileToMap().toString())
|
||||||
@ -77,16 +78,16 @@ public class IDOREditOtherProfiile extends AssignmentEndpoint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (currentUserProfile.getRole() > 1
|
if (currentUserProfile.getRole() > 1
|
||||||
&& currentUserProfile.getColor().toLowerCase().equals("red")) {
|
&& currentUserProfile.getColor().equalsIgnoreCase("red")) {
|
||||||
return success(this)
|
return failed(this)
|
||||||
.feedback("idor.edit.profile.failure1")
|
.feedback("idor.edit.profile.failure1")
|
||||||
.output(currentUserProfile.profileToMap().toString())
|
.output(currentUserProfile.profileToMap().toString())
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentUserProfile.getRole() <= 1
|
if (currentUserProfile.getRole() <= 1
|
||||||
&& !currentUserProfile.getColor().toLowerCase().equals("red")) {
|
&& !currentUserProfile.getColor().equalsIgnoreCase("red")) {
|
||||||
return success(this)
|
return failed(this)
|
||||||
.feedback("idor.edit.profile.failure2")
|
.feedback("idor.edit.profile.failure2")
|
||||||
.output(currentUserProfile.profileToMap().toString())
|
.output(currentUserProfile.profileToMap().toString())
|
||||||
.build();
|
.build();
|
||||||
@ -97,7 +98,8 @@ public class IDOREditOtherProfiile extends AssignmentEndpoint {
|
|||||||
.feedback("idor.edit.profile.failure3")
|
.feedback("idor.edit.profile.failure3")
|
||||||
.output(currentUserProfile.profileToMap().toString())
|
.output(currentUserProfile.profileToMap().toString())
|
||||||
.build();
|
.build();
|
||||||
} else if (userSubmittedProfile.getUserId().equals(authUserId)) {
|
} else if (userSubmittedProfile.getUserId() != null
|
||||||
|
&& userSubmittedProfile.getUserId().equals(authUserId)) {
|
||||||
return failed(this).feedback("idor.edit.profile.failure4").build();
|
return failed(this).feedback("idor.edit.profile.failure4").build();
|
||||||
}
|
}
|
||||||
|
|
@ -15,7 +15,8 @@
|
|||||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
* 02111-1307, USA.
|
* 02111-1307, USA.
|
||||||
*
|
*
|
||||||
* Getting Source ==============
|
* Getting Source
|
||||||
|
* ==============
|
||||||
*
|
*
|
||||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||||
*/
|
*/
|
||||||
|
@ -15,16 +15,15 @@
|
|||||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
* 02111-1307, USA.
|
* 02111-1307, USA.
|
||||||
*
|
*
|
||||||
* Getting Source ==============
|
* Getting Source
|
||||||
|
* ==============
|
||||||
*
|
*
|
||||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.owasp.webgoat.lessons.idor;
|
package org.owasp.webgoat.lessons.idor;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import java.util.Map;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
|
||||||
import org.owasp.webgoat.container.assignments.AssignmentHints;
|
import org.owasp.webgoat.container.assignments.AssignmentHints;
|
||||||
import org.owasp.webgoat.container.assignments.AttackResult;
|
import org.owasp.webgoat.container.assignments.AttackResult;
|
||||||
@ -56,9 +55,9 @@ public class IDORViewOtherProfile extends AssignmentEndpoint {
|
|||||||
produces = {"application/json"})
|
produces = {"application/json"})
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AttackResult completed(@PathVariable("userId") String userId, HttpServletResponse resp) {
|
public AttackResult completed(@PathVariable("userId") String userId, HttpServletResponse resp) {
|
||||||
Map<String, Object> details = new HashMap<>();
|
|
||||||
|
|
||||||
if (userSessionData.getValue("idor-authenticated-as").equals("tom")) {
|
Object obj = userSessionData.getValue("idor-authenticated-as");
|
||||||
|
if (obj != null && obj.equals("tom")) {
|
||||||
// going to use session auth to view this one
|
// going to use session auth to view this one
|
||||||
String authUserId = (String) userSessionData.getValue("idor-authenticated-user-id");
|
String authUserId = (String) userSessionData.getValue("idor-authenticated-user-id");
|
||||||
if (userId != null && !userId.equals(authUserId)) {
|
if (userId != null && !userId.equals(authUserId)) {
|
||||||
@ -66,7 +65,8 @@ public class IDORViewOtherProfile extends AssignmentEndpoint {
|
|||||||
UserProfile requestedProfile = new UserProfile(userId);
|
UserProfile requestedProfile = new UserProfile(userId);
|
||||||
// secure code would ensure there was a horizontal access control check prior to dishing up
|
// secure code would ensure there was a horizontal access control check prior to dishing up
|
||||||
// the requested profile
|
// the requested profile
|
||||||
if (requestedProfile.getUserId().equals("2342388")) {
|
if (requestedProfile.getUserId() != null
|
||||||
|
&& requestedProfile.getUserId().equals("2342388")) {
|
||||||
return success(this)
|
return success(this)
|
||||||
.feedback("idor.view.profile.success")
|
.feedback("idor.view.profile.success")
|
||||||
.output(requestedProfile.profileToMap().toString())
|
.output(requestedProfile.profileToMap().toString())
|
||||||
|
@ -15,7 +15,8 @@
|
|||||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
* 02111-1307, USA.
|
* 02111-1307, USA.
|
||||||
*
|
*
|
||||||
* Getting Source ==============
|
* Getting Source
|
||||||
|
* ==============
|
||||||
*
|
*
|
||||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||||
*/
|
*/
|
||||||
|
@ -15,7 +15,8 @@
|
|||||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
* 02111-1307, USA.
|
* 02111-1307, USA.
|
||||||
*
|
*
|
||||||
* Getting Source ==============
|
* Getting Source
|
||||||
|
* ==============
|
||||||
*
|
*
|
||||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||||
*/
|
*/
|
||||||
@ -68,7 +69,7 @@ public class IDORViewOwnProfileAltUrl extends AssignmentEndpoint {
|
|||||||
return failed(this).feedback("idor.view.own.profile.failure2").build();
|
return failed(this).feedback("idor.view.own.profile.failure2").build();
|
||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
return failed(this).feedback("an error occurred with your request").build();
|
return failed(this).output("an error occurred with your request").build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,8 @@
|
|||||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
* 02111-1307, USA.
|
* 02111-1307, USA.
|
||||||
*
|
*
|
||||||
* Getting Source ==============
|
* Getting Source
|
||||||
|
* ==============
|
||||||
*
|
*
|
||||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||||
*/
|
*/
|
||||||
|
@ -31,14 +31,14 @@ import io.jsonwebtoken.Jwt;
|
|||||||
import io.jsonwebtoken.JwtException;
|
import io.jsonwebtoken.JwtException;
|
||||||
import io.jsonwebtoken.Jwts;
|
import io.jsonwebtoken.Jwts;
|
||||||
import io.jsonwebtoken.impl.TextCodec;
|
import io.jsonwebtoken.impl.TextCodec;
|
||||||
|
import jakarta.annotation.PostConstruct;
|
||||||
|
import jakarta.servlet.http.Cookie;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.annotation.PostConstruct;
|
|
||||||
import javax.servlet.http.Cookie;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
|
||||||
import org.owasp.webgoat.container.assignments.AssignmentHints;
|
import org.owasp.webgoat.container.assignments.AssignmentHints;
|
||||||
|
@ -0,0 +1,70 @@
|
|||||||
|
package org.owasp.webgoat.lessons.jwt.claimmisuse;
|
||||||
|
|
||||||
|
import com.auth0.jwk.JwkException;
|
||||||
|
import com.auth0.jwk.JwkProvider;
|
||||||
|
import com.auth0.jwk.JwkProviderBuilder;
|
||||||
|
import com.auth0.jwt.JWT;
|
||||||
|
import com.auth0.jwt.algorithms.Algorithm;
|
||||||
|
import com.auth0.jwt.exceptions.JWTVerificationException;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.security.interfaces.RSAPublicKey;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
|
||||||
|
import org.owasp.webgoat.container.assignments.AssignmentHints;
|
||||||
|
import org.owasp.webgoat.container.assignments.AttackResult;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RequestMapping("/JWT/jku")
|
||||||
|
@RestController
|
||||||
|
@AssignmentHints({
|
||||||
|
"jwt-jku-hint1",
|
||||||
|
"jwt-jku-hint2",
|
||||||
|
"jwt-jku-hint3",
|
||||||
|
"jwt-jku-hint4",
|
||||||
|
"jwt-jku-hint5"
|
||||||
|
})
|
||||||
|
public class JWTHeaderJKUEndpoint extends AssignmentEndpoint {
|
||||||
|
|
||||||
|
@PostMapping("/follow/{user}")
|
||||||
|
public @ResponseBody String follow(@PathVariable("user") String user) {
|
||||||
|
if ("Jerry".equals(user)) {
|
||||||
|
return "Following yourself seems redundant";
|
||||||
|
} else {
|
||||||
|
return "You are now following Tom";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/delete")
|
||||||
|
public @ResponseBody AttackResult resetVotes(@RequestParam("token") String token) {
|
||||||
|
if (StringUtils.isEmpty(token)) {
|
||||||
|
return failed(this).feedback("jwt-invalid-token").build();
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
var decodedJWT = JWT.decode(token);
|
||||||
|
var jku = decodedJWT.getHeaderClaim("jku");
|
||||||
|
JwkProvider jwkProvider = new JwkProviderBuilder(new URL(jku.asString())).build();
|
||||||
|
var jwk = jwkProvider.get(decodedJWT.getKeyId());
|
||||||
|
var algorithm = Algorithm.RSA256((RSAPublicKey) jwk.getPublicKey());
|
||||||
|
JWT.require(algorithm).build().verify(decodedJWT);
|
||||||
|
|
||||||
|
String username = decodedJWT.getClaims().get("username").asString();
|
||||||
|
if ("Jerry".equals(username)) {
|
||||||
|
return failed(this).feedback("jwt-final-jerry-account").build();
|
||||||
|
}
|
||||||
|
if ("Tom".equals(username)) {
|
||||||
|
return success(this).build();
|
||||||
|
} else {
|
||||||
|
return failed(this).feedback("jwt-final-not-tom").build();
|
||||||
|
}
|
||||||
|
} catch (MalformedURLException | JWTVerificationException | JwkException e) {
|
||||||
|
return failed(this).feedback("jwt-invalid-token").output(e.toString()).build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -20,7 +20,7 @@
|
|||||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.owasp.webgoat.lessons.jwt;
|
package org.owasp.webgoat.lessons.jwt.claimmisuse;
|
||||||
|
|
||||||
import io.jsonwebtoken.Claims;
|
import io.jsonwebtoken.Claims;
|
||||||
import io.jsonwebtoken.JwsHeader;
|
import io.jsonwebtoken.JwsHeader;
|
||||||
@ -38,28 +38,30 @@ import org.owasp.webgoat.container.assignments.AssignmentHints;
|
|||||||
import org.owasp.webgoat.container.assignments.AttackResult;
|
import org.owasp.webgoat.container.assignments.AttackResult;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
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;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@AssignmentHints({
|
@AssignmentHints({
|
||||||
"jwt-final-hint1",
|
"jwt-kid-hint1",
|
||||||
"jwt-final-hint2",
|
"jwt-kid-hint2",
|
||||||
"jwt-final-hint3",
|
"jwt-kid-hint3",
|
||||||
"jwt-final-hint4",
|
"jwt-kid-hint4",
|
||||||
"jwt-final-hint5",
|
"jwt-kid-hint5",
|
||||||
"jwt-final-hint6"
|
"jwt-kid-hint6"
|
||||||
})
|
})
|
||||||
public class JWTFinalEndpoint extends AssignmentEndpoint {
|
@RequestMapping("/JWT/kid")
|
||||||
|
public class JWTHeaderKIDEndpoint extends AssignmentEndpoint {
|
||||||
|
|
||||||
private final LessonDataSource dataSource;
|
private final LessonDataSource dataSource;
|
||||||
|
|
||||||
private JWTFinalEndpoint(LessonDataSource dataSource) {
|
private JWTHeaderKIDEndpoint(LessonDataSource dataSource) {
|
||||||
this.dataSource = dataSource;
|
this.dataSource = dataSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/JWT/final/follow/{user}")
|
@PostMapping("/follow/{user}")
|
||||||
public @ResponseBody String follow(@PathVariable("user") String user) {
|
public @ResponseBody String follow(@PathVariable("user") String user) {
|
||||||
if ("Jerry".equals(user)) {
|
if ("Jerry".equals(user)) {
|
||||||
return "Following yourself seems redundant";
|
return "Following yourself seems redundant";
|
||||||
@ -68,7 +70,7 @@ public class JWTFinalEndpoint extends AssignmentEndpoint {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/JWT/final/delete")
|
@PostMapping("/delete")
|
||||||
public @ResponseBody AttackResult resetVotes(@RequestParam("token") String token) {
|
public @ResponseBody AttackResult resetVotes(@RequestParam("token") String token) {
|
||||||
if (StringUtils.isEmpty(token)) {
|
if (StringUtils.isEmpty(token)) {
|
||||||
return failed(this).feedback("jwt-invalid-token").build();
|
return failed(this).feedback("jwt-invalid-token").build();
|
@ -22,10 +22,10 @@
|
|||||||
|
|
||||||
package org.owasp.webgoat.lessons.logging;
|
package org.owasp.webgoat.lessons.logging;
|
||||||
|
|
||||||
|
import jakarta.annotation.PostConstruct;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import javax.annotation.PostConstruct;
|
|
||||||
import org.apache.logging.log4j.util.Strings;
|
import org.apache.logging.log4j.util.Strings;
|
||||||
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
|
||||||
import org.owasp.webgoat.container.assignments.AttackResult;
|
import org.owasp.webgoat.container.assignments.AttackResult;
|
||||||
|
@ -39,7 +39,8 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
"access-control.hash.hint9",
|
"access-control.hash.hint9",
|
||||||
"access-control.hash.hint10",
|
"access-control.hash.hint10",
|
||||||
"access-control.hash.hint11",
|
"access-control.hash.hint11",
|
||||||
"access-control.hash.hint12"
|
"access-control.hash.hint12",
|
||||||
|
"access-control.hash.hint13"
|
||||||
})
|
})
|
||||||
public class MissingFunctionACYourHashAdmin extends AssignmentEndpoint {
|
public class MissingFunctionACYourHashAdmin extends AssignmentEndpoint {
|
||||||
|
|
||||||
|
@ -22,8 +22,8 @@
|
|||||||
|
|
||||||
package org.owasp.webgoat.lessons.passwordreset;
|
package org.owasp.webgoat.lessons.passwordreset;
|
||||||
|
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
|
||||||
import org.owasp.webgoat.container.assignments.AttackResult;
|
import org.owasp.webgoat.container.assignments.AttackResult;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
@ -48,16 +48,19 @@ public class ResetLinkAssignmentForgotPassword extends AssignmentEndpoint {
|
|||||||
private final RestTemplate restTemplate;
|
private final RestTemplate restTemplate;
|
||||||
private String webWolfHost;
|
private String webWolfHost;
|
||||||
private String webWolfPort;
|
private String webWolfPort;
|
||||||
|
private String webWolfURL;
|
||||||
private final String webWolfMailURL;
|
private final String webWolfMailURL;
|
||||||
|
|
||||||
public ResetLinkAssignmentForgotPassword(
|
public ResetLinkAssignmentForgotPassword(
|
||||||
RestTemplate restTemplate,
|
RestTemplate restTemplate,
|
||||||
@Value("${webwolf.host}") String webWolfHost,
|
@Value("${webwolf.host}") String webWolfHost,
|
||||||
@Value("${webwolf.port}") String webWolfPort,
|
@Value("${webwolf.port}") String webWolfPort,
|
||||||
|
@Value("${webwolf.url}") String webWolfURL,
|
||||||
@Value("${webwolf.mail.url}") String webWolfMailURL) {
|
@Value("${webwolf.mail.url}") String webWolfMailURL) {
|
||||||
this.restTemplate = restTemplate;
|
this.restTemplate = restTemplate;
|
||||||
this.webWolfHost = webWolfHost;
|
this.webWolfHost = webWolfHost;
|
||||||
this.webWolfPort = webWolfPort;
|
this.webWolfPort = webWolfPort;
|
||||||
|
this.webWolfURL = webWolfURL;
|
||||||
this.webWolfMailURL = webWolfMailURL;
|
this.webWolfMailURL = webWolfMailURL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,12 +70,12 @@ public class ResetLinkAssignmentForgotPassword extends AssignmentEndpoint {
|
|||||||
@RequestParam String email, HttpServletRequest request) {
|
@RequestParam String email, HttpServletRequest request) {
|
||||||
String resetLink = UUID.randomUUID().toString();
|
String resetLink = UUID.randomUUID().toString();
|
||||||
ResetLinkAssignment.resetLinks.add(resetLink);
|
ResetLinkAssignment.resetLinks.add(resetLink);
|
||||||
String host = request.getHeader("host");
|
String host = request.getHeader(HttpHeaders.HOST);
|
||||||
if (ResetLinkAssignment.TOM_EMAIL.equals(email)
|
if (ResetLinkAssignment.TOM_EMAIL.equals(email)
|
||||||
&& (host.contains(webWolfPort)
|
&& (host.contains(webWolfPort)
|
||||||
|| host.contains(webWolfHost))) { // User indeed changed the host header.
|
&& host.contains(webWolfHost))) { // User indeed changed the host header.
|
||||||
ResetLinkAssignment.userToTomResetLink.put(getWebSession().getUserName(), resetLink);
|
ResetLinkAssignment.userToTomResetLink.put(getWebSession().getUserName(), resetLink);
|
||||||
fakeClickingLinkEmail(host, resetLink);
|
fakeClickingLinkEmail(webWolfURL, resetLink);
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
sendMailToUser(email, host, resetLink);
|
sendMailToUser(email, host, resetLink);
|
||||||
@ -97,13 +100,13 @@ public class ResetLinkAssignmentForgotPassword extends AssignmentEndpoint {
|
|||||||
this.restTemplate.postForEntity(webWolfMailURL, mail, Object.class);
|
this.restTemplate.postForEntity(webWolfMailURL, mail, Object.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fakeClickingLinkEmail(String host, String resetLink) {
|
private void fakeClickingLinkEmail(String webWolfURL, String resetLink) {
|
||||||
try {
|
try {
|
||||||
HttpHeaders httpHeaders = new HttpHeaders();
|
HttpHeaders httpHeaders = new HttpHeaders();
|
||||||
HttpEntity httpEntity = new HttpEntity(httpHeaders);
|
HttpEntity httpEntity = new HttpEntity(httpHeaders);
|
||||||
new RestTemplate()
|
new RestTemplate()
|
||||||
.exchange(
|
.exchange(
|
||||||
String.format("http://%s/PasswordReset/reset/reset-password/%s", host, resetLink),
|
String.format("%s/PasswordReset/reset/reset-password/%s", webWolfURL, resetLink),
|
||||||
HttpMethod.GET,
|
HttpMethod.GET,
|
||||||
httpEntity,
|
httpEntity,
|
||||||
Void.class);
|
Void.class);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package org.owasp.webgoat.lessons.passwordreset.resetlink;
|
package org.owasp.webgoat.lessons.passwordreset.resetlink;
|
||||||
|
|
||||||
import javax.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
import javax.validation.constraints.Size;
|
import jakarta.validation.constraints.Size;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package org.owasp.webgoat.lessons.pathtraversal;
|
package org.owasp.webgoat.lessons.pathtraversal;
|
||||||
|
|
||||||
|
import jakarta.annotation.PostConstruct;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -8,8 +10,6 @@ import java.net.URI;
|
|||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
import javax.annotation.PostConstruct;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.RandomUtils;
|
import org.apache.commons.lang3.RandomUtils;
|
||||||
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
|
||||||
|
@ -15,7 +15,8 @@
|
|||||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
* 02111-1307, USA.
|
* 02111-1307, USA.
|
||||||
*
|
*
|
||||||
* Getting Source ==============
|
* Getting Source
|
||||||
|
* ==============
|
||||||
*
|
*
|
||||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||||
*/
|
*/
|
||||||
|
@ -15,18 +15,20 @@
|
|||||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
* 02111-1307, USA.
|
* 02111-1307, USA.
|
||||||
*
|
*
|
||||||
* Getting Source ==============
|
* Getting Source
|
||||||
|
* ==============
|
||||||
*
|
*
|
||||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.owasp.webgoat.lessons.spoofcookie;
|
package org.owasp.webgoat.lessons.spoofcookie;
|
||||||
|
|
||||||
|
import jakarta.servlet.http.Cookie;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.servlet.http.Cookie;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
|
||||||
|
import org.owasp.webgoat.container.assignments.AssignmentHints;
|
||||||
import org.owasp.webgoat.container.assignments.AttackResult;
|
import org.owasp.webgoat.container.assignments.AttackResult;
|
||||||
import org.owasp.webgoat.lessons.spoofcookie.encoders.EncDec;
|
import org.owasp.webgoat.lessons.spoofcookie.encoders.EncDec;
|
||||||
import org.springframework.web.bind.UnsatisfiedServletRequestParameterException;
|
import org.springframework.web.bind.UnsatisfiedServletRequestParameterException;
|
||||||
@ -44,6 +46,7 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@AssignmentHints({"spoofcookie.hint1", "spoofcookie.hint2", "spoofcookie.hint3"})
|
||||||
@RestController
|
@RestController
|
||||||
public class SpoofCookieAssignment extends AssignmentEndpoint {
|
public class SpoofCookieAssignment extends AssignmentEndpoint {
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user