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 |
2
.github/FUNDING.yml
vendored
2
.github/FUNDING.yml
vendored
@ -1 +1 @@
|
||||
custom: https://owasp.org/donate/?reponame=www-project-webgoat&title=OWASP+WebGoat
|
||||
custom: https://owasp.org/donate/?reponame=www-project-webgoat&title=OWASP+WebGoat
|
||||
|
3
.github/dependabot.yml
vendored
3
.github/dependabot.yml
vendored
@ -8,10 +8,7 @@ updates:
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
ignore:
|
||||
- dependency-name: "org.webjars:bootstrap" # First the WebWolf UI needs to be refactored due to breaking changes
|
||||
- package-ecosystem: "docker"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
|
||||
|
@ -15,7 +15,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up JDK ${{ matrix.java-version }}
|
||||
uses: actions/setup-java@v3
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: ${{ matrix.java-version }}
|
||||
@ -51,4 +51,4 @@ jobs:
|
||||
file: ./Dockerfile_desktop
|
||||
push: false
|
||||
build-args: |
|
||||
webgoat_version=${{ env.WEBGOAT_MAVEN_VERSION }}
|
||||
webgoat_version=${{ env.WEBGOAT_MAVEN_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:
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- '.txt'
|
||||
- 'LICENSE'
|
||||
- 'docs/**'
|
||||
branches: [main]
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
pr-build:
|
||||
if: >
|
||||
github.event_name == 'pull_request' && !github.event.pull_request.draft && (
|
||||
github.event.action == 'opened' ||
|
||||
github.event.action == 'reopened' ||
|
||||
github.event.action == 'synchronize'
|
||||
)
|
||||
build:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
@ -21,7 +19,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v3
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 17
|
||||
@ -34,27 +32,3 @@ jobs:
|
||||
restore-keys: ${{ runner.os }}-m2-
|
||||
- name: Build with Maven
|
||||
run: mvn --no-transfer-progress verify
|
||||
- name: "Set up QEMU"
|
||||
if: runner.os == 'Linux'
|
||||
uses: docker/setup-qemu-action@v2.2.0
|
||||
- name: "Set up Docker Buildx"
|
||||
if: runner.os == 'Linux'
|
||||
uses: docker/setup-buildx-action@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()
|
15
.github/workflows/release.yml
vendored
15
.github/workflows/release.yml
vendored
@ -8,13 +8,15 @@ jobs:
|
||||
if: github.repository == 'WebGoat/WebGoat'
|
||||
name: Release WebGoat
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
environment:
|
||||
name: release
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v3
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 17
|
||||
@ -44,7 +46,7 @@ jobs:
|
||||
files: |
|
||||
target/webgoat-${{ env.WEBGOAT_MAVEN_VERSION }}.jar
|
||||
body: |
|
||||
## Version ${{ github.ref_name }}
|
||||
## Version ${{ github.ref_name }}
|
||||
|
||||
### New functionality
|
||||
|
||||
@ -53,8 +55,8 @@ jobs:
|
||||
### Bug fixes
|
||||
|
||||
- [#743 - Character encoding errors](https://github.com/WebGoat/WebGoat/issues/743)
|
||||
|
||||
Full change log: https://github.com/WebGoat/WebGoat/compare/${{ github.ref_name }}...${{ github.ref_name }}
|
||||
|
||||
Full change log: https://github.com/WebGoat/WebGoat/compare/${{ github.ref_name }}...${{ github.ref_name }}
|
||||
|
||||
|
||||
## Contributors
|
||||
@ -91,7 +93,7 @@ jobs:
|
||||
context: ./
|
||||
file: ./Dockerfile
|
||||
push: true
|
||||
platforms: linux/amd64, linux/arm64, linux/arm/v7
|
||||
platforms: linux/amd64, linux/arm64
|
||||
tags: |
|
||||
webgoat/webgoat:${{ env.WEBGOAT_TAG_VERSION }}
|
||||
webgoat/webgoat:latest
|
||||
@ -121,7 +123,7 @@ jobs:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v3
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 17
|
||||
@ -145,4 +147,3 @@ jobs:
|
||||
github_token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
title: ${{ github.event.commits[0].message }}
|
||||
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: actions/checkout@v3
|
||||
# Uses an action to add Python to the VM
|
||||
- name: Setup Pyton
|
||||
uses: actions/setup-python@v4
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.7'
|
||||
architecture: x64
|
||||
# Uses an action to add JDK 17 to the VM (and mvn?)
|
||||
- name: set up JDK 17
|
||||
uses: actions/setup-java@v3
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
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'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/first-interaction@v1.2.0
|
||||
- uses: actions/first-interaction@v1.3.0
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
issue-message: 'Thanks for submitting your first issue, we will have a look as quickly as possible.'
|
||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -56,4 +56,4 @@ TestClass.class
|
||||
**/*.flattened-pom.xml
|
||||
/.gitconfig
|
||||
|
||||
webgoat.gitconfig
|
||||
webgoat.gitconfig
|
||||
|
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
|
@ -16,4 +16,4 @@ not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, B
|
||||
|
||||
Getting Source ==============
|
||||
|
||||
Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||
Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||
|
@ -11,11 +11,11 @@ Update the release notes with the correct version. Use `git shortlog -s -n --sin
|
||||
committers. In order to fetch the list of issues included use: `git log --graph --pretty='%C(auto)%d%Creset%s' v2023.4..origin/main`
|
||||
|
||||
```
|
||||
mvn versions:set
|
||||
mvn versions:set
|
||||
<< update release notes >>
|
||||
mvn verify
|
||||
git commit ....
|
||||
git tag v2023.01
|
||||
git tag v2023.01
|
||||
git push --tags
|
||||
```
|
||||
|
||||
|
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"
|
||||
MAINTAINER "WebGoat team"
|
||||
|
||||
@ -14,6 +14,8 @@ COPY --chown=webgoat target/webgoat-*.jar /home/webgoat/webgoat.jar
|
||||
EXPOSE 8080
|
||||
EXPOSE 9090
|
||||
|
||||
ENV TZ=Europe/Amsterdam
|
||||
|
||||
WORKDIR /home/webgoat
|
||||
ENTRYPOINT [ "java", \
|
||||
"-Duser.home=/home/webgoat", \
|
||||
@ -30,8 +32,4 @@ ENTRYPOINT [ "java", \
|
||||
"--add-opens", "java.base/sun.nio.ch=ALL-UNNAMED", \
|
||||
"--add-opens", "java.base/java.io=ALL-UNNAMED", \
|
||||
"-Drunning.in.docker=true", \
|
||||
"-Dwebgoat.host=0.0.0.0", \
|
||||
"-Dwebwolf.host=0.0.0.0", \
|
||||
"-Dwebgoat.port=8080", \
|
||||
"-Dwebwolf.port=9090", \
|
||||
"-jar", "webgoat.jar" ]
|
||||
"-jar", "webgoat.jar", "--server.address", "0.0.0.0" ]
|
||||
|
1
FAQ.md
1
FAQ.md
@ -5,4 +5,3 @@
|
||||
### Integration tests fail
|
||||
|
||||
Try to run the command in the console `java -jar ...` and remove `-Dlogging.pattern.console=` from the command line.
|
||||
|
||||
|
@ -16,4 +16,4 @@ not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, B
|
||||
|
||||
Getting Source ==============
|
||||
|
||||
Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||
Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||
|
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
|
||||
```
|
||||
|
||||
If you want to reuse the container, give it a name:
|
||||
For some lessons you need the container run in the same timezone. For this you can set the TZ environment variable.
|
||||
E.g.
|
||||
|
||||
```shell
|
||||
docker run --name webgoat -it -p 127.0.0.1:8080:8080 -p 127.0.0.1:9090:9090 webgoat/webgoat
|
||||
docker run -it -p 127.0.0.1:8080:8080 -p 127.0.0.1:9090:9090 -e TZ=America/Boise webgoat/webgoat
|
||||
```
|
||||
|
||||
As long as you don't remove the container you can use:
|
||||
If you want to use OWASP ZAP or another proxy, you can no longer use 127.0.0.1 or localhost. but
|
||||
you can use custom host entries. For example:
|
||||
|
||||
```shell
|
||||
docker start webgoat
|
||||
127.0.0.1 www.webgoat.local www.webwolf.local
|
||||
```
|
||||
|
||||
This way, you can start where you left off. If you remove the container, you need to use `docker run` again.
|
||||
Then you can run the container with:
|
||||
|
||||
```shell
|
||||
docker run -it -p 127.0.0.1:8080:8080 -p 127.0.0.1:9090:9090 -e WEBGOAT_HOST=www.webgoat.local -e WEBWOLF_HOST=www.webwolf.local -e TZ=America/Boise webgoat/webgoat
|
||||
```
|
||||
|
||||
Then visit http://www.webgoat.local:8080/WebGoat/ and http://www.webwolf.local:9090/WebWolf/
|
||||
|
||||
## 2. Run using Docker with complete Linux Desktop
|
||||
|
||||
@ -71,7 +79,8 @@ docker run -p 127.0.0.1:3000:3000 webgoat/webgoat-desktop
|
||||
Download the latest WebGoat release from [https://github.com/WebGoat/WebGoat/releases](https://github.com/WebGoat/WebGoat/releases)
|
||||
|
||||
```shell
|
||||
java -Dfile.encoding=UTF-8 -Dwebgoat.port=8080 -Dwebwolf.port=9090 -jar webgoat-2023.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.
|
||||
@ -80,7 +89,7 @@ Click the link in the log to start WebGoat.
|
||||
|
||||
### Prerequisites:
|
||||
|
||||
* Java 17
|
||||
* Java 17 or 21
|
||||
* Your favorite IDE
|
||||
* Git, or Git support in your IDE
|
||||
|
||||
@ -132,9 +141,10 @@ For specialist only. There is a way to set up WebGoat with a personalized menu.
|
||||
For instance running as a jar on a Linux/macOS it will look like this:
|
||||
|
||||
```Shell
|
||||
export TZ=Europe/Amsterdam # or your timezone
|
||||
export EXCLUDE_CATEGORIES="CLIENT_SIDE,GENERAL,CHALLENGE"
|
||||
export EXCLUDE_LESSONS="SqlInjectionAdvanced,SqlInjectionMitigations"
|
||||
java -jar target/webgoat-2023.4-SNAPSHOT.jar
|
||||
java -jar target/webgoat-2023.6-SNAPSHOT.jar
|
||||
```
|
||||
|
||||
Or in a docker run it would (once this version is pushed into docker hub) look like this:
|
||||
|
@ -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. Add the parts for showing the flag and providing the correct value for the flag= parameter
|
||||
2.
|
||||
3. Add a flag image to src/main/resources/webgoat/static/css/img
|
||||
2.
|
||||
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
|
||||
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)
|
||||
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)
|
||||
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
|
||||
2. Adding WebGoatLabels.properties of a specific language if you want to
|
||||
7. 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
|
||||
6. Run mvn clean to see if the LabelAndHintIntegration test passes
|
||||
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
|
||||
|
@ -1,5 +1,25 @@
|
||||
# WebGoat release notes
|
||||
|
||||
## Version 2023.8
|
||||
|
||||
### 🚀 New functionality
|
||||
|
||||
- Consistent environment values and url references (#1677)
|
||||
- Show directly requested file in requests overview
|
||||
- Show creating time in file upload overview
|
||||
|
||||
### 🐞 Bug fixes
|
||||
|
||||
- Fix startup message (#1687)
|
||||
- Fix/state of software supply chain links (#1683)
|
||||
- Fix WebWolf UI (#1686)
|
||||
|
||||
### 🔄 Technical tasks
|
||||
|
||||
- bump actions/setup-java from 3 to 4 (#1690)
|
||||
- bump commons-io:commons-io from 2.14.0 to 2.15.1 (#1689)
|
||||
- bump com.diffplug.spotless:spotless-maven-plugin (#1688)
|
||||
|
||||
## Version 2023.5
|
||||
|
||||
### New functionality
|
||||
@ -195,4 +215,3 @@ Special thanks to the following contributors providing us with a pull request:
|
||||
And everyone who provided feedback through Github.
|
||||
|
||||
Team WebGoat
|
||||
|
||||
|
@ -8,4 +8,4 @@
|
||||
<suppress files="ContentTypeAssignment.java" checks="IllegalImportCheck" />
|
||||
<suppress files="SimpleXXE.java" checks="IllegalImportCheck" />
|
||||
<suppress files="HtmlTamperingTask.java" checks="ParameterName" />
|
||||
</suppressions>
|
||||
</suppressions>
|
||||
|
@ -1,4 +1,3 @@
|
||||
# WebGoat landing page
|
||||
|
||||
Old GitHub page which now redirects to OWASP website.
|
||||
|
||||
|
@ -11,4 +11,4 @@
|
||||
The page been moved to <a href="https://owasp.org/www-project-webgoat/">https://owasp.org/www-project-webgoat/</a>
|
||||
</h1>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
2
mvnw
vendored
2
mvnw
vendored
@ -246,7 +246,7 @@ else
|
||||
else
|
||||
curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
|
||||
fi
|
||||
|
||||
|
||||
else
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Falling back to using Java to download"
|
||||
|
46
pom.xml
46
pom.xml
@ -10,7 +10,7 @@
|
||||
|
||||
<groupId>org.owasp.webgoat</groupId>
|
||||
<artifactId>webgoat</artifactId>
|
||||
<version>2023.5</version>
|
||||
<version>2023.9-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>WebGoat</name>
|
||||
@ -110,12 +110,12 @@
|
||||
<properties>
|
||||
<!-- Shared properties with plugins and version numbers across submodules-->
|
||||
<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>
|
||||
<!-- do not update necessary for lesson -->
|
||||
<checkstyle.version>3.3.1</checkstyle.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-text.version>1.10.0</commons-text.version>
|
||||
<guava.version>32.1.3-jre</guava.version>
|
||||
@ -141,10 +141,9 @@
|
||||
<thymeleaf.version>3.1.1.RELEASE</thymeleaf.version>
|
||||
<webdriver.version>5.3.3</webdriver.version>
|
||||
<webgoat.context>/</webgoat.context>
|
||||
<webgoat.port>8080</webgoat.port>
|
||||
<webgoat.sslenabled>false</webgoat.sslenabled>
|
||||
<webjars-locator-core.version>0.53</webjars-locator-core.version>
|
||||
<webwolf.context>/</webwolf.context>
|
||||
<webwolf.port>9090</webwolf.port>
|
||||
<wiremock.version>2.27.2</wiremock.version>
|
||||
<xml-resolver.version>1.2</xml-resolver.version>
|
||||
<xstream.version>1.4.5</xstream.version>
|
||||
@ -513,10 +512,19 @@
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<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>
|
||||
<logback.configurationFile>${basedir}/src/test/resources/logback-test.xml</logback.configurationFile>
|
||||
</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>
|
||||
</configuration>
|
||||
<executions>
|
||||
@ -557,7 +565,6 @@
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
<version>${checkstyle.version}</version>
|
||||
<configuration>
|
||||
<encoding>UTF-8</encoding>
|
||||
<consoleOutput>true</consoleOutput>
|
||||
<failsOnError>true</failsOnError>
|
||||
<configLocation>config/checkstyle/checkstyle.xml</configLocation>
|
||||
@ -568,7 +575,7 @@
|
||||
<plugin>
|
||||
<groupId>com.diffplug.spotless</groupId>
|
||||
<artifactId>spotless-maven-plugin</artifactId>
|
||||
<version>2.38.0</version>
|
||||
<version>2.41.1</version>
|
||||
<configuration>
|
||||
<formats>
|
||||
<format>
|
||||
@ -686,16 +693,15 @@
|
||||
<portNames>
|
||||
<portName>webgoat.port</portName>
|
||||
<portName>webwolf.port</portName>
|
||||
<portName>jmxPort</portName>
|
||||
</portNames>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.bazaarvoice.maven.plugins</groupId>
|
||||
<groupId>org.honton.chas</groupId>
|
||||
<artifactId>process-exec-maven-plugin</artifactId>
|
||||
<version>0.9</version>
|
||||
<version>0.9.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>start-jar</id>
|
||||
@ -703,8 +709,18 @@
|
||||
<goal>start</goal>
|
||||
</goals>
|
||||
<phase>pre-integration-test</phase>
|
||||
|
||||
<configuration>
|
||||
<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>
|
||||
<argument>java</argument>
|
||||
<argument>-jar</argument>
|
||||
@ -712,10 +728,6 @@
|
||||
<argument>-Dwebgoat.server.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>-Dwebgoat.port=${webgoat.port}</argument>
|
||||
<argument>-Dwebgoat.context=${webgoat.context}</argument>
|
||||
<argument>-Dwebwolf.port=${webwolf.port}</argument>
|
||||
<argument>-Dwebwolf.context=${webwolf.context}</argument>
|
||||
<argument>--add-opens</argument>
|
||||
<argument>java.base/java.lang=ALL-UNNAMED</argument>
|
||||
<argument>--add-opens</argument>
|
||||
@ -741,8 +753,6 @@
|
||||
<argument>${project.build.directory}/webgoat-${project.version}.jar</argument>
|
||||
</arguments>
|
||||
<waitForInterrupt>false</waitForInterrupt>
|
||||
<waitAfterLaunch>120</waitAfterLaunch>
|
||||
<healthcheckUrl>http://localhost:${webgoat.port}/WebGoat/actuator/health</healthcheckUrl>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
@ -767,7 +777,6 @@
|
||||
<plugin>
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-maven</artifactId>
|
||||
<version>8.4.3</version>
|
||||
<configuration>
|
||||
<failBuildOnCVSS>7</failBuildOnCVSS>
|
||||
<skipProvidedScope>false</skipProvidedScope>
|
||||
@ -816,7 +825,6 @@
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<version>${jacoco.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>before-unit-test</id>
|
||||
|
@ -253,6 +253,7 @@ public class CSRFIntegrationTest extends IntegrationTest {
|
||||
Overview[] assignments =
|
||||
RestAssured.given()
|
||||
.cookie("JSESSIONID", getWebGoatCookie())
|
||||
.relaxedHTTPSValidation()
|
||||
.get(url("service/lessonoverview.mvc"))
|
||||
.then()
|
||||
.extract()
|
||||
|
@ -5,7 +5,6 @@ import static io.restassured.RestAssured.given;
|
||||
import io.restassured.RestAssured;
|
||||
import io.restassured.http.ContentType;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import lombok.Getter;
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.hamcrest.MatcherAssert;
|
||||
@ -15,23 +14,26 @@ import org.springframework.http.HttpStatus;
|
||||
|
||||
public abstract class IntegrationTest {
|
||||
|
||||
private static String webGoatPort =
|
||||
Objects.requireNonNull(System.getProperty("webgoatport", "8080"));
|
||||
private static String webGoatPort = System.getenv().getOrDefault("WEBGOAT_PORT", "8080");
|
||||
private static String webGoatContext =
|
||||
Objects.requireNonNull(System.getProperty("webgoatcontext", "/WebGoat/"));
|
||||
System.getenv().getOrDefault("WEBGOAT_CONTEXT", "/WebGoat/");
|
||||
|
||||
@Getter private static String webWolfPort = System.getenv().getOrDefault("WEBWOLF_PORT", "9090");
|
||||
|
||||
@Getter
|
||||
private static String webWolfPort =
|
||||
Objects.requireNonNull(System.getProperty("webwolfport", "9090"));
|
||||
private static String webWolfHost = System.getenv().getOrDefault("WEBWOLF_HOST", "127.0.0.1");
|
||||
|
||||
@Getter
|
||||
private static String webGoatHost = System.getenv().getOrDefault("WEBGOAT_HOST", "127.0.0.1");
|
||||
|
||||
private static String webWolfContext =
|
||||
Objects.requireNonNull(System.getProperty("webwolfcontext", "/WebWolf/"));
|
||||
System.getenv().getOrDefault("WEBWOLF_CONTEXT", "/WebWolf/");
|
||||
|
||||
private static boolean useSSL = false;
|
||||
private static boolean useSSL =
|
||||
Boolean.valueOf(System.getenv().getOrDefault("WEBGOAT_SSLENABLED", "false"));
|
||||
private static String webgoatUrl =
|
||||
(useSSL ? "https:" : "http:") + "//localhost:" + webGoatPort + webGoatContext;
|
||||
private static String webWolfUrl =
|
||||
(useSSL ? "https:" : "http:") + "//localhost:" + webWolfPort + webWolfContext;
|
||||
(useSSL ? "https://" : "http://") + webGoatHost + ":" + webGoatPort + webGoatContext;
|
||||
private static String webWolfUrl = "http://" + webWolfHost + ":" + webWolfPort + webWolfContext;
|
||||
@Getter private String webGoatCookie;
|
||||
@Getter private String webWolfCookie;
|
||||
@Getter private final String user = "webgoat";
|
||||
|
@ -69,7 +69,6 @@ public class PasswordResetLessonIntegrationTest extends IntegrationTest {
|
||||
|
||||
// WebWolf
|
||||
var link = getPasswordResetLinkFromLandingPage();
|
||||
|
||||
// WebGoat
|
||||
changePassword(link);
|
||||
checkAssignment(
|
||||
@ -137,7 +136,7 @@ public class PasswordResetLessonIntegrationTest extends IntegrationTest {
|
||||
private void clickForgotEmailLink(String user) {
|
||||
RestAssured.given()
|
||||
.when()
|
||||
.header(HttpHeaders.HOST, String.format("%s:%s", "127.0.0.1", getWebWolfPort()))
|
||||
.header(HttpHeaders.HOST, String.format("%s:%s", getWebWolfHost(), getWebWolfPort()))
|
||||
.relaxedHTTPSValidation()
|
||||
.cookie("JSESSIONID", getWebGoatCookie())
|
||||
.formParams("email", user)
|
||||
|
@ -6,7 +6,6 @@ import javax.sql.DataSource;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flywaydb.core.Flyway;
|
||||
import org.owasp.webgoat.container.lessons.LessonScanner;
|
||||
import org.owasp.webgoat.container.service.RestartLessonService;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@ -20,7 +19,6 @@ import org.springframework.jdbc.datasource.DriverManagerDataSource;
|
||||
public class DatabaseConfiguration {
|
||||
|
||||
private final DataSourceProperties properties;
|
||||
private final LessonScanner lessonScanner;
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
|
@ -1,12 +1,9 @@
|
||||
package org.owasp.webgoat.container.asciidoc;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.asciidoctor.ast.ContentNode;
|
||||
import org.asciidoctor.extension.InlineMacroProcessor;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
/**
|
||||
* Usage in asciidoc:
|
||||
@ -26,7 +23,7 @@ public class WebWolfMacro extends InlineMacroProcessor {
|
||||
@Override
|
||||
public Object process(ContentNode contentNode, String linkText, Map<String, Object> attributes) {
|
||||
var env = EnvironmentExposure.getEnv();
|
||||
var hostname = determineHost(env.getProperty("webwolf.port"));
|
||||
var hostname = env.getProperty("webwolf.url");
|
||||
var target = (String) attributes.getOrDefault("target", "home");
|
||||
var href = hostname + "/" + target;
|
||||
|
||||
@ -45,29 +42,4 @@ public class WebWolfMacro extends InlineMacroProcessor {
|
||||
private boolean displayCompleteLinkNoFormatting(Map<String, Object> attributes) {
|
||||
return attributes.values().stream().anyMatch(a -> a.equals("noLink"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the host from the hostname and ports that were used. The purpose is to make it
|
||||
* possible to use the application behind a reverse proxy. For instance in the docker
|
||||
* compose/stack version with webgoat webwolf and nginx proxy. You do not have to use the
|
||||
* indicated hostname, but if you do, you should define two hosts aliases 127.0.0.1
|
||||
* www.webgoat.local www.webwolf.local
|
||||
*/
|
||||
private String determineHost(String port) {
|
||||
HttpServletRequest request =
|
||||
((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
|
||||
String host = request.getHeader("Host");
|
||||
int semicolonIndex = host.indexOf(":");
|
||||
if (semicolonIndex == -1 || host.endsWith(":80")) {
|
||||
host = host.replace(":80", "").replace("www.webgoat.local", "www.webwolf.local");
|
||||
} else {
|
||||
host = host.substring(0, semicolonIndex);
|
||||
host = host.concat(":").concat(port);
|
||||
}
|
||||
return "http://" + host + (includeWebWolfContext() ? "/WebWolf" : "");
|
||||
}
|
||||
|
||||
protected boolean includeWebWolfContext() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -17,9 +17,4 @@ public class WebWolfRootMacro extends WebWolfMacro {
|
||||
public WebWolfRootMacro(String macroName, Map<String, Object> 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.session.UserSessionData;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@ -41,10 +40,9 @@ public class CSRFGetFlag {
|
||||
@Autowired UserSessionData userSessionData;
|
||||
@Autowired private PluginMessages pluginMessages;
|
||||
|
||||
@RequestMapping(
|
||||
@PostMapping(
|
||||
path = "/csrf/basic-get-flag",
|
||||
produces = {"application/json"},
|
||||
method = RequestMethod.POST)
|
||||
produces = {"application/json"})
|
||||
@ResponseBody
|
||||
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.springframework.beans.factory.annotation.Autowired;
|
||||
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.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
@ -43,7 +42,7 @@ public class Ping {
|
||||
|
||||
@Autowired private WebSession webSession;
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET)
|
||||
@GetMapping
|
||||
@ResponseBody
|
||||
public String logRequest(
|
||||
@RequestHeader("User-Agent") String userAgent, @RequestParam(required = false) String text) {
|
||||
|
@ -25,24 +25,36 @@
|
||||
|
||||
package org.owasp.webgoat.server;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.owasp.webgoat.container.WebGoat;
|
||||
import org.owasp.webgoat.webwolf.WebWolf;
|
||||
import org.springframework.boot.Banner;
|
||||
import org.springframework.boot.WebApplicationType;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
@Slf4j
|
||||
public class StartWebGoat {
|
||||
|
||||
public static void main(String[] args) {
|
||||
new SpringApplicationBuilder()
|
||||
.parent(ParentConfig.class)
|
||||
.web(WebApplicationType.NONE)
|
||||
.bannerMode(Banner.Mode.OFF)
|
||||
.child(WebGoat.class)
|
||||
.web(WebApplicationType.SERVLET)
|
||||
.sibling(WebWolf.class)
|
||||
.bannerMode(Banner.Mode.OFF)
|
||||
.web(WebApplicationType.SERVLET)
|
||||
.run(args);
|
||||
var parentBuilder =
|
||||
new SpringApplicationBuilder()
|
||||
.parent(ParentConfig.class)
|
||||
.web(WebApplicationType.NONE)
|
||||
.bannerMode(Banner.Mode.OFF);
|
||||
parentBuilder.child(WebWolf.class).web(WebApplicationType.SERVLET).run(args);
|
||||
ApplicationContext webGoatContext =
|
||||
parentBuilder.child(WebGoat.class).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;
|
||||
|
||||
import static java.util.Comparator.comparing;
|
||||
import static org.springframework.http.MediaType.ALL_VALUE;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.io.File;
|
||||
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 lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import java.util.TimeZone;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
@ -51,6 +55,9 @@ import org.springframework.web.servlet.view.RedirectView;
|
||||
@Slf4j
|
||||
public class FileServer {
|
||||
|
||||
private static final DateTimeFormatter dateTimeFormatter =
|
||||
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
@Value("${webwolf.fileserver.location}")
|
||||
private String fileLocation;
|
||||
|
||||
@ -87,16 +94,9 @@ public class FileServer {
|
||||
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")
|
||||
public ModelAndView getFiles(HttpServletRequest request, Authentication authentication) {
|
||||
public ModelAndView getFiles(
|
||||
HttpServletRequest request, Authentication authentication, TimeZone timezone) {
|
||||
String username = (null != authentication) ? authentication.getName() : "anonymous";
|
||||
File destinationDir = new File(fileLocation, username);
|
||||
|
||||
@ -108,18 +108,33 @@ public class FileServer {
|
||||
}
|
||||
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);
|
||||
if (files != null) {
|
||||
for (File file : files) {
|
||||
String size = FileUtils.byteCountToDisplaySize(file.length());
|
||||
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);
|
||||
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;
|
||||
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import java.time.Instant;
|
||||
@ -67,10 +65,10 @@ public class Requests {
|
||||
var model = new ModelAndView("requests");
|
||||
String username = (null != authentication) ? authentication.getName() : "anonymous";
|
||||
var traces =
|
||||
traceRepository.findAllTraces().stream()
|
||||
traceRepository.findAll().stream()
|
||||
.filter(t -> allowedTrace(t, username))
|
||||
.map(t -> new Tracert(t.getTimestamp(), path(t), toJsonString(t)))
|
||||
.collect(toList());
|
||||
.toList();
|
||||
model.addObject("traces", traces);
|
||||
|
||||
return model;
|
||||
@ -93,7 +91,7 @@ public class Requests {
|
||||
}
|
||||
|
||||
private String path(HttpExchange t) {
|
||||
return (String) t.getRequest().getUri().getPath();
|
||||
return t.getRequest().getUri().getPath();
|
||||
}
|
||||
|
||||
private String toJsonString(HttpExchange t) {
|
||||
|
@ -22,6 +22,9 @@
|
||||
|
||||
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 java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -36,31 +39,50 @@ import org.springframework.boot.actuate.web.exchanges.HttpExchangeRepository;
|
||||
* @since 8/13/17.
|
||||
*/
|
||||
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 List<String> exclusionList =
|
||||
private final List<Exclusion> exclusionList =
|
||||
List.of(
|
||||
"/tmpdir",
|
||||
"/home",
|
||||
"/files",
|
||||
"/images/",
|
||||
"/js/",
|
||||
"/webjars/",
|
||||
"/requests",
|
||||
"/css/",
|
||||
"/mail");
|
||||
contains("/tmpdir"),
|
||||
contains("/home"),
|
||||
endsWith("/files"),
|
||||
contains("/images/"),
|
||||
contains("/js/"),
|
||||
contains("/webjars/"),
|
||||
contains("/requests"),
|
||||
contains("/css/"),
|
||||
contains("/mail"));
|
||||
|
||||
@Override
|
||||
public List<HttpExchange> findAll() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
public List<HttpExchange> findAllTraces() {
|
||||
return new ArrayList<>(traces);
|
||||
}
|
||||
|
||||
private boolean isInExclusionList(String path) {
|
||||
return exclusionList.stream().anyMatch(e -> path.contains(e));
|
||||
return exclusionList.stream().anyMatch(e -> e.matches(path));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,9 +1,9 @@
|
||||
server.error.include-stacktrace=always
|
||||
server.error.path=/error.html
|
||||
server.servlet.context-path=${webgoat.context}
|
||||
server.servlet.context-path=${WEBGOAT_CONTEXT:/WebGoat}
|
||||
server.servlet.session.persistent=false
|
||||
server.port=${webgoat.port}
|
||||
server.address=${webgoat.host}
|
||||
server.port=${WEBGOAT_PORT:8080}
|
||||
server.address=${WEBGOAT_HOST:127.0.0.1}
|
||||
webgoat.host=${WEBGOAT_HOST:127.0.0.1}
|
||||
webgoat.port=${WEBGOAT_PORT:8080}
|
||||
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.database.connection.string=jdbc:hsqldb:mem:{USER}
|
||||
webgoat.default.language=en
|
||||
webgoat.url=http://${server.address}:${server.port}${server.servlet.context-path}
|
||||
|
||||
webwolf.host=${WEBWOLF_HOST:127.0.0.1}
|
||||
webwolf.port=${WEBWOLF_PORT:9090}
|
||||
webwolf.context=${WEBWOLF_CONTEXT:/WebWolf}
|
||||
webwolf.url=http://${webwolf.host}:${webwolf.port}${webwolf.context}
|
||||
webwolf.url=http://${WEBWOLF_HOST:127.0.0.1}:${WEBWOLF_PORT:9090}${WEBWOLF_CONTEXT:/WebWolf}
|
||||
webwolf.landingpage.url=${webwolf.url}/landing
|
||||
webwolf.mail.url=${webwolf.url}/mail
|
||||
|
||||
@ -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-secret=${WEBGOAT_OAUTH_CLIENTSECRET:dummy}
|
||||
|
||||
|
@ -63,4 +63,4 @@ CREATE TABLE CONTAINER.EMAIL(
|
||||
TITLE VARCHAR(255)
|
||||
);
|
||||
|
||||
ALTER TABLE CONTAINER.EMAIL ALTER COLUMN ID RESTART WITH 2;
|
||||
ALTER TABLE CONTAINER.EMAIL ALTER COLUMN ID RESTART WITH 2;
|
||||
|
@ -1,4 +1,3 @@
|
||||
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.USER_TRACKER ALTER COLUMN ID SET GENERATED BY DEFAULT AS IDENTITY(START WITH 1);
|
||||
|
||||
|
@ -53,7 +53,7 @@ reset.lesson=Reset lesson
|
||||
sign.in=Sign in
|
||||
register.new=or register yourself as a new user
|
||||
sign.up=Sign up
|
||||
register.title=Register
|
||||
register.title=Register
|
||||
searchmenu=Search lesson
|
||||
|
||||
|
||||
@ -66,7 +66,7 @@ security.enabled=Security enabled, you can try the previous challenges and see t
|
||||
security.disabled=Security enabled, you can try the previous challenges and see the effect!
|
||||
termsofuse=Terms of use
|
||||
register.condition.1=While running this program your machine will be extremely vulnerable to attack.\
|
||||
You should disconnect from the Internet while using this program. WebGoat's default configuration binds to localhost to minimize the exposure.
|
||||
You should disconnect from the Internet while using this program. WebGoat's default configuration binds to localhost to minimize the exposure.
|
||||
register.condition.2=This program is for educational purposes only. If you attempt \
|
||||
these techniques without authorization, you are very likely to get caught. If \
|
||||
you are caught engaging in unauthorized hacking, most companies will fire you. \
|
||||
|
@ -37,5 +37,4 @@ username=Benutzername
|
||||
password=Passwort
|
||||
password.confirm=Wiederhohl Passwort
|
||||
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
|
@ -59,4 +59,4 @@ register.condition.1=Wanneer u WebGoat runt op uw computer, bent u kwetsbaar voo
|
||||
Zorg dat u geen verbinding heeft met internet en dat toegang tot WebGoat alleen lokaal mogelijk is om het aanvalsoppervlak te verkleinen.
|
||||
register.condition.2=WebGoat is bedoeld als educatieve applicatie op het gebied van secure software development. \
|
||||
Gebruik wat u leert om applicaties beter te maken en niet om zonder toestemming applicaties te schaden. \
|
||||
In dat laatste geval loopt u risico op rechtsvervoling en ontslag.
|
||||
In dat laatste geval loopt u risico op rechtsvervoling en ontslag.
|
||||
|
@ -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.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?
|
||||
|
||||
|
@ -2,4 +2,4 @@
|
||||
position: relative;
|
||||
padding: 7px;
|
||||
margin-top: 7px;
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
@ -40,4 +40,4 @@
|
||||
}
|
||||
.review-block-description{
|
||||
font-size:13px;
|
||||
}
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
The admin forgot where the password is stashed, can you help?
|
||||
The admin forgot where the password is stashed, can you help?
|
||||
|
@ -0,0 +1 @@
|
||||
El administrador olvidó dónde se guarda la contraseña, ¿puedes ayudar?
|
@ -1 +1 @@
|
||||
Can you login as Larry?
|
||||
Can you login as Larry?
|
||||
|
@ -0,0 +1 @@
|
||||
¿Puedes iniciar sesión como Larry?
|
@ -1 +1 @@
|
||||
Can you login as Tom? It may be a little harder than it was for Larry.
|
||||
Can you login as Tom? It may be a little harder than it was for 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.
|
@ -1 +1 @@
|
||||
Can you still vote?
|
||||
Can you still vote?
|
||||
|
@ -0,0 +1 @@
|
||||
¿Todavía puedes votar?
|
@ -26,4 +26,4 @@ an e-mail.
|
||||
Team WebGoat
|
||||
|
||||
|
||||
image::images/boss.jpg[]
|
||||
image::images/boss.jpg[]
|
||||
|
@ -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[]
|
@ -19,9 +19,9 @@ input.invalid=Input for user, email and/or password is empty or too long, please
|
||||
challenge.flag.correct=Congratulations you have solved the challenge!!
|
||||
challenge.flag.incorrect=Sorry this is not the correct flag, please try again.
|
||||
|
||||
ip.address.unknown=IP address unknown, e-mail has been sent.
|
||||
ip.address.unknown=IP address unknown, e-mail has been sent.
|
||||
|
||||
|
||||
|
||||
required4=Missing username or password, please specify both.
|
||||
user.not.larry=Please try to log in as Larry not {0}.
|
||||
user.not.larry=Please try to log in as Larry not {0}.
|
||||
|
File diff suppressed because one or more lines are too long
@ -15,4 +15,4 @@ $(function() {
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
@ -54,4 +54,4 @@ function doVote(stars) {
|
||||
})
|
||||
loadVotes();
|
||||
average();
|
||||
}
|
||||
}
|
||||
|
@ -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"]
|
@ -37,4 +37,4 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,3 @@
|
||||
#lesson_wrapper {height: 435px;width: 500px;}
|
||||
#lesson_header {background-image: url(../images/lesson1_header.jpg); width: 490px;padding-right: 10px;padding-top: 60px;background-repeat: no-repeat;}
|
||||
.lesson_workspace {background-image: url(../images/lesson1_workspace.jpg); width: 490px;height: 325px;padding-left: 10px;padding-top: 10px;background-repeat: no-repeat;}
|
||||
.lesson_workspace {background-image: url(../images/lesson1_workspace.jpg); width: 490px;height: 325px;padding-left: 10px;padding-top: 10px;background-repeat: no-repeat;}
|
||||
|
@ -30,4 +30,4 @@ div.section > div > input {margin:0px;padding-left:5px;font-size:10px;padding-ri
|
||||
}
|
||||
.section{width:104%;}
|
||||
.menu-items{padding-left:0px;}
|
||||
}
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
No need to pay if you know the code ...
|
||||
No need to pay if you know the code ...
|
||||
|
@ -164,6 +164,3 @@
|
||||
</div>
|
||||
|
||||
</html>
|
||||
|
||||
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
client.side.filtering.title=Client side filtering
|
||||
ClientSideFilteringSelectUser=Select user:
|
||||
ClientSideFilteringSelectUser=Select user:
|
||||
ClientSideFilteringUserID=User ID
|
||||
ClientSideFilteringFirstName=First Name
|
||||
ClientSideFilteringLastName=Last Name
|
||||
ClientSideFilteringSSN=SSN
|
||||
ClientSideFilteringSalary=Salary
|
||||
ClientSideFilteringErrorGenerating=Error generating
|
||||
ClientSideFilteringErrorGenerating=Error generating
|
||||
ClientSideFilteringStage1Complete=Stage 1 completed.
|
||||
ClientSideFilteringStage1Question=What is Neville Bartholomew's salary?
|
||||
ClientSideFilteringStage1Question=What is Neville Bartholomew's salary?
|
||||
ClientSideFilteringStage1SubmitAnswer=Submit Answer
|
||||
ClientSideFilteringStage2Finish=Click here when you believe you have completed the lesson.
|
||||
ClientSideFilteringChoose=Choose employee
|
||||
@ -16,7 +16,7 @@ ClientSideFilteringHint2=Use Firebug to find where the information is stored on
|
||||
ClientSideFilteringHint3=Examine the hidden table to see if there is anyone listed who is not in the drop down menu.
|
||||
ClientSideFilteringHint4=Look in the last row of the hidden table.
|
||||
ClientSideFilteringHint5a=Stage 1: You can access the server directly
|
||||
ClientSideFilteringHint5b=here
|
||||
ClientSideFilteringHint5b=here
|
||||
ClientSideFilteringHint5c=to see what results are being returned
|
||||
ClientSideFilteringHint6=Stage 2: The server uses an XPath query against an XML database.
|
||||
ClientSideFilteringHint7=Stage 2: The query currently returns all of the contents of the database.
|
||||
|
@ -39,4 +39,4 @@ function ajaxFunction(userId) {
|
||||
var container = document.getElementById("hiddenEmployeeRecords");
|
||||
container.appendChild(newdiv);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -61,4 +61,4 @@ $(document).ready(function () {
|
||||
$('#price').text(quantity * 899);
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
@ -9,29 +9,29 @@
|
||||
<p><b>Lesson Plan Title:</b> Client Side Filtering</p>
|
||||
|
||||
<p><b>Concept / Topic To Teach:</b><br/>
|
||||
It is always a good practice to send to the client
|
||||
only information which they are supposed to have access to.
|
||||
In this lesson, too much information is being sent to the
|
||||
It is always a good practice to send to the client
|
||||
only information which they are supposed to have access to.
|
||||
In this lesson, too much information is being sent to the
|
||||
client, creating a serious access control problem.
|
||||
</p>
|
||||
</p>
|
||||
|
||||
<p><b>General Goal(s):</b><br/>
|
||||
For this exercise, your mission is exploit the extraneous
|
||||
information being returned by the server to discover information
|
||||
to which you should not have access.
|
||||
For this exercise, your mission is exploit the extraneous
|
||||
information being returned by the server to discover information
|
||||
to which you should not have access.
|
||||
</p>
|
||||
|
||||
<b>Solution:</b><br/>
|
||||
<p>
|
||||
This Lab consists of two Stages. In the first Stage you have to
|
||||
This Lab consists of two Stages. In the first Stage you have to
|
||||
get sensitive information . In the second one you have to fix the problem.<br/>
|
||||
</p>
|
||||
<b>Stage 1</b>
|
||||
<p>
|
||||
Use Firebug to solve this stage. If you are using IE you can try it with
|
||||
Use Firebug to solve this stage. If you are using IE you can try it with
|
||||
IEWatch.</p>
|
||||
|
||||
First use any person from the list and see what you get. After doing this you
|
||||
First use any person from the list and see what you get. After doing this you
|
||||
can search for a specific person in Firebug. Make sure you find the hidden table with
|
||||
the information, including the salary and so on. In the same table you will find
|
||||
Neville.
|
||||
@ -44,36 +44,36 @@ Now write the salary into the text edit box and submit your answer!
|
||||
</p>
|
||||
<b>Stage 2</b>
|
||||
<p>
|
||||
In this stage you have to modify the clientSideFiltering.jsp which you will find under
|
||||
In this stage you have to modify the clientSideFiltering.jsp which you will find under
|
||||
the WebContent in the lessons/Ajax folder. The Problem is that
|
||||
the server sends all information to the client. As you could see
|
||||
even if it is hidden it is easy to find the sensitive date. In this
|
||||
stage you will add a filter to the XPath queries. In this file you will find
|
||||
stage you will add a filter to the XPath queries. In this file you will find
|
||||
following construct:<br><br></p>
|
||||
<code>
|
||||
StringBuilder sb = new StringBuilder();<br>
|
||||
|
||||
|
||||
sb.append("/Employees/Employee/UserID | ");<br>
|
||||
sb.append("/Employees/Employee/FirstName | ");<br>
|
||||
sb.append("/Employees/Employee/LastName | ");<br>
|
||||
sb.append("/Employees/Employee/SSN | ");<br>
|
||||
sb.append("/Employees/Employee/Salary ");<br>
|
||||
|
||||
|
||||
String expression = sb.toString();<br>
|
||||
</code>
|
||||
<p>
|
||||
This string will be used for the XPath query. You have to guarantee that a manger only
|
||||
This string will be used for the XPath query. You have to guarantee that a manger only
|
||||
can see employees which are working for him. To archive this you can use
|
||||
filters in XPath. Following code will exactly do this:</p>
|
||||
<code>
|
||||
StringBuilder sb = new StringBuilder();<br>
|
||||
|
||||
|
||||
sb.append("/Employees/Employee[Managers/Manager/text() = " + userId + "]/UserID | ");<br>
|
||||
sb.append("/Employees/Employee[Managers/Manager/text() = " + userId + "]/FirstName | ");<br>
|
||||
sb.append("/Employees/Employee[Managers/Manager/text() = " + userId + "]/LastName | ");<br>
|
||||
sb.append("/Employees/Employee[Managers/Manager/text() = " + userId + "]/SSN | ");<br>
|
||||
sb.append("/Employees/Employee[Managers/Manager/text() = " + userId + "]/Salary ");<br>
|
||||
|
||||
|
||||
String expression = sb.toString();<br>
|
||||
</code>
|
||||
<p>
|
||||
|
@ -1,6 +1,6 @@
|
||||
= Cryptography Basics
|
||||
|
||||
== Concept
|
||||
= Cryptography Basics
|
||||
|
||||
== Concept
|
||||
|
||||
ifeval::["{lang}" == "nl"]
|
||||
Deze les behandelt verschillende cryptografische technieken die voorkomen in webapplicaties.
|
||||
@ -31,5 +31,3 @@ The goal is to get familiar with the following forms of techniques:
|
||||
=== Assignments
|
||||
|
||||
After the explanation of an item there will be several assignments.
|
||||
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
= Security defaults
|
||||
= Security defaults
|
||||
|
||||
A big problem in all kinds of systems is the use of default configurations.
|
||||
E.g. default username/passwords in routers, default passwords for keystores, default unencrypted mode, etc.
|
||||
@ -15,10 +15,10 @@ Are you using an ssh key for GitHub and or other sites and are you leaving it un
|
||||
|
||||
When you are getting a virtual server from some hosting provider, there are usually a lot of not so secure defaults. One of which is that ssh to the server runs on the default port 22 and allows username/password attempts. One of the first things you should do, is to change the configuration that you cannot ssh as user root, and you cannot ssh using username/password, but only with a valid and strong ssh key. If not, then you will notice continuous brute force attempts to login to your server.
|
||||
|
||||
|
||||
|
||||
== Assignment
|
||||
|
||||
In this exercise you need to retrieve a secret that has accidentally been left inside a docker container image. With this secret, you can decrypt the following message: *U2FsdGVkX199jgh5oANElFdtCxIEvdEvciLi+v+5loE+VCuy6Ii0b+5byb5DXp32RPmT02Ek1pf55ctQN+DHbwCPiVRfFQamDmbHBUpD7as=*.
|
||||
In this exercise you need to retrieve a secret that has accidentally been left inside a docker container image. With this secret, you can decrypt the following message: *U2FsdGVkX199jgh5oANElFdtCxIEvdEvciLi+v+5loE+VCuy6Ii0b+5byb5DXp32RPmT02Ek1pf55ctQN+DHbwCPiVRfFQamDmbHBUpD7as=*.
|
||||
You can decrypt the message by logging in to the running container (docker exec ...) and getting access to the password file located in /root. Then use the openssl command inside the container (for portability issues in openssl on Windows/Mac/Linux)
|
||||
You can find the secret in the following docker image, which you can start as:
|
||||
|
||||
@ -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 ....
|
||||
----
|
||||
|
||||
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
= Cryptography Basics
|
||||
|
||||
== Base64 Encoding
|
||||
= Cryptography Basics
|
||||
|
||||
Encoding is not really cryptography, but it is used a lot in all kinds of standards around cryptographic functions. Especially Base64 encoding.
|
||||
== Base64 Encoding
|
||||
|
||||
Encoding is not really cryptography, but it is used a lot in all kinds of standards around cryptographic functions. Especially Base64 encoding.
|
||||
|
||||
Base64 encoding is a technique used to transform all kinds of bytes to a specific range of bytes. This specific range is the ASCII readable bytes.
|
||||
This way you can transfer binary data such as secret or private keys more easily. You could even print these out or write them down.
|
||||
@ -11,7 +11,7 @@ Encoding is also reversible. So if you have the encoded version, you can create
|
||||
On wikipedia you can find more details. Basically it goes through all the bytes and transforms each set of 6 bits into a readable byte (8 bits). The result is that the size of the encoded bytes is increased with about 33%.
|
||||
|
||||
Hello ==> SGVsbG8=
|
||||
0x4d 0x61 ==> TWE=
|
||||
0x4d 0x61 ==> TWE=
|
||||
|
||||
=== Basic Authentication
|
||||
|
||||
@ -19,8 +19,7 @@ Basic authentication is sometimes used by web applications. This uses base64 enc
|
||||
|
||||
$echo -n "myuser:mypassword" | base64
|
||||
bXl1c2VyOm15cGFzc3dvcmQ=
|
||||
|
||||
|
||||
The HTTP header will look like:
|
||||
|
||||
|
||||
Authorization: Basic bXl1c2VyOm15cGFzc3dvcmQ=
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
= Cryptography Basics
|
||||
|
||||
== Other Encoding
|
||||
= Cryptography Basics
|
||||
|
||||
Also other encodings are used.
|
||||
== Other Encoding
|
||||
|
||||
Also other encodings are used.
|
||||
|
||||
=== URL encoding
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
= Encryption
|
||||
|
||||
== Symmetric encryption
|
||||
= Encryption
|
||||
|
||||
== Symmetric encryption
|
||||
|
||||
Symmetric encryption is based on a shared secret that is used for both encryption as well as decryption. Therefore, both parties (that are involved in exchanging secrets) share the same key.
|
||||
|
||||
@ -12,7 +12,7 @@ Example protocols are:
|
||||
== Asymmetric encryption
|
||||
|
||||
Asymmetric encryption is based on mathematical principles that consist of a key pair. The two keys are usually called a private key and a public key. The private key needs to be protected very well and is only known to one party. All others can freely use the public key. Something encrypted with the private key can be decrypted by all that have the public key, and something encrypted with the public key can only be decrypted with the private key.
|
||||
|
||||
|
||||
Example protocols are:
|
||||
|
||||
* RSA
|
||||
@ -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.
|
||||
|
||||
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.
|
||||
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
= Cryptography Basics
|
||||
|
||||
== Plain Hashing
|
||||
= Cryptography Basics
|
||||
|
||||
Hashing is a type of cryptography which is mostly used to detect if the original data has been changed. A hash is generated from the original data. It is based on irreversible cryptographic techniques.
|
||||
== Plain Hashing
|
||||
|
||||
Hashing is a type of cryptography which is mostly used to detect if the original data has been changed. A hash is generated from the original data. It is based on irreversible cryptographic techniques.
|
||||
If the original data is changed by even one byte, the resulting hash is also different.
|
||||
|
||||
So in a way it looks like a secure technique. However, it is NOT and even NEVER a good solution when using it for passwords. The problem here is that you can generate passwords from dictionaries and calculate all kinds of variants from these passwords. For each password you can calculate a hash. This can all be stored in large databases. So whenever you find a hash that could be a password, you just look up the hash in the database and find out the password.
|
||||
|
@ -1,35 +1,35 @@
|
||||
= Keystores & Truststores
|
||||
|
||||
A keystore is a place where you store keys. Besides *_keystore_* the term *_truststore_* is also used frequently. A truststore is the same thing as a keystore. Only it usually contains only the certificates (so basically only public keys and issuer information) of trusted certificates or certificate authorities.
|
||||
|
||||
== File based keystores
|
||||
A keystore is a place where you store keys. Besides *_keystore_* the term *_truststore_* is also used frequently. A truststore is the same thing as a keystore. Only it usually contains only the certificates (so basically only public keys and issuer information) of trusted certificates or certificate authorities.
|
||||
|
||||
== File based keystores
|
||||
|
||||
A file based keystore is something that in the end has the keys on a file system.
|
||||
Storing public certificates in a file based keystore is very common
|
||||
|
||||
== Database keystores
|
||||
|
||||
Keys and especially public certificates can of course also be stored in a database.
|
||||
Keys and especially public certificates can of course also be stored in a database.
|
||||
|
||||
== Hardware keystore
|
||||
|
||||
A hardware keystore is a system that has some sort of hardware which contain the actual keys.
|
||||
This is typically done in high end security environments where the private key is really private.
|
||||
In comparison with file based or database keystores, it is impossible to make a copy of the keystore to send it to some unknown and untrusted environment.
|
||||
In comparison with file based or database keystores, it is impossible to make a copy of the keystore to send it to some unknown and untrusted environment.
|
||||
|
||||
Some certificate authorities that are used to provide you with a server certificate for your website, also create the private keys for you (as-a-service). However, it is by definition no longer considered a private key. For all keystore types, you should keep the private key private and use a certificate signing request to order your signing or server certificates.
|
||||
|
||||
== Managed keystores in operating system, browser and other applications
|
||||
|
||||
When you visit a website and your browser says that the certificates are fine, it means that the certificate used for the website is issued by a trusted certificate authority. But this list of trusted certificate authorities is managed. Some CA's might be revoked or removed. These updates happen in the background when browser updates are installed.
|
||||
When you visit a website and your browser says that the certificates are fine, it means that the certificate used for the website is issued by a trusted certificate authority. But this list of trusted certificate authorities is managed. Some CA's might be revoked or removed. These updates happen in the background when browser updates are installed.
|
||||
Not only the browser maintains a list of trusted certificate authorities, the operation system does so as well. And the Java runtime also has its own list which is kept in the cacerts file. Updates of the OS and Java JRE keep this list up to date. In corporate environments, these are usually maintained by the company and also contain company root certificates.
|
||||
|
||||
== Extra check for website certificates using DNS CAA records
|
||||
|
||||
Some companies inspect all or most internet traffic. Even the ones were you think you have an end-2-end secured connection. This works as follows. An employee opens a browser and googles some information. The browser will use https and go to the site of google. The link looks real and the lock is shown in the browser. However, if you would inspect the certificate, you might notice that it has been issued by one of your companies root CA's! So you have established an end-2-end secure connection with a server of your company, and that server has the secure connection with google.
|
||||
Some companies inspect all or most internet traffic. Even the ones were you think you have an end-2-end secured connection. This works as follows. An employee opens a browser and googles some information. The browser will use https and go to the site of google. The link looks real and the lock is shown in the browser. However, if you would inspect the certificate, you might notice that it has been issued by one of your companies root CA's! So you have established an end-2-end secure connection with a server of your company, and that server has the secure connection with google.
|
||||
In order to prevent such man in the middle connections to your server, modern browsers now will also check the DNS CAA records to see whether or not a certain issuer is allowed for a certain website.
|
||||
More information: https://en.wikipedia.org/wiki/DNS_Certification_Authority_Authorization[Wiki DNS CAA,window=_blank]
|
||||
More information: https://en.wikipedia.org/wiki/DNS_Certification_Authority_Authorization[Wiki DNS CAA,window=_blank]
|
||||
|
||||
== Free certificates from Let's encrypt
|
||||
|
||||
https://letsencrypt.org[Let's encrypt,,window=_blank] is a free, automated and open Certificate Authority. It allows you to create valid certificates for the websites that you control. By following and implementing a certain protocol, your identity is checked and a certificate will be issued. The certificates are free of charge and this is done to stimulate the use of authorised certificates and to lower the use of self-signed certificates on the internet. Certificates are valid for 90 days, so they need to be automatically renewed. (Which makes sure that the proof of identity/ownership also takes place frequently)
|
||||
https://letsencrypt.org[Let's encrypt,,window=_blank] is a free, automated and open Certificate Authority. It allows you to create valid certificates for the websites that you control. By following and implementing a certain protocol, your identity is checked and a certificate will be issued. The certificates are free of charge and this is done to stimulate the use of authorised certificates and to lower the use of self-signed certificates on the internet. Certificates are valid for 90 days, so they need to be automatically renewed. (Which makes sure that the proof of identity/ownership also takes place frequently)
|
||||
|
@ -1,12 +1,12 @@
|
||||
= Signing
|
||||
= Signing
|
||||
|
||||
A signature is a hash that can be used to check the validity of some data. The signature can be supplied separately from the data that it validates, or in the case of CMS or SOAP can be included in the same file. (Where parts of that file contain the data and parts contain the signature).
|
||||
|
||||
Signing is used when integrity is important. It is meant to be a guarantee that data sent from Party-A to Party-B was not altered. So Party-A signs the data by calculating the hash of the data and encrypting that hash using an asymmetric private key. Party-B can then verify the data by calculating the hash of the data and decrypting the signature to compare if both hashes are the same.
|
||||
|
||||
== RAW signatures
|
||||
|
||||
A raw signature is usually calculated by Party-A as follows:
|
||||
== RAW signatures
|
||||
|
||||
A raw signature is usually calculated by Party-A as follows:
|
||||
|
||||
* create a hash of the data (e.g. SHA-256 hash)
|
||||
* encrypt the hash using an asymmetric private key (e.g. RSA 2048 bit key)
|
||||
@ -20,7 +20,7 @@ A CMS signature is a standardized way to send data + signature + certificate wit
|
||||
|
||||
== SOAP signatures
|
||||
|
||||
A SOAP signature also contains data and the signature and optionally the certificate. All in one XML payload. There are special steps involved in calculating the hash of the data. This has to do with the fact that the SOAP XML sent from system to system might introduce extra elements or timestamps.
|
||||
A SOAP signature also contains data and the signature and optionally the certificate. All in one XML payload. There are special steps involved in calculating the hash of the data. This has to do with the fact that the SOAP XML sent from system to system might introduce extra elements or timestamps.
|
||||
Also, SOAP Signing offers the possibility to sign different parts of the message by different parties.
|
||||
|
||||
|
||||
@ -36,5 +36,3 @@ Governments usually send official documents with a PDF that contains a certifica
|
||||
== 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.
|
||||
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
<header>
|
||||
<script>
|
||||
/**
|
||||
* JavaScript to load initial assignment tokens
|
||||
* JavaScript to load initial assignment tokens
|
||||
*/
|
||||
function initialise() {
|
||||
$("#sha256token").load('crypto/hashing/sha256');
|
||||
@ -29,15 +29,15 @@ $(document).ready(initialise);
|
||||
Now suppose you have intercepted the following header:<br/>
|
||||
<div id="basicauthtoken" ></div><br/>
|
||||
<form class="attack-form" method="POST" name="form" action="crypto/encoding/basic-auth">
|
||||
Then what was the username
|
||||
Then what was the username
|
||||
<input name="answer_user" value="" type="TEXT"/>
|
||||
and what was the password:
|
||||
and what was the password:
|
||||
<input name="answer_pwd" value="" type="TEXT"/>
|
||||
<input name="SUBMIT" value="post the answer" type="SUBMIT"/>
|
||||
</form>
|
||||
<div class="attack-feedback"></div>
|
||||
<div class="attack-output"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 3. encoding xor -->
|
||||
<div class="lesson-page-wrapper">
|
||||
@ -71,9 +71,9 @@ $(document).ready(initialise);
|
||||
</form>
|
||||
<div class="attack-feedback"></div>
|
||||
<div class="attack-output"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 5. encryption -->
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="~{doc:lessons/cryptography/documentation/encryption.adoc}"></div>
|
||||
@ -88,9 +88,9 @@ $(document).ready(initialise);
|
||||
Now suppose you have the following private key:<br/>
|
||||
<pre><div id="privatekey" ></div></pre><br/>
|
||||
<form class="attack-form" method="POST" name="form" action="crypto/signing/verify">
|
||||
Then what was the modulus of the public key
|
||||
Then what was the modulus of the public key
|
||||
<input name="modulus" value="" type="TEXT"/>
|
||||
and now provide a signature for us based on that modulus
|
||||
and now provide a signature for us based on that modulus
|
||||
<input name="signature" value="" type="TEXT"/>
|
||||
<input name="SUBMIT" value="post the answer" type="SUBMIT"/>
|
||||
</form>
|
||||
@ -98,12 +98,12 @@ $(document).ready(initialise);
|
||||
<div class="attack-output"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 7. keystores -->
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="~{doc:lessons/cryptography/documentation/keystores.adoc}"></div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 8. security defaults -->
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="~{doc:lessons/cryptography/documentation/defaults.adoc}"></div>
|
||||
|
@ -12,9 +12,9 @@ crypto-hashing.hints.2=Find a online hash database or just google on the hash it
|
||||
|
||||
crypto-signing.hints.1=Use openssl to get the public key from the private key. Apparently both private and public key information are stored.
|
||||
crypto-signing.hints.2=Use the private key to sign the "modulus" value of the public key.
|
||||
crypto-signing.hints.3=Actually the "modulus" of the public key is the same as the private key. You could use openssl rsa -in test.key -pubout > test.pub and then openssl rsa -in test.pub -pubin -modulus -noout or other components.
|
||||
crypto-signing.hints.3=Actually the "modulus" of the public key is the same as the private key. You could use openssl rsa -in test.key -pubout > test.pub and then openssl rsa -in test.pub -pubin -modulus -noout or other components.
|
||||
crypto-signing.hints.4=Make sure that you do not take hidden characters into account. You might want to use echo -n "00AE89..." | openssl dgst -sign somekey -sha256 ... and do not forget to base64 encode the outcome
|
||||
|
||||
|
||||
|
||||
crypto-signing.notok=The signature does not match the data (modulus)
|
||||
crypto-signing.modulusnotok=The modulus is not correct
|
||||
|
@ -72,4 +72,4 @@
|
||||
}
|
||||
.post .post-footer .comments-list .comment > .comments-list {
|
||||
margin-left: 50px;
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,3 @@
|
||||
== Confirm Flag
|
||||
|
||||
Confirm the flag you should have gotten on the previous page below.
|
||||
Confirm the flag you should have gotten on the previous page below.
|
||||
|
@ -20,4 +20,4 @@ POST /csrf/feedback/message HTTP/1.1
|
||||
More information can be found http://pentestmonkey.net/blog/csrf-xml-post-request[here]
|
||||
|
||||
Remember you need to make the call from another origin (WebWolf can help here) and you need to be logged in into
|
||||
WebGoat.
|
||||
WebGoat.
|
||||
|
@ -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.
|
||||
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]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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.
|
||||
Of course in most cases the website might have multiple controls to approve the request.
|
||||
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
== Basic Get CSRF Exercise
|
||||
|
||||
Trigger the form below from an external source while logged in. The response will include a 'flag' (a numeric value).
|
||||
|
||||
|
@ -43,4 +43,4 @@ ____
|
||||
|
||||
{nbsp} +
|
||||
Both Firefox and Chrome fixed this issue, but it shows why you should implement a CSRF protection instead
|
||||
of relying on the content-type of your APIs.
|
||||
of relying on the content-type of your APIs.
|
||||
|
@ -2,11 +2,11 @@
|
||||
|
||||
== Login CSRF attack
|
||||
|
||||
In a login CSRF attack, the attacker forges a login request to an honest site using the attacker’s username
|
||||
and password at that site. If the forgery succeeds, the honest server responds with a `Set-Cookie` header
|
||||
In a login CSRF attack, the attacker forges a login request to an honest site using the attacker’s username
|
||||
and password at that site. If the forgery succeeds, the honest server responds with a `Set-Cookie` header
|
||||
that instructs the browser to mutate its state by storing a session cookie, logging the user into
|
||||
the honest site as the attacker. This session cookie is used to bind subsequent requests to the user's session and hence
|
||||
to the attacker's authentication credentials. Login CSRF attacks can have serious consequences, for example
|
||||
to the attacker's authentication credentials. Login CSRF attacks can have serious consequences, for example
|
||||
see the picture below where an attacker created an account at google.com the victim visits the malicious
|
||||
website and the user is logged in as the attacker. The attacker could then later on gather information about
|
||||
the activities of the user.
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user