Compare commits
154 Commits
v8.0.0.M13
...
v8.0.0.M22
Author | SHA1 | Date | |
---|---|---|---|
7b8e3cdb52 | |||
9be4361afc | |||
b0e3a06b50 | |||
9170dcb87f | |||
dc5f9880af | |||
ed490a5ecf | |||
81d6e12ae1 | |||
c3ee0b7662 | |||
959a3c6420 | |||
3fa10c4b10 | |||
ec225558b9 | |||
dd1009bc54 | |||
bf45a0a8e5 | |||
f81a6852db | |||
6699456ee1 | |||
ecbbb5258e | |||
1520c7571f | |||
5921a06747 | |||
b6e4995d11 | |||
a2f28460c0 | |||
0797c3e2bf | |||
f9a4061604 | |||
580e50f558 | |||
3d58049af6 | |||
bca8b3c650 | |||
1252e3dc21 | |||
63a50df7a1 | |||
f9e552f1cd | |||
2233550fe1 | |||
cb18295f9f | |||
651698d96c | |||
4d7d0058c3 | |||
e3fba396de | |||
3536fd0b6d | |||
bc84e8f207 | |||
14dbd47675 | |||
898dd90c6f | |||
ac12a009e4 | |||
699b1bfd89 | |||
ad77a7ab24 | |||
b7278590f5 | |||
9dd93d88d9 | |||
4c767cb977 | |||
12123ef13b | |||
c7da546249 | |||
a41ff0083c | |||
701a99cf8f | |||
844808bfa7 | |||
81aac93dfe | |||
e5ec2c1ee0 | |||
b0fbeaff2c | |||
b47bb96534 | |||
3b9b695ef1 | |||
1d2575a211 | |||
56fc983414 | |||
268adbcf7e | |||
f383454440 | |||
bae3e75ae2 | |||
a7b82985d4 | |||
3d282e163c | |||
7068c84c6a | |||
0030c7bdfb | |||
89f6a73275 | |||
cf0e4e40cf | |||
dfd51f8b54 | |||
5e8c610fbf | |||
71514fc39b | |||
1734170e9e | |||
c89afe6334 | |||
9af0054b5b | |||
26aa72e721 | |||
c510bd9bf1 | |||
6bf853d953 | |||
b298440985 | |||
c7a714a590 | |||
93620f148b | |||
ecb7688e08 | |||
0de784eb32 | |||
4691bc5fd5 | |||
fc2c99bcb4 | |||
7292a577e3 | |||
396c1c1d47 | |||
2911788679 | |||
985148ede3 | |||
9587550bc5 | |||
9a0995dae5 | |||
4e07e0ebfa | |||
6e95fdfe56 | |||
e045bc692d | |||
589872ad47 | |||
5f4889cefe | |||
55793dd153 | |||
1edceb0aa8 | |||
d2b6725f3b | |||
6e003bc088 | |||
f8a7a61e85 | |||
eaf68d38c5 | |||
8d7ecb19d7 | |||
e0cf5b4a84 | |||
5b524d3a94 | |||
dda6f674a3 | |||
e06d4642eb | |||
4a8fdcf887 | |||
fd96ba18f1 | |||
60ef35e241 | |||
9d7886d572 | |||
7a0820bf89 | |||
ea9c1a453d | |||
63ca11a1bb | |||
5378d72600 | |||
93d6d0e6b7 | |||
84860e65f6 | |||
a73bf58d36 | |||
0ff6000511 | |||
91d9db5f80 | |||
ac1b9e8311 | |||
9d49373486 | |||
ead78d40e6 | |||
7b5bb6d6f1 | |||
408a637649 | |||
e96ab488ff | |||
31f7ea6985 | |||
6cf96f971d | |||
0b9a027c19 | |||
186f24f1df | |||
089dd56a15 | |||
6cfefba0ee | |||
20e45da8ae | |||
e34faa13d6 | |||
927bbad488 | |||
6a5ca43e7e | |||
5d28ef9fbe | |||
9aa674e326 | |||
84e3fcde07 | |||
6209b3fe8d | |||
a1db8e8bd9 | |||
6b4a488c8c | |||
0e160c19f5 | |||
8050a2b56d | |||
11ffa5702c | |||
32927c8109 | |||
8b8a89a8ab | |||
e4ca0c4836 | |||
e422da4c64 | |||
76daac0db5 | |||
245ba2c3d1 | |||
672d78eebc | |||
f4eb96fc6a | |||
46fedf3764 | |||
f30db3abfc | |||
a922c00182 | |||
f21fe7f2c3 | |||
3cd349bb4b | |||
e3e7ed004f |
9
.gitignore
vendored
9
.gitignore
vendored
@ -42,3 +42,12 @@ webgoat-lessons/**/target
|
|||||||
**/.DS_Store
|
**/.DS_Store
|
||||||
webgoat-server/mongo-data/*
|
webgoat-server/mongo-data/*
|
||||||
webgoat-lessons/vulnerable-components/dependency-reduced-pom.xml
|
webgoat-lessons/vulnerable-components/dependency-reduced-pom.xml
|
||||||
|
**/.sts4-cache/*
|
||||||
|
**/.vscode/*
|
||||||
|
**/.factorypath
|
||||||
|
/.sonatype
|
||||||
|
**/bin/*
|
||||||
|
webgoat.lck
|
||||||
|
webgoat.log
|
||||||
|
webgoat.properties
|
||||||
|
webgoat.script
|
1
.mvn/wrapper/maven-wrapper.properties
vendored
Normal file
1
.mvn/wrapper/maven-wrapper.properties
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip
|
@ -2,7 +2,7 @@ services:
|
|||||||
- docker
|
- docker
|
||||||
language: java
|
language: java
|
||||||
jdk:
|
jdk:
|
||||||
- oraclejdk8
|
- openjdk11
|
||||||
install: "/bin/true"
|
install: "/bin/true"
|
||||||
script:
|
script:
|
||||||
- export BRANCH=$(if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then echo $TRAVIS_BRANCH; else echo $TRAVIS_PULL_REQUEST_BRANCH; fi)
|
- export BRANCH=$(if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then echo $TRAVIS_BRANCH; else echo $TRAVIS_PULL_REQUEST_BRANCH; fi)
|
||||||
@ -28,12 +28,6 @@ deploy:
|
|||||||
on:
|
on:
|
||||||
repo: WebGoat/WebGoat
|
repo: WebGoat/WebGoat
|
||||||
tags: true
|
tags: true
|
||||||
- provider: script
|
|
||||||
skip_cleanup: true
|
|
||||||
script: bash scripts/deploy-webgoat.sh
|
|
||||||
on:
|
|
||||||
repo: WebGoat/WebGoat
|
|
||||||
branch: develop
|
|
||||||
- provider: releases
|
- provider: releases
|
||||||
skip_cleanup: true
|
skip_cleanup: true
|
||||||
overwrite: true
|
overwrite: true
|
||||||
|
@ -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.M3
|
|
||||||
git push origin v8.0.0.M3
|
|
||||||
```
|
```
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
|
|
||||||
|
60
README.MD
60
README.MD
@ -29,61 +29,47 @@ first thing that all hackers claim.*
|
|||||||
|
|
||||||
# Run Instructions:
|
# Run Instructions:
|
||||||
|
|
||||||
## 1. Run using Docker
|
## 1. Standalone
|
||||||
|
|
||||||
From time to time we publish a new development preview of WebGoat 8 on Docker HUB, you can download this version
|
Download the latest WebGoat release from [https://github.com/WebGoat/WebGoat/releases](https://github.com/WebGoat/WebGoat/releases)
|
||||||
[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
|
```Shell
|
||||||
docker pull webgoat/webgoat-8.0
|
java -jar webgoat-server-8.0.0.VERSION.jar [--server.port=8080] [--server.address=localhost]
|
||||||
docker run -p 8080:8080 -it webgoat/webgoat-8.0 /home/webgoat/start.sh
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Wait for the Docker container to start, and run `docker ps` to verify it's running.
|
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)
|
||||||
|
|
||||||
- If you are using `docker-machine`, verify the machine IP using `docker-machine env`
|
If you use Java 9 or higher you need to run WebGoat as follows:
|
||||||
- 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._
|
|
||||||
|
|
||||||
## 2. Standalone
|
|
||||||
|
|
||||||
Download the latest WebWolf release from [https://github.com/WebGoat/WebGoat/releases](https://github.com/WebGoat/WebGoat/releases)
|
|
||||||
|
|
||||||
```Shell
|
```Shell
|
||||||
java -jar webgoat-server-<<version>>.jar
|
java --add-modules java.xml.bind -jar webgoat-server-8.0.0.VERSION.jar
|
||||||
```
|
```
|
||||||
|
|
||||||
By default WebGoat starts at port 8080 in order to change this use the following property:
|
## 2. Run using Docker
|
||||||
|
|
||||||
```Shell
|
Every release is also published on [DockerHub]((https://hub.docker.com/r/webgoat/webgoat-8.0/)).
|
||||||
java -jar webgoat-server-<<version>>.jar --server.port=9090
|
|
||||||
|
### Using docker-compose
|
||||||
|
|
||||||
|
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
|
||||||
```
|
```
|
||||||
|
|
||||||
You can specify one of the following arguments when starting WebGoat:
|
**Important**: the current directory on your host will be mapped into the container for keeping state.
|
||||||
|
|
||||||
```Shell
|
Using the `docker-compose` file will simplify getting WebGoat and WebWolf up and running.
|
||||||
java -jar webgoat-server-<<version>>.jar --server.port=9090 --server.address=x.x.x.x
|
|
||||||
```
|
|
||||||
|
|
||||||
This will start WebGoat on a different port and/or different address.
|
|
||||||
|
|
||||||
|
|
||||||
## 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
|
||||||
@ -118,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
|
||||||
@ -126,7 +112,7 @@ We supply a complete development environment using Vagrant, to run WebGoat with
|
|||||||
```
|
```
|
||||||
|
|
||||||
Once the provisioning is complete login to the Virtualbox with username vagrant and password vagrant.
|
Once the provisioning is complete login to the Virtualbox with username vagrant and password vagrant.
|
||||||
The source code will be available in the home directory.
|
WebGoat and WebWolf will automatically start when you login to this image.
|
||||||
|
|
||||||
|
|
||||||
# Building a new Docker image
|
# Building a new Docker image
|
||||||
|
13
docker-compose-local.yml
Normal file
13
docker-compose-local.yml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
version: '2.1'
|
||||||
|
|
||||||
|
services:
|
||||||
|
webgoat:
|
||||||
|
image: webgoat/webgoat-v8.0.0.snapshot
|
||||||
|
extends:
|
||||||
|
file: docker-compose.yml
|
||||||
|
service: webgoat
|
||||||
|
webwolf:
|
||||||
|
extends:
|
||||||
|
file: docker-compose.yml
|
||||||
|
service: webwolf
|
||||||
|
image: webgoat/webwolf-v8.0.0.snapshot
|
40
docker-compose-postgres.yml
Normal file
40
docker-compose-postgres.yml
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
version: '2.0'
|
||||||
|
|
||||||
|
services:
|
||||||
|
webgoat:
|
||||||
|
image: webgoat/webgoat-8.0
|
||||||
|
user: webgoat
|
||||||
|
environment:
|
||||||
|
- WEBWOLF_HOST=webwolf
|
||||||
|
- WEBWOLF_PORT=9090
|
||||||
|
- spring.datasource.url=jdbc:postgresql://webgoat_db:5432/webgoat
|
||||||
|
- spring.datasource.username=webgoat
|
||||||
|
- spring.datasource.password=webgoat
|
||||||
|
- spring.datasource.driver-class-name=org.postgresql.Driver
|
||||||
|
- spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL94Dialect
|
||||||
|
- webgoat.server.directory=/home/webgoat/.webgoat/
|
||||||
|
- webgoat.user.directory=/home/webgoat/.webgoat/
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
|
webwolf:
|
||||||
|
image: webgoat/webwolf
|
||||||
|
environment:
|
||||||
|
- spring.datasource.url=jdbc:postgresql://webgoat_db:5432/webgoat
|
||||||
|
- spring.datasource.username=webgoat
|
||||||
|
- spring.datasource.password=webgoat
|
||||||
|
- spring.datasource.driver-class-name=org.postgresql.Driver
|
||||||
|
- spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL94Dialect
|
||||||
|
ports:
|
||||||
|
- "9090:9090"
|
||||||
|
webgoat_db:
|
||||||
|
image: postgres:9.4
|
||||||
|
# Uncomment to store the state of the database on the host.
|
||||||
|
# volumes:
|
||||||
|
# - ./database:/var/lib/postgresql
|
||||||
|
environment:
|
||||||
|
- POSTGRES_PASSWORD=webgoat
|
||||||
|
- POSTGRES_USER=webgoat
|
||||||
|
- POSTGRES_DB=webgoat
|
||||||
|
ports:
|
||||||
|
- "5432:5432"
|
||||||
|
|
@ -1,15 +1,18 @@
|
|||||||
version: '2.0'
|
version: '2.1'
|
||||||
|
|
||||||
services:
|
services:
|
||||||
webgoat:
|
webgoat:
|
||||||
build: webgoat-server/
|
image: webgoat/webgoat-8.0
|
||||||
command: "sh /home/webgoat/start.sh"
|
environment:
|
||||||
|
- WEBWOLF_HOST=webwolf
|
||||||
|
- WEBWOLF_PORT=9090
|
||||||
ports:
|
ports:
|
||||||
- "8080:8080"
|
- "8080:8080"
|
||||||
|
- "9001:9001"
|
||||||
|
volumes:
|
||||||
|
- .:/home/webgoat/.webgoat
|
||||||
webwolf:
|
webwolf:
|
||||||
build: webwolf/
|
image: webgoat/webwolf
|
||||||
command: "sh /home/webwolf/start.sh"
|
|
||||||
depends_on:
|
|
||||||
- webgoat
|
|
||||||
ports:
|
ports:
|
||||||
- "8081:8081"
|
- "9090:9090"
|
||||||
|
command: --spring.datasource.url=jdbc:hsqldb:hsql://webgoat:9001/webgoat --server.address=0.0.0.0
|
286
mvnw
vendored
Executable file
286
mvnw
vendored
Executable file
@ -0,0 +1,286 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
# Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
# or more contributor license agreements. See the NOTICE file
|
||||||
|
# distributed with this work for additional information
|
||||||
|
# regarding copyright ownership. The ASF licenses this file
|
||||||
|
# to you under the Apache License, Version 2.0 (the
|
||||||
|
# "License"); you may not use this file except in compliance
|
||||||
|
# with the License. You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing,
|
||||||
|
# software distributed under the License is distributed on an
|
||||||
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
# KIND, either express or implied. See the License for the
|
||||||
|
# specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
# Maven2 Start Up Batch script
|
||||||
|
#
|
||||||
|
# Required ENV vars:
|
||||||
|
# ------------------
|
||||||
|
# JAVA_HOME - location of a JDK home dir
|
||||||
|
#
|
||||||
|
# Optional ENV vars
|
||||||
|
# -----------------
|
||||||
|
# M2_HOME - location of maven2's installed home dir
|
||||||
|
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||||
|
# e.g. to debug Maven itself, use
|
||||||
|
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||||
|
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
if [ -z "$MAVEN_SKIP_RC" ] ; then
|
||||||
|
|
||||||
|
if [ -f /etc/mavenrc ] ; then
|
||||||
|
. /etc/mavenrc
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f "$HOME/.mavenrc" ] ; then
|
||||||
|
. "$HOME/.mavenrc"
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
# OS specific support. $var _must_ be set to either true or false.
|
||||||
|
cygwin=false;
|
||||||
|
darwin=false;
|
||||||
|
mingw=false
|
||||||
|
case "`uname`" in
|
||||||
|
CYGWIN*) cygwin=true ;;
|
||||||
|
MINGW*) mingw=true;;
|
||||||
|
Darwin*) darwin=true
|
||||||
|
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
|
||||||
|
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
|
||||||
|
if [ -z "$JAVA_HOME" ]; then
|
||||||
|
if [ -x "/usr/libexec/java_home" ]; then
|
||||||
|
export JAVA_HOME="`/usr/libexec/java_home`"
|
||||||
|
else
|
||||||
|
export JAVA_HOME="/Library/Java/Home"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ -z "$JAVA_HOME" ] ; then
|
||||||
|
if [ -r /etc/gentoo-release ] ; then
|
||||||
|
JAVA_HOME=`java-config --jre-home`
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$M2_HOME" ] ; then
|
||||||
|
## resolve links - $0 may be a link to maven's home
|
||||||
|
PRG="$0"
|
||||||
|
|
||||||
|
# need this for relative symlinks
|
||||||
|
while [ -h "$PRG" ] ; do
|
||||||
|
ls=`ls -ld "$PRG"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
PRG="$link"
|
||||||
|
else
|
||||||
|
PRG="`dirname "$PRG"`/$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
saveddir=`pwd`
|
||||||
|
|
||||||
|
M2_HOME=`dirname "$PRG"`/..
|
||||||
|
|
||||||
|
# make it fully qualified
|
||||||
|
M2_HOME=`cd "$M2_HOME" && pwd`
|
||||||
|
|
||||||
|
cd "$saveddir"
|
||||||
|
# echo Using m2 at $M2_HOME
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Cygwin, ensure paths are in UNIX format before anything is touched
|
||||||
|
if $cygwin ; then
|
||||||
|
[ -n "$M2_HOME" ] &&
|
||||||
|
M2_HOME=`cygpath --unix "$M2_HOME"`
|
||||||
|
[ -n "$JAVA_HOME" ] &&
|
||||||
|
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||||
|
[ -n "$CLASSPATH" ] &&
|
||||||
|
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Mingw, ensure paths are in UNIX format before anything is touched
|
||||||
|
if $mingw ; then
|
||||||
|
[ -n "$M2_HOME" ] &&
|
||||||
|
M2_HOME="`(cd "$M2_HOME"; pwd)`"
|
||||||
|
[ -n "$JAVA_HOME" ] &&
|
||||||
|
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
|
||||||
|
# TODO classpath?
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$JAVA_HOME" ]; then
|
||||||
|
javaExecutable="`which javac`"
|
||||||
|
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
|
||||||
|
# readlink(1) is not available as standard on Solaris 10.
|
||||||
|
readLink=`which readlink`
|
||||||
|
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
|
||||||
|
if $darwin ; then
|
||||||
|
javaHome="`dirname \"$javaExecutable\"`"
|
||||||
|
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
|
||||||
|
else
|
||||||
|
javaExecutable="`readlink -f \"$javaExecutable\"`"
|
||||||
|
fi
|
||||||
|
javaHome="`dirname \"$javaExecutable\"`"
|
||||||
|
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
|
||||||
|
JAVA_HOME="$javaHome"
|
||||||
|
export JAVA_HOME
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$JAVACMD" ] ; then
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||||
|
else
|
||||||
|
JAVACMD="$JAVA_HOME/bin/java"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD="`which java`"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
echo "Error: JAVA_HOME is not defined correctly." >&2
|
||||||
|
echo " We cannot execute $JAVACMD" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$JAVA_HOME" ] ; then
|
||||||
|
echo "Warning: JAVA_HOME environment variable is not set."
|
||||||
|
fi
|
||||||
|
|
||||||
|
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
|
||||||
|
|
||||||
|
# traverses directory structure from process work directory to filesystem root
|
||||||
|
# first directory with .mvn subdirectory is considered project base directory
|
||||||
|
find_maven_basedir() {
|
||||||
|
|
||||||
|
if [ -z "$1" ]
|
||||||
|
then
|
||||||
|
echo "Path not specified to find_maven_basedir"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
basedir="$1"
|
||||||
|
wdir="$1"
|
||||||
|
while [ "$wdir" != '/' ] ; do
|
||||||
|
if [ -d "$wdir"/.mvn ] ; then
|
||||||
|
basedir=$wdir
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
|
||||||
|
if [ -d "${wdir}" ]; then
|
||||||
|
wdir=`cd "$wdir/.."; pwd`
|
||||||
|
fi
|
||||||
|
# end of workaround
|
||||||
|
done
|
||||||
|
echo "${basedir}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# concatenates all lines of a file
|
||||||
|
concat_lines() {
|
||||||
|
if [ -f "$1" ]; then
|
||||||
|
echo "$(tr -s '\n' ' ' < "$1")"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
BASE_DIR=`find_maven_basedir "$(pwd)"`
|
||||||
|
if [ -z "$BASE_DIR" ]; then
|
||||||
|
exit 1;
|
||||||
|
fi
|
||||||
|
|
||||||
|
##########################################################################################
|
||||||
|
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||||
|
# This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||||
|
##########################################################################################
|
||||||
|
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
|
||||||
|
if [ "$MVNW_VERBOSE" = true ]; then
|
||||||
|
echo "Found .mvn/wrapper/maven-wrapper.jar"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [ "$MVNW_VERBOSE" = true ]; then
|
||||||
|
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
|
||||||
|
fi
|
||||||
|
jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"
|
||||||
|
while IFS="=" read key value; do
|
||||||
|
case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
|
||||||
|
esac
|
||||||
|
done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
|
||||||
|
if [ "$MVNW_VERBOSE" = true ]; then
|
||||||
|
echo "Downloading from: $jarUrl"
|
||||||
|
fi
|
||||||
|
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
|
||||||
|
|
||||||
|
if command -v wget > /dev/null; then
|
||||||
|
if [ "$MVNW_VERBOSE" = true ]; then
|
||||||
|
echo "Found wget ... using wget"
|
||||||
|
fi
|
||||||
|
wget "$jarUrl" -O "$wrapperJarPath"
|
||||||
|
elif command -v curl > /dev/null; then
|
||||||
|
if [ "$MVNW_VERBOSE" = true ]; then
|
||||||
|
echo "Found curl ... using curl"
|
||||||
|
fi
|
||||||
|
curl -o "$wrapperJarPath" "$jarUrl"
|
||||||
|
else
|
||||||
|
if [ "$MVNW_VERBOSE" = true ]; then
|
||||||
|
echo "Falling back to using Java to download"
|
||||||
|
fi
|
||||||
|
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
|
||||||
|
if [ -e "$javaClass" ]; then
|
||||||
|
if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
|
||||||
|
if [ "$MVNW_VERBOSE" = true ]; then
|
||||||
|
echo " - Compiling MavenWrapperDownloader.java ..."
|
||||||
|
fi
|
||||||
|
# Compiling the Java class
|
||||||
|
("$JAVA_HOME/bin/javac" "$javaClass")
|
||||||
|
fi
|
||||||
|
if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
|
||||||
|
# Running the downloader
|
||||||
|
if [ "$MVNW_VERBOSE" = true ]; then
|
||||||
|
echo " - Running MavenWrapperDownloader.java ..."
|
||||||
|
fi
|
||||||
|
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
##########################################################################################
|
||||||
|
# End of extension
|
||||||
|
##########################################################################################
|
||||||
|
|
||||||
|
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
|
||||||
|
if [ "$MVNW_VERBOSE" = true ]; then
|
||||||
|
echo $MAVEN_PROJECTBASEDIR
|
||||||
|
fi
|
||||||
|
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
|
||||||
|
|
||||||
|
# For Cygwin, switch paths to Windows format before running java
|
||||||
|
if $cygwin; then
|
||||||
|
[ -n "$M2_HOME" ] &&
|
||||||
|
M2_HOME=`cygpath --path --windows "$M2_HOME"`
|
||||||
|
[ -n "$JAVA_HOME" ] &&
|
||||||
|
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
|
||||||
|
[ -n "$CLASSPATH" ] &&
|
||||||
|
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
|
||||||
|
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
|
||||||
|
MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
|
||||||
|
fi
|
||||||
|
|
||||||
|
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||||
|
|
||||||
|
exec "$JAVACMD" \
|
||||||
|
$MAVEN_OPTS \
|
||||||
|
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
|
||||||
|
"-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
|
||||||
|
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
|
161
mvnw.cmd
vendored
Normal file
161
mvnw.cmd
vendored
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
@REM ----------------------------------------------------------------------------
|
||||||
|
@REM Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
@REM or more contributor license agreements. See the NOTICE file
|
||||||
|
@REM distributed with this work for additional information
|
||||||
|
@REM regarding copyright ownership. The ASF licenses this file
|
||||||
|
@REM to you under the Apache License, Version 2.0 (the
|
||||||
|
@REM "License"); you may not use this file except in compliance
|
||||||
|
@REM with the License. You may obtain a copy of the License at
|
||||||
|
@REM
|
||||||
|
@REM http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
@REM
|
||||||
|
@REM Unless required by applicable law or agreed to in writing,
|
||||||
|
@REM software distributed under the License is distributed on an
|
||||||
|
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
@REM KIND, either express or implied. See the License for the
|
||||||
|
@REM specific language governing permissions and limitations
|
||||||
|
@REM under the License.
|
||||||
|
@REM ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@REM ----------------------------------------------------------------------------
|
||||||
|
@REM Maven2 Start Up Batch script
|
||||||
|
@REM
|
||||||
|
@REM Required ENV vars:
|
||||||
|
@REM JAVA_HOME - location of a JDK home dir
|
||||||
|
@REM
|
||||||
|
@REM Optional ENV vars
|
||||||
|
@REM M2_HOME - location of maven2's installed home dir
|
||||||
|
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
|
||||||
|
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
|
||||||
|
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||||
|
@REM e.g. to debug Maven itself, use
|
||||||
|
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||||
|
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||||
|
@REM ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
|
||||||
|
@echo off
|
||||||
|
@REM set title of command window
|
||||||
|
title %0
|
||||||
|
@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
|
||||||
|
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
|
||||||
|
|
||||||
|
@REM set %HOME% to equivalent of $HOME
|
||||||
|
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
|
||||||
|
|
||||||
|
@REM Execute a user defined script before this one
|
||||||
|
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
|
||||||
|
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
|
||||||
|
if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
|
||||||
|
if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
|
||||||
|
:skipRcPre
|
||||||
|
|
||||||
|
@setlocal
|
||||||
|
|
||||||
|
set ERROR_CODE=0
|
||||||
|
|
||||||
|
@REM To isolate internal variables from possible post scripts, we use another setlocal
|
||||||
|
@setlocal
|
||||||
|
|
||||||
|
@REM ==== START VALIDATION ====
|
||||||
|
if not "%JAVA_HOME%" == "" goto OkJHome
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo Error: JAVA_HOME not found in your environment. >&2
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||||
|
echo location of your Java installation. >&2
|
||||||
|
echo.
|
||||||
|
goto error
|
||||||
|
|
||||||
|
:OkJHome
|
||||||
|
if exist "%JAVA_HOME%\bin\java.exe" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo Error: JAVA_HOME is set to an invalid directory. >&2
|
||||||
|
echo JAVA_HOME = "%JAVA_HOME%" >&2
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||||
|
echo location of your Java installation. >&2
|
||||||
|
echo.
|
||||||
|
goto error
|
||||||
|
|
||||||
|
@REM ==== END VALIDATION ====
|
||||||
|
|
||||||
|
:init
|
||||||
|
|
||||||
|
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
|
||||||
|
@REM Fallback to current working directory if not found.
|
||||||
|
|
||||||
|
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
|
||||||
|
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
|
||||||
|
|
||||||
|
set EXEC_DIR=%CD%
|
||||||
|
set WDIR=%EXEC_DIR%
|
||||||
|
:findBaseDir
|
||||||
|
IF EXIST "%WDIR%"\.mvn goto baseDirFound
|
||||||
|
cd ..
|
||||||
|
IF "%WDIR%"=="%CD%" goto baseDirNotFound
|
||||||
|
set WDIR=%CD%
|
||||||
|
goto findBaseDir
|
||||||
|
|
||||||
|
:baseDirFound
|
||||||
|
set MAVEN_PROJECTBASEDIR=%WDIR%
|
||||||
|
cd "%EXEC_DIR%"
|
||||||
|
goto endDetectBaseDir
|
||||||
|
|
||||||
|
:baseDirNotFound
|
||||||
|
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
|
||||||
|
cd "%EXEC_DIR%"
|
||||||
|
|
||||||
|
:endDetectBaseDir
|
||||||
|
|
||||||
|
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
|
||||||
|
|
||||||
|
@setlocal EnableExtensions EnableDelayedExpansion
|
||||||
|
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
|
||||||
|
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
|
||||||
|
|
||||||
|
:endReadAdditionalConfig
|
||||||
|
|
||||||
|
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
|
||||||
|
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
|
||||||
|
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||||
|
|
||||||
|
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"
|
||||||
|
FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO (
|
||||||
|
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
|
||||||
|
)
|
||||||
|
|
||||||
|
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||||
|
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||||
|
if exist %WRAPPER_JAR% (
|
||||||
|
echo Found %WRAPPER_JAR%
|
||||||
|
) else (
|
||||||
|
echo Couldn't find %WRAPPER_JAR%, downloading it ...
|
||||||
|
echo Downloading from: %DOWNLOAD_URL%
|
||||||
|
powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"
|
||||||
|
echo Finished downloading %WRAPPER_JAR%
|
||||||
|
)
|
||||||
|
@REM End of extension
|
||||||
|
|
||||||
|
%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
|
||||||
|
if ERRORLEVEL 1 goto error
|
||||||
|
goto end
|
||||||
|
|
||||||
|
:error
|
||||||
|
set ERROR_CODE=1
|
||||||
|
|
||||||
|
:end
|
||||||
|
@endlocal & set ERROR_CODE=%ERROR_CODE%
|
||||||
|
|
||||||
|
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
|
||||||
|
@REM check for post script, once with legacy .bat ending and once with .cmd ending
|
||||||
|
if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
|
||||||
|
if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
|
||||||
|
:skipRcPost
|
||||||
|
|
||||||
|
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
|
||||||
|
if "%MAVEN_BATCH_PAUSE%" == "on" pause
|
||||||
|
|
||||||
|
if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
|
||||||
|
|
||||||
|
exit /B %ERROR_CODE%
|
4
platformQuickStarts/GCP/GKE-Docker/deploy.cfg
Normal file
4
platformQuickStarts/GCP/GKE-Docker/deploy.cfg
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
CURTAG=webgoat/webgoat-8.0
|
||||||
|
DEST_TAG=gcr.io/astech-training/raging-wire-webgoat
|
||||||
|
CLUSTER_NAME=raging-wire-webgoat
|
||||||
|
PORT_NUM=8080
|
4
platformQuickStarts/GCP/GKE-Docker/gke-deploy-config.sh
Normal file
4
platformQuickStarts/GCP/GKE-Docker/gke-deploy-config.sh
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
CURTAG=webgoat/webgoat-8.0
|
||||||
|
DEST_TAG=gcr.io/your-gke-project/your-webgoat-tag
|
||||||
|
CLUSTER_NAME=your-cluster-name
|
||||||
|
PORT_NUM=8080
|
146
pom.xml
146
pom.xml
@ -1,11 +1,12 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<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>8.0.0.M3</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>
|
||||||
@ -20,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.9.RELEASE</version>
|
<version>1.5.18.RELEASE</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<licenses>
|
<licenses>
|
||||||
@ -106,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>
|
||||||
@ -128,42 +126,37 @@
|
|||||||
<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>
|
||||||
<gatling-plugin.version>2.2.4</gatling-plugin.version>
|
<gatling-plugin.version>2.2.4</gatling-plugin.version>
|
||||||
<guava.version>18.0</guava.version>
|
<guava.version>18.0</guava.version>
|
||||||
<h2.version>1.4.190</h2.version>
|
<h2.version>1.4.190</h2.version>
|
||||||
<hsqldb.version>2.3.2</hsqldb.version>
|
<hsqldb.version>2.3.4</hsqldb.version>
|
||||||
<j2h.version>1.3.1</j2h.version>
|
<j2h.version>1.3.1</j2h.version>
|
||||||
<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>
|
||||||
@ -199,103 +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>
|
||||||
@ -303,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>
|
||||||
@ -339,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>
|
||||||
|
|
||||||
|
34
scripts/build-all.sh
Executable file
34
scripts/build-all.sh
Executable file
@ -0,0 +1,34 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
nc -zv 127.0.0.1 8080 2>/dev/null
|
||||||
|
SUCCESS=$?
|
||||||
|
nc -zv 127.0.0.1 9090 2>/dev/null
|
||||||
|
SUCCESS=${SUCCESS}$?
|
||||||
|
|
||||||
|
if [[ "${SUCCESS}" -eq 0 ]] ; then
|
||||||
|
echo "WebGoat and or WebWolf are still running, please stop them first otherwise unit tests might fail!"
|
||||||
|
exit 127
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
sh mvnw clean install
|
||||||
|
if [[ "$?" -ne 0 ]] ; then
|
||||||
|
exit y$?
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd -
|
||||||
|
sh build_docker.sh
|
||||||
|
if [[ "$?" -ne 0 ]] ; then
|
||||||
|
exit y$?
|
||||||
|
fi
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
read -p "Do you want to run docker-compose?" yn
|
||||||
|
case ${yn} in
|
||||||
|
[Yy]* ) sh clean-run-docker-compose.sh; break;;
|
||||||
|
[Nn]* ) exit;;
|
||||||
|
* ) echo "Please answer yes or no.";;
|
||||||
|
esac
|
||||||
|
done
|
10
scripts/build_docker.sh
Normal file
10
scripts/build_docker.sh
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
WEBGOAT_HOME=$(pwd)/../
|
||||||
|
|
||||||
|
cd "${WEBGOAT_HOME}"/webgoat-server
|
||||||
|
docker build -t webgoat/webgoat-v8.0.0.snapshot .
|
||||||
|
|
||||||
|
cd "${WEBGOAT_HOME}"/webwolf
|
||||||
|
docker build -t webgoat/webwolf-v8.0.0.snapshot .
|
||||||
|
|
5
scripts/clean-run-docker-compose.sh
Normal file
5
scripts/clean-run-docker-compose.sh
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
docker-compose rm -f
|
||||||
|
docker-compose -f docker-compose-local.yml up
|
@ -6,14 +6,14 @@ 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
|
||||||
elif [ ! -z "${TRAVIS_TAG}" ]; then
|
#elif [ ! -z "${TRAVIS_TAG}" ]; then
|
||||||
# Creating a tag build we push it to Docker with that tag
|
# # Creating a tag build we push it to Docker with that tag
|
||||||
docker build --build-arg webgoat_version=${TRAVIS_TAG:1} -f Dockerfile -t $REPO:${TRAVIS_TAG} -t $REPO:latest .
|
# docker build --build-arg webgoat_version=${TRAVIS_TAG:1} -f Dockerfile -t $REPO:${TRAVIS_TAG} -t $REPO:latest .
|
||||||
docker push $REPO
|
# docker push $REPO
|
||||||
#elif [ "${BRANCH}" == "develop" ]; then
|
#elif [ "${BRANCH}" == "develop" ]; then
|
||||||
# docker build -f Dockerfile -t $REPO:snapshot .
|
# docker build -f Dockerfile -t $REPO:snapshot .
|
||||||
# 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
|
4
scripts/run-docker-compose.sh
Normal file
4
scripts/run-docker-compose.sh
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
docker-compose up
|
18
scripts/start.sh
Normal file
18
scripts/start.sh
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
DATABASE_PORT=9001
|
||||||
|
|
||||||
|
checkDatabaseAvailable(){
|
||||||
|
|
||||||
|
#for i in $(seq 1 5); do command && s=0 && break || s=$? && sleep 15; done; (exit $s)
|
||||||
|
local started = $(netstat -lnt | grep ${DATABASE_PORT})
|
||||||
|
echo $?
|
||||||
|
}
|
||||||
|
|
||||||
|
#java -Djava.security.egd=file:/dev/./urandom -jar home/webgoat/webgoat.jar --server.address=0.0.0.0
|
||||||
|
$(checkDatabaseAvailable)
|
||||||
|
|
||||||
|
|
||||||
|
#java -Djava.security.egd=file:/dev/./urandom -jar /home/webwolf/webwolf.jar --server.port=9090 --server.address=0.0.0.0
|
||||||
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.owasp.webgoat</groupId>
|
<groupId>org.owasp.webgoat</groupId>
|
||||||
<artifactId>webgoat-parent</artifactId>
|
<artifactId>webgoat-parent</artifactId>
|
||||||
<version>8.0.0.M3</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>
|
||||||
|
@ -35,7 +35,9 @@ import com.google.common.collect.Sets;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.asciidoctor.Asciidoctor;
|
import org.asciidoctor.Asciidoctor;
|
||||||
import org.asciidoctor.extension.JavaExtensionRegistry;
|
import org.asciidoctor.extension.JavaExtensionRegistry;
|
||||||
|
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;
|
||||||
@ -86,6 +88,8 @@ 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);
|
||||||
|
|
||||||
asciidoctor.convert(new InputStreamReader(is), writer, createAttributes());
|
asciidoctor.convert(new InputStreamReader(is), writer, createAttributes());
|
||||||
return new ByteArrayInputStream(writer.getBuffer().toString().getBytes(UTF_8));
|
return new ByteArrayInputStream(writer.getBuffer().toString().getBytes(UTF_8));
|
||||||
|
@ -130,6 +130,7 @@ public class MvcConfiguration extends WebMvcConfigurerAdapter {
|
|||||||
@Bean
|
@Bean
|
||||||
public PluginMessages pluginMessages(Messages messages, Language language) {
|
public PluginMessages pluginMessages(Messages messages, Language language) {
|
||||||
PluginMessages pluginMessages = new PluginMessages(messages, language);
|
PluginMessages pluginMessages = new PluginMessages(messages, language);
|
||||||
|
pluginMessages.setDefaultEncoding("UTF-8");
|
||||||
pluginMessages.setBasenames("i18n/WebGoatLabels");
|
pluginMessages.setBasenames("i18n/WebGoatLabels");
|
||||||
return pluginMessages;
|
return pluginMessages;
|
||||||
}
|
}
|
||||||
@ -142,6 +143,7 @@ public class MvcConfiguration extends WebMvcConfigurerAdapter {
|
|||||||
@Bean
|
@Bean
|
||||||
public Messages messageSource(Language language) {
|
public Messages messageSource(Language language) {
|
||||||
Messages messages = new Messages(language);
|
Messages messages = new Messages(language);
|
||||||
|
messages.setDefaultEncoding("UTF-8");
|
||||||
messages.setBasename("classpath:i18n/messages");
|
messages.setBasename("classpath:i18n/messages");
|
||||||
return messages;
|
return messages;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
package org.owasp.webgoat.asciidoc;
|
||||||
|
|
||||||
|
import org.asciidoctor.ast.AbstractBlock;
|
||||||
|
import org.asciidoctor.extension.InlineMacroProcessor;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
import org.springframework.web.context.request.RequestContextHolder;
|
||||||
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class WebGoatVersionMacro extends InlineMacroProcessor {
|
||||||
|
|
||||||
|
public WebGoatVersionMacro(String macroName, Map<String, Object> config) {
|
||||||
|
super(macroName, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String process(AbstractBlock parent, String target, Map<String, Object> attributes) {
|
||||||
|
return EnvironmentExposure.getEnv().getProperty("webgoat.build.version");
|
||||||
|
}
|
||||||
|
}
|
@ -10,6 +10,12 @@ import org.springframework.web.context.request.ServletRequestAttributes;
|
|||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import java.util.Map;
|
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 WebWolfMacro extends InlineMacroProcessor {
|
public class WebWolfMacro extends InlineMacroProcessor {
|
||||||
|
|
||||||
public WebWolfMacro(String macroName, Map<String, Object> config) {
|
public WebWolfMacro(String macroName, Map<String, Object> config) {
|
||||||
@ -20,9 +26,17 @@ public class WebWolfMacro extends InlineMacroProcessor {
|
|||||||
protected String process(AbstractBlock parent, String target, Map<String, Object> attributes) {
|
protected String process(AbstractBlock parent, String target, Map<String, Object> attributes) {
|
||||||
Environment env = EnvironmentExposure.getEnv();
|
Environment env = EnvironmentExposure.getEnv();
|
||||||
String hostname = determineHost(env.getProperty("webwolf.host"), env.getProperty("webwolf.port"));
|
String hostname = determineHost(env.getProperty("webwolf.host"), env.getProperty("webwolf.port"));
|
||||||
|
|
||||||
|
if (displayCompleteLinkNoFormatting(attributes)) {
|
||||||
|
return hostname + (hostname.endsWith("/") ? "" : "/") + target;
|
||||||
|
}
|
||||||
return "<a href=\"" + hostname + "\" target=\"_blank\">" + target + "</a>";
|
return "<a href=\"" + hostname + "\" target=\"_blank\">" + target + "</a>";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean displayCompleteLinkNoFormatting(Map<String, Object> attributes) {
|
||||||
|
return attributes.values().stream().filter(a -> a.equals("noLink")).findFirst().isPresent();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Look at the remote address from received from the browser first. This way it will also work if you run
|
* Look at the remote address from received from the browser first. This way it will also work if you run
|
||||||
* the browser in a Docker container and WebGoat on your local machine.
|
* the browser in a Docker container and WebGoat on your local machine.
|
||||||
@ -31,6 +45,10 @@ public class WebWolfMacro extends InlineMacroProcessor {
|
|||||||
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
|
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
|
||||||
String ip = request.getRemoteAddr();
|
String ip = request.getRemoteAddr();
|
||||||
String hostname = StringUtils.hasText(ip) ? ip : host;
|
String hostname = StringUtils.hasText(ip) ? ip : host;
|
||||||
return "http://" + hostname + ":" + port + "/WebWolf";
|
return "http://" + hostname + ":" + port + (includeWebWolfContext() ? "/WebWolf" : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean includeWebWolfContext() {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
package org.owasp.webgoat.asciidoc;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Usage in asciidoc:
|
||||||
|
* <p>
|
||||||
|
* webWolfLink:here[] will display a href with here as text
|
||||||
|
* webWolfLink:landing[noLink] will display the complete url, for example: http://WW_HOST:WW_PORT/landing
|
||||||
|
*/
|
||||||
|
public class WebWolfRootMacro extends WebWolfMacro {
|
||||||
|
|
||||||
|
public WebWolfRootMacro(String macroName, Map<String, Object> config) {
|
||||||
|
super(macroName, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean includeWebWolfContext() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -46,6 +46,7 @@ public enum Category {
|
|||||||
INSECURE_CONFIGURATION("Insecure Configuration", new Integer(600)),
|
INSECURE_CONFIGURATION("Insecure Configuration", new Integer(600)),
|
||||||
INSECURE_COMMUNICATION("Insecure Communication", new Integer(700)),
|
INSECURE_COMMUNICATION("Insecure Communication", new Integer(700)),
|
||||||
INSECURE_STORAGE("Insecure Storage", new Integer(800)),
|
INSECURE_STORAGE("Insecure Storage", new Integer(800)),
|
||||||
|
INSECURE_DESERIALIZATION("Insecure Deserialization", new Integer(850)),
|
||||||
REQUEST_FORGERIES("Request Forgeries", new Integer(900)),
|
REQUEST_FORGERIES("Request Forgeries", new Integer(900)),
|
||||||
VULNERABLE_COMPONENTS("Vulnerable Components - A9", new Integer(950)),
|
VULNERABLE_COMPONENTS("Vulnerable Components - A9", new Integer(950)),
|
||||||
AJAX_SECURITY("AJAX Security", new Integer(1000)),
|
AJAX_SECURITY("AJAX Security", new Integer(1000)),
|
||||||
|
@ -2,7 +2,6 @@ package org.owasp.webgoat.lessons;
|
|||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.owasp.webgoat.session.WebSession;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>LessonInfoModel class.</p>
|
* <p>LessonInfoModel class.</p>
|
||||||
|
@ -40,9 +40,10 @@ public class LessonProgressService {
|
|||||||
@RequestMapping(value = "/service/lessonprogress.mvc", produces = "application/json")
|
@RequestMapping(value = "/service/lessonprogress.mvc", produces = "application/json")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public Map getLessonInfo() {
|
public Map getLessonInfo() {
|
||||||
UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName());
|
|
||||||
LessonTracker lessonTracker = userTracker.getLessonTracker(webSession.getCurrentLesson());
|
|
||||||
Map json = Maps.newHashMap();
|
Map json = Maps.newHashMap();
|
||||||
|
UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName());
|
||||||
|
if (webSession.getCurrentLesson() != null) {
|
||||||
|
LessonTracker lessonTracker = userTracker.getLessonTracker(webSession.getCurrentLesson());
|
||||||
String successMessage = "";
|
String successMessage = "";
|
||||||
boolean lessonCompleted = false;
|
boolean lessonCompleted = false;
|
||||||
if (lessonTracker != null) {
|
if (lessonTracker != null) {
|
||||||
@ -51,6 +52,7 @@ public class LessonProgressService {
|
|||||||
}
|
}
|
||||||
json.put("lessonCompleted", lessonCompleted);
|
json.put("lessonCompleted", lessonCompleted);
|
||||||
json.put("successMessage", successMessage);
|
json.put("successMessage", successMessage);
|
||||||
|
}
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@ import com.google.common.collect.Lists;
|
|||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
import org.owasp.webgoat.i18n.PluginMessages;
|
||||||
import org.owasp.webgoat.lessons.AbstractLesson;
|
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||||
import org.owasp.webgoat.session.Course;
|
import org.owasp.webgoat.session.Course;
|
||||||
import org.owasp.webgoat.session.WebSession;
|
import org.owasp.webgoat.session.WebSession;
|
||||||
@ -57,6 +58,7 @@ public class ReportCardService {
|
|||||||
private final WebSession webSession;
|
private final WebSession webSession;
|
||||||
private final UserTrackerRepository userTrackerRepository;
|
private final UserTrackerRepository userTrackerRepository;
|
||||||
private final Course course;
|
private final Course course;
|
||||||
|
private final PluginMessages pluginMessages;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Endpoint which generates the report card for the current use to show the stats on the solved lessons
|
* Endpoint which generates the report card for the current use to show the stats on the solved lessons
|
||||||
@ -74,7 +76,7 @@ public class ReportCardService {
|
|||||||
for (AbstractLesson lesson : lessons) {
|
for (AbstractLesson lesson : lessons) {
|
||||||
LessonTracker lessonTracker = userTracker.getLessonTracker(lesson);
|
LessonTracker lessonTracker = userTracker.getLessonTracker(lesson);
|
||||||
LessonStatistics lessonStatistics = new LessonStatistics();
|
LessonStatistics lessonStatistics = new LessonStatistics();
|
||||||
lessonStatistics.setName(lesson.getTitle());
|
lessonStatistics.setName(pluginMessages.getMessage(lesson.getTitle()));
|
||||||
lessonStatistics.setNumberOfAttempts(lessonTracker.getNumberOfAttempts());
|
lessonStatistics.setNumberOfAttempts(lessonTracker.getNumberOfAttempts());
|
||||||
lessonStatistics.setSolved(lessonTracker.isLessonSolved());
|
lessonStatistics.setSolved(lessonTracker.isLessonSolved());
|
||||||
reportCard.lessonStatistics.add(lessonStatistics);
|
reportCard.lessonStatistics.add(lessonStatistics);
|
||||||
|
@ -81,6 +81,39 @@ public class CreateDB {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param connection Description of the Parameter
|
||||||
|
* @throws SQLException Description of the Exception
|
||||||
|
*/
|
||||||
|
private void createJWTKeys(Connection connection) throws SQLException {
|
||||||
|
Statement statement = connection.createStatement();
|
||||||
|
|
||||||
|
// Drop servers table
|
||||||
|
try {
|
||||||
|
String dropTable = "DROP TABLE jwt_keys";
|
||||||
|
statement.executeUpdate(dropTable);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
System.out.println("Info - Could not drop jwtkeys table");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the new table
|
||||||
|
try {
|
||||||
|
String createTableStatement = "CREATE TABLE jwt_keys"
|
||||||
|
+ " (" + "id varchar(20),"
|
||||||
|
+ "key varchar(20))";
|
||||||
|
statement.executeUpdate(createTableStatement);
|
||||||
|
|
||||||
|
String insertData1 = "INSERT INTO jwt_keys VALUES ('webgoat_key', 'qwertyqwerty1234')";
|
||||||
|
String insertData2 = "INSERT INTO jwt_keys VALUES ('webwolf_key', 'doesnotreallymatter')";
|
||||||
|
statement.executeUpdate(insertData1);
|
||||||
|
statement.executeUpdate(insertData2);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
System.out.println("Error creating product table " + e.getLocalizedMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Description of the Method
|
* Description of the Method
|
||||||
@ -199,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) {
|
||||||
@ -207,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);
|
||||||
@ -975,6 +1008,7 @@ public class CreateDB {
|
|||||||
createTanTable(connection);
|
createTanTable(connection);
|
||||||
createMFEImagesTable(connection);
|
createMFEImagesTable(connection);
|
||||||
createModifyWithSQLLessonTable(connection);
|
createModifyWithSQLLessonTable(connection);
|
||||||
|
createJWTKeys(connection);
|
||||||
System.out.println("Success: creating tables.");
|
System.out.println("Success: creating tables.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import lombok.Getter;
|
|||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
|
import javax.validation.constraints.Pattern;
|
||||||
import javax.validation.constraints.Size;
|
import javax.validation.constraints.Size;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -16,6 +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, digits, and -")
|
||||||
private String username;
|
private String username;
|
||||||
@NotNull
|
@NotNull
|
||||||
@Size(min=6, max=10)
|
@Size(min=6, max=10)
|
||||||
|
@ -52,6 +52,7 @@ public class UserTracker {
|
|||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
private Long id;
|
private Long id;
|
||||||
|
@Column(name = "username")
|
||||||
private String user;
|
private String user;
|
||||||
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
|
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
|
||||||
private Set<LessonTracker> lessonTrackers = Sets.newHashSet();
|
private Set<LessonTracker> lessonTrackers = Sets.newHashSet();
|
||||||
|
@ -5,12 +5,14 @@ server.contextPath=/WebGoat
|
|||||||
server.port=8080
|
server.port=8080
|
||||||
server.address=127.0.0.1
|
server.address=127.0.0.1
|
||||||
|
|
||||||
spring.datasource.url=jdbc:hsqldb:file:${webgoat.server.directory}/data/webgoat
|
spring.datasource.url=jdbc:hsqldb:hsql://localhost:9001/webgoat
|
||||||
spring.jpa.hibernate.ddl-auto=update
|
spring.jpa.hibernate.ddl-auto=update
|
||||||
|
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.HSQLDialect
|
||||||
|
spring.datasource.driver-class-name=org.hsqldb.jdbc.JDBCDriver
|
||||||
|
|
||||||
|
|
||||||
logging.level.org.springframework=WARN
|
logging.level.org.springframework=INFO
|
||||||
logging.level.org.springframework.boot.devtools=WARN
|
logging.level.org.springframework.boot.devtools=INFO
|
||||||
logging.level.org.owasp=DEBUG
|
logging.level.org.owasp=DEBUG
|
||||||
logging.level.org.owasp.webgoat=TRACE
|
logging.level.org.owasp.webgoat=TRACE
|
||||||
|
|
||||||
@ -20,6 +22,7 @@ security.enable-csrf=false
|
|||||||
spring.resources.cache-period=0
|
spring.resources.cache-period=0
|
||||||
spring.thymeleaf.cache=false
|
spring.thymeleaf.cache=false
|
||||||
|
|
||||||
|
webgoat.start.hsqldb=true
|
||||||
webgoat.clean=false
|
webgoat.clean=false
|
||||||
webgoat.server.directory=${user.home}/.webgoat-${webgoat.build.version}/
|
webgoat.server.directory=${user.home}/.webgoat-${webgoat.build.version}/
|
||||||
webgoat.user.directory=${user.home}/.webgoat-${webgoat.build.version}/
|
webgoat.user.directory=${user.home}/.webgoat-${webgoat.build.version}/
|
||||||
@ -34,9 +37,9 @@ webgoat.database.connection.string=jdbc:hsqldb:mem:{USER}
|
|||||||
webgoat.default.language=en
|
webgoat.default.language=en
|
||||||
|
|
||||||
webwolf.host=${WEBWOLF_HOST:localhost}
|
webwolf.host=${WEBWOLF_HOST:localhost}
|
||||||
webwolf.port=${WEBWOLF_PORT:8081}
|
webwolf.port=${WEBWOLF_PORT:9090}
|
||||||
webwolf.url=http://${webwolf.host}:${webwolf.port}/WebWolf
|
webwolf.url=http://${webwolf.host}:${webwolf.port}/WebWolf
|
||||||
webworf.url.landingpage=http://${webwolf.host}:${webwolf.port}/landing
|
webwolf.url.landingpage=http://${webwolf.host}:${webwolf.port}/landing
|
||||||
webwolf.url.mail=http://${webwolf.host}:${webwolf.port}/mail
|
webwolf.url.mail=http://${webwolf.host}:${webwolf.port}/mail
|
||||||
|
|
||||||
spring.jackson.serialization.indent_output=true
|
spring.jackson.serialization.indent_output=true
|
||||||
|
@ -1066,6 +1066,7 @@ span.show-next-page, span.show-prev-page {
|
|||||||
|
|
||||||
/* ATTACK DISPLAY */
|
/* ATTACK DISPLAY */
|
||||||
.attack-container {
|
.attack-container {
|
||||||
|
position: relative;
|
||||||
background-color: #f1f1f1;
|
background-color: #f1f1f1;
|
||||||
border: 2px solid #a66;
|
border: 2px solid #a66;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
@ -1151,3 +1152,15 @@ div.captured-flag {
|
|||||||
width: 1268px;
|
width: 1268px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#content {
|
||||||
|
position:relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.webwolf-enabled {
|
||||||
|
position:absolute;
|
||||||
|
top: 10px;
|
||||||
|
right: 25px;
|
||||||
|
width: 42px;
|
||||||
|
height: 47px;
|
||||||
|
}
|
@ -73,25 +73,27 @@ define(['jquery',
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.loadLesson = function(name,pageNum) {
|
this.loadLesson = function(name,pageNum) {
|
||||||
|
|
||||||
if (this.name === name) {
|
if (this.name === name) {
|
||||||
this.listenToOnce(this.lessonHintView, 'hints:showButton', this.onShowHintsButton);
|
this.listenToOnce(this.lessonHintView, 'hints:showButton', this.onShowHintsButton);
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pageNum && !this.name) {
|
||||||
|
//placeholder
|
||||||
|
}
|
||||||
|
|
||||||
this.helpsLoaded = {};
|
this.helpsLoaded = {};
|
||||||
if (typeof(name) === 'undefined' || name === null) {
|
if (typeof(name) === 'undefined' || name === null) {
|
||||||
//TODO: implement lesson not found or return to welcome page?
|
//TODO: implement lesson not found or return to welcome page?
|
||||||
}
|
}
|
||||||
this.lessonContent.loadData({'name':name});
|
this.lessonContent.loadData({'name':name});
|
||||||
// this.planView = {};
|
|
||||||
// this.solutionView = {};
|
|
||||||
// this.sourceView = {};
|
|
||||||
// this.lessonHintView = {};
|
|
||||||
this.name = name;
|
this.name = name;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -124,15 +126,8 @@ define(['jquery',
|
|||||||
this.helpControlsView = null;
|
this.helpControlsView = null;
|
||||||
this.lessonContentView.model = this.lessonContent;
|
this.lessonContentView.model = this.lessonContent;
|
||||||
this.lessonContentView.render();
|
this.lessonContentView.render();
|
||||||
|
//TODO: consider moving hintView as child of lessonContentView ...
|
||||||
//this.planView = new PlanView();
|
this.createLessonHintView();
|
||||||
//this.solutionView = new SolutionView();
|
|
||||||
//this.sourceView = new SourceView();
|
|
||||||
if (this.lessonHintView) {
|
|
||||||
this.lessonHintView.stopListening();
|
|
||||||
this.lessonHintView = null;
|
|
||||||
}
|
|
||||||
this.lessonHintView = new HintView();
|
|
||||||
|
|
||||||
//TODO: instantiate model with values (not sure why was not working before)
|
//TODO: instantiate model with values (not sure why was not working before)
|
||||||
var paramModel = new ParamModel({});
|
var paramModel = new ParamModel({});
|
||||||
@ -148,42 +143,25 @@ define(['jquery',
|
|||||||
this.lessonProgressModel.completed();
|
this.lessonProgressModel.completed();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.createLessonHintView = function () {
|
||||||
|
if (this.lessonHintView) {
|
||||||
|
this.lessonHintView.stopListening();
|
||||||
|
this.lessonHintView = null;
|
||||||
|
}
|
||||||
|
this.lessonHintView = new HintView();
|
||||||
|
}
|
||||||
|
|
||||||
this.addCurHelpState = function (curHelp) {
|
this.addCurHelpState = function (curHelp) {
|
||||||
this.helpsLoaded[curHelp.helpElement] = curHelp.value;
|
this.helpsLoaded[curHelp.helpElement] = curHelp.value;
|
||||||
};
|
};
|
||||||
|
|
||||||
// this.hideShowHelps = function(showHelp) {
|
|
||||||
// var showId = '#lesson-' + showHelp + '-row';
|
|
||||||
// var contentId = '#lesson-' + showHelp + '-content';
|
|
||||||
// $('.lesson-help').not(showId).hide();
|
|
||||||
// if (!showId) {
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if ($(showId).is(':visible')) {
|
|
||||||
// $(showId).hide();
|
|
||||||
// return;
|
|
||||||
// } else {
|
|
||||||
// //TODO: move individual .html operations into individual help views
|
|
||||||
// switch(showHelp) {
|
|
||||||
// case 'plan':
|
|
||||||
// $(contentId).html(this.planView.model.get('content'));
|
|
||||||
// break;
|
|
||||||
// case 'solution':
|
|
||||||
// $(showId).html(this.solutionView.model.get('content'));
|
|
||||||
// break;
|
|
||||||
// case 'source':
|
|
||||||
// $(contentId).html('<pre>' + this.sourceView.model.get('content') + '</pre>');
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// $(showId).show();
|
|
||||||
// GoatUtils.scrollToHelp()
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
|
|
||||||
this.showHintsView = function() {
|
this.showHintsView = function() {
|
||||||
|
if (!this.lessonHintView) {
|
||||||
|
this.createLessonHintView();
|
||||||
|
}
|
||||||
|
//
|
||||||
this.lessonHintView.render();
|
this.lessonHintView.render();
|
||||||
if (this.lessonHintView.getHintsCount > 0) {
|
if (this.lessonHintView.getHintsCount() > 0) {
|
||||||
this.helpControlsView.showHintsButton();
|
this.helpControlsView.showHintsButton();
|
||||||
} else {
|
} else {
|
||||||
this.helpControlsView.hideHintsButton();
|
this.helpControlsView.hideHintsButton();
|
||||||
|
@ -32,7 +32,11 @@ define(['jquery',
|
|||||||
}
|
}
|
||||||
this.set('content',content);
|
this.set('content',content);
|
||||||
this.set('lessonUrl',document.URL.replace(/\.lesson.*/,'.lesson'));
|
this.set('lessonUrl',document.URL.replace(/\.lesson.*/,'.lesson'));
|
||||||
|
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);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -7,9 +7,13 @@ define(['jquery',
|
|||||||
return Backbone.Collection.extend({
|
return Backbone.Collection.extend({
|
||||||
model: MenuModel,
|
model: MenuModel,
|
||||||
url: 'service/lessonmenu.mvc',
|
url: 'service/lessonmenu.mvc',
|
||||||
|
|
||||||
initialize: function () {
|
initialize: function () {
|
||||||
var self = this;
|
var self = this;
|
||||||
this.fetch();
|
this.fetch();
|
||||||
|
setInterval(function () {
|
||||||
|
this.fetch()
|
||||||
|
}.bind(this), 5000);
|
||||||
},
|
},
|
||||||
|
|
||||||
onDataLoaded: function () {
|
onDataLoaded: function () {
|
||||||
|
@ -67,7 +67,7 @@ define(['jquery',
|
|||||||
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
|
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
|
||||||
success: function (data) {
|
success: function (data) {
|
||||||
//devs leave stuff like this in all the time
|
//devs leave stuff like this in all the time
|
||||||
console.log('phone home said ' + data);
|
console.log('phone home said ' + JSON.stringify(data));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
@ -25,6 +25,9 @@ define(['jquery',
|
|||||||
self.navToPage(page);
|
self.navToPage(page);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
setInterval(function () {
|
||||||
|
this.updatePagination();
|
||||||
|
}.bind(this), 5000);
|
||||||
},
|
},
|
||||||
|
|
||||||
findPage: function(assignment) {
|
findPage: function(assignment) {
|
||||||
@ -56,11 +59,13 @@ define(['jquery',
|
|||||||
var currentPage = (!isNaN(startPageNum) && startPageNum && startPageNum < this.$contentPages) ? startPageNum : 0;
|
var currentPage = (!isNaN(startPageNum) && startPageNum && startPageNum < this.$contentPages) ? startPageNum : 0;
|
||||||
//init views & pagination
|
//init views & pagination
|
||||||
this.showCurContentPage(currentPage);
|
this.showCurContentPage(currentPage);
|
||||||
this.paginationControlView = new PaginationControlView(this.$contentPages,this.model.get('lessonUrl'));
|
this.paginationControlView = new PaginationControlView(this.$contentPages,this.model.get('lessonUrl'),startPageNum);
|
||||||
},
|
},
|
||||||
|
|
||||||
updatePagination: function() {
|
updatePagination: function() {
|
||||||
|
if ( this.paginationControlView != undefined ) {
|
||||||
this.paginationControlView.updateCollection();
|
this.paginationControlView.updateCollection();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getCurrentPage: function () {
|
getCurrentPage: function () {
|
||||||
@ -85,6 +90,8 @@ define(['jquery',
|
|||||||
var prepareDataFunctionName = $(curForm).attr('prepareData');
|
var prepareDataFunctionName = $(curForm).attr('prepareData');
|
||||||
var callbackFunctionName = $(curForm).attr('callback');
|
var callbackFunctionName = $(curForm).attr('callback');
|
||||||
var submitData = (typeof webgoat.customjs[prepareDataFunctionName] === 'function') ? webgoat.customjs[prepareDataFunctionName]() : $(curForm).serialize();
|
var submitData = (typeof webgoat.customjs[prepareDataFunctionName] === 'function') ? webgoat.customjs[prepareDataFunctionName]() : $(curForm).serialize();
|
||||||
|
var additionalHeadersFunctionName = $(curForm).attr('additionalHeaders');
|
||||||
|
var additionalHeaders = (typeof webgoat.customjs[additionalHeadersFunctionName] === 'function') ? webgoat.customjs[additionalHeadersFunctionName]() : function() {};
|
||||||
var successCallBackFunctionName = $(curForm).attr('successCallback');
|
var successCallBackFunctionName = $(curForm).attr('successCallback');
|
||||||
var failureCallbackFunctionName = $(curForm).attr('failureCallback');
|
var failureCallbackFunctionName = $(curForm).attr('failureCallback');
|
||||||
var callbackFunction = (typeof webgoat.customjs[callbackFunctionName] === 'function') ? webgoat.customjs[callbackFunctionName] : function() {};
|
var callbackFunction = (typeof webgoat.customjs[callbackFunctionName] === 'function') ? webgoat.customjs[callbackFunctionName] : function() {};
|
||||||
@ -99,6 +106,7 @@ define(['jquery',
|
|||||||
$.ajax({
|
$.ajax({
|
||||||
//data:submitData,
|
//data:submitData,
|
||||||
url:formUrl,
|
url:formUrl,
|
||||||
|
headers: additionalHeaders,
|
||||||
method:formMethod,
|
method:formMethod,
|
||||||
contentType:contentType,
|
contentType:contentType,
|
||||||
data: submitData,
|
data: submitData,
|
||||||
@ -146,14 +154,23 @@ define(['jquery',
|
|||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
removeSlashesFromJSON: function(str) {
|
||||||
|
// slashes are leftover escapes from JSON serialization by server
|
||||||
|
// for every two char sequence starting with backslash,
|
||||||
|
// replace them in the text with second char only
|
||||||
|
return str.replace(/\\(.)/g, "$1");
|
||||||
|
},
|
||||||
|
|
||||||
renderFeedback: function(feedback) {
|
renderFeedback: function(feedback) {
|
||||||
this.$curFeedback.html(polyglot.t(feedback) || "");
|
var s = this.removeSlashesFromJSON(feedback);
|
||||||
|
this.$curFeedback.html(polyglot.t(s) || "");
|
||||||
this.$curFeedback.show(400)
|
this.$curFeedback.show(400)
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
renderOutput: function(output) {
|
renderOutput: function(output) {
|
||||||
this.$curOutput.html(polyglot.t(output) || "");
|
var s = this.removeSlashesFromJSON(output);
|
||||||
|
this.$curOutput.html(polyglot.t(s) || "");
|
||||||
this.$curOutput.show(400)
|
this.$curOutput.show(400)
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -173,13 +190,19 @@ define(['jquery',
|
|||||||
return endpoints;
|
return endpoints;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onNavToPage: function(pageNum) {
|
||||||
|
var assignmentPaths = this.findAssigmentEndpointsOnPage(pageNum);
|
||||||
|
this.trigger('endpoints:filtered',assignmentPaths);
|
||||||
|
},
|
||||||
|
|
||||||
navToPage: function (pageNum) {
|
navToPage: function (pageNum) {
|
||||||
this.paginationControlView.setCurrentPage(pageNum);//provides validation
|
this.paginationControlView.setCurrentPage(pageNum);//provides validation
|
||||||
this.showCurContentPage(this.paginationControlView.currentPage);
|
this.showCurContentPage(this.paginationControlView.currentPage);
|
||||||
this.paginationControlView.render();
|
this.paginationControlView.render();
|
||||||
this.paginationControlView.hideShowNavButtons();
|
this.paginationControlView.hideShowNavButtons();
|
||||||
var assignmentPaths = this.findAssigmentEndpointsOnPage(pageNum);
|
this.onNavToPage(pageNum);
|
||||||
this.trigger('endpoints:filtered',assignmentPaths);
|
//var assignmentPaths = this.findAssigmentEndpointsOnPage(pageNum);
|
||||||
|
//this.trigger('endpoints:filtered',assignmentPaths);
|
||||||
},
|
},
|
||||||
|
|
||||||
/* for testing */
|
/* for testing */
|
||||||
|
@ -12,14 +12,14 @@ define(['jquery',
|
|||||||
template: PaginationTemplate,
|
template: PaginationTemplate,
|
||||||
el: '#lesson-page-controls',
|
el: '#lesson-page-controls',
|
||||||
|
|
||||||
initialize: function ($contentPages,baseLessonUrl) {
|
initialize: function ($contentPages,baseLessonUrl,initPageNum) {
|
||||||
this.$contentPages = $contentPages;
|
this.$contentPages = $contentPages;
|
||||||
this.collection = new LessonOverviewCollection();
|
this.collection = new LessonOverviewCollection();
|
||||||
this.listenTo(this.collection, 'reset', this.render);
|
this.listenTo(this.collection, 'reset', this.render);
|
||||||
this.numPages = this.$contentPages.length;
|
this.numPages = this.$contentPages.length;
|
||||||
this.baseUrl = baseLessonUrl;
|
this.baseUrl = baseLessonUrl;
|
||||||
this.collection.fetch({reset:true});
|
this.collection.fetch({reset:true});
|
||||||
this.initPagination();
|
this.initPagination(initPageNum);
|
||||||
//this.render();
|
//this.render();
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -117,9 +117,9 @@ define(['jquery',
|
|||||||
$('span.glyphicon-class.glyphicon.glyphicon-circle-arrow-right.show-next-page').hide();
|
$('span.glyphicon-class.glyphicon.glyphicon-circle-arrow-right.show-next-page').hide();
|
||||||
},
|
},
|
||||||
|
|
||||||
initPagination: function() {
|
initPagination: function(initPageNum) {
|
||||||
//track pagination state in this view ... start at 0
|
//track pagination state in this view ... start at 0 .. unless a pageNum was provided
|
||||||
this.currentPage = 0;
|
this.currentPage = !initPageNum ? 0 : initPageNum;
|
||||||
},
|
},
|
||||||
|
|
||||||
setCurrentPage: function (pageNum) {
|
setCurrentPage: function (pageNum) {
|
||||||
|
@ -30,7 +30,7 @@ require.config({
|
|||||||
shim: {
|
shim: {
|
||||||
"jqueryui": {
|
"jqueryui": {
|
||||||
exports:"$",
|
exports:"$",
|
||||||
deps: ['jquery']
|
deps: ['libs/jquery-2.1.4.min']
|
||||||
},
|
},
|
||||||
underscore: {
|
underscore: {
|
||||||
exports: "_"
|
exports: "_"
|
||||||
|
@ -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}">
|
||||||
|
@ -76,24 +76,25 @@
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li role="presentation" class="divider"></li>
|
<li role="presentation" class="divider"></li>
|
||||||
<li role="presentation" class="disabled"><a role="menuitem" tabindex="-1" href="#"
|
<li role="presentation" class="disabled"><a role="menuitem" tabindex="-1" href="#">
|
||||||
th:text="#{version}">Version: <span
|
<span th:text="#{version}">Version:</span><span>: </span>
|
||||||
th:text="${@environment.getProperty('webgoat.build.version')}"></span></a>
|
<span th:text="${@environment.getProperty('webgoat.build.version')}"></span></a>
|
||||||
</li>
|
</li>
|
||||||
<li role="presentation" class="disabled"><a role="menuitem" tabindex="-1" href="#"
|
<li role="presentation" class="disabled"><a role="menuitem" tabindex="-1" href="#">
|
||||||
th:text="#{build}">Build:
|
<span th:text="#{build}">Build:</span><span>: </span>
|
||||||
<span th:text="${@environment.getProperty('webgoat.build.number')}"></span></a></li>
|
<span th:text="${@environment.getProperty('webgoat.build.number')}"></span></a></li>
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div style="display:inline" id="settings">
|
<div style="display:inline" id="settings">
|
||||||
<!--<button type="button" id="admin-button" class="btn btn-default right_nav_button" title="Administrator">-->
|
<!--<button type="button" id="admin-button" class="btn btn-default right_nav_button" title="Administrator">-->
|
||||||
<!--<i class="fa fa-cog"></i>-->
|
<!--<i class="fa fa-cog"></i>-->
|
||||||
<!--</button>-->
|
<!--</button>-->
|
||||||
|
<a href="#reportCard">
|
||||||
<button type="button" id="report-card-button" class="btn btn-default right_nav_button button-up"
|
<button type="button" id="report-card-button" class="btn btn-default right_nav_button button-up"
|
||||||
th:title="#{report.card}">
|
th:title="#{report.card}">
|
||||||
<a href="#reportCard"><i class="fa fa-bar-chart-o"></i></a>
|
<i class="fa fa-bar-chart-o"></i>
|
||||||
</button>
|
</button>
|
||||||
|
</a>
|
||||||
<!--<button type="button" id="user-management" class="btn btn-default right_nav_button"-->
|
<!--<button type="button" id="user-management" class="btn btn-default right_nav_button"-->
|
||||||
<!--title="User management">-->
|
<!--title="User management">-->
|
||||||
<!--<i class="fa fa-users"></i>-->
|
<!--<i class="fa fa-users"></i>-->
|
||||||
|
@ -6,6 +6,7 @@ import org.junit.Test;
|
|||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.runners.MockitoJUnitRunner;
|
import org.mockito.runners.MockitoJUnitRunner;
|
||||||
|
import org.owasp.webgoat.i18n.PluginMessages;
|
||||||
import org.owasp.webgoat.lessons.AbstractLesson;
|
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||||
import org.owasp.webgoat.session.Course;
|
import org.owasp.webgoat.session.Course;
|
||||||
import org.owasp.webgoat.session.WebSession;
|
import org.owasp.webgoat.session.WebSession;
|
||||||
@ -40,10 +41,13 @@ public class ReportCardServiceTest {
|
|||||||
private UserTrackerRepository userTrackerRepository;
|
private UserTrackerRepository userTrackerRepository;
|
||||||
@Mock
|
@Mock
|
||||||
private WebSession websession;
|
private WebSession websession;
|
||||||
|
@Mock
|
||||||
|
private PluginMessages pluginMessages;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
this.mockMvc = standaloneSetup(new ReportCardService(websession, userTrackerRepository, course)).build();
|
this.mockMvc = standaloneSetup(new ReportCardService(websession, userTrackerRepository, course, pluginMessages)).build();
|
||||||
|
when(pluginMessages.getMessage(anyString())).thenReturn("Test");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -1 +1,15 @@
|
|||||||
<configuration />
|
<configuration />
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Enable below if you want to debug a unit test and see why the controller fails the configuration above is there
|
||||||
|
to keep the Travis build going otherwise it fails with too much logging.
|
||||||
|
//TODO we should use a different Spring profile for Travis
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<configuration>
|
||||||
|
<include resource="org/springframework/boot/logging/logback/base.xml"/>
|
||||||
|
<logger name="org.springframework.web" level="DEBUG"/>
|
||||||
|
</configuration>
|
||||||
|
|
||||||
|
-->
|
10
webgoat-images/vagrant-training/Vagrantfile
vendored
10
webgoat-images/vagrant-training/Vagrantfile
vendored
@ -3,7 +3,7 @@
|
|||||||
Vagrant.configure(2) do |config|
|
Vagrant.configure(2) do |config|
|
||||||
config.vm.box = "ubuntu/trusty64"
|
config.vm.box = "ubuntu/trusty64"
|
||||||
config.vm.network :forwarded_port, guest: 8080, host: 8080
|
config.vm.network :forwarded_port, guest: 8080, host: 8080
|
||||||
config.vm.network :forwarded_port, guest: 8081, host: 8081
|
config.vm.network :forwarded_port, guest: 9090, host: 9090
|
||||||
config.vm.provider "virtualbox" do |vb|
|
config.vm.provider "virtualbox" do |vb|
|
||||||
vb.gui = false
|
vb.gui = false
|
||||||
vb.memory = "4096"
|
vb.memory = "4096"
|
||||||
@ -19,17 +19,17 @@ Vagrant.configure(2) do |config|
|
|||||||
end
|
end
|
||||||
|
|
||||||
config.vm.provision "shell", inline: <<-SHELL
|
config.vm.provision "shell", inline: <<-SHELL
|
||||||
wget https://github.com/WebGoat/WebGoat/releases/download/v8.0.0.RELEASE/webgoat-server-8.0.0.RELEASE.jar
|
wget https://github.com/WebGoat/WebGoat/releases/download/v8.0.0.M21/webgoat-server-8.0.0.M21.jar
|
||||||
wget https://github.com/WebGoat/WebGoat/releases/download/v8.0.0.RELEASE/webwolf-8.0.0.RELEASE.jar
|
wget https://github.com/WebGoat/WebGoat/releases/download/v8.0.0.M21/webwolf-8.0.0.M21.jar
|
||||||
sudo add-apt-repository ppa:openjdk-r/ppa
|
sudo add-apt-repository ppa:openjdk-r/ppa
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install openjdk-8-jre -y
|
sudo apt-get install openjdk-8-jre -y
|
||||||
SHELL
|
SHELL
|
||||||
|
|
||||||
config.vm.provision "shell", run: "always", privileged: false, inline: <<-SHELL
|
config.vm.provision "shell", run: "always", privileged: false, inline: <<-SHELL
|
||||||
java -jar webgoat-server-8.0.0.RELEASE.jar &
|
java -jar webgoat-server-8.0.0.M21.jar --server.address=0.0.0.0 &
|
||||||
sleep 40s
|
sleep 40s
|
||||||
java -jar webwolf-8.0.0.RELEASE.jar
|
java -jar webwolf-8.0.0.M21.jar --server.address=0.0.0.0 &
|
||||||
SHELL
|
SHELL
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.owasp.webgoat.lesson</groupId>
|
<groupId>org.owasp.webgoat.lesson</groupId>
|
||||||
<artifactId>webgoat-lessons-parent</artifactId>
|
<artifactId>webgoat-lessons-parent</artifactId>
|
||||||
<version>8.0.0.M3</version>
|
<version>v8.0.0.M22</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@ -58,7 +58,7 @@ public class AccountVerificationHelper {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (submittedQuestions.containsKey("secQuestion1") && !submittedQuestions.get("seQuestion1").equals(secQuestionStore.get(verifyUserId).get("secQuestion1"))) {
|
if (submittedQuestions.containsKey("secQuestion1") && !submittedQuestions.get("secQuestion1").equals(secQuestionStore.get(verifyUserId).get("secQuestion1"))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
== Authentication Bpasses
|
== Authentication Bypasses
|
||||||
|
|
||||||
Authentication Bypasses happen in many ways, but usually take advantage of some flaw in the configuration or logic. Tampering to achieve the right conditions.
|
Authentication Bypasses happen in many ways, but usually take advantage of some flaw in the configuration or logic. Tampering to achieve the right conditions.
|
||||||
|
|
||||||
@ -12,4 +12,4 @@ Sometimes, if an attacker doesn't know the correct value of a parameter, they ma
|
|||||||
|
|
||||||
=== Forced Browsing
|
=== Forced Browsing
|
||||||
|
|
||||||
If an area of a site is not protected properly by configuation, that area of the site may be accessed by guessing/brute-forcing.
|
If an area of a site is not protected properly by configuration, that area of the site may be accessed by guessing/brute-forcing.
|
||||||
|
@ -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>8.0.0.M3</version>
|
<version>v8.0.0.M22</version>
|
||||||
</parent>
|
</parent>
|
||||||
</project>
|
</project>
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.owasp.webgoat.lesson</groupId>
|
<groupId>org.owasp.webgoat.lesson</groupId>
|
||||||
<artifactId>webgoat-lessons-parent</artifactId>
|
<artifactId>webgoat-lessons-parent</artifactId>
|
||||||
<version>8.0.0.M3</version>
|
<version>v8.0.0.M22</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
||||||
|
@ -10,11 +10,6 @@ public interface SolutionConstants {
|
|||||||
|
|
||||||
//TODO should be random generated when starting the server
|
//TODO should be random generated when starting the server
|
||||||
String PASSWORD = "!!webgoat_admin_1234!!";
|
String PASSWORD = "!!webgoat_admin_1234!!";
|
||||||
String SUPER_COUPON_CODE = "get_it_for_free";
|
|
||||||
String PASSWORD_TOM = "thisisasecretfortomonly";
|
String PASSWORD_TOM = "thisisasecretfortomonly";
|
||||||
String PASSWORD_LARRY = "larryknows";
|
|
||||||
String JWT_PASSWORD = "victory";
|
|
||||||
String ADMIN_PASSWORD_LINK = "375afe1104f4a487a73823c50a9292a2";
|
String ADMIN_PASSWORD_LINK = "375afe1104f4a487a73823c50a9292a2";
|
||||||
String PASSWORD_TOM_9 = "somethingVeryRandomWhichNoOneWillEverTypeInAsPasswordForTom";
|
|
||||||
String TOM_EMAIL = "tom@webgoat-cloud.org";
|
|
||||||
}
|
}
|
||||||
|
@ -1,39 +0,0 @@
|
|||||||
package org.owasp.webgoat.plugin.challenge2;
|
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import org.owasp.webgoat.lessons.Category;
|
|
||||||
import org.owasp.webgoat.lessons.NewLesson;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 3/21/17.
|
|
||||||
*/
|
|
||||||
public class Challenge2 extends NewLesson {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Category getDefaultCategory() {
|
|
||||||
return Category.CHALLENGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> getHints() {
|
|
||||||
return Lists.newArrayList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Integer getDefaultRanking() {
|
|
||||||
return 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTitle() {
|
|
||||||
return "challenge2.title";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getId() {
|
|
||||||
return "Challenge2";
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,150 +0,0 @@
|
|||||||
package org.owasp.webgoat.plugin.challenge3;
|
|
||||||
|
|
||||||
import com.beust.jcommander.internal.Lists;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import com.google.common.collect.EvictingQueue;
|
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
import com.google.common.io.Files;
|
|
||||||
import lombok.SneakyThrows;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.joda.time.DateTime;
|
|
||||||
import org.joda.time.format.DateTimeFormat;
|
|
||||||
import org.joda.time.format.DateTimeFormatter;
|
|
||||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
|
||||||
import org.owasp.webgoat.assignments.AssignmentPath;
|
|
||||||
import org.owasp.webgoat.assignments.AttackResult;
|
|
||||||
import org.owasp.webgoat.plugin.Flag;
|
|
||||||
import org.owasp.webgoat.session.WebSession;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.http.MediaType;
|
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
|
||||||
import org.springframework.web.bind.annotation.RequestHeader;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
|
||||||
import javax.xml.bind.JAXBContext;
|
|
||||||
import javax.xml.bind.Unmarshaller;
|
|
||||||
import javax.xml.stream.XMLInputFactory;
|
|
||||||
import javax.xml.stream.XMLStreamReader;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.StringReader;
|
|
||||||
import java.nio.charset.Charset;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static org.springframework.http.MediaType.ALL_VALUE;
|
|
||||||
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
|
|
||||||
import static org.springframework.web.bind.annotation.RequestMethod.GET;
|
|
||||||
import static org.springframework.web.bind.annotation.RequestMethod.POST;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 4/8/17.
|
|
||||||
*/
|
|
||||||
@AssignmentPath("/challenge/3")
|
|
||||||
@Slf4j
|
|
||||||
public class Assignment3 extends AssignmentEndpoint {
|
|
||||||
|
|
||||||
@Value("${webgoat.server.directory}")
|
|
||||||
private String webGoatHomeDirectory;
|
|
||||||
@Autowired
|
|
||||||
private WebSession webSession;
|
|
||||||
private static DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyy-MM-dd, HH:mm:ss");
|
|
||||||
|
|
||||||
private static final Map<String, EvictingQueue<Comment>> userComments = Maps.newHashMap();
|
|
||||||
private static final EvictingQueue<Comment> comments = EvictingQueue.create(100);
|
|
||||||
private static final String secretContents = "Congratulations you may now collect your flag";
|
|
||||||
|
|
||||||
static {
|
|
||||||
comments.add(new Comment("webgoat", DateTime.now().toString(fmt), "Silly cat...."));
|
|
||||||
comments.add(new Comment("guest", DateTime.now().toString(fmt), "I think I will use this picture in one of my projects."));
|
|
||||||
comments.add(new Comment("guest", DateTime.now().toString(fmt), "Lol!! :-)."));
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostConstruct
|
|
||||||
@SneakyThrows
|
|
||||||
public void copyFile() {
|
|
||||||
File targetDirectory = new File(webGoatHomeDirectory);
|
|
||||||
if (!targetDirectory.exists()) {
|
|
||||||
targetDirectory.mkdir();
|
|
||||||
}
|
|
||||||
log.info("Copied secret.txt to: {}", targetDirectory);
|
|
||||||
Files.write(secretContents, new File(targetDirectory, "secret.txt"), Charset.defaultCharset());
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping(method = GET, produces = MediaType.APPLICATION_JSON_VALUE)
|
|
||||||
@ResponseBody
|
|
||||||
public Collection<Comment> retrieveComments() {
|
|
||||||
Collection<Comment> allComments = Lists.newArrayList();
|
|
||||||
Collection<Comment> xmlComments = userComments.get(webSession.getUserName());
|
|
||||||
if (xmlComments != null) {
|
|
||||||
allComments.addAll(xmlComments);
|
|
||||||
}
|
|
||||||
allComments.addAll(comments);
|
|
||||||
return allComments;
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping(method = POST, consumes = ALL_VALUE, produces = APPLICATION_JSON_VALUE)
|
|
||||||
@ResponseBody
|
|
||||||
public AttackResult createNewComment(@RequestBody String commentStr, @RequestHeader("Content-Type") String contentType) throws Exception {
|
|
||||||
Comment comment = null;
|
|
||||||
AttackResult attackResult = failed().build();
|
|
||||||
if (APPLICATION_JSON_VALUE.equals(contentType)) {
|
|
||||||
comment = parseJson(commentStr);
|
|
||||||
comment.setDateTime(DateTime.now().toString(fmt));
|
|
||||||
comment.setUser(webSession.getUserName());
|
|
||||||
comments.add(comment);
|
|
||||||
}
|
|
||||||
if (MediaType.APPLICATION_XML_VALUE.equals(contentType)) {
|
|
||||||
//Do not show these comments to all users
|
|
||||||
comment = parseXml(commentStr);
|
|
||||||
comment.setDateTime(DateTime.now().toString(fmt));
|
|
||||||
comment.setUser(webSession.getUserName());
|
|
||||||
EvictingQueue<Comment> comments = userComments.getOrDefault(webSession.getUserName(), EvictingQueue.create(100));
|
|
||||||
comments.add(comment);
|
|
||||||
userComments.put(webSession.getUserName(), comments);
|
|
||||||
}
|
|
||||||
if (checkSolution(comment)) {
|
|
||||||
attackResult = success().feedback("challenge.solved").feedbackArgs(Flag.FLAGS.get(3)).build();
|
|
||||||
}
|
|
||||||
return attackResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean checkSolution(Comment comment) {
|
|
||||||
if (comment.getText().contains(secretContents)) {
|
|
||||||
comment.setText("Congratulations to " + webSession.getUserName() + " for finding the flag!! Check your original response where you posted the XXE attack ");
|
|
||||||
comments.add(comment);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Comment parseXml(String xml) throws Exception {
|
|
||||||
JAXBContext jc = JAXBContext.newInstance(Comment.class);
|
|
||||||
|
|
||||||
XMLInputFactory xif = XMLInputFactory.newFactory();
|
|
||||||
xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, true);
|
|
||||||
xif.setProperty(XMLInputFactory.IS_VALIDATING, false);
|
|
||||||
|
|
||||||
xif.setProperty(XMLInputFactory.SUPPORT_DTD, true);
|
|
||||||
XMLStreamReader xsr = xif.createXMLStreamReader(new StringReader(xml));
|
|
||||||
|
|
||||||
Unmarshaller unmarshaller = jc.createUnmarshaller();
|
|
||||||
return (Comment) unmarshaller.unmarshal(xsr);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Comment parseJson(String comment) {
|
|
||||||
ObjectMapper mapper = new ObjectMapper();
|
|
||||||
try {
|
|
||||||
return mapper.readValue(comment, Comment.class);
|
|
||||||
} catch (IOException e) {
|
|
||||||
return new Comment();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
|||||||
package org.owasp.webgoat.plugin.challenge3;
|
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import org.owasp.webgoat.lessons.Category;
|
|
||||||
import org.owasp.webgoat.lessons.NewLesson;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 3/21/17.
|
|
||||||
*/
|
|
||||||
public class Challenge3 extends NewLesson {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Category getDefaultCategory() {
|
|
||||||
return Category.CHALLENGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> getHints() {
|
|
||||||
return Lists.newArrayList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Integer getDefaultRanking() {
|
|
||||||
return 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTitle() {
|
|
||||||
return "challenge3.title";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getId() {
|
|
||||||
return "Challenge3";
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
package org.owasp.webgoat.plugin.challenge3;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlRootElement;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 4/8/17.
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@AllArgsConstructor
|
|
||||||
@NoArgsConstructor
|
|
||||||
@XmlRootElement
|
|
||||||
public class Comment {
|
|
||||||
private String user;
|
|
||||||
private String dateTime;
|
|
||||||
private String text;
|
|
||||||
}
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
|||||||
package org.owasp.webgoat.plugin.challenge4;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
|
||||||
import org.owasp.webgoat.assignments.AssignmentPath;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 5/3/17.
|
|
||||||
*/
|
|
||||||
@AssignmentPath("/challenge/4")
|
|
||||||
@Slf4j
|
|
||||||
public class Assignment4 extends AssignmentEndpoint {
|
|
||||||
|
|
||||||
//just empty, posting the flag will mark the challenge as done as well no need to specify an endpoint here
|
|
||||||
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
package org.owasp.webgoat.plugin.challenge4;
|
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import org.owasp.webgoat.lessons.Category;
|
|
||||||
import org.owasp.webgoat.lessons.NewLesson;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 3/21/17.
|
|
||||||
*/
|
|
||||||
public class Challenge4 extends NewLesson {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Category getDefaultCategory() {
|
|
||||||
return Category.CHALLENGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> getHints() {
|
|
||||||
return Lists.newArrayList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Integer getDefaultRanking() {
|
|
||||||
return 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTitle() {
|
|
||||||
return "challenge4.title";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getId() {
|
|
||||||
return "Challenge4";
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
package org.owasp.webgoat.plugin.challenge4;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 4/30/17.
|
|
||||||
*/
|
|
||||||
public class Views {
|
|
||||||
interface GuestView {
|
|
||||||
}
|
|
||||||
|
|
||||||
interface UserView extends GuestView {
|
|
||||||
}
|
|
||||||
|
|
||||||
interface AdminView extends UserView {
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,75 +0,0 @@
|
|||||||
/* Component: Posts */
|
|
||||||
.post .post-heading {
|
|
||||||
height: 95px;
|
|
||||||
padding: 20px 15px;
|
|
||||||
}
|
|
||||||
.post .post-heading .avatar {
|
|
||||||
width: 60px;
|
|
||||||
height: 60px;
|
|
||||||
display: block;
|
|
||||||
margin-right: 15px;
|
|
||||||
}
|
|
||||||
.post .post-heading .meta .title {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
.post .post-heading .meta .title a {
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
.post .post-heading .meta .title a:hover {
|
|
||||||
color: #aaaaaa;
|
|
||||||
}
|
|
||||||
.post .post-heading .meta .time {
|
|
||||||
margin-top: 8px;
|
|
||||||
color: #999;
|
|
||||||
}
|
|
||||||
.post .post-image .image {
|
|
||||||
width:20%;
|
|
||||||
height: 40%;
|
|
||||||
}
|
|
||||||
.post .post-description {
|
|
||||||
padding: 5px;
|
|
||||||
}
|
|
||||||
.post .post-footer {
|
|
||||||
border-top: 1px solid #ddd;
|
|
||||||
padding: 15px;
|
|
||||||
}
|
|
||||||
.post .post-footer .input-group-addon a {
|
|
||||||
color: #454545;
|
|
||||||
}
|
|
||||||
.post .post-footer .comments-list {
|
|
||||||
padding: 0;
|
|
||||||
margin-top: 20px;
|
|
||||||
list-style-type: none;
|
|
||||||
}
|
|
||||||
.post .post-footer .comments-list .comment {
|
|
||||||
display: block;
|
|
||||||
width: 100%;
|
|
||||||
margin: 20px 0;
|
|
||||||
}
|
|
||||||
.post .post-footer .comments-list .comment .avatar {
|
|
||||||
width: 35px;
|
|
||||||
height: 35px;
|
|
||||||
}
|
|
||||||
.post .post-footer .comments-list .comment .comment-heading {
|
|
||||||
display: block;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.post .post-footer .comments-list .comment .comment-heading .user {
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: bold;
|
|
||||||
display: inline;
|
|
||||||
margin-top: 0;
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
.post .post-footer .comments-list .comment .comment-heading .time {
|
|
||||||
font-size: 12px;
|
|
||||||
color: #aaa;
|
|
||||||
margin-top: 0;
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
.post .post-footer .comments-list .comment .comment-body {
|
|
||||||
margin-left: 50px;
|
|
||||||
}
|
|
||||||
.post .post-footer .comments-list .comment > .comments-list {
|
|
||||||
margin-left: 50px;
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
a.list-group-item {
|
|
||||||
height:auto;
|
|
||||||
}
|
|
||||||
a.list-group-item.active small {
|
|
||||||
color:#fff;
|
|
||||||
}
|
|
||||||
.stars {
|
|
||||||
margin:20px auto 1px;
|
|
||||||
}
|
|
||||||
.img-responsive {
|
|
||||||
min-width: 100%;
|
|
||||||
}
|
|
@ -1,112 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
|
|
||||||
<html xmlns:th="http://www.thymeleaf.org">
|
|
||||||
|
|
||||||
|
|
||||||
<div class="lesson-page-wrapper">
|
|
||||||
<div class="adoc-content" th:replace="doc:Challenge_2.adoc"></div>
|
|
||||||
<link rel="stylesheet" type="text/css" th:href="@{/lesson_css/challenge2.css}"/>
|
|
||||||
<script th:src="@{/lesson_js/challenge2.js}" language="JavaScript"></script>
|
|
||||||
<div class="attack-container">
|
|
||||||
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
|
|
||||||
|
|
||||||
<div class="container-fluid">
|
|
||||||
<form class="attack-form" accept-charset="UNKNOWN"
|
|
||||||
method="POST" name="form"
|
|
||||||
action="/WebGoat/challenge/2"
|
|
||||||
enctype="application/json;charset=UTF-8">
|
|
||||||
|
|
||||||
<input id="discount" type="hidden" value="0"/>
|
|
||||||
<div class="row">
|
|
||||||
|
|
||||||
<div class="col-xs-3 item-photo">
|
|
||||||
<img style="max-width:100%;" th:src="@{/images/samsung-black.jpg}"/>
|
|
||||||
</div>
|
|
||||||
<div class="col-xs-5" style="border:0px solid gray">
|
|
||||||
<h3>Samsung Galaxy S8</h3>
|
|
||||||
<h5 style="color:#337ab7"><a href="http://www.samsung.com">Samsung</a> ·
|
|
||||||
<small style="color:#337ab7">(124421 reviews)</small>
|
|
||||||
</h5>
|
|
||||||
|
|
||||||
<h6 class="title-price">
|
|
||||||
<small>PRICE</small>
|
|
||||||
</h6>
|
|
||||||
<h3 style="margin-top:0px;"><span>US $</span><span id="price">899</span></h3>
|
|
||||||
|
|
||||||
<div class="section">
|
|
||||||
<h6 class="title-attr" style="margin-top:15px;">
|
|
||||||
<small>COLOR</small>
|
|
||||||
</h6>
|
|
||||||
<div>
|
|
||||||
<div class="attr" style="width:25px;background:lightgrey;"></div>
|
|
||||||
<div class="attr" style="width:25px;background:black;"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="section" style="padding-bottom:5px;">
|
|
||||||
<h6 class="title-attr">
|
|
||||||
<small>CAPACITY</small>
|
|
||||||
</h6>
|
|
||||||
<div>
|
|
||||||
<div class="attr2">64 GB</div>
|
|
||||||
<div class="attr2">128 GB</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="section" style="padding-bottom:5px;">
|
|
||||||
<h6 class="title-attr">
|
|
||||||
<small>QUANTITY</small>
|
|
||||||
</h6>
|
|
||||||
<div>
|
|
||||||
<div class="btn-minus"><span class="glyphicon glyphicon-minus"></span></div>
|
|
||||||
<input class="quantity" value="1"/>
|
|
||||||
<div class="btn-plus"><span class="glyphicon glyphicon-plus"></span></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="section" style="padding-bottom:5px;">
|
|
||||||
<h6 class="title-attr">
|
|
||||||
<small>CHECKOUT CODE</small>
|
|
||||||
</h6>
|
|
||||||
<!--
|
|
||||||
Checkout code: webgoat, owasp, owasp-webgoat
|
|
||||||
-->
|
|
||||||
<input name="checkoutCode" class="checkoutCode" value=""/>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="section" style="padding-bottom:20px;">
|
|
||||||
<button type="submit" class="btn btn-success"><span style="margin-right:20px"
|
|
||||||
class="glyphicon glyphicon-shopping-cart"
|
|
||||||
aria-hidden="true"></span>Buy
|
|
||||||
</button>
|
|
||||||
<h6><a href="#"><span class="glyphicon glyphicon-heart-empty"
|
|
||||||
style="cursor:pointer;"></span>
|
|
||||||
Like</a></h6>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<br/>
|
|
||||||
<form class="attack-form" method="POST" name="form" action="/WebGoat/challenge/flag">
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-addon"><i class="fa fa-flag-checkered" aria-hidden="true"
|
|
||||||
style="font-size:20px"></i></div>
|
|
||||||
<input type="text" class="form-control" id="flag" name="flag"
|
|
||||||
placeholder="a7179f89-906b-4fec-9d99-f15b796e7208"/>
|
|
||||||
</div>
|
|
||||||
<div class="input-group" style="margin-top: 10px">
|
|
||||||
<button type="submit" class="btn btn-primary">Submit flag</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<br/>
|
|
||||||
<div class="attack-feedback"></div>
|
|
||||||
<div class="attack-output"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</html>
|
|
@ -1,72 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
|
|
||||||
<html xmlns:th="http://www.thymeleaf.org">
|
|
||||||
|
|
||||||
|
|
||||||
<div class="lesson-page-wrapper">
|
|
||||||
<div class="adoc-content" th:replace="doc:Challenge_3.adoc"></div>
|
|
||||||
<link rel="stylesheet" type="text/css" th:href="@{/lesson_css/challenge3.css}"/>
|
|
||||||
<script th:src="@{/lesson_js/challenge3.js}" language="JavaScript"></script>
|
|
||||||
<div class="attack-container">
|
|
||||||
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
|
|
||||||
|
|
||||||
<div class="container-fluid">
|
|
||||||
<div class="panel post">
|
|
||||||
<div class="post-heading">
|
|
||||||
<div class="pull-left image">
|
|
||||||
<img th:src="@{/images/avatar1.png}"
|
|
||||||
class="img-circle avatar" alt="user profile image"/>
|
|
||||||
</div>
|
|
||||||
<div class="pull-left meta">
|
|
||||||
<div class="title h5">
|
|
||||||
<a href="#"><b>John Doe</b></a>
|
|
||||||
uploaded a photo.
|
|
||||||
</div>
|
|
||||||
<h6 class="text-muted time">24 days ago</h6>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="post-image">
|
|
||||||
<img th:src="@{images/cat.jpg}" class="image" alt="image post"/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="post-description">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="post-footer">
|
|
||||||
<div class="input-group">
|
|
||||||
<input class="form-control" id="commentInput" placeholder="Add a comment" type="text"/>
|
|
||||||
<span class="input-group-addon">
|
|
||||||
<i id="postComment" class="fa fa-edit" style="font-size: 20px"></i>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<ul class="comments-list">
|
|
||||||
<div id="list">
|
|
||||||
</div>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<form class="attack-form" method="POST" name="form" action="/WebGoat/challenge/flag">
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-addon"><i class="fa fa-flag-checkered" aria-hidden="true"
|
|
||||||
style="font-size:20px"></i></div>
|
|
||||||
<input type="text" class="form-control" id="flag" name="flag"
|
|
||||||
placeholder="a7179f89-906b-4fec-9d99-f15b796e7208"/>
|
|
||||||
</div>
|
|
||||||
<div class="input-group" style="margin-top: 10px">
|
|
||||||
<button type="submit" class="btn btn-primary">Submit flag</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
|
|
||||||
|
|
||||||
<br/>
|
|
||||||
<div class="attack-feedback"></div>
|
|
||||||
<div class="attack-output"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</html>
|
|
@ -1,75 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
|
|
||||||
<html xmlns:th="http://www.thymeleaf.org">
|
|
||||||
|
|
||||||
|
|
||||||
<div class="lesson-page-wrapper">
|
|
||||||
<div class="adoc-content" th:replace="doc:Challenge_4.adoc"></div>
|
|
||||||
<link rel="stylesheet" type="text/css" th:href="@{/lesson_css/challenge4.css}"/>
|
|
||||||
<script th:src="@{/lesson_js/bootstrap.min.js}" language="JavaScript"></script>
|
|
||||||
<script th:src="@{/lesson_js/challenge4.js}" language="JavaScript"></script>
|
|
||||||
<div class="attack-container">
|
|
||||||
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
|
|
||||||
<div class="container-fluid">
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
|
|
||||||
<div class="well">
|
|
||||||
<div class="pull-right">
|
|
||||||
<div class="dropdown">
|
|
||||||
<button type="button" data-toggle="dropdown" class="btn btn-default dropdown-toggle">
|
|
||||||
<i class="fa fa-user"></i> <span class="caret"></span>
|
|
||||||
</button>
|
|
||||||
<ul class="dropdown-menu dropdown-menu-left">
|
|
||||||
<li role="presentation"><a role="menuitem" tabindex="-1"
|
|
||||||
onclick="javascript:login('Guest')"
|
|
||||||
th:text="Guest">current</a></li>
|
|
||||||
<li role="presentation"><a role="menuitem" tabindex="-1"
|
|
||||||
onclick="javascript:login('Tom')"
|
|
||||||
th:text="Tom">current</a></li>
|
|
||||||
<li role="presentation"><a role="menuitem" tabindex="-1"
|
|
||||||
onclick="javascript:login('Jerry')"
|
|
||||||
th:text="Jerry">current</a></li>
|
|
||||||
<li role="presentation"><a role="menuitem" tabindex="-1"
|
|
||||||
onclick="javascript:login('Sylvester')"
|
|
||||||
th:text="Sylvester">current</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<p class="text-right">Welcome back, <b><span id="name"></span></b></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<h3>Vote for your favorite</h3>
|
|
||||||
</div>
|
|
||||||
<div id ="votesList" class="list-group">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<br/>
|
|
||||||
<form class="attack-form" method="POST" name="form" action="/WebGoat/challenge/flag">
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-addon"><i class="fa fa-flag-checkered" aria-hidden="true"
|
|
||||||
style="font-size:20px"></i></div>
|
|
||||||
<input type="text" class="form-control" id="flag" name="flag"
|
|
||||||
placeholder="a7179f89-906b-4fec-9d99-f15b796e7208"/>
|
|
||||||
</div>
|
|
||||||
<div class="input-group" style="margin-top: 10px">
|
|
||||||
<button type="submit" class="btn btn-primary">Submit flag</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<br/>
|
|
||||||
<div class="attack-feedback"></div>
|
|
||||||
<div class="attack-output"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</html>
|
|
@ -1,109 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html xmlns:th="http://www.thymeleaf.org">
|
|
||||||
|
|
||||||
|
|
||||||
<div class="lesson-page-wrapper">
|
|
||||||
<div class="adoc-content" th:replace="doc:Challenge_9.adoc"></div>
|
|
||||||
<script th:src="@{/lesson_js/challenge9.js}" language="JavaScript"></script>
|
|
||||||
|
|
||||||
<div class="attack-container">
|
|
||||||
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
|
|
||||||
|
|
||||||
<div class="container-fluid">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-6">
|
|
||||||
<h4 style="border-bottom: 1px solid #c5c5c5;">
|
|
||||||
<i class="glyphicon glyphicon-user"></i>
|
|
||||||
Account Access
|
|
||||||
</h4>
|
|
||||||
<div style="padding: 20px;" id="form-login">
|
|
||||||
<form id="login-form" class="attack-form" accept-charset="UNKNOWN"
|
|
||||||
method="POST" name="form"
|
|
||||||
action="/WebGoat/challenge/9/login"
|
|
||||||
enctype="application/json;charset=UTF-8" role="form">
|
|
||||||
<fieldset>
|
|
||||||
<div class="form-group input-group">
|
|
||||||
<span class="input-group-addon"> @ </span>
|
|
||||||
<input class="form-control" placeholder="Email" name="email" type="email"
|
|
||||||
required="" autofocus=""/>
|
|
||||||
</div>
|
|
||||||
<div class="form-group input-group">
|
|
||||||
<span class="input-group-addon">
|
|
||||||
<i class="glyphicon glyphicon-lock">
|
|
||||||
</i>
|
|
||||||
</span>
|
|
||||||
<input class="form-control" placeholder="Password" name="password" type="password"
|
|
||||||
value="" required=""/>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<button type="submit" class="btn btn-primary btn-block">
|
|
||||||
Access
|
|
||||||
</button>
|
|
||||||
<p class="help-block">
|
|
||||||
<a class="pull-right text-muted" href="#" id="login">
|
|
||||||
<small>Forgot your password?</small>
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</fieldset>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<div style="display: none;" id="form-login">
|
|
||||||
<h4 class="">
|
|
||||||
Forgot your password?
|
|
||||||
</h4>
|
|
||||||
<form id="login-form" class="attack-form" accept-charset="UNKNOWN"
|
|
||||||
method="POST" name="form"
|
|
||||||
action="/WebGoat/challenge/9/create-password-reset-link"
|
|
||||||
enctype="application/json;charset=UTF-8" role="form">
|
|
||||||
<fieldset>
|
|
||||||
<span class="help-block">
|
|
||||||
Email address you use to log in to your account
|
|
||||||
<br/>
|
|
||||||
We'll send you an email with instructions to choose a new password.
|
|
||||||
</span>
|
|
||||||
<div class="form-group input-group">
|
|
||||||
<span class="input-group-addon">
|
|
||||||
@
|
|
||||||
</span>
|
|
||||||
<input class="form-control" placeholder="Email" name="email" type="email"
|
|
||||||
required=""/>
|
|
||||||
</div>
|
|
||||||
<button type="submit" class="btn btn-primary btn-block" id="btn-login">
|
|
||||||
Continue
|
|
||||||
</button>
|
|
||||||
<p class="help-block">
|
|
||||||
<a class="text-muted" href="#" id="forgot">
|
|
||||||
<small>Account Access</small>
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
</fieldset>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<br/>
|
|
||||||
<form class="attack-form" method="POST" name="form" action="/WebGoat/challenge/flag">
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-addon"><i class="fa fa-flag-checkered" aria-hidden="true"
|
|
||||||
style="font-size:20px"></i></div>
|
|
||||||
<input type="text" class="form-control" id="flag" name="flag"
|
|
||||||
placeholder="a7179f89-906b-4fec-9d99-f15b796e7208"/>
|
|
||||||
</div>
|
|
||||||
<div class="input-group" style="margin-top: 10px">
|
|
||||||
<button type="submit" class="btn btn-primary">Submit flag</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<br/>
|
|
||||||
<div class="attack-feedback"></div>
|
|
||||||
<div class="attack-output"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</html>
|
|
@ -2,7 +2,6 @@ challenge0.title=WebGoat Challenge
|
|||||||
challenge1.title=Admin lost password
|
challenge1.title=Admin lost password
|
||||||
challenge2.title=Get it for free
|
challenge2.title=Get it for free
|
||||||
challenge3.title=Photo comments
|
challenge3.title=Photo comments
|
||||||
challenge4.title=Voting
|
|
||||||
challenge5.title=Without password
|
challenge5.title=Without password
|
||||||
challenge6.title=Creating a new account
|
challenge6.title=Creating a new account
|
||||||
challenge7.title=Admin password reset
|
challenge7.title=Admin password reset
|
||||||
@ -22,8 +21,7 @@ challenge.flag.incorrect=Sorry this is not the correct flag, please try again.
|
|||||||
|
|
||||||
ip.address.unknown=IP address unknown, e-mail has been sent.
|
ip.address.unknown=IP address unknown, e-mail has been sent.
|
||||||
|
|
||||||
login_failed=Login failed
|
|
||||||
login_failed.tom=Sorry only Tom can login at the moment
|
|
||||||
|
|
||||||
required4=Missing username or password, please specify both.
|
required4=Missing username or password, please specify both.
|
||||||
user.not.larry=Please try to log in as Larry not {0}.
|
user.not.larry=Please try to log in as Larry not {0}.
|
Binary file not shown.
Before Width: | Height: | Size: 8.9 KiB |
@ -1,45 +0,0 @@
|
|||||||
$(document).ready(function () {
|
|
||||||
$("#postComment").on("click", function () {
|
|
||||||
var commentInput = $("#commentInput").val();
|
|
||||||
$.ajax({
|
|
||||||
type: 'POST',
|
|
||||||
url: 'challenge/3',
|
|
||||||
data: JSON.stringify({text: commentInput}),
|
|
||||||
contentType: "application/json",
|
|
||||||
dataType: 'json'
|
|
||||||
}).then(
|
|
||||||
function () {
|
|
||||||
getChallenges();
|
|
||||||
$("#commentInput").val('');
|
|
||||||
}
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
var html = '<li class="comment">' +
|
|
||||||
'<div class="pull-left">' +
|
|
||||||
'<img class="avatar" src="images/avatar1.png" alt="avatar"/>' +
|
|
||||||
'</div>' +
|
|
||||||
'<div class="comment-body">' +
|
|
||||||
'<div class="comment-heading">' +
|
|
||||||
'<h4 class="user">USER</h4>' +
|
|
||||||
'<h5 class="time">DATETIME</h5>' +
|
|
||||||
'</div>' +
|
|
||||||
'<p>COMMENT</p>' +
|
|
||||||
'</div>' +
|
|
||||||
'</li>';
|
|
||||||
|
|
||||||
getChallenges();
|
|
||||||
|
|
||||||
function getChallenges() {
|
|
||||||
$("#list").empty();
|
|
||||||
$.get("challenge/3", function (result, status) {
|
|
||||||
for (var i = 0; i < result.length; i++) {
|
|
||||||
var comment = html.replace('USER', result[i].user);
|
|
||||||
comment = comment.replace('DATETIME', result[i].dateTime);
|
|
||||||
comment = comment.replace('COMMENT', result[i].text);
|
|
||||||
$("#list").append(comment);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
@ -1,10 +0,0 @@
|
|||||||
$(document).ready(function() {
|
|
||||||
$('#login').click(function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
$('div#form-login').toggle('500');
|
|
||||||
});
|
|
||||||
$('#forgot').click(function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
$('div#form-login').toggle('500');
|
|
||||||
});
|
|
||||||
});
|
|
@ -1 +0,0 @@
|
|||||||
Changing language can help you find the 'secret' file
|
|
@ -1 +0,0 @@
|
|||||||
Try to change to a different user, maybe you can find the flag?
|
|
@ -1,3 +0,0 @@
|
|||||||
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
|
|
||||||
that password.
|
|
@ -1,49 +0,0 @@
|
|||||||
package org.owasp.webgoat.plugin.challenge2;
|
|
||||||
|
|
||||||
import org.hamcrest.CoreMatchers;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.mockito.runners.MockitoJUnitRunner;
|
|
||||||
import org.owasp.webgoat.assignments.AssignmentEndpointTest;
|
|
||||||
import org.owasp.webgoat.plugin.Flag;
|
|
||||||
import org.owasp.webgoat.plugin.SolutionConstants;
|
|
||||||
import org.springframework.test.web.servlet.MockMvc;
|
|
||||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
|
||||||
|
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
|
||||||
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 5/2/17.
|
|
||||||
*/
|
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
|
||||||
public class Assignment2Test extends AssignmentEndpointTest {
|
|
||||||
|
|
||||||
private MockMvc mockMvc;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setup() {
|
|
||||||
Assignment2 assignment2 = new Assignment2();
|
|
||||||
init(assignment2);
|
|
||||||
new Flag().initFlags();
|
|
||||||
this.mockMvc = standaloneSetup(assignment2).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void success() throws Exception {
|
|
||||||
mockMvc.perform(MockMvcRequestBuilders.post("/challenge/2")
|
|
||||||
.param("checkoutCode", SolutionConstants.SUPER_COUPON_CODE))
|
|
||||||
.andExpect(jsonPath("$.feedback", CoreMatchers.containsString("flag: " + Flag.FLAGS.get(2))))
|
|
||||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(true)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void wrongCouponCode() throws Exception {
|
|
||||||
mockMvc.perform(MockMvcRequestBuilders.post("/challenge/2")
|
|
||||||
.param("checkoutCode", "test"))
|
|
||||||
.andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("assignment.not.solved"))))
|
|
||||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false)));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,161 +0,0 @@
|
|||||||
package org.owasp.webgoat.plugin.challenge4;
|
|
||||||
|
|
||||||
import org.hamcrest.CoreMatchers;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.mockito.runners.MockitoJUnitRunner;
|
|
||||||
import org.owasp.webgoat.plugin.Flag;
|
|
||||||
import org.springframework.test.web.servlet.MockMvc;
|
|
||||||
import org.springframework.test.web.servlet.MvcResult;
|
|
||||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
|
||||||
|
|
||||||
import javax.servlet.http.Cookie;
|
|
||||||
|
|
||||||
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.unauthenticated;
|
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
|
|
||||||
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 5/2/17.
|
|
||||||
*/
|
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
|
||||||
public class VotesEndpointTest {
|
|
||||||
|
|
||||||
private MockMvc mockMvc;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setup() {
|
|
||||||
VotesEndpoint votesEndpoint = new VotesEndpoint();
|
|
||||||
votesEndpoint.initVotes();
|
|
||||||
new Flag().initFlags();
|
|
||||||
this.mockMvc = standaloneSetup(votesEndpoint).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void loginWithUnknownUser() throws Exception {
|
|
||||||
mockMvc.perform(MockMvcRequestBuilders.get("/votings/login")
|
|
||||||
.param("user", "uknown"))
|
|
||||||
.andExpect(unauthenticated());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void loginWithTomShouldGiveJwtToken() throws Exception {
|
|
||||||
mockMvc.perform(MockMvcRequestBuilders.get("/votings/login")
|
|
||||||
.param("user", "Tom"))
|
|
||||||
.andExpect(status().isOk()).andExpect(cookie().exists("access_token"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void loginWithGuestShouldNotGiveJwtToken() throws Exception {
|
|
||||||
mockMvc.perform(MockMvcRequestBuilders.get("/votings/login")
|
|
||||||
.param("user", "Guest"))
|
|
||||||
.andExpect(unauthenticated()).andExpect(cookie().value("access_token", ""));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void userShouldSeeMore() throws Exception {
|
|
||||||
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.get("/votings/login")
|
|
||||||
.param("user", "Tom"))
|
|
||||||
.andExpect(status().isOk()).andExpect(cookie().exists("access_token")).andReturn();
|
|
||||||
mockMvc.perform(MockMvcRequestBuilders.get("/votings")
|
|
||||||
.cookie(mvcResult.getResponse().getCookie("access_token")))
|
|
||||||
.andExpect(jsonPath("$.[*].numberOfVotes").exists());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void guestShouldNotSeeNumberOfVotes() throws Exception {
|
|
||||||
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.get("/votings/login")
|
|
||||||
.param("user", "Guest"))
|
|
||||||
.andExpect(unauthenticated()).andExpect(cookie().exists("access_token")).andReturn();
|
|
||||||
mockMvc.perform(MockMvcRequestBuilders.get("/votings")
|
|
||||||
.cookie(mvcResult.getResponse().getCookie("access_token")))
|
|
||||||
.andExpect(jsonPath("$.[*].numberOfVotes").doesNotExist());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void adminShouldSeeFlags() throws Exception {
|
|
||||||
mockMvc.perform(MockMvcRequestBuilders.get("/votings")
|
|
||||||
.cookie(new Cookie("access_token", "eyJhbGciOiJub25lIn0.eyJhZG1pbiI6InRydWUiLCJ1c2VyIjoiSmVycnkifQ.")))
|
|
||||||
.andExpect(jsonPath("$.[*].flag").isNotEmpty());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void votingIsNotAllowedAsGuest() throws Exception {
|
|
||||||
mockMvc.perform(MockMvcRequestBuilders.post("/votings/Get it for free"))
|
|
||||||
.andExpect(unauthenticated());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void normalUserShouldBeAbleToVote() throws Exception {
|
|
||||||
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.get("/votings/login")
|
|
||||||
.param("user", "Tom"))
|
|
||||||
.andExpect(status().isOk()).andExpect(cookie().exists("access_token")).andReturn();
|
|
||||||
mockMvc.perform(MockMvcRequestBuilders.post("/votings/Get it for free")
|
|
||||||
.cookie(mvcResult.getResponse().getCookie("access_token")));
|
|
||||||
mockMvc.perform(MockMvcRequestBuilders.get("/votings/")
|
|
||||||
.cookie(mvcResult.getResponse().getCookie("access_token")))
|
|
||||||
.andExpect(jsonPath("$..[?(@.title == 'Get it for free')].numberOfVotes", CoreMatchers.hasItem(20001)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void votingForUnknownLessonShouldNotCrash() throws Exception {
|
|
||||||
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.get("/votings/login")
|
|
||||||
.param("user", "Tom"))
|
|
||||||
.andExpect(status().isOk()).andExpect(cookie().exists("access_token")).andReturn();
|
|
||||||
mockMvc.perform(MockMvcRequestBuilders.post("/votings/UKNOWN_VOTE")
|
|
||||||
.cookie(mvcResult.getResponse().getCookie("access_token"))).andExpect(status().isAccepted());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void votingWithInvalidToken() throws Exception {
|
|
||||||
mockMvc.perform(MockMvcRequestBuilders.post("/votings/UKNOWN_VOTE")
|
|
||||||
.cookie(new Cookie("access_token", "abc"))).andExpect(unauthenticated());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void gettingVotesWithInvalidToken() throws Exception {
|
|
||||||
mockMvc.perform(MockMvcRequestBuilders.get("/votings/")
|
|
||||||
.cookie(new Cookie("access_token", "abc"))).andExpect(unauthenticated());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void gettingVotesWithUnknownUserInToken() throws Exception {
|
|
||||||
mockMvc.perform(MockMvcRequestBuilders.get("/votings/")
|
|
||||||
.cookie(new Cookie("access_token", "eyJhbGciOiJub25lIn0.eyJhZG1pbiI6InRydWUiLCJ1c2VyIjoiVW5rbm93biJ9.")))
|
|
||||||
.andExpect(unauthenticated())
|
|
||||||
.andExpect(jsonPath("$.[*].numberOfVotes").doesNotExist());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void gettingVotesForUnknownShouldWork() throws Exception {
|
|
||||||
mockMvc.perform(MockMvcRequestBuilders.get("/votings/")
|
|
||||||
.cookie(new Cookie("access_token", "eyJhbGciOiJub25lIn0.eyJ1c2VyIjoiVW5rbm93biJ9.")))
|
|
||||||
.andExpect(unauthenticated())
|
|
||||||
.andExpect(jsonPath("$.[*].numberOfVotes").doesNotExist());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void gettingVotesForKnownWithoutAdminFieldShouldWork() throws Exception {
|
|
||||||
mockMvc.perform(MockMvcRequestBuilders.get("/votings/")
|
|
||||||
.cookie(new Cookie("access_token", "eyJhbGciOiJub25lIn0.eyJ1c2VyIjoiVG9tIn0.")))
|
|
||||||
.andExpect(status().isOk())
|
|
||||||
.andExpect(jsonPath("$.[*].numberOfVotes").exists());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void gettingVotesWithEmptyToken() throws Exception {
|
|
||||||
mockMvc.perform(MockMvcRequestBuilders.get("/votings/")
|
|
||||||
.cookie(new Cookie("access_token", "")))
|
|
||||||
.andExpect(status().isOk())
|
|
||||||
.andExpect(jsonPath("$.[*].numberOfVotes").doesNotExist());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void votingAsUnknownUserShouldNotBeAllowed() throws Exception {
|
|
||||||
mockMvc.perform(MockMvcRequestBuilders.post("/votings/Get it for free")
|
|
||||||
.cookie(new Cookie("access_token", "eyJhbGciOiJub25lIn0.eyJ1c2VyIjoiVW5rbm93biJ9.")))
|
|
||||||
.andExpect(unauthenticated());
|
|
||||||
}
|
|
||||||
}
|
|
@ -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>8.0.0.M3</version>
|
<version>v8.0.0.M22</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@ -56,7 +56,7 @@ public class ClientSideFiltering extends NewLesson {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getTitle() {
|
public String getTitle() {
|
||||||
return "Client side filtering";
|
return "client.side.filtering.title";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package org.owasp.webgoat.plugin.challenge2;
|
package org.owasp.webgoat.plugin;
|
||||||
|
|
||||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
||||||
|
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.Flag;
|
|
||||||
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;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
@ -11,22 +11,23 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import static org.owasp.webgoat.plugin.SolutionConstants.SUPER_COUPON_CODE;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author nbaars
|
* @author nbaars
|
||||||
* @since 4/6/17.
|
* @since 4/6/17.
|
||||||
*/
|
*/
|
||||||
@AssignmentPath("/challenge/2")
|
@AssignmentPath("/clientSideFiltering/getItForFree")
|
||||||
public class Assignment2 extends AssignmentEndpoint {
|
@AssignmentHints({"client.side.filtering.free.hint1", "client.side.filtering.free.hint2", "client.side.filtering.free.hint3"})
|
||||||
|
public class ClientSideFilteringFreeAssignment extends AssignmentEndpoint {
|
||||||
|
|
||||||
|
public static final String SUPER_COUPON_CODE = "get_it_for_free";
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.POST)
|
@RequestMapping(method = RequestMethod.POST)
|
||||||
public
|
public
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
AttackResult completed(@RequestParam String checkoutCode) throws IOException {
|
AttackResult completed(@RequestParam String checkoutCode) {
|
||||||
if (SUPER_COUPON_CODE.equals(checkoutCode)) {
|
if (SUPER_COUPON_CODE.equals(checkoutCode)) {
|
||||||
return success().feedback("challenge.solved").feedbackArgs(Flag.FLAGS.get(2)).build();
|
return trackProgress(success().build());
|
||||||
}
|
}
|
||||||
return failed().build();
|
return trackProgress(failed().build());
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package org.owasp.webgoat.plugin.challenge2;
|
package org.owasp.webgoat.plugin;
|
||||||
|
|
||||||
import com.beust.jcommander.internal.Lists;
|
import com.beust.jcommander.internal.Lists;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
@ -12,21 +12,21 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import static org.owasp.webgoat.plugin.SolutionConstants.SUPER_COUPON_CODE;
|
import static org.owasp.webgoat.plugin.ClientSideFilteringFreeAssignment.SUPER_COUPON_CODE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author nbaars
|
* @author nbaars
|
||||||
* @since 4/6/17.
|
* @since 4/6/17.
|
||||||
*/
|
*/
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("challenge-store")
|
@RequestMapping("/clientSideFiltering/challenge-store")
|
||||||
public class ShopEndpoint {
|
public class ShopEndpoint {
|
||||||
|
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
private class CheckoutCodes {
|
private class CheckoutCodes {
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private List<CheckoutCode> codes = Lists.newArrayList();
|
private List<CheckoutCode> codes;
|
||||||
|
|
||||||
public Optional<CheckoutCode> get(String code) {
|
public Optional<CheckoutCode> get(String code) {
|
||||||
return codes.stream().filter(c -> c.getCode().equals(code)).findFirst();
|
return codes.stream().filter(c -> c.getCode().equals(code)).findFirst();
|
@ -73,7 +73,96 @@
|
|||||||
<!-- ... of course, you can move them if you want to, but that will not look consistent to other lessons -->
|
<!-- ... of course, you can move them if you want to, but that will not look consistent to other lessons -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="lesson-page-wrapper">
|
||||||
|
<div class="adoc-content" th:replace="doc:ClientSideFiltering_final.adoc"></div>
|
||||||
|
<link rel="stylesheet" type="text/css" th:href="@{/lesson_css/clientSideFilteringFree.css}"/>
|
||||||
|
<script th:src="@{/lesson_js/clientSideFilteringFree.js}" language="JavaScript"></script>
|
||||||
|
<div class="attack-container">
|
||||||
|
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
|
||||||
|
|
||||||
|
<div class="container-fluid">
|
||||||
|
<form class="attack-form" accept-charset="UNKNOWN"
|
||||||
|
method="POST" name="form"
|
||||||
|
action="/WebGoat/clientSideFiltering/getItForFree"
|
||||||
|
enctype="application/json;charset=UTF-8">
|
||||||
|
|
||||||
|
<input id="discount" type="hidden" value="0"/>
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<div class="col-xs-3 item-photo">
|
||||||
|
<img style="max-width:100%;" th:src="@{/images/samsung-black.jpg}"/>
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-5" style="border:0px solid gray">
|
||||||
|
<h3>Samsung Galaxy S8</h3>
|
||||||
|
<h5 style="color:#337ab7"><a href="http://www.samsung.com">Samsung</a> ·
|
||||||
|
<small style="color:#337ab7">(124421 reviews)</small>
|
||||||
|
</h5>
|
||||||
|
|
||||||
|
<h6 class="title-price">
|
||||||
|
<small>PRICE</small>
|
||||||
|
</h6>
|
||||||
|
<h3 style="margin-top:0px;"><span>US $</span><span id="price">899</span></h3>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<h6 class="title-attr" style="margin-top:15px;">
|
||||||
|
<small>COLOR</small>
|
||||||
|
</h6>
|
||||||
|
<div>
|
||||||
|
<div class="attr" style="width:25px;background:lightgrey;"></div>
|
||||||
|
<div class="attr" style="width:25px;background:black;"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="section" style="padding-bottom:5px;">
|
||||||
|
<h6 class="title-attr">
|
||||||
|
<small>CAPACITY</small>
|
||||||
|
</h6>
|
||||||
|
<div>
|
||||||
|
<div class="attr2">64 GB</div>
|
||||||
|
<div class="attr2">128 GB</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="section" style="padding-bottom:5px;">
|
||||||
|
<h6 class="title-attr">
|
||||||
|
<small>QUANTITY</small>
|
||||||
|
</h6>
|
||||||
|
<div>
|
||||||
|
<div class="btn-minus"><span class="glyphicon glyphicon-minus"></span></div>
|
||||||
|
<input class="quantity" value="1"/>
|
||||||
|
<div class="btn-plus"><span class="glyphicon glyphicon-plus"></span></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section" style="padding-bottom:5px;">
|
||||||
|
<h6 class="title-attr">
|
||||||
|
<small>CHECKOUT CODE</small>
|
||||||
|
</h6>
|
||||||
|
<!--
|
||||||
|
Checkout code: webgoat, owasp, owasp-webgoat
|
||||||
|
-->
|
||||||
|
<input name="checkoutCode" class="checkoutCode" value=""/>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section" style="padding-bottom:20px;">
|
||||||
|
<button type="submit" class="btn btn-success"><span style="margin-right:20px"
|
||||||
|
class="glyphicon glyphicon-shopping-cart"
|
||||||
|
aria-hidden="true"></span>Buy
|
||||||
|
</button>
|
||||||
|
<h6><a href="#"><span class="glyphicon glyphicon-heart-empty"
|
||||||
|
style="cursor:pointer;"></span>
|
||||||
|
Like</a></h6>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<br/>
|
||||||
|
<br/>
|
||||||
|
<div class="attack-feedback"></div>
|
||||||
|
<div class="attack-output"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
client.side.filtering.title=Client side filtering
|
||||||
ClientSideFilteringSelectUser=Select user:
|
ClientSideFilteringSelectUser=Select user:
|
||||||
ClientSideFilteringUserID=User ID
|
ClientSideFilteringUserID=User ID
|
||||||
ClientSideFilteringFirstName=First Name
|
ClientSideFilteringFirstName=First Name
|
||||||
@ -25,3 +26,7 @@ ClientSideFilteringHint10=Stage 2: Your filter operator should look something li
|
|||||||
ClientSideFilteringInstructions1=STAGE 1: You are logged in as Moe Stooge, CSO of Goat Hills Financial. You have access to everyone in the company's information, except the CEO, . Or at least you shouldn't have access to the CEO's information. For this exercise, examine the contents of the page to see what extra information you can find.
|
ClientSideFilteringInstructions1=STAGE 1: You are logged in as Moe Stooge, CSO of Goat Hills Financial. You have access to everyone in the company's information, except the CEO, . Or at least you shouldn't have access to the CEO's information. For this exercise, examine the contents of the page to see what extra information you can find.
|
||||||
ClientSideFilteringInstructions2=STAGE 2: Now, fix the problem. Modify the server to only return results that Moe Stooge is allowed to see.
|
ClientSideFilteringInstructions2=STAGE 2: Now, fix the problem. Modify the server to only return results that Moe Stooge is allowed to see.
|
||||||
ClientSideFiltering.incorrect=This is not the salary from Neville Bartholomew...
|
ClientSideFiltering.incorrect=This is not the salary from Neville Bartholomew...
|
||||||
|
|
||||||
|
client.side.filtering.free.hint1=Look through the webpage inspect the sources etc
|
||||||
|
client.side.filtering.free.hint2=Try to see the flow of request from the page to the backend
|
||||||
|
client.side.fiterling.free.hint3=One of the responses contains the answer
|
||||||
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
@ -38,7 +38,7 @@ $(document).ready(function () {
|
|||||||
})
|
})
|
||||||
$(".checkoutCode").on("blur", function () {
|
$(".checkoutCode").on("blur", function () {
|
||||||
var checkoutCode = $(".checkoutCode").val();
|
var checkoutCode = $(".checkoutCode").val();
|
||||||
$.get("challenge-store/coupons/" + checkoutCode, function (result, status) {
|
$.get("clientSideFiltering/challenge-store/coupons/" + checkoutCode, function (result, status) {
|
||||||
var discount = result.discount;
|
var discount = result.discount;
|
||||||
if (discount > 0) {
|
if (discount > 0) {
|
||||||
$('#discount').text(discount);
|
$('#discount').text(discount);
|
@ -0,0 +1,49 @@
|
|||||||
|
package org.owasp.webgoat.plugin;
|
||||||
|
|
||||||
|
import org.hamcrest.CoreMatchers;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.runners.MockitoJUnitRunner;
|
||||||
|
import org.owasp.webgoat.plugins.LessonTest;
|
||||||
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
|
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||||
|
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
import static org.owasp.webgoat.plugin.ClientSideFilteringFreeAssignment.SUPER_COUPON_CODE;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author nbaars
|
||||||
|
* @since 5/2/17.
|
||||||
|
*/
|
||||||
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
|
public class ClientSideFilteringFreeAssignmentTest extends LessonTest {
|
||||||
|
|
||||||
|
private MockMvc mockMvc;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() {
|
||||||
|
ClientSideFiltering clientSideFiltering = new ClientSideFiltering();
|
||||||
|
when(webSession.getCurrentLesson()).thenReturn(clientSideFiltering);
|
||||||
|
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
|
||||||
|
when(webSession.getUserName()).thenReturn("unit-test");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void success() throws Exception {
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders.post("/clientSideFiltering/getItForFree")
|
||||||
|
.param("checkoutCode", SUPER_COUPON_CODE))
|
||||||
|
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(true)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void wrongCouponCode() throws Exception {
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders.post("/clientSideFiltering/getItForFree")
|
||||||
|
.param("checkoutCode", "test"))
|
||||||
|
.andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("assignment.not.solved"))))
|
||||||
|
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false)));
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package org.owasp.webgoat.plugin.challenge2;
|
package org.owasp.webgoat.plugin;
|
||||||
|
|
||||||
import org.hamcrest.CoreMatchers;
|
import org.hamcrest.CoreMatchers;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@ -9,7 +9,7 @@ import org.springframework.test.web.servlet.MockMvc;
|
|||||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
import static org.owasp.webgoat.plugin.SolutionConstants.SUPER_COUPON_CODE;
|
import static org.owasp.webgoat.plugin.ClientSideFilteringFreeAssignment.SUPER_COUPON_CODE;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||||
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;
|
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;
|
||||||
|
|
||||||
@ -30,28 +30,28 @@ public class ShopEndpointTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getSuperCoupon() throws Exception {
|
public void getSuperCoupon() throws Exception {
|
||||||
mockMvc.perform(MockMvcRequestBuilders.get("/challenge-store/coupons/" + SUPER_COUPON_CODE))
|
mockMvc.perform(MockMvcRequestBuilders.get("/clientSideFiltering/challenge-store/coupons/" + SUPER_COUPON_CODE))
|
||||||
.andExpect(jsonPath("$.code", CoreMatchers.is(SUPER_COUPON_CODE)))
|
.andExpect(jsonPath("$.code", CoreMatchers.is(SUPER_COUPON_CODE)))
|
||||||
.andExpect(jsonPath("$.discount", CoreMatchers.is(100)));
|
.andExpect(jsonPath("$.discount", CoreMatchers.is(100)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getCoupon() throws Exception {
|
public void getCoupon() throws Exception {
|
||||||
mockMvc.perform(MockMvcRequestBuilders.get("/challenge-store/coupons/webgoat"))
|
mockMvc.perform(MockMvcRequestBuilders.get("/clientSideFiltering/challenge-store/coupons/webgoat"))
|
||||||
.andExpect(jsonPath("$.code", CoreMatchers.is("webgoat")))
|
.andExpect(jsonPath("$.code", CoreMatchers.is("webgoat")))
|
||||||
.andExpect(jsonPath("$.discount", CoreMatchers.is(25)));
|
.andExpect(jsonPath("$.discount", CoreMatchers.is(25)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void askForUnknownCouponCode() throws Exception {
|
public void askForUnknownCouponCode() throws Exception {
|
||||||
mockMvc.perform(MockMvcRequestBuilders.get("/challenge-store/coupons/does-not-exists"))
|
mockMvc.perform(MockMvcRequestBuilders.get("/clientSideFiltering/challenge-store/coupons/does-not-exists"))
|
||||||
.andExpect(jsonPath("$.code", CoreMatchers.is("no")))
|
.andExpect(jsonPath("$.code", CoreMatchers.is("no")))
|
||||||
.andExpect(jsonPath("$.discount", CoreMatchers.is(0)));
|
.andExpect(jsonPath("$.discount", CoreMatchers.is(0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void fetchAllTheCouponsShouldContainGetItForFree() throws Exception {
|
public void fetchAllTheCouponsShouldContainGetItForFree() throws Exception {
|
||||||
mockMvc.perform(MockMvcRequestBuilders.get("/challenge-store/coupons/"))
|
mockMvc.perform(MockMvcRequestBuilders.get("/clientSideFiltering/challenge-store/coupons/"))
|
||||||
.andExpect(jsonPath("$.codes[3].code", is("get_it_for_free")));
|
.andExpect(jsonPath("$.codes[3].code", is("get_it_for_free")));
|
||||||
}
|
}
|
||||||
|
|
@ -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>8.0.0.M3</version>
|
<version>v8.0.0.M22</version>
|
||||||
</parent>
|
</parent>
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
|
@ -60,7 +60,7 @@ public class CrossSiteScripting extends NewLesson {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getTitle() {
|
public String getTitle() {
|
||||||
return "Cross Site Scripting";
|
return "xss.title";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
# XSS success, failure messages and hints
|
# XSS success, failure messages and hints
|
||||||
|
xss.title=Cross Site Scripting
|
||||||
xss-reflected-5a-success=well done, but alerts aren't very impressive are they? Please continue.
|
xss-reflected-5a-success=well done, but alerts aren't very impressive are they? Please continue.
|
||||||
xss-reflected-5a-failure=Try again. We do want to see this specific javascript (in case you are trying to do something more fancy)
|
xss-reflected-5a-failure=Try again. We do want to see this specific javascript (in case you are trying to do something more fancy)
|
||||||
xss-reflected-5b-success=Correct ... because <ul><li>The script was not triggered by the URL/QueryString</li><li>Even if you use the attack URL in a new tab, it won't execute (becuase of response type). Try it if you like.</li></ul>
|
xss-reflected-5b-success=Correct ... because <ul><li>The script was not triggered by the URL/QueryString</li><li>Even if you use the attack URL in a new tab, it won't execute (becuase of response type). Try it if you like.</li></ul>
|
||||||
xss-reflected-5b-failure=Nope, pretty easy to guess now though.
|
xss-reflected-5b-failure=Nope, pretty easy to guess now though.
|
||||||
xss-reflected-6a-success=Correct! Now, see if you can send in an exploit to that route in the next assignment.
|
xss-reflected-6a-success=Correct! Now, see if you can send in an exploit to that route in the next assignment.
|
||||||
xss-reflected-6a-failure=No, look at the example. Check the GoatRouter.js file. It should be pretty easy to determine.
|
xss-reflected-6a-failure=No, look at the example. Check the <a href="/WebGoat/js/goatApp/view/GoatRouter.js" target="_blank">GoatRouter.js</a> file. It should be pretty easy to determine.
|
||||||
xss.lesson1.failure=Are you sure? Try using a tab from a different site.
|
xss.lesson1.failure=Are you sure? Try using a tab from a different site.
|
||||||
xss-dom-message-success=Correct, I hope you didn't cheat, using the console!
|
xss-dom-message-success=Correct, I hope you didn't cheat, using the console!
|
||||||
xss-dom-message-failure=Incorrect, keep trying. It should be obvious in the log when you are successful.
|
xss-dom-message-failure=Incorrect, keep trying. It should be obvious in the log when you are successful.
|
||||||
|
@ -4,7 +4,7 @@ You should have been able to execute script with the last example. At this point
|
|||||||
|
|
||||||
Why is that?
|
Why is that?
|
||||||
|
|
||||||
That is because there is no link that would tigger that XSS.
|
That is because there is no link that would trigger that XSS.
|
||||||
You can try it yourself to see what happens ... go to (substitute localhost with your server's name or IP if you need to):
|
You can try it yourself to see what happens ... go to (substitute localhost with your server's name or IP if you need to):
|
||||||
|
|
||||||
link: http://localhost:8080/WebGoat/CrossSiteScripting/attack5a?QTY1=1&QTY2=1&QTY3=1&QTY4=1&field1=<script>alert('myjavascripthere')</script>4128+3214+0002+1999&field2=111
|
link: http://localhost:8080/WebGoat/CrossSiteScripting/attack5a?QTY1=1&QTY2=1&QTY3=1&QTY4=1&field1=<script>alert('my%20javascript%20here')</script>4128+3214+0002+1999&field2=111
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
== Ientify Potential for DOM-Based XSS
|
== Identify Potential for DOM-Based XSS
|
||||||
|
|
||||||
DOM-Based XSS can usually be found by looking for the route configurations in the client-side code.
|
DOM-Based XSS can usually be found by looking for the route configurations in the client-side code.
|
||||||
Look for a route that takes inputs that you can ID being 'reflected' to the page.
|
Look for a route that takes inputs that are being 'reflected' to the page.
|
||||||
|
|
||||||
For this example, you'll want to look for some 'test' code in the route handlers (WebGoat uses backbone as its primary javascript library).
|
For this example, you'll want to look for some 'test' code in the route handlers (WebGoat uses backbone as its primary javascript library).
|
||||||
Sometimes, test code gets left in production (and often times test code is very simple and lacks security or any quality controls!).
|
Sometimes, test code gets left in production (and often times test code is very simple and lacks security or any quality controls!).
|
||||||
|
|
||||||
Your objective is to find the route and exploit it. First though ... what is the base route? As an example, look at the URL for this lesson ...
|
Your objective is to find the route and exploit it. First though ... what is the base route? As an example, look at the URL for this lesson ...
|
||||||
it should look something like /WebGoat/start.mvc#lesson/CrossSiteScripting.lesson/5 (although maybe slightly different). The 'base route' in this case is:
|
it should look something like /WebGoat/start.mvc#lesson/CrossSiteScripting.lesson/9. The 'base route' in this case is:
|
||||||
*start.mvc#lesson/*
|
*start.mvc#lesson/*
|
||||||
|
The *CrossSiteScripting.lesson/9* after that are parameters that are processed by the javascript route handler.
|
||||||
|
|
||||||
The *CrossSiteScripting.lesson/#* after that are parameters that are processed by javascript route handler.
|
So, what is the route for the test code that stayed in the app during production?
|
||||||
|
To answer this question, you have to check the javascript source.
|
||||||
So, what is test route for this test code?
|
|
@ -8,4 +8,4 @@ The function you want to execute is ...
|
|||||||
|
|
||||||
Sure, you could just use console/debug to trigger it, but you need to trigger it via a URL in a new tab.
|
Sure, you could just use console/debug to trigger it, but you need to trigger it via a URL in a new tab.
|
||||||
|
|
||||||
Once you do trigger it, a subsequent response will come to the browser with a random number. Put that random number in below.
|
Once you do trigger it, a subsequent response will come to your browser's console with a random number. Put that random number in below.
|
||||||
|
@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
|
|
||||||
=== Why?
|
=== Why?
|
||||||
Hopefully we've covered that by now. Bottom line, you don't want someone else's code running in the context of your users and their logged-in seession
|
Hopefully we've covered that by now. Bottom line, you don't want someone else's code running in the context of your users and their logged-in session
|
||||||
|
|
||||||
=== What to encode?
|
=== What to encode?
|
||||||
The basic premise of defending against XSS is *output endoding* any untrusted input that goes to the screen.
|
The basic premise of defending against XSS is *output encoding* any untrusted input that goes to the screen.
|
||||||
That may be changing with more sophisticated attacks, but is still the best defense we currently have. *AND* ... *context matters*
|
That may be changing with more sophisticated attacks, but is still the best defense we currently have. *AND* ... *context matters*
|
||||||
|
|
||||||
Another word on 'untrusted input'. If in doubt, treat everything (even data you populated in your DB as untrusted).
|
Another word on 'untrusted input'. If in doubt, treat everything (even data you populated in your DB as untrusted).
|
||||||
|
@ -33,8 +33,10 @@ import org.mockito.runners.MockitoJUnitRunner;
|
|||||||
import org.owasp.webgoat.assignments.AssignmentEndpointTest;
|
import org.owasp.webgoat.assignments.AssignmentEndpointTest;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.test.web.servlet.MockMvc;
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
|
import org.springframework.test.web.servlet.MvcResult;
|
||||||
import org.springframework.test.web.servlet.ResultActions;
|
import org.springframework.test.web.servlet.ResultActions;
|
||||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||||
@ -80,13 +82,13 @@ public class StoredXssCommentsTest extends AssignmentEndpointTest {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
//Ensures it is vulnerable
|
//Ensures it is vulnerable
|
||||||
// @Test
|
@Test
|
||||||
// public void isNotEncoded() throws Exception {
|
public void isNotEncoded() throws Exception {
|
||||||
// //do get to get comments after posting xss payload
|
//do get to get comments after posting xss payload
|
||||||
// ResultActions taintedResults = mockMvc.perform(MockMvcRequestBuilders.get("/CrossSiteScripting/stored-xss"));
|
ResultActions taintedResults = mockMvc.perform(MockMvcRequestBuilders.get("/CrossSiteScripting/stored-xss"));
|
||||||
// taintedResults.andExpect(jsonPath("$[0].text",CoreMatchers.is(CoreMatchers.containsString("<script>console.warn('unit test me')</script>"))));
|
MvcResult mvcResult = taintedResults.andReturn();
|
||||||
// }
|
assert(mvcResult.getResponse().getContentAsString().contains("<script>console.warn"));
|
||||||
|
}
|
||||||
|
|
||||||
//Could be used to test an encoding solution ... commented out so build will pass. Uncommenting will fail build, but leaving in as positive Security Unit Test
|
//Could be used to test an encoding solution ... commented out so build will pass. Uncommenting will fail build, but leaving in as positive Security Unit Test
|
||||||
// @Test
|
// @Test
|
||||||
|
@ -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>8.0.0.M3</version>
|
<version>v8.0.0.M22</version>
|
||||||
</parent>
|
</parent>
|
||||||
</project>
|
</project>
|
@ -6,12 +6,9 @@ import org.owasp.webgoat.assignments.AssignmentPath;
|
|||||||
import org.owasp.webgoat.assignments.AttackResult;
|
import org.owasp.webgoat.assignments.AttackResult;
|
||||||
import org.owasp.webgoat.session.UserSessionData;
|
import org.owasp.webgoat.session.UserSessionData;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by jason on 9/29/17.
|
* Created by jason on 9/29/17.
|
||||||
*/
|
*/
|
||||||
@ -24,12 +21,16 @@ public class CSRFConfirmFlag1 extends AssignmentEndpoint {
|
|||||||
UserSessionData userSessionData;
|
UserSessionData userSessionData;
|
||||||
|
|
||||||
@PostMapping(produces = {"application/json"})
|
@PostMapping(produces = {"application/json"})
|
||||||
public @ResponseBody AttackResult completed(String confirmFlagVal) {
|
public @ResponseBody
|
||||||
|
AttackResult completed(String confirmFlagVal) {
|
||||||
|
|
||||||
if (confirmFlagVal.equals(userSessionData.getValue("csrf-get-success").toString())) {
|
Object userSessionDataStr = userSessionData.getValue("csrf-get-success");
|
||||||
return success().feedback("csrf-get-null-referer.success").output("Correct, the flag was " + userSessionData.getValue("csrf-get-success")).build();
|
if (userSessionDataStr != null && confirmFlagVal.equals(userSessionDataStr.toString())) {
|
||||||
|
return trackProgress(
|
||||||
|
success().feedback("csrf-get-null-referer.success").output("Correct, the flag was " + userSessionData.getValue("csrf-get-success")).build()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return failed().feedback("").build();
|
return trackProgress(failed().build());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,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 host = request.getHeader("host");
|
String host = request.getHeader("host");
|
||||||
return !StringUtils.contains(referer, host);
|
if (referer != null) {
|
||||||
|
return !referer.contains(host);
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean requestContainsWebGoatCookie(Cookie[] cookies) {
|
private boolean requestContainsWebGoatCookie(Cookie[] cookies) {
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user