Compare commits
34 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 |
3
.github/dependabot.yml
vendored
3
.github/dependabot.yml
vendored
@ -8,10 +8,7 @@ updates:
|
|||||||
directory: "/"
|
directory: "/"
|
||||||
schedule:
|
schedule:
|
||||||
interval: "weekly"
|
interval: "weekly"
|
||||||
ignore:
|
|
||||||
- dependency-name: "org.webjars:bootstrap" # First the WebWolf UI needs to be refactored due to breaking changes
|
|
||||||
- package-ecosystem: "docker"
|
- package-ecosystem: "docker"
|
||||||
directory: "/"
|
directory: "/"
|
||||||
schedule:
|
schedule:
|
||||||
interval: "weekly"
|
interval: "weekly"
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- name: Set up JDK ${{ matrix.java-version }}
|
- name: Set up JDK ${{ matrix.java-version }}
|
||||||
uses: actions/setup-java@v3
|
uses: actions/setup-java@v4
|
||||||
with:
|
with:
|
||||||
distribution: 'temurin'
|
distribution: 'temurin'
|
||||||
java-version: ${{ matrix.java-version }}
|
java-version: ${{ matrix.java-version }}
|
40
.github/workflows/build.yml
vendored
40
.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,7 +19,7 @@ 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
|
||||||
@ -34,27 +32,3 @@ jobs:
|
|||||||
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.2.0
|
|
||||||
- name: "Set up Docker Buildx"
|
|
||||||
if: runner.os == 'Linux'
|
|
||||||
uses: docker/setup-buildx-action@v3
|
|
||||||
- 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 }}
|
|
||||||
|
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()
|
9
.github/workflows/release.yml
vendored
9
.github/workflows/release.yml
vendored
@ -8,13 +8,15 @@ 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
|
||||||
@ -91,7 +93,7 @@ jobs:
|
|||||||
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
|
||||||
@ -121,7 +123,7 @@ 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'
|
distribution: 'temurin'
|
||||||
java-version: 17
|
java-version: 17
|
||||||
@ -145,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
|
||||||
|
|
||||||
|
6
.github/workflows/test.yml
vendored
6
.github/workflows/test.yml
vendored
@ -23,14 +23,14 @@ 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
|
||||||
|
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.2.0
|
- 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
|
10
Dockerfile
10
Dockerfile
@ -1,4 +1,4 @@
|
|||||||
FROM docker.io/eclipse-temurin:19-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", \
|
||||||
@ -30,8 +32,4 @@ 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", \
|
||||||
"-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" ]
|
|
||||||
|
1
FAQ.md
1
FAQ.md
@ -5,4 +5,3 @@
|
|||||||
### Integration tests fail
|
### Integration tests fail
|
||||||
|
|
||||||
Try to run the command in the console `java -jar ...` and remove `-Dlogging.pattern.console=` from the command line.
|
Try to run the command in the console `java -jar ...` and remove `-Dlogging.pattern.console=` from the command line.
|
||||||
|
|
||||||
|
26
README.md
26
README.md
@ -44,19 +44,27 @@ Every release is also published on [DockerHub](https://hub.docker.com/r/webgoat/
|
|||||||
docker run -it -p 127.0.0.1:8080:8080 -p 127.0.0.1:9090:9090 webgoat/webgoat
|
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
|
||||||
|
|
||||||
@ -71,7 +79,8 @@ docker run -p 127.0.0.1:3000:3000 webgoat/webgoat-desktop
|
|||||||
Download the latest WebGoat release from [https://github.com/WebGoat/WebGoat/releases](https://github.com/WebGoat/WebGoat/releases)
|
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.4.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.
|
||||||
@ -80,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
|
||||||
|
|
||||||
@ -132,9 +141,10 @@ For specialist only. There is a way to set up WebGoat with a personalized menu.
|
|||||||
For instance running as a jar on a Linux/macOS it will look like this:
|
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.4-SNAPSHOT.jar
|
java -jar target/webgoat-2023.6-SNAPSHOT.jar
|
||||||
```
|
```
|
||||||
|
|
||||||
Or in a docker run it would (once this version is pushed into docker hub) look like this:
|
Or in a docker run it would (once this version is pushed into docker hub) look like this:
|
||||||
|
@ -16,19 +16,19 @@ 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,25 @@
|
|||||||
# 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
|
## Version 2023.5
|
||||||
|
|
||||||
### New functionality
|
### New functionality
|
||||||
@ -195,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
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
|
||||||
|
46
pom.xml
46
pom.xml
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
<groupId>org.owasp.webgoat</groupId>
|
<groupId>org.owasp.webgoat</groupId>
|
||||||
<artifactId>webgoat</artifactId>
|
<artifactId>webgoat</artifactId>
|
||||||
<version>2023.5</version>
|
<version>2023.9-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>WebGoat</name>
|
<name>WebGoat</name>
|
||||||
@ -110,12 +110,12 @@
|
|||||||
<properties>
|
<properties>
|
||||||
<!-- Shared properties with plugins and version numbers across submodules-->
|
<!-- Shared properties with plugins and version numbers across submodules-->
|
||||||
<asciidoctorj.version>2.5.10</asciidoctorj.version>
|
<asciidoctorj.version>2.5.10</asciidoctorj.version>
|
||||||
<bootstrap.version>5.3.1</bootstrap.version>
|
<bootstrap.version>5.3.2</bootstrap.version>
|
||||||
<cglib.version>3.3.0</cglib.version>
|
<cglib.version>3.3.0</cglib.version>
|
||||||
<!-- do not update necessary for lesson -->
|
<!-- do not update necessary for lesson -->
|
||||||
<checkstyle.version>3.3.1</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.14.0</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.10.0</commons-text.version>
|
<commons-text.version>1.10.0</commons-text.version>
|
||||||
<guava.version>32.1.3-jre</guava.version>
|
<guava.version>32.1.3-jre</guava.version>
|
||||||
@ -141,10 +141,9 @@
|
|||||||
<thymeleaf.version>3.1.1.RELEASE</thymeleaf.version>
|
<thymeleaf.version>3.1.1.RELEASE</thymeleaf.version>
|
||||||
<webdriver.version>5.3.3</webdriver.version>
|
<webdriver.version>5.3.3</webdriver.version>
|
||||||
<webgoat.context>/</webgoat.context>
|
<webgoat.context>/</webgoat.context>
|
||||||
<webgoat.port>8080</webgoat.port>
|
<webgoat.sslenabled>false</webgoat.sslenabled>
|
||||||
<webjars-locator-core.version>0.53</webjars-locator-core.version>
|
<webjars-locator-core.version>0.53</webjars-locator-core.version>
|
||||||
<webwolf.context>/</webwolf.context>
|
<webwolf.context>/</webwolf.context>
|
||||||
<webwolf.port>9090</webwolf.port>
|
|
||||||
<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>
|
||||||
@ -513,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} -Dwebwolfcontext=${webwolf.context} -Dwebgoatcontext=${webgoat.context}</argLine>
|
<argLine>-Xmx512m</argLine>
|
||||||
<includes>org/owasp/webgoat/*Test</includes>
|
<includes>org/owasp/webgoat/*Test</includes>
|
||||||
</configuration>
|
</configuration>
|
||||||
<executions>
|
<executions>
|
||||||
@ -557,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>
|
||||||
@ -568,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.38.0</version>
|
<version>2.41.1</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<formats>
|
<formats>
|
||||||
<format>
|
<format>
|
||||||
@ -686,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>
|
||||||
@ -703,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>
|
||||||
@ -712,10 +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>-Dwebgoat.context=${webgoat.context}</argument>
|
|
||||||
<argument>-Dwebwolf.port=${webwolf.port}</argument>
|
|
||||||
<argument>-Dwebwolf.context=${webwolf.context}</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>
|
||||||
@ -741,8 +753,6 @@
|
|||||||
<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>
|
||||||
<waitAfterLaunch>120</waitAfterLaunch>
|
|
||||||
<healthcheckUrl>http://localhost:${webgoat.port}/WebGoat/actuator/health</healthcheckUrl>
|
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
<execution>
|
<execution>
|
||||||
@ -767,7 +777,6 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.owasp</groupId>
|
<groupId>org.owasp</groupId>
|
||||||
<artifactId>dependency-check-maven</artifactId>
|
<artifactId>dependency-check-maven</artifactId>
|
||||||
<version>8.4.3</version>
|
|
||||||
<configuration>
|
<configuration>
|
||||||
<failBuildOnCVSS>7</failBuildOnCVSS>
|
<failBuildOnCVSS>7</failBuildOnCVSS>
|
||||||
<skipProvidedScope>false</skipProvidedScope>
|
<skipProvidedScope>false</skipProvidedScope>
|
||||||
@ -816,7 +825,6 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.jacoco</groupId>
|
<groupId>org.jacoco</groupId>
|
||||||
<artifactId>jacoco-maven-plugin</artifactId>
|
<artifactId>jacoco-maven-plugin</artifactId>
|
||||||
<version>${jacoco.version}</version>
|
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>before-unit-test</id>
|
<id>before-unit-test</id>
|
||||||
|
@ -253,6 +253,7 @@ public class CSRFIntegrationTest extends IntegrationTest {
|
|||||||
Overview[] assignments =
|
Overview[] assignments =
|
||||||
RestAssured.given()
|
RestAssured.given()
|
||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
|
.relaxedHTTPSValidation()
|
||||||
.get(url("service/lessonoverview.mvc"))
|
.get(url("service/lessonoverview.mvc"))
|
||||||
.then()
|
.then()
|
||||||
.extract()
|
.extract()
|
||||||
|
@ -5,7 +5,6 @@ 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;
|
||||||
@ -15,23 +14,26 @@ import org.springframework.http.HttpStatus;
|
|||||||
|
|
||||||
public abstract class IntegrationTest {
|
public abstract class IntegrationTest {
|
||||||
|
|
||||||
private static String webGoatPort =
|
private static String webGoatPort = System.getenv().getOrDefault("WEBGOAT_PORT", "8080");
|
||||||
Objects.requireNonNull(System.getProperty("webgoatport", "8080"));
|
|
||||||
private static String webGoatContext =
|
private static String webGoatContext =
|
||||||
Objects.requireNonNull(System.getProperty("webgoatcontext", "/WebGoat/"));
|
System.getenv().getOrDefault("WEBGOAT_CONTEXT", "/WebGoat/");
|
||||||
|
|
||||||
|
@Getter private static String webWolfPort = System.getenv().getOrDefault("WEBWOLF_PORT", "9090");
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private static String webWolfPort =
|
private static String webWolfHost = System.getenv().getOrDefault("WEBWOLF_HOST", "127.0.0.1");
|
||||||
Objects.requireNonNull(System.getProperty("webwolfport", "9090"));
|
|
||||||
|
@Getter
|
||||||
|
private static String webGoatHost = System.getenv().getOrDefault("WEBGOAT_HOST", "127.0.0.1");
|
||||||
|
|
||||||
private static String webWolfContext =
|
private static String webWolfContext =
|
||||||
Objects.requireNonNull(System.getProperty("webwolfcontext", "/WebWolf/"));
|
System.getenv().getOrDefault("WEBWOLF_CONTEXT", "/WebWolf/");
|
||||||
|
|
||||||
private static boolean useSSL = false;
|
private static boolean useSSL =
|
||||||
|
Boolean.valueOf(System.getenv().getOrDefault("WEBGOAT_SSLENABLED", "false"));
|
||||||
private static String webgoatUrl =
|
private static String webgoatUrl =
|
||||||
(useSSL ? "https:" : "http:") + "//localhost:" + webGoatPort + webGoatContext;
|
(useSSL ? "https://" : "http://") + webGoatHost + ":" + webGoatPort + webGoatContext;
|
||||||
private static String webWolfUrl =
|
private static String webWolfUrl = "http://" + webWolfHost + ":" + webWolfPort + webWolfContext;
|
||||||
(useSSL ? "https:" : "http:") + "//localhost:" + webWolfPort + webWolfContext;
|
|
||||||
@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";
|
||||||
|
@ -69,7 +69,6 @@ public class PasswordResetLessonIntegrationTest extends IntegrationTest {
|
|||||||
|
|
||||||
// WebWolf
|
// WebWolf
|
||||||
var link = getPasswordResetLinkFromLandingPage();
|
var link = getPasswordResetLinkFromLandingPage();
|
||||||
|
|
||||||
// WebGoat
|
// WebGoat
|
||||||
changePassword(link);
|
changePassword(link);
|
||||||
checkAssignment(
|
checkAssignment(
|
||||||
@ -137,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(HttpHeaders.HOST, String.format("%s:%s", "127.0.0.1", getWebWolfPort()))
|
.header(HttpHeaders.HOST, String.format("%s:%s", getWebWolfHost(), getWebWolfPort()))
|
||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
.formParams("email", user)
|
.formParams("email", user)
|
||||||
|
@ -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
|
||||||
|
@ -1,12 +1,9 @@
|
|||||||
package org.owasp.webgoat.container.asciidoc;
|
package org.owasp.webgoat.container.asciidoc;
|
||||||
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -29,8 +29,7 @@ import java.util.Random;
|
|||||||
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) {
|
||||||
|
|
||||||
|
@ -29,9 +29,8 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import org.owasp.webgoat.container.session.WebSession;
|
import org.owasp.webgoat.container.session.WebSession;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestHeader;
|
import org.springframework.web.bind.annotation.RequestHeader;
|
||||||
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.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
|
||||||
@ -43,7 +42,7 @@ public class Ping {
|
|||||||
|
|
||||||
@Autowired private WebSession webSession;
|
@Autowired private WebSession webSession;
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.GET)
|
@GetMapping
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public String logRequest(
|
public String logRequest(
|
||||||
@RequestHeader("User-Agent") String userAgent, @RequestParam(required = false) String text) {
|
@RequestHeader("User-Agent") String userAgent, @RequestParam(required = false) String text) {
|
||||||
|
@ -25,24 +25,36 @@
|
|||||||
|
|
||||||
package org.owasp.webgoat.server;
|
package org.owasp.webgoat.server;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.owasp.webgoat.container.WebGoat;
|
import org.owasp.webgoat.container.WebGoat;
|
||||||
import org.owasp.webgoat.webwolf.WebWolf;
|
import org.owasp.webgoat.webwolf.WebWolf;
|
||||||
import org.springframework.boot.Banner;
|
import org.springframework.boot.Banner;
|
||||||
import org.springframework.boot.WebApplicationType;
|
import org.springframework.boot.WebApplicationType;
|
||||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
public class StartWebGoat {
|
public class StartWebGoat {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
new SpringApplicationBuilder()
|
var parentBuilder =
|
||||||
.parent(ParentConfig.class)
|
new SpringApplicationBuilder()
|
||||||
.web(WebApplicationType.NONE)
|
.parent(ParentConfig.class)
|
||||||
.bannerMode(Banner.Mode.OFF)
|
.web(WebApplicationType.NONE)
|
||||||
.child(WebGoat.class)
|
.bannerMode(Banner.Mode.OFF);
|
||||||
.web(WebApplicationType.SERVLET)
|
parentBuilder.child(WebWolf.class).web(WebApplicationType.SERVLET).run(args);
|
||||||
.sibling(WebWolf.class)
|
ApplicationContext webGoatContext =
|
||||||
.bannerMode(Banner.Mode.OFF)
|
parentBuilder.child(WebGoat.class).web(WebApplicationType.SERVLET).run(args);
|
||||||
.web(WebApplicationType.SERVLET)
|
|
||||||
.run(args);
|
printStartUpMessage(webGoatContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void printStartUpMessage(ApplicationContext webGoatContext) {
|
||||||
|
var url = webGoatContext.getEnvironment().getProperty("webgoat.url");
|
||||||
|
var sslEnabled =
|
||||||
|
webGoatContext.getEnvironment().getProperty("server.ssl.enabled", Boolean.class);
|
||||||
|
log.warn(
|
||||||
|
"Please browse to " + "{} to start using WebGoat...",
|
||||||
|
sslEnabled ? url.replace("http", "https") : url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,35 +0,0 @@
|
|||||||
package org.owasp.webgoat.server;
|
|
||||||
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
|
||||||
import org.springframework.context.event.ContextStoppedEvent;
|
|
||||||
import org.springframework.context.event.EventListener;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
@Slf4j
|
|
||||||
@NoArgsConstructor
|
|
||||||
public class StartupMessage {
|
|
||||||
|
|
||||||
private String port;
|
|
||||||
private String address;
|
|
||||||
private String contextPath;
|
|
||||||
|
|
||||||
@EventListener
|
|
||||||
void onStartup(ApplicationReadyEvent event) {
|
|
||||||
|
|
||||||
port = event.getApplicationContext().getEnvironment().getProperty("server.port");
|
|
||||||
address = event.getApplicationContext().getEnvironment().getProperty("server.address");
|
|
||||||
contextPath =
|
|
||||||
event.getApplicationContext().getEnvironment().getProperty("server.servlet.context-path");
|
|
||||||
if (StringUtils.hasText(port)
|
|
||||||
&& !StringUtils.hasText(System.getProperty("running.in.docker"))) {
|
|
||||||
log.warn("Please browse to http://{}:{}{} to get started...", address, port, contextPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventListener
|
|
||||||
void onShutdown(ContextStoppedEvent event) {}
|
|
||||||
}
|
|
@ -22,14 +22,18 @@
|
|||||||
|
|
||||||
package org.owasp.webgoat.webwolf;
|
package org.owasp.webgoat.webwolf;
|
||||||
|
|
||||||
|
import static java.util.Comparator.comparing;
|
||||||
import static org.springframework.http.MediaType.ALL_VALUE;
|
import static org.springframework.http.MediaType.ALL_VALUE;
|
||||||
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.attribute.FileTime;
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import lombok.AllArgsConstructor;
|
import java.util.TimeZone;
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
@ -51,6 +55,9 @@ import org.springframework.web.servlet.view.RedirectView;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class FileServer {
|
public class FileServer {
|
||||||
|
|
||||||
|
private static final DateTimeFormatter dateTimeFormatter =
|
||||||
|
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||||
|
|
||||||
@Value("${webwolf.fileserver.location}")
|
@Value("${webwolf.fileserver.location}")
|
||||||
private String fileLocation;
|
private String fileLocation;
|
||||||
|
|
||||||
@ -87,16 +94,9 @@ public class FileServer {
|
|||||||
new ModelMap().addAttribute("uploadSuccess", "File uploaded successful"));
|
new ModelMap().addAttribute("uploadSuccess", "File uploaded successful"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@AllArgsConstructor
|
|
||||||
@Getter
|
|
||||||
private class UploadedFile {
|
|
||||||
private final String name;
|
|
||||||
private final String size;
|
|
||||||
private final String link;
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping(value = "/files")
|
@GetMapping(value = "/files")
|
||||||
public ModelAndView getFiles(HttpServletRequest request, Authentication authentication) {
|
public ModelAndView getFiles(
|
||||||
|
HttpServletRequest request, Authentication authentication, TimeZone timezone) {
|
||||||
String username = (null != authentication) ? authentication.getName() : "anonymous";
|
String username = (null != authentication) ? authentication.getName() : "anonymous";
|
||||||
File destinationDir = new File(fileLocation, username);
|
File destinationDir = new File(fileLocation, username);
|
||||||
|
|
||||||
@ -108,18 +108,33 @@ public class FileServer {
|
|||||||
}
|
}
|
||||||
changeIndicatorFile.delete();
|
changeIndicatorFile.delete();
|
||||||
|
|
||||||
var uploadedFiles = new ArrayList<>();
|
record UploadedFile(String name, String size, String link, String creationTime) {}
|
||||||
|
|
||||||
|
var uploadedFiles = new ArrayList<UploadedFile>();
|
||||||
File[] files = destinationDir.listFiles(File::isFile);
|
File[] files = destinationDir.listFiles(File::isFile);
|
||||||
if (files != null) {
|
if (files != null) {
|
||||||
for (File file : files) {
|
for (File file : files) {
|
||||||
String size = FileUtils.byteCountToDisplaySize(file.length());
|
String size = FileUtils.byteCountToDisplaySize(file.length());
|
||||||
String link = String.format("files/%s/%s", username, file.getName());
|
String link = String.format("files/%s/%s", username, file.getName());
|
||||||
uploadedFiles.add(new UploadedFile(file.getName(), size, link));
|
uploadedFiles.add(
|
||||||
|
new UploadedFile(file.getName(), size, link, getCreationTime(timezone, file)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
modelAndView.addObject("files", uploadedFiles);
|
modelAndView.addObject(
|
||||||
|
"files",
|
||||||
|
uploadedFiles.stream().sorted(comparing(UploadedFile::creationTime).reversed()).toList());
|
||||||
modelAndView.addObject("webwolf_url", "http://" + server + ":" + port + contextPath);
|
modelAndView.addObject("webwolf_url", "http://" + server + ":" + port + contextPath);
|
||||||
return modelAndView;
|
return modelAndView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getCreationTime(TimeZone timezone, File file) {
|
||||||
|
try {
|
||||||
|
FileTime creationTime = (FileTime) Files.getAttribute(file.toPath(), "creationTime");
|
||||||
|
ZonedDateTime zonedDateTime = creationTime.toInstant().atZone(timezone.toZoneId());
|
||||||
|
return dateTimeFormatter.format(zonedDateTime);
|
||||||
|
} catch (IOException e) {
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,8 +22,6 @@
|
|||||||
|
|
||||||
package org.owasp.webgoat.webwolf.requests;
|
package org.owasp.webgoat.webwolf.requests;
|
||||||
|
|
||||||
import static java.util.stream.Collectors.toList;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
@ -67,10 +65,10 @@ public class Requests {
|
|||||||
var model = new ModelAndView("requests");
|
var model = new ModelAndView("requests");
|
||||||
String username = (null != authentication) ? authentication.getName() : "anonymous";
|
String username = (null != authentication) ? authentication.getName() : "anonymous";
|
||||||
var traces =
|
var traces =
|
||||||
traceRepository.findAllTraces().stream()
|
traceRepository.findAll().stream()
|
||||||
.filter(t -> allowedTrace(t, username))
|
.filter(t -> allowedTrace(t, username))
|
||||||
.map(t -> new Tracert(t.getTimestamp(), path(t), toJsonString(t)))
|
.map(t -> new Tracert(t.getTimestamp(), path(t), toJsonString(t)))
|
||||||
.collect(toList());
|
.toList();
|
||||||
model.addObject("traces", traces);
|
model.addObject("traces", traces);
|
||||||
|
|
||||||
return model;
|
return model;
|
||||||
@ -93,7 +91,7 @@ public class Requests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String path(HttpExchange t) {
|
private String path(HttpExchange t) {
|
||||||
return (String) t.getRequest().getUri().getPath();
|
return t.getRequest().getUri().getPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String toJsonString(HttpExchange t) {
|
private String toJsonString(HttpExchange t) {
|
||||||
|
@ -22,6 +22,9 @@
|
|||||||
|
|
||||||
package org.owasp.webgoat.webwolf.requests;
|
package org.owasp.webgoat.webwolf.requests;
|
||||||
|
|
||||||
|
import static org.owasp.webgoat.webwolf.requests.WebWolfTraceRepository.Exclusion.contains;
|
||||||
|
import static org.owasp.webgoat.webwolf.requests.WebWolfTraceRepository.Exclusion.endsWith;
|
||||||
|
|
||||||
import com.google.common.collect.EvictingQueue;
|
import com.google.common.collect.EvictingQueue;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -36,31 +39,50 @@ import org.springframework.boot.actuate.web.exchanges.HttpExchangeRepository;
|
|||||||
* @since 8/13/17.
|
* @since 8/13/17.
|
||||||
*/
|
*/
|
||||||
public class WebWolfTraceRepository implements HttpExchangeRepository {
|
public class WebWolfTraceRepository implements HttpExchangeRepository {
|
||||||
|
private enum MatchingMode {
|
||||||
|
CONTAINS,
|
||||||
|
ENDS_WITH,
|
||||||
|
EQUALS;
|
||||||
|
}
|
||||||
|
|
||||||
|
record Exclusion(String path, MatchingMode mode) {
|
||||||
|
public boolean matches(String path) {
|
||||||
|
return switch (mode) {
|
||||||
|
case CONTAINS -> path.contains(this.path);
|
||||||
|
case ENDS_WITH -> path.endsWith(this.path);
|
||||||
|
case EQUALS -> path.equals(this.path);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Exclusion contains(String exclusionPattern) {
|
||||||
|
return new Exclusion(exclusionPattern, MatchingMode.CONTAINS);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Exclusion endsWith(String exclusionPattern) {
|
||||||
|
return new Exclusion(exclusionPattern, MatchingMode.ENDS_WITH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private final EvictingQueue<HttpExchange> traces = EvictingQueue.create(10000);
|
private final EvictingQueue<HttpExchange> traces = EvictingQueue.create(10000);
|
||||||
private final List<String> exclusionList =
|
private final List<Exclusion> exclusionList =
|
||||||
List.of(
|
List.of(
|
||||||
"/tmpdir",
|
contains("/tmpdir"),
|
||||||
"/home",
|
contains("/home"),
|
||||||
"/files",
|
endsWith("/files"),
|
||||||
"/images/",
|
contains("/images/"),
|
||||||
"/js/",
|
contains("/js/"),
|
||||||
"/webjars/",
|
contains("/webjars/"),
|
||||||
"/requests",
|
contains("/requests"),
|
||||||
"/css/",
|
contains("/css/"),
|
||||||
"/mail");
|
contains("/mail"));
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<HttpExchange> findAll() {
|
public List<HttpExchange> findAll() {
|
||||||
return List.of();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<HttpExchange> findAllTraces() {
|
|
||||||
return new ArrayList<>(traces);
|
return new ArrayList<>(traces);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isInExclusionList(String path) {
|
private boolean isInExclusionList(String path) {
|
||||||
return exclusionList.stream().anyMatch(e -> path.contains(e));
|
return exclusionList.stream().anyMatch(e -> e.matches(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
server.error.include-stacktrace=always
|
server.error.include-stacktrace=always
|
||||||
server.error.path=/error.html
|
server.error.path=/error.html
|
||||||
server.servlet.context-path=${webgoat.context}
|
server.servlet.context-path=${WEBGOAT_CONTEXT:/WebGoat}
|
||||||
server.servlet.session.persistent=false
|
server.servlet.session.persistent=false
|
||||||
server.port=${webgoat.port}
|
server.port=${WEBGOAT_PORT:8080}
|
||||||
server.address=${webgoat.host}
|
server.address=${WEBGOAT_HOST:127.0.0.1}
|
||||||
webgoat.host=${WEBGOAT_HOST:127.0.0.1}
|
webgoat.host=${WEBGOAT_HOST:127.0.0.1}
|
||||||
webgoat.port=${WEBGOAT_PORT:8080}
|
webgoat.port=${WEBGOAT_PORT:8080}
|
||||||
webgoat.context=${WEBGOAT_CONTEXT:/WebGoat}
|
webgoat.context=${WEBGOAT_CONTEXT:/WebGoat}
|
||||||
@ -43,11 +43,12 @@ webgoat.feedback.address=webgoat@owasp.org
|
|||||||
webgoat.feedback.address.html=<A HREF=mailto:webgoat@owasp.org>webgoat@owasp.org</A>
|
webgoat.feedback.address.html=<A HREF=mailto:webgoat@owasp.org>webgoat@owasp.org</A>
|
||||||
webgoat.database.connection.string=jdbc:hsqldb:mem:{USER}
|
webgoat.database.connection.string=jdbc:hsqldb:mem:{USER}
|
||||||
webgoat.default.language=en
|
webgoat.default.language=en
|
||||||
|
webgoat.url=http://${server.address}:${server.port}${server.servlet.context-path}
|
||||||
|
|
||||||
webwolf.host=${WEBWOLF_HOST:127.0.0.1}
|
webwolf.host=${WEBWOLF_HOST:127.0.0.1}
|
||||||
webwolf.port=${WEBWOLF_PORT:9090}
|
webwolf.port=${WEBWOLF_PORT:9090}
|
||||||
webwolf.context=${WEBWOLF_CONTEXT:/WebWolf}
|
webwolf.context=${WEBWOLF_CONTEXT:/WebWolf}
|
||||||
webwolf.url=http://${webwolf.host}:${webwolf.port}${webwolf.context}
|
webwolf.url=http://${WEBWOLF_HOST:127.0.0.1}:${WEBWOLF_PORT:9090}${WEBWOLF_CONTEXT:/WebWolf}
|
||||||
webwolf.landingpage.url=${webwolf.url}/landing
|
webwolf.landingpage.url=${webwolf.url}/landing
|
||||||
webwolf.mail.url=${webwolf.url}/mail
|
webwolf.mail.url=${webwolf.url}/mail
|
||||||
|
|
||||||
@ -69,4 +70,3 @@ management.endpoints.web.exposure.include=env, health,configprops
|
|||||||
|
|
||||||
spring.security.oauth2.client.registration.github.client-id=${WEBGOAT_OAUTH_CLIENTID:dummy}
|
spring.security.oauth2.client.registration.github.client-id=${WEBGOAT_OAUTH_CLIENTID:dummy}
|
||||||
spring.security.oauth2.client.registration.github.client-secret=${WEBGOAT_OAUTH_CLIENTSECRET:dummy}
|
spring.security.oauth2.client.registration.github.client-secret=${WEBGOAT_OAUTH_CLIENTSECRET:dummy}
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
ALTER TABLE CONTAINER.ASSIGNMENT ALTER COLUMN ID SET GENERATED BY DEFAULT AS IDENTITY(START WITH 1);
|
ALTER TABLE CONTAINER.ASSIGNMENT ALTER COLUMN ID SET GENERATED BY DEFAULT AS IDENTITY(START WITH 1);
|
||||||
ALTER TABLE CONTAINER.LESSON_TRACKER ALTER COLUMN ID SET GENERATED BY DEFAULT AS IDENTITY(START WITH 1);
|
ALTER TABLE CONTAINER.LESSON_TRACKER ALTER COLUMN ID SET GENERATED BY DEFAULT AS IDENTITY(START WITH 1);
|
||||||
ALTER TABLE CONTAINER.USER_TRACKER ALTER COLUMN ID SET GENERATED BY DEFAULT AS IDENTITY(START WITH 1);
|
ALTER TABLE CONTAINER.USER_TRACKER ALTER COLUMN ID SET GENERATED BY DEFAULT AS IDENTITY(START WITH 1);
|
||||||
|
|
||||||
|
@ -38,4 +38,3 @@ password=Passwort
|
|||||||
password.confirm=Wiederhohl Passwort
|
password.confirm=Wiederhohl Passwort
|
||||||
sign.up=Anmelden
|
sign.up=Anmelden
|
||||||
register.title=Registrieren
|
register.title=Registrieren
|
||||||
|
|
||||||
|
50
src/main/resources/i18n/messages_es.properties
Normal file
50
src/main/resources/i18n/messages_es.properties
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
lesson.completed=Felicidades. Has completado con éxito esta lección.
|
||||||
|
assignment.solved=Felicidades. Has completado con éxito la tarea.
|
||||||
|
assignment.not.solved=Lo siento, la solución no es correcta. Por favor, inténtalo de nuevo.
|
||||||
|
RestartLesson=Reiniciar esta lección
|
||||||
|
SolutionVideos=Videos de la solución
|
||||||
|
ErrorGenerating=Error generando
|
||||||
|
InvalidData=Datos inválidos
|
||||||
|
Go!=!Vamos!
|
||||||
|
password=Contraseña
|
||||||
|
password.confirm=Confirmar contraseña
|
||||||
|
username=Nombre de usuario
|
||||||
|
logged_out=Has cerrado sesión correctamente.
|
||||||
|
invalid_username_password=Nombre de usuario y contraseña inválidos.
|
||||||
|
login.page.title=Página de inicio de sesión
|
||||||
|
accounts.build.in=Las siguientes cuentas están integradas en WebGoat
|
||||||
|
accounts.table.account=Cuenta
|
||||||
|
accounts.table.user=Usuario
|
||||||
|
accounts.table.password=Contraseña
|
||||||
|
logout=Cerrar sesión
|
||||||
|
version=Versión
|
||||||
|
build=Compilación
|
||||||
|
report.card=Informe
|
||||||
|
about=Acerca de WebGoat
|
||||||
|
contact=Contáctanos
|
||||||
|
show.hints=Mostrar pistas
|
||||||
|
lesson.overview=Descripción de la lección
|
||||||
|
reset.lesson=Restablecer lección
|
||||||
|
sign.in=Iniciar sesión
|
||||||
|
register.new=o regístrate como un nuevo usuario
|
||||||
|
sign.up=Registrarse
|
||||||
|
register.title=Registro
|
||||||
|
searchmenu=Búsqueda de lecciones
|
||||||
|
|
||||||
|
|
||||||
|
not.empty=Este campo es obligatorio.
|
||||||
|
username.size=Por favor, utiliza entre 6 y 10 caracteres.
|
||||||
|
username.duplicate=El usuario ya existe.
|
||||||
|
password.size=La contraseña debe contener al menos 6 caracteres.
|
||||||
|
password.diff=Las contraseñas no coinciden.
|
||||||
|
security.enabled=Seguridad habilitada, puedes probar los desafíos anteriores y ver el efecto.
|
||||||
|
security.disabled=Seguridad deshabilitada, puedes probar los desafíos anteriores y ver el efecto.
|
||||||
|
termsofuse=Términos de uso
|
||||||
|
register.condition.1=Mientras ejecutas este programa, tu máquina será extremadamente vulnerable a ataques.\
|
||||||
|
Deberías desconectarte de Internet mientras usas este programa. La configuración predeterminada de WebGoat se une a localhost para minimizar la exposición.
|
||||||
|
register.condition.2=Este programa es solo con fines educativos. Si intentas \
|
||||||
|
estas técnicas sin autorización, es muy probable que te descubran. Si \
|
||||||
|
te descubren participando en hacking no autorizado, la mayoría de las empresas te despedirán. \
|
||||||
|
Alegar que estabas realizando investigación de seguridad no funcionará, ya que eso es lo \
|
||||||
|
primero que afirman todos los hackers.
|
||||||
|
terms.agree=Aceptar los términos y condiciones
|
@ -0,0 +1,11 @@
|
|||||||
|
== Restablecimiento de contraseña con autenticación de dos factores (2FA)
|
||||||
|
|
||||||
|
Un excelente ejemplo de elusión de autenticación es (https://henryhoggard.co.uk/blog/Paypal-2FA-Bypass). El usuario no pudo recibir un SMS con un código, así que optó por un método alternativo que implicaba preguntas de seguridad. Utilizando un proxy, eliminó por completo los parámetros y tuvo éxito.
|
||||||
|
|
||||||
|
image::images/paypal-2fa-bypass.png[Paypal 2FA bypass,1397,645,style="lesson-image"]
|
||||||
|
|
||||||
|
=== El escenario
|
||||||
|
|
||||||
|
Cuando restableces tu contraseña desde un lugar o dispositivo no reconocido por tu proveedor, te solicitarán responder a las preguntas de seguridad que configuraste. El inconveniente adicional es que estas preguntas de seguridad también están almacenadas en otro dispositivo, que no tienes contigo y del cual no recuerdas las respuestas.
|
||||||
|
|
||||||
|
Ya has proporcionado tu nombre de usuario/correo electrónico y has optado por el método de verificación alternativo.
|
@ -0,0 +1,15 @@
|
|||||||
|
== Elusion de Autenticación
|
||||||
|
|
||||||
|
En el contexto de elusiones de autenticación, los atacantes realizan manipulaciones en el sistema con el objetivo de crear las condiciones necesarias para evadir los mecanismos de autenticación. Estas manipulaciones pueden implicar cambios en la configuración o la lógica del sistema, con el fin de aprovechar posibles fallos y eludir las medidas de seguridad establecidas.
|
||||||
|
|
||||||
|
=== Entradas Ocultas
|
||||||
|
|
||||||
|
Una estrategia básica implica confiar en una entrada que se encuentra oculta en la página web o en el Modelo de Objetos del Documento (DOM).
|
||||||
|
|
||||||
|
=== Eliminación de Parámetros
|
||||||
|
|
||||||
|
A veces, si un atacante no conoce el valor correcto de un parámetro en la solicitud web, puede optar por eliminarlo por completo para observar las consecuencias.
|
||||||
|
|
||||||
|
=== Navegación Forzada
|
||||||
|
|
||||||
|
Si una sección de un sitio no está adecuadamente protegida por la configuración, esa sección del sitio puede ser accedida mediante adivinanzas/fuerza bruta.
|
@ -0,0 +1,7 @@
|
|||||||
|
=== Más Contenido, También Videos ...
|
||||||
|
|
||||||
|
Puedes estructurar y dar formato al contenido como prefieras. Incluso puedes incluir videos si lo deseas (aunque puede depender del soporte del navegador). Tal vez prefieras que esté más relacionado con la seguridad de las aplicaciones web que el contenido de este.
|
||||||
|
|
||||||
|
video::video/sample-video.m4v[width=480,start=5]
|
||||||
|
|
||||||
|
see http://asciidoctor.org/docs/asciidoc-syntax-quick-reference/#videos for more detail on video syntax
|
@ -8,4 +8,3 @@ auth-bypass.hints.verify.1=The attack on this is similar to the story referenced
|
|||||||
auth-bypass.hints.verify.2=You do want to tamper the security question parameters, but not delete them
|
auth-bypass.hints.verify.2=You do want to tamper the security question parameters, but not delete them
|
||||||
auth-bypass.hints.verify.3=The logic to verify the account does expect 2 security questions to be answered, but there is a flaw in the implementation
|
auth-bypass.hints.verify.3=The logic to verify the account does expect 2 security questions to be answered, but there is a flaw in the implementation
|
||||||
auth-bypass.hints.verify.4=Have you tried renaming the secQuestion0 and secQuestion1 parameters?
|
auth-bypass.hints.verify.4=Have you tried renaming the secQuestion0 and secQuestion1 parameters?
|
||||||
|
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
== Restricciones de Campo
|
||||||
|
En la mayoría de los navegadores, el cliente tiene control total o casi total sobre la parte HTML de la página web. Pueden modificar valores o restricciones según sus preferencias.
|
||||||
|
|
||||||
|
=== Tarea
|
||||||
|
Envía una solicitud que eluda las restricciones de los cuatro campos mencionados.
|
@ -0,0 +1,6 @@
|
|||||||
|
== Validación
|
||||||
|
|
||||||
|
A menudo, hay algún mecanismo para evitar que los usuarios envíen valores de campo alterados al servidor, como la validación antes del envío. La mayoría de los navegadores populares, como Chrome, no permiten editar scripts durante la ejecución. Tendremos que eludir la validación de alguna otra manera.
|
||||||
|
|
||||||
|
=== Tarea
|
||||||
|
Envía una solicitud que no cumpla con la expresión regular ubicada encima del campo en todos los campos.
|
@ -0,0 +1,9 @@
|
|||||||
|
== Concepto
|
||||||
|
|
||||||
|
Los usuarios tienen un gran control sobre la interfaz del usuario de la aplicación web. Pueden modificar el código HTML, y a veces también los scripts. Las aplicaciones que requieren un formato de entrada específico deben validar también los datos en el lado del servidor.
|
||||||
|
|
||||||
|
== Objetivos
|
||||||
|
|
||||||
|
* El usuario debe tener conocimientos básicos de HTML.
|
||||||
|
* El usuario debe poder manipular una solicitud antes de enviarla (con un proxy u otras herramientas).
|
||||||
|
* El usuario tiene que manipular las restricciones de campo y eludir la validación del lado del cliente.
|
@ -0,0 +1 @@
|
|||||||
|
El administrador olvidó dónde se guarda la contraseña, ¿puedes ayudar?
|
@ -0,0 +1 @@
|
|||||||
|
¿Puedes iniciar sesión como Larry?
|
@ -0,0 +1 @@
|
|||||||
|
¿Puedes iniciar sesión como Tom? Puede ser un poco más difícil que cuando lo hiciste con Larry.
|
@ -0,0 +1 @@
|
|||||||
|
Intenta restablecer la contraseña de admin.
|
@ -0,0 +1 @@
|
|||||||
|
¿Todavía puedes votar?
|
@ -0,0 +1,24 @@
|
|||||||
|
=== Bienvenido al desafío WebGoat (CTF)
|
||||||
|
|
||||||
|
==== Introducción
|
||||||
|
|
||||||
|
Los desafíos contienen lecciones más parecidas a un CTF, donde no proporcionamos explicaciones sobre lo que debes hacer y no se darán pistas. Puedes utilizar estos desafíos en un estilo CTF, donde puedes ejecutar WebGoat en un servidor y todos los participantes pueden unirse y hackear los desafíos. Hay un marcador disponible en el link:scoreboard["scoreboard",window=_blank]
|
||||||
|
|
||||||
|
:hardbreaks:
|
||||||
|
En este CTF, deberás resolver varios desafíos; cada uno te proporcionará una bandera que deberás enviar para obtener puntos.
|
||||||
|
|
||||||
|
Las banderas tienen el siguiente formato: `a7179f89-906b-4fec-9d99-f15b796e7208`
|
||||||
|
|
||||||
|
==== Reglas
|
||||||
|
|
||||||
|
- No intentes hackear la infraestructura de la competición. Si descubres algún error o vulnerabilidad, por favor, envíanos un correo electrónico.
|
||||||
|
|
||||||
|
- Juega limpio, no intentes sabotear a otros equipos competidores ni obstaculizar de ninguna manera el progreso de otro equipo.
|
||||||
|
|
||||||
|
- No se permite el uso de fuerza bruta en desafíos/flags.
|
||||||
|
|
||||||
|
:hardbreaks:
|
||||||
|
*¡Diviértete!*
|
||||||
|
El equipo WebGoat
|
||||||
|
|
||||||
|
image::images/boss.jpg[]
|
@ -0,0 +1,6 @@
|
|||||||
|
== ¡Pruébalo! Trabajando con la pestaña de Red
|
||||||
|
|
||||||
|
En esta tarea, debes encontrar una solicitud HTTP específica y leer un número aleatorio.
|
||||||
|
Para comenzar, haz clic en el primer botón. Esto generará una solicitud HTTP. Intenta encontrar la solicitud HTTP específica.
|
||||||
|
La solicitud debería contener un campo: `networkNum:`
|
||||||
|
Copia el número que se muestra después en el campo de entrada a continuación y haz clic en el botón de verificación.
|
@ -0,0 +1,8 @@
|
|||||||
|
== ¡Pruébalo! Utilizando la consola
|
||||||
|
|
||||||
|
Vamos a intentarlo. Utiliza la consola en las herramientas de desarrollo y llama a la función de JavaScript *webgoat.customjs.phoneHome()*.
|
||||||
|
Deberías recibir una respuesta en la consola. Tu resultado debería lucir algo así:
|
||||||
|
`phone home dijo
|
||||||
|
{"lessonCompleted:true, ... ,"output":"la respuesta de phone home es..."`
|
||||||
|
Después de eso, pega el número aleatorio en el campo de texto a continuación.
|
||||||
|
(Asegúrate de tener el número más reciente, ya que se genera aleatoriamente cada vez que llamas a la función)
|
@ -0,0 +1,15 @@
|
|||||||
|
== La pestaña de la Consola
|
||||||
|
|
||||||
|
En la pestaña de la consola, puedes ver cualquier cosa que un archivo JavaScript cargado haya impreso.
|
||||||
|
No te preocupes si ves algo en rojo. Aunque sea un error, probablemente se haya resuelto por sí mismo.
|
||||||
|
A través de la pestaña de la consola, también puedes ejecutar tu línea de código JavaScript.
|
||||||
|
|
||||||
|
Comienza limpiando la consola con el atajo `CTRL+L`.
|
||||||
|
|
||||||
|
Para ejecutar tu JavaScript, haz clic dentro de la consola y escribe algo como:
|
||||||
|
`console.log("¡Hola WebGoat!");` Presiona Enter. `¡Hola WebGoat!` debería aparecer ahora en tu consola.
|
||||||
|
La consola también te permite hacer algunas operaciones aritméticas básicas. Si escribes, por ejemplo, `1+3` y presionas Enter, la consola debería mostrar 4.
|
||||||
|
|
||||||
|
Nota: Puede que veas un `undefined` en la consola. Puedes ignorar esta declaración de manera segura, solo significa que la función de JavaScript que has llamado no devolvió nada.
|
||||||
|
|
||||||
|
image::images/ChromeDev_Console_Ex.jpg[DeveloperToolsConsoleExample,500,500,style="lesson-image"]
|
@ -0,0 +1,19 @@
|
|||||||
|
== La Pestaña de Elementos
|
||||||
|
|
||||||
|
La pestaña de Elementos te permite examinar el código HTML y CSS utilizado para definir y estilizar el sitio web.
|
||||||
|
|
||||||
|
=== Fuente HTML
|
||||||
|
|
||||||
|
Si pasas el ratón sobre una línea, verás que una parte del sitio web se vuelve azul. Eso significa que
|
||||||
|
esta línea HTML en particular define esta sección del sitio web.
|
||||||
|
La pestaña de Elementos te permite realizar cambios en cada elemento HTML individual. Por ejemplo, si haces clic dentro de una etiqueta de párrafo (<p>...</p>), puedes editar el contenido del sitio web. Si has realizado cambios y luego haces clic en Enter,
|
||||||
|
Chrome actualizará el sitio web para mostrar tus ediciones. También puedes cambiar la etiqueta HTML utilizada, las clases y los identificadores (id) que una etiqueta tiene, y mucho más.
|
||||||
|
|
||||||
|
image::images/ChromeDev_Elements.jpg[DeveloperToolsElements,500,350,style="lesson-image"]
|
||||||
|
|
||||||
|
=== Fuente CSS
|
||||||
|
|
||||||
|
Puedes encontrar información sobre el CSS utilizado para estilizar el sitio web debajo de la fuente HTML. Al igual que con el HTML, también puedes editar el CSS y, por lo tanto, ajustar el estilo del sitio web.
|
||||||
|
Puedes editar valores específicos o desactivar el estilo individual.
|
||||||
|
|
||||||
|
image::images/ChromeDev_Elements_CSS.jpg[DeveloperToolsElementsCSS,500,350,style="lesson-image"]
|
@ -0,0 +1,17 @@
|
|||||||
|
== Herramientas de Desarrollo de Google Chrome
|
||||||
|
|
||||||
|
Para completar ciertas tareas, a veces es necesario examinar el código fuente de JavaScript o ejecutar un comando de JavaScript por tu cuenta.
|
||||||
|
Para hacer eso, Google Chrome tiene un conjunto de herramientas que te permiten hacer eso y mucho más.
|
||||||
|
Aunque estas herramientas no son exclusivas de Google Chrome, casi todos los navegadores modernos tienen un conjunto propio.
|
||||||
|
Nuestra introducción se centrará en las que se encuentran en Google Chrome.
|
||||||
|
Sin embargo, aún puedes utilizar el navegador que prefieras, como Firefox o Safari, aunque algunos pasos de este tutorial pueden ser diferentes para ti.
|
||||||
|
|
||||||
|
Ten en cuenta que este tutorial no está diseñado para enseñar todo sobre estas herramientas.
|
||||||
|
Se centrará únicamente en los conocimientos esenciales para completar tareas específicas.
|
||||||
|
Además, si ya estás familiarizado con estas herramientas, puedes saltar estas lecciones sin problema.
|
||||||
|
|
||||||
|
Para comenzar: *abre las herramientas de desarrollo*. Hay varias formas de abrirlas:
|
||||||
|
|
||||||
|
1. Haz clic derecho en cualquier parte de la ventana del navegador y selecciona la opción _"Inspeccionar"_.
|
||||||
|
2. Ve al menú del navegador (tres puntos en la esquina superior derecha), luego ve a _"Más herramientas"_ y selecciona la opción _"Herramientas de desarrollo"_.
|
||||||
|
3. Utiliza el atajo de teclado _Ctrl + Shift + I_.
|
@ -0,0 +1,15 @@
|
|||||||
|
== La pestaña de Fuentes
|
||||||
|
|
||||||
|
En la pestaña de Fuentes, puedes examinar el sistema de archivos y ver todos los archivos HTML, CSS y JavaScript utilizados para
|
||||||
|
crear el sitio web. Haz clic en un archivo para ver su contenido.
|
||||||
|
|
||||||
|
image::images/ChromeDev_Sources.jpg[DeveloperToolsSources,400,500,style="lesson-image"]
|
||||||
|
|
||||||
|
== La pestaña de Red
|
||||||
|
|
||||||
|
En la pestaña de Red, puedes ver las solicitudes HTTP y las respuestas que ha realizado el sitio web.
|
||||||
|
Simplemente haz clic en una si deseas obtener información más detallada sobre una solicitud específica.
|
||||||
|
La "Línea de tiempo" sobre los puntos azules representa cuándo se realizaron estas solicitudes y respuestas.
|
||||||
|
También puedes ver las solicitudes realizadas en un marco de tiempo específico simplemente haciendo clic y arrastrando en la línea de tiempo. La ventana inferior solo mostrará las solicitudes y respuestas realizadas en ese marco de tiempo.
|
||||||
|
|
||||||
|
image::images/ChromeDev_Network.jpg[DeveloperToolsNetwork,400,500,style="lesson-image"]
|
@ -164,6 +164,3 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,5 +31,3 @@ The goal is to get familiar with the following forms of techniques:
|
|||||||
=== Assignments
|
=== Assignments
|
||||||
|
|
||||||
After the explanation of an item there will be several assignments.
|
After the explanation of an item there will be several assignments.
|
||||||
|
|
||||||
|
|
||||||
|
@ -28,6 +28,3 @@ You can find the secret in the following docker image, which you can start as:
|
|||||||
----
|
----
|
||||||
echo "U2FsdGVkX199jgh5oANElFdtCxIEvdEvciLi+v+5loE+VCuy6Ii0b+5byb5DXp32RPmT02Ek1pf55ctQN+DHbwCPiVRfFQamDmbHBUpD7as=" | openssl enc -aes-256-cbc -d -a -kfile ....
|
echo "U2FsdGVkX199jgh5oANElFdtCxIEvdEvciLi+v+5loE+VCuy6Ii0b+5byb5DXp32RPmT02Ek1pf55ctQN+DHbwCPiVRfFQamDmbHBUpD7as=" | openssl enc -aes-256-cbc -d -a -kfile ....
|
||||||
----
|
----
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,4 +23,3 @@ Basic authentication is sometimes used by web applications. This uses base64 enc
|
|||||||
The HTTP header will look like:
|
The HTTP header will look like:
|
||||||
|
|
||||||
Authorization: Basic bXl1c2VyOm15cGFzc3dvcmQ=
|
Authorization: Basic bXl1c2VyOm15cGFzc3dvcmQ=
|
||||||
|
|
||||||
|
@ -28,5 +28,3 @@ Here is a short description of what happens if you open your browser and go to a
|
|||||||
* At the end of this process both the browser and the webserver will use the exchanged symmetric key (in the asymmetric key exchange process) to encrypt and decrypt messages that are sent back and forth between the browser and the webserver.
|
* At the end of this process both the browser and the webserver will use the exchanged symmetric key (in the asymmetric key exchange process) to encrypt and decrypt messages that are sent back and forth between the browser and the webserver.
|
||||||
|
|
||||||
Symmetric keys are used because it can be used more easily with large sets of data and requires less processing power in doing so. However, the information on these pages is just for a basic understanding of cryptography. Look on the internet for more detailed information about these topics.
|
Symmetric keys are used because it can be used more easily with large sets of data and requires less processing power in doing so. However, the information on these pages is just for a basic understanding of cryptography. Look on the internet for more detailed information about these topics.
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,5 +36,3 @@ Governments usually send official documents with a PDF that contains a certifica
|
|||||||
== Assignment
|
== Assignment
|
||||||
|
|
||||||
Here is a simple assignment. A private RSA key is sent to you. Determine the modulus of the RSA key as a hex string, and calculate a signature for that hex string using the key. The exercise requires some experience with OpenSSL. You can search on the Internet for useful commands and/or use the HINTS button to get some tips.
|
Here is a simple assignment. A private RSA key is sent to you. Determine the modulus of the RSA key as a hex string, and calculate a signature for that hex string using the key. The exercise requires some experience with OpenSSL. You can search on the Internet for useful commands and/or use the HINTS button to get some tips.
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,8 +20,3 @@ with the server are performed with JavaScript. On the server side you only need
|
|||||||
if this header is not present deny the request.
|
if this header is not present deny the request.
|
||||||
Some frameworks offer this implementation by default however researcher Alex Infuhr found out that this can be bypassed
|
Some frameworks offer this implementation by default however researcher Alex Infuhr found out that this can be bypassed
|
||||||
as well. You can read about: https://insert-script.blogspot.com/2018/05/adobe-reader-pdf-client-side-request.html[Adobe Reader PDF - Client Side Request Injection]
|
as well. You can read about: https://insert-script.blogspot.com/2018/05/adobe-reader-pdf-client-side-request.html[Adobe Reader PDF - Client Side Request Injection]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,5 +6,3 @@ This is the most simple CSRF attack to perform. For example you receive an e-mai
|
|||||||
|
|
||||||
If the user is still logged in to the website of bank.com this simple GET request will transfer money from one account to another.
|
If the user is still logged in to the website of bank.com this simple GET request will transfer money from one account to another.
|
||||||
Of course in most cases the website might have multiple controls to approve the request.
|
Of course in most cases the website might have multiple controls to approve the request.
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
== Basic Get CSRF Exercise
|
== Basic Get CSRF Exercise
|
||||||
|
|
||||||
Trigger the form below from an external source while logged in. The response will include a 'flag' (a numeric value).
|
Trigger the form below from an external source while logged in. The response will include a 'flag' (a numeric value).
|
||||||
|
|
||||||
|
@ -6,4 +6,3 @@ finding somewhere that you want to execute the CSRF attack. The classic example
|
|||||||
|
|
||||||
But we're keeping it simple here. In this case, you just need to trigger a review submission on behalf of the currently
|
But we're keeping it simple here. In this case, you just need to trigger a review submission on behalf of the currently
|
||||||
logged in user.
|
logged in user.
|
||||||
|
|
||||||
|
@ -21,7 +21,3 @@ something. Forcing the victim to retrieve data doesn't benefit an attacker becau
|
|||||||
As such, CSRF attacks target state-changing requests.
|
As such, CSRF attacks target state-changing requests.
|
||||||
|
|
||||||
Let's continue with some exercises to address way to perform a CSRF request.
|
Let's continue with some exercises to address way to perform a CSRF request.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
= Hijack a Session
|
= Hijack a Session
|
||||||
|
|
||||||
In this lesson we are trying to predict the 'hijack_cookie' value. The 'hijack_cookie' is used to differentiate authenticated and anonymous users of WebGoat.
|
In this lesson we are trying to predict the 'hijack_cookie' value. The 'hijack_cookie' is used to differentiate authenticated and anonymous users of WebGoat.
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
== The Quiz
|
== The Quiz
|
||||||
|
|
||||||
What type of HTTP command did WebGoat use for this lesson. A POST or a GET.
|
What type of HTTP command did WebGoat use for this lesson. A POST or a GET.
|
||||||
|
|
||||||
|
@ -25,4 +25,3 @@ The client initiates a transaction as follows:
|
|||||||
** User-Agent: Mozilla/4.06 Accept: image/gif,image/jpeg, */*
|
** User-Agent: Mozilla/4.06 Accept: image/gif,image/jpeg, */*
|
||||||
|
|
||||||
* In a POST request, the user supplied data will follow the optional headers and is not part of the contained within the POST URL.
|
* In a POST request, the user supplied data will follow the optional headers and is not part of the contained within the POST URL.
|
||||||
|
|
||||||
|
@ -7,5 +7,3 @@ Otherwise, this will show you how to set up ZAP as a proxy on your local host.
|
|||||||
* First download and install https://www.zaproxy.org/download/[ZAP] for your operating system
|
* First download and install https://www.zaproxy.org/download/[ZAP] for your operating system
|
||||||
* Start ZAP
|
* Start ZAP
|
||||||
* Start the browser directly from ZAP
|
* Start the browser directly from ZAP
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,5 +26,3 @@ image::images/zap_edit_and_send.png[Open/Resend with Request Editor,style="lesso
|
|||||||
++++
|
++++
|
||||||
|
|
||||||
image::images/zap_edit_and_response.png[Open/Resend response,style="lesson-image"]
|
image::images/zap_edit_and_response.png[Open/Resend response,style="lesson-image"]
|
||||||
|
|
||||||
|
|
||||||
|
@ -52,5 +52,3 @@ image::images/chrome-manual-proxy.png[Chrome Proxy Config,700,447,style="lesson-
|
|||||||
image::images/chrome-manual-proxy-win.png[Chrome Proxy, 394,346,style="lesson-image"]
|
image::images/chrome-manual-proxy-win.png[Chrome Proxy, 394,346,style="lesson-image"]
|
||||||
|
|
||||||
(Win config image above)
|
(Win config image above)
|
||||||
|
|
||||||
|
|
||||||
|
@ -56,4 +56,3 @@ Instead, use static keys that are securely managed and updated regularly.
|
|||||||
- **Audit and monitoring**: Regularly audit JWT usage, monitor for suspicious activity, and implement anomaly detection mechanisms.
|
- **Audit and monitoring**: Regularly audit JWT usage, monitor for suspicious activity, and implement anomaly detection mechanisms.
|
||||||
|
|
||||||
- **Security testing**: Regularly perform security testing, including penetration testing and code reviews, to identify and remediate potential vulnerabilities.
|
- **Security testing**: Regularly perform security testing, including penetration testing and code reviews, to identify and remediate potential vulnerabilities.
|
||||||
|
|
||||||
|
@ -3,4 +3,3 @@
|
|||||||
Below you see two accounts, one of Jerry and one of Tom.
|
Below you see two accounts, one of Jerry and one of Tom.
|
||||||
Jerry wants to remove Tom's account from Twitter, but his token can only delete his account.
|
Jerry wants to remove Tom's account from Twitter, but his token can only delete his account.
|
||||||
Can you try to help him and delete Toms account?
|
Can you try to help him and delete Toms account?
|
||||||
|
|
||||||
|
@ -9,4 +9,3 @@ eyJhbGciOiJIUzI1NiJ9.ew0KICAiYXV0aG9yaXRpZXMiIDogWyAiUk9MRV9BRE1JTiIsICJST0xFX1V
|
|||||||
----
|
----
|
||||||
|
|
||||||
Copy and paste the following token and decode the token, can you find the user inside the token?
|
Copy and paste the following token and decode the token, can you find the user inside the token?
|
||||||
|
|
||||||
|
@ -58,4 +58,3 @@ try {
|
|||||||
----
|
----
|
||||||
|
|
||||||
Can you spot the weakness?
|
Can you spot the weakness?
|
||||||
|
|
||||||
|
@ -16,4 +16,3 @@ information in the token to identify the user.
|
|||||||
|
|
||||||
The token contains claims to identify the user and all other information necessary for the server to fulfill the request.
|
The token contains claims to identify the user and all other information necessary for the server to fulfill the request.
|
||||||
Be aware not to store sensitive information in the token and always send it over a secure channel.
|
Be aware not to store sensitive information in the token and always send it over a secure channel.
|
||||||
|
|
||||||
|
@ -34,7 +34,3 @@ the validity and integrity of the token in a secure way, all of this in a statel
|
|||||||
and portable approach (portable in the way that client and server technologies can
|
and portable approach (portable in the way that client and server technologies can
|
||||||
be different including also the transport channel even if HTTP is the most often used)
|
be different including also the transport channel even if HTTP is the most often used)
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -85,4 +85,3 @@ application you are better of using plain old cookies. See for more information:
|
|||||||
- http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-for-sessions/[stop-using-jwt-for-sessions, window="_blank"]
|
- http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-for-sessions/[stop-using-jwt-for-sessions, window="_blank"]
|
||||||
- http://cryto.net/~joepie91/blog/2016/06/19/stop-using-jwt-for-sessions-part-2-why-your-solution-doesnt-work/[stop-using-jwt-for-sessions-part-2-why-your-solution-doesnt-work, window="_blank"]
|
- http://cryto.net/~joepie91/blog/2016/06/19/stop-using-jwt-for-sessions-part-2-why-your-solution-doesnt-work/[stop-using-jwt-for-sessions-part-2-why-your-solution-doesnt-work, window="_blank"]
|
||||||
- http://cryto.net/~joepie91/blog/attachments/jwt-flowchart.png[flowchart, window="_blank"]
|
- http://cryto.net/~joepie91/blog/attachments/jwt-flowchart.png[flowchart, window="_blank"]
|
||||||
|
|
||||||
|
@ -9,5 +9,3 @@ found in a private bug bounty program on Bugcrowd, you can read the full write u
|
|||||||
|
|
||||||
From a breach of last year the following logfile is available link:images/logs.txt[here]
|
From a breach of last year the following logfile is available link:images/logs.txt[here]
|
||||||
Can you find a way to order the books but let *Tom* pay for them?
|
Can you find a way to order the books but let *Tom* pay for them?
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,7 +14,3 @@ to be aware of before validating the token.
|
|||||||
== Assignment
|
== Assignment
|
||||||
|
|
||||||
Try to change the token you receive and become an admin user by changing the token and once you are admin reset the votes
|
Try to change the token you receive and become an admin user by changing the token and once you are admin reset the votes
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -86,6 +86,3 @@ Now we can replace the token in the cookie and perform the reset again. One thin
|
|||||||
For more information take a look at the following video:
|
For more information take a look at the following video:
|
||||||
|
|
||||||
video::wt3UixCiPfo[youtube, height=480, width=100%]
|
video::wt3UixCiPfo[youtube, height=480, width=100%]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,5 +13,3 @@ The token is base64 encoded and consists of three parts:
|
|||||||
|
|
||||||
Both header and claims consist are represented by a JSON object. The header describes the cryptographic operations applied to the JWT and optionally, additional properties of the JWT.
|
Both header and claims consist are represented by a JSON object. The header describes the cryptographic operations applied to the JWT and optionally, additional properties of the JWT.
|
||||||
The claims represent a JSON object whose members are the claims conveyed by the JWT.
|
The claims represent a JSON object whose members are the claims conveyed by the JWT.
|
||||||
|
|
||||||
|
|
||||||
|
@ -7,4 +7,3 @@ dictionary attack is not feasible. Once you have a token you can start an offlin
|
|||||||
=== Assignment
|
=== Assignment
|
||||||
|
|
||||||
Given we have the following token try to find out secret key and submit a new key with the username changed to WebGoat.
|
Given we have the following token try to find out secret key and submit a new key with the username changed to WebGoat.
|
||||||
|
|
||||||
|
@ -31,6 +31,3 @@ function updateTotal() {
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,4 +6,3 @@ function follow(user) {
|
|||||||
$("#toast").append(result);
|
$("#toast").append(result);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,4 +84,3 @@ function vote(title) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,4 +6,3 @@ This lesson describes the steps needed to add a new lesson to WebGoat. In genera
|
|||||||
- Add one or more assignments within the lesson
|
- Add one or more assignments within the lesson
|
||||||
|
|
||||||
Let's see how to create a new lesson.
|
Let's see how to create a new lesson.
|
||||||
|
|
||||||
|
@ -8,4 +8,3 @@ lesson-template.sample-attack.failure-1=Sample failure message
|
|||||||
lesson-template.sample-attack.failure-2=Sample failure message 2
|
lesson-template.sample-attack.failure-2=Sample failure message 2
|
||||||
|
|
||||||
lesson-template.sample-attack.success=Sample success message
|
lesson-template.sample-attack.success=Sample success message
|
||||||
|
|
||||||
|
@ -1,2 +1 @@
|
|||||||
logging.title=Logging Security
|
logging.title=Logging Security
|
||||||
|
|
||||||
|
@ -17,4 +17,3 @@ that password. Note: it is not possible to use OWASP ZAP for this lesson, also b
|
|||||||
tools like `curl` and the like will be more successful for this attack.
|
tools like `curl` and the like will be more successful for this attack.
|
||||||
|
|
||||||
Tom always resets his password immediately after receiving the email with the link.
|
Tom always resets his password immediately after receiving the email with the link.
|
||||||
|
|
||||||
|
@ -18,6 +18,3 @@ resets, a good resource for security questions is: http://goodsecurityquestions.
|
|||||||
Users can retrieve their password if they can answer the secret question properly. There is no lock-out mechanism on
|
Users can retrieve their password if they can answer the secret question properly. There is no lock-out mechanism on
|
||||||
this 'Forgot Password' page. Your username is 'webgoat' and your favorite color is 'red'. The goal is to retrieve the
|
this 'Forgot Password' page. Your username is 'webgoat' and your favorite color is 'red'. The goal is to retrieve the
|
||||||
password of another user. Users you could try are: "tom", "admin" and "larry".
|
password of another user. Users you could try are: "tom", "admin" and "larry".
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,4 +3,3 @@
|
|||||||
Let's first do a simple assignment to make sure you are able to read e-mails with WebWolf, first start WebWolf (see webWolfLink:here[])
|
Let's first do a simple assignment to make sure you are able to read e-mails with WebWolf, first start WebWolf (see webWolfLink:here[])
|
||||||
In the reset page below send an e-mail to `username@webgoat.org` (part behind the @ is not important)
|
In the reset page below send an e-mail to `username@webgoat.org` (part behind the @ is not important)
|
||||||
Open WebWolf and read the e-mail and login with your username and the password provided in the e-mail.
|
Open WebWolf and read the e-mail and login with your username and the password provided in the e-mail.
|
||||||
|
|
||||||
|
@ -19,5 +19,3 @@ it again to `../`.
|
|||||||
Also, note that avoiding applications filtering those encodings double encoding might work as well. Double encoding
|
Also, note that avoiding applications filtering those encodings double encoding might work as well. Double encoding
|
||||||
might be necessary when you have a system A which calls system B. System A will only decode once and
|
might be necessary when you have a system A which calls system B. System A will only decode once and
|
||||||
call B with the still encoded URL.
|
call B with the still encoded URL.
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,5 +2,3 @@
|
|||||||
|
|
||||||
Path traversals are not limited to file uploads; when retrieving files, it can be the case that a path traversal
|
Path traversals are not limited to file uploads; when retrieving files, it can be the case that a path traversal
|
||||||
is possible to retrieve other files from the system. In this assignment, try to find a file called `path-traversal-secret.jpg`
|
is possible to retrieve other files from the system. In this assignment, try to find a file called `path-traversal-secret.jpg`
|
||||||
|
|
||||||
|
|
||||||
|
@ -67,4 +67,3 @@ if you replace `1.jpg` with `../../secret.txt`, it will block the request. With
|
|||||||
will not be there.
|
will not be there.
|
||||||
|
|
||||||
In the lesson about "File uploads" more examples of vulnerabilities are shown.
|
In the lesson about "File uploads" more examples of vulnerabilities are shown.
|
||||||
|
|
||||||
|
@ -11,5 +11,3 @@ To make the assignment a bit easier below you will find the location of the prof
|
|||||||
|`webGoatTempDir:temppath[]PathTraversal/username:user[]/username:user[].jpg`
|
|`webGoatTempDir:temppath[]PathTraversal/username:user[]/username:user[].jpg`
|
||||||
|
|
||||||
|===
|
|===
|
||||||
|
|
||||||
|
|
||||||
|
@ -55,4 +55,3 @@ path-traversal-zip-slip.hint4=Check the http request to find out which image nam
|
|||||||
|
|
||||||
path-traversal-zip-slip.no-zip=Please upload a zip file
|
path-traversal-zip-slip.no-zip=Please upload a zip file
|
||||||
path-traversal-zip-slip.extracted=Zip file extracted successfully failed to copy the image. Please get in touch with our helpdesk.
|
path-traversal-zip-slip.extracted=Zip file extracted successfully failed to copy the image. Please get in touch with our helpdesk.
|
||||||
|
|
||||||
|
@ -88,5 +88,3 @@ for the deserialization: got to the link: http://www.pwntester.com/blog/2013/12
|
|||||||
</handler>
|
</handler>
|
||||||
</dynamic-proxy>
|
</dynamic-proxy>
|
||||||
</sorted-set>
|
</sorted-set>
|
||||||
|
|
||||||
|
|
||||||
|
@ -28,4 +28,3 @@ var obs = new MutationObserver(function(mutations) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
obs.observe(target, { characterData: false, attributes: false, childList: true, subtree: false });
|
obs.observe(target, { characterData: false, attributes: false, childList: true, subtree: false });
|
||||||
|
|
||||||
|
@ -11,4 +11,3 @@ INSERT INTO grant_rights VALUES ('89762','Tobi', 'Barnett', 'Development', 7
|
|||||||
INSERT INTO grant_rights VALUES ('96134','Bob', 'Franco', 'Marketing', 83700);
|
INSERT INTO grant_rights VALUES ('96134','Bob', 'Franco', 'Marketing', 83700);
|
||||||
INSERT INTO grant_rights VALUES ('34477','Abraham ', 'Holman', 'Development', 50000);
|
INSERT INTO grant_rights VALUES ('34477','Abraham ', 'Holman', 'Development', 50000);
|
||||||
INSERT INTO grant_rights VALUES ('37648','John', 'Smith', 'Marketing', 64350);
|
INSERT INTO grant_rights VALUES ('37648','John', 'Smith', 'Marketing', 64350);
|
||||||
|
|
||||||
|
@ -10,4 +10,3 @@
|
|||||||
* SQL injection
|
* SQL injection
|
||||||
|
|
||||||
=== Often the database is considered trusted
|
=== Often the database is considered trusted
|
||||||
|
|
||||||
|
@ -10,4 +10,3 @@ Let's repeat one of the previous assignments, the developer fixed the possible S
|
|||||||
spot the weakness in this approach?
|
spot the weakness in this approach?
|
||||||
|
|
||||||
Read about the lesson goal link:start.mvc#lesson/SqlInjectionAdvanced.lesson/2[here].
|
Read about the lesson goal link:start.mvc#lesson/SqlInjectionAdvanced.lesson/2[here].
|
||||||
|
|
||||||
|
@ -4,5 +4,3 @@ So the last attempt to validate if the query did not contain any spaces failed,
|
|||||||
into the direction of only performing input validation, can you find out where it went wrong this time?
|
into the direction of only performing input validation, can you find out where it went wrong this time?
|
||||||
|
|
||||||
Read about the lesson goal link:start.mvc#lesson/SqlInjectionAdvanced.lesson/2[here].
|
Read about the lesson goal link:start.mvc#lesson/SqlInjectionAdvanced.lesson/2[here].
|
||||||
|
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user