Compare commits

...

6 Commits

37 changed files with 483 additions and 334 deletions

View File

@ -1,4 +1,4 @@
# WebGoat: A deliberately insecure Web Application
# WebGoat 8: A deliberately insecure Web Application
[![Build Status](https://travis-ci.org/WebGoat/WebGoat.svg?branch=develop)](https://travis-ci.org/WebGoat/WebGoat)
[![Coverage Status](https://coveralls.io/repos/WebGoat/WebGoat/badge.svg?branch=develop&service=github)](https://coveralls.io/github/WebGoat/WebGoat?branch=master)
@ -6,10 +6,6 @@
[![Dependency Status](https://www.versioneye.com/user/projects/562da95ae346d7000e0369aa/badge.svg?style=flat)](https://www.versioneye.com/user/projects/562da95ae346d7000e0369aa)
[![OWASP Labs](https://img.shields.io/badge/owasp-labs-orange.svg)](https://www.owasp.org/index.php/OWASP_Project_Inventory#tab=Labs_Projects)
# Important
This is the development version of WebGoat 8, if you are looking for a released stable version please go to: https://github.com/WebGoat/WebGoat/wiki/Running-WebGoat
# Introduction
@ -68,6 +64,11 @@ Download the latest WebWolf release from [https://github.com/WebGoat/WebGoat/rel
java -jar webgoat-server-<<version>>.jar
```
By default WebGoat starts at port 8080 in order to change this use the following property:
```Shell
java -jar webgoat-server-<<version>>.jar --server.port=9090
```
## 3. Run from the sources
@ -88,20 +89,22 @@ Now let's start by compiling the project.
```Shell
cd WebGoat
git checkout develop
git checkout <<branch_name>>
mvn clean install
```
Now we are ready to run the project. WebGoat 8.x is using Spring-Boot.
```Shell
mvn -pl webwolf spring-boot:run
mvn -pl webgoat-server spring-boot:run
```
... you should be running webgoat on localhost:8080/WebGoat momentarily
To change IP addresss add the following variable to WebGoat/webgoat-container/src/main/resources/application.properties file
```server.address=x.x.x.x
```
server.address=x.x.x.x
```
# Vagrant

View File

@ -1,34 +1,15 @@
version: '2.0'
services:
mongo:
image: mongo:latest
expose:
- "27017"
volumes:
- './mongo-data:/data/db'
webgoat:
build: webgoat-server/
command: "sh /home/webgoat/start.sh"
ports:
- "8080:8080"
depends_on:
[mongo, activemq]
environment:
WG_MONGO_PORT: 27017
WG_MONGO_HOST: mongo
WG_MQ_HOST: activemq
WG_MQ_PORT: 61616
WG_INTERNAL_MONGO: "false"
webwolf:
build: webwolf/
command: "sh /home/webwolf/start.sh"
depends_on:
- webgoat
ports:
- "8081:8081"
environment:
WG_MONGO_PORT: 27017
WG_MONGO_HOST: mongo
WG_MQ_HOST: activemq
WG_MQ_PORT: 61616
- "8081:8081"

View File

@ -12,7 +12,7 @@ if [ "${BRANCH}" == "master" ] && [ ! -z "${TRAVIS_TAG}" ]; then
docker push $REPO
elif [ ! -z "${TRAVIS_TAG}" ]; then
# 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} .
docker build --build-arg webgoat_version=${TRAVIS_TAG:1} -f Dockerfile -t $REPO:${TRAVIS_TAG} -t $REPO:latest .
docker push $REPO
elif [ "${BRANCH}" == "develop" ]; then
docker build -f Dockerfile -t $REPO:snapshot .

View File

@ -36,16 +36,6 @@
</profiles>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
<version>2.0.0</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<resources>
<resource>
@ -127,7 +117,7 @@
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
@ -202,12 +192,6 @@
<version>${junit.version}</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>com.github.fakemongo</groupId>
<artifactId>fongo</artifactId>
<version>2.1.0</version>
<scope>test</scope>
</dependency>
<!-- ************* END: Dependencies for Unit and Integration Testing ************** -->
<!-- ************* END: <dependencies> ************** -->
</dependencies>

View File

@ -42,6 +42,7 @@ import org.thymeleaf.templateresolver.TemplateResolver;
import java.io.*;
import java.util.Map;
import static org.apache.commons.lang3.CharEncoding.UTF_8;
import static org.asciidoctor.Asciidoctor.Factory.create;
/**
@ -82,7 +83,7 @@ public class AsciiDoctorTemplateResolver extends TemplateResolver {
} else {
StringWriter writer = new StringWriter();
asciidoctor.convert(new InputStreamReader(is), writer, createAttributes());
return new ByteArrayInputStream(writer.getBuffer().toString().getBytes());
return new ByteArrayInputStream(writer.getBuffer().toString().getBytes(UTF_8));
}
} catch (IOException e) {
//no html yet

View File

@ -23,11 +23,5 @@ public class CleanupLocalProgressFiles {
@PostConstruct
public void clean() {
File dir = new File(webgoatHome);
//do it safe, check whether the subdir mongodb is available as subdirectory
File[] mongoDir = dir.listFiles(f -> f.isDirectory() && f.getName().contains("mongodb"));
if (mongoDir != null && mongoDir.length == 1) {
FileSystemUtils.deleteRecursively(dir);
}
}
}

View File

@ -2,6 +2,10 @@ package org.owasp.webgoat.lessons;
import lombok.*;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Transient;
import java.util.List;
/**
@ -38,11 +42,14 @@ import java.util.List;
@NoArgsConstructor
@Getter
@EqualsAndHashCode
@Entity
public class Assignment {
@NonNull
@Id
private String name;
@NonNull
private String path;
@Transient
private List<String> hints;
}

View File

@ -7,6 +7,7 @@ import lombok.Getter;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.lessons.Assignment;
import javax.persistence.*;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@ -44,16 +45,20 @@ import java.util.stream.Collectors;
* @version $Id: $Id
* @since October 29, 2003
*/
@Entity
public class LessonTracker {
@Getter
@Id
private String lessonName;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private final Set<Assignment> solvedAssignments = Sets.newHashSet();
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private final List<Assignment> allAssignments = Lists.newArrayList();
@Getter
private int numberOfAttempts = 0;
protected LessonTracker() {
//Mongo
private LessonTracker() {
//JPA
}
public LessonTracker(AbstractLesson lesson) {

View File

@ -1,6 +1,6 @@
package org.owasp.webgoat.users;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
@ -8,7 +8,7 @@ import java.util.List;
* @author nbaars
* @since 3/19/17.
*/
public interface UserRepository extends MongoRepository<WebGoatUser, String> {
public interface UserRepository extends JpaRepository<WebGoatUser, String> {
WebGoatUser findByUsername(String username);

View File

@ -5,8 +5,8 @@ import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.lessons.Assignment;
import org.springframework.data.annotation.Id;
import javax.persistence.*;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@ -44,12 +44,16 @@ import java.util.stream.Collectors;
* @since October 29, 2003
*/
@Slf4j
@Entity
public class UserTracker {
@Id
private final String user;
private String user;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private List<LessonTracker> lessonTrackers = Lists.newArrayList();
private UserTracker() {}
public UserTracker(final String user) {
this.user = user;
}

View File

@ -1,12 +1,12 @@
package org.owasp.webgoat.users;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.jpa.repository.JpaRepository;
/**
* @author nbaars
* @since 4/30/17.
*/
public interface UserTrackerRepository extends MongoRepository<UserTracker, String> {
public interface UserTrackerRepository extends JpaRepository<UserTracker, String> {
}

View File

@ -1,13 +1,14 @@
package org.owasp.webgoat.users;
import lombok.Getter;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Transient;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Transient;
import java.util.Collection;
import java.util.Collections;
@ -16,6 +17,7 @@ import java.util.Collections;
* @since 3/19/17.
*/
@Getter
@Entity
public class WebGoatUser implements UserDetails {
public static final String ROLE_USER = "WEBGOAT_USER";

View File

@ -4,6 +4,9 @@ server.session.timeout=600
server.contextPath=/WebGoat
server.port=8080
spring.datasource.url=jdbc:hsqldb:file:${webgoat.server.directory}/data/webgoat
spring.jpa.hibernate.ddl-auto=update
logging.level.org.springframework=WARN
logging.level.org.springframework.boot.devtools=WARN
@ -28,7 +31,6 @@ webgoat.feedback.address.html=<A HREF=mailto:webgoat@owasp.org>webgoat@owasp.org
webgoat.database.driver=org.hsqldb.jdbcDriver
webgoat.database.connection.string=jdbc:hsqldb:mem:{USER}
webgoat.default.language=en
webgoat.embedded.mongo=${WG_INTERNAL_MONGO:true}
webwolf.host=${WEBWOLF_HOST:localhost}
webwolf.port=${WEBWOLF_PORT:8081}
@ -39,10 +41,5 @@ webwolf.url.mail=http://${webwolf.host}:${webwolf.port}/mail
spring.jackson.serialization.indent_output=true
spring.jackson.serialization.write-dates-as-timestamps=false
spring.data.mongodb.host=${WG_MONGO_HOST:localhost}
spring.data.mongodb.port=${WG_MONGO_PORT:27017}
spring.data.mongodb.database=webgoat
spring.mongodb.embedded.storage.databaseDir=${webgoat.user.directory}/mongodb/
#For static file refresh ... and faster dev :D
spring.devtools.restart.additional-paths=webgoat-container/src/main/resources/static/js,webgoat-container/src/main/resources/static/css

View File

@ -1,23 +0,0 @@
package org.owasp.webgoat.plugins;
import com.github.fakemongo.Fongo;
import com.mongodb.MongoClient;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.config.AbstractMongoConfiguration;
/**
* Using Fongo for embedded in memory MongoDB testing
*/
@Configuration
public class TestConfig extends AbstractMongoConfiguration {
@Override
protected String getDatabaseName() {
return "test";
}
@Override
public MongoClient mongo() throws Exception {
return new Fongo(getDatabaseName()).getMongo();
}
}

View File

@ -0,0 +1,29 @@
package org.owasp.webgoat.users;
import org.assertj.core.api.Assertions;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.junit4.SpringRunner;
@DataJpaTest
@RunWith(SpringRunner.class)
public class UserRepositoryTest {
@Autowired
private UserRepository userRepository;
@Test
public void userShouldBeSaved() {
WebGoatUser user = new WebGoatUser("test", "password");
userRepository.saveAndFlush(user);
user = userRepository.findByUsername("test");
Assertions.assertThat(user.getUsername()).isEqualTo("test");
Assertions.assertThat(user.getPassword()).isEqualTo("password");
}
}

View File

@ -0,0 +1,101 @@
package org.owasp.webgoat.users;
import org.assertj.core.api.Assertions;
import org.assertj.core.util.Lists;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.owasp.webgoat.lessons.Assignment;
import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.lessons.NewLesson;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;
@DataJpaTest
@RunWith(SpringRunner.class)
public class UserTrackerRepositoryTest {
private class TestLesson extends NewLesson {
@Override
public Category getDefaultCategory() {
return Category.AJAX_SECURITY;
}
@Override
public List<String> getHints() {
return Lists.newArrayList();
}
@Override
public Integer getDefaultRanking() {
return 12;
}
@Override
public String getTitle() {
return "test";
}
@Override
public String getId() {
return "test";
}
@Override
public List<Assignment> getAssignments() {
Assignment assignment = new Assignment("test", "test", Lists.newArrayList());
return Lists.newArrayList(assignment);
}
}
@Autowired
private UserTrackerRepository userTrackerRepository;
@Test
public void saveUserTracker() {
UserTracker userTracker = new UserTracker("test");
LessonTracker lessonTracker = userTracker.getLessonTracker(new TestLesson());
userTrackerRepository.save(userTracker);
userTracker = userTrackerRepository.findOne("test");
Assertions.assertThat(userTracker.getLessonTracker("test")).isNotNull();
}
@Test
public void solvedAssignmentsShouldBeSaved() {
UserTracker userTracker = new UserTracker("test");
TestLesson lesson = new TestLesson();
userTracker.getLessonTracker(lesson);
userTracker.assignmentFailed(lesson);
userTracker.assignmentFailed(lesson);
userTracker.assignmentSolved(lesson, "test");
userTrackerRepository.saveAndFlush(userTracker);
userTracker = userTrackerRepository.findOne("test");
Assertions.assertThat(userTracker.numberOfAssignmentsSolved()).isEqualTo(1);
}
@Test
public void saveAndLoadShouldHaveCorrectNumberOfAttemtps() {
UserTracker userTracker = new UserTracker("test");
TestLesson lesson = new TestLesson();
userTracker.getLessonTracker(lesson);
userTracker.assignmentFailed(lesson);
userTracker.assignmentFailed(lesson);
userTrackerRepository.saveAndFlush(userTracker);
userTracker = userTrackerRepository.findOne("test");
userTracker.assignmentFailed(lesson);
userTracker.assignmentFailed(lesson);
userTrackerRepository.saveAndFlush(userTracker);
Assertions.assertThat(userTracker.getLessonTracker(lesson).getNumberOfAttempts()).isEqualTo(4);
}
}

View File

@ -1 +1,4 @@
webgoat.user.directory=${java.io.tmpdir}
webgoat.user.directory=${java.io.tmpdir}
spring.datasource.url=jdbc:hsqldb:mem:test
spring.jpa.hibernate.ddl-auto=create-drop

View File

@ -0,0 +1,35 @@
# Setup a Linux box headless which will start WebGoat and WebWolf helpful image to give away during training
Vagrant.configure(2) do |config|
config.vm.box = "ubuntu/trusty64"
config.vm.network :forwarded_port, guest: 8080, host: 8080
config.vm.network :forwarded_port, guest: 8081, host: 8081
config.vm.provider "virtualbox" do |vb|
vb.gui = false
vb.memory = "4096"
vb.cpus = 2
vb.name = "WebGoat-Training"
vb.customize ["modifyvm", :id, "--nictype1", "virtio"]
end
config.vm.provider "vmware_fusion" do |vf|
vf.gui = false
vf.vmx["memsize"] = 4096
vf.vmx["numvcpus"] = 2
vf.vmx["displayname"] = "WebGoat-Training"
end
config.vm.provision "shell", inline: <<-SHELL
wget https://github.com/WebGoat/WebGoat/releases/download/v8.0.0.M5/webgoat-server-8.0.0.M6.jar
wget https://github.com/WebGoat/WebGoat/releases/download/v8.0.0.M5/webwolf-8.0.0.M6.jar
sudo add-apt-repository ppa:openjdk-r/ppa
sudo apt-get update
sudo apt-get install openjdk-8-jre -y
SHELL
config.vm.provision "shell", run: "always", privileged: false, inline: <<-SHELL
java -jar webgoat-server-8.0.0.M6.jar &
sleep 40s
java -jar webwolf-8.0.0.M6.jar
SHELL
end

View File

@ -43,34 +43,13 @@
<version>${project.version}</version>
<scope>provided</scope>
<type>jar</type>
<!-- Exclude Mongo embedded so testcases do not start it automatically, seems to be
the easiest way to stop the autoconfiguration of Spring Boot -->
<exclusions>
<exclusion>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--<dependency>-->
<!--<groupId>org.apache.commons</groupId>-->
<!--<artifactId>commons-exec</artifactId>-->
<!--<version>1.3</version>-->
<!--</dependency>-->
<dependency>
<groupId>org.owasp.webgoat</groupId>
<artifactId>webgoat-container</artifactId>
<version>${project.version}</version>
<classifier>tests</classifier>
<scope>test</scope>
<!-- Exclude Mongo embedded so testcases do not start it automatically, seems to be
the easiest way to stop the autoconfiguration of Spring Boot -->
<exclusions>
<exclusion>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>junit</groupId>
@ -96,12 +75,6 @@
<version>4.1.3.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.fakemongo</groupId>
<artifactId>fongo</artifactId>
<version>2.1.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.owasp.encoder</groupId>
<artifactId>encoder</artifactId>

View File

@ -10,7 +10,5 @@ COPY start.sh /home/webgoat/start.sh
RUN chmod +x /home/webgoat/start.sh
USER webgoat
RUN mkdir -p /home/webgoat/.embedmongo/linux
RUN curl -o /home/webgoat/.embedmongo/linux/mongodb-linux-x86_64-3.2.2.tgz https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.2.2.tgz
RUN cd /home/webgoat/; mkdir -p .webgoat
COPY target/webgoat-server-${webgoat_version}.jar /home/webgoat/webgoat.jar

View File

@ -90,11 +90,6 @@
<scope>test</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>org.owasp.webgoat</groupId>
<artifactId>webgoat-container</artifactId>

View File

@ -1,40 +0,0 @@
package org.owasp.webgoat;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import de.flapdoodle.embed.mongo.MongodExecutable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.mongo.MongoProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
import java.io.IOException;
/**
* If we run
*/
@Configuration
@ConditionalOnProperty(value = "webgoat.embedded.mongo", havingValue = "false")
public class ExternalMongoConfiguration {
@Autowired
private MongoProperties properties;
@Autowired(required = false)
private MongoClientOptions options;
@Bean
public MongodExecutable mongodExecutable() throws IOException {
return null;
}
@Bean
public MongoDbFactory mongoDbFactory(Environment env) throws Exception {
MongoClient client = properties.createMongoClient(this.options, env);
return new SimpleMongoDbFactory(client, properties.getDatabase());
}
}

View File

@ -1,4 +0,0 @@
WG_MONGO_PORT=27017
WG_MONGO_HOST=mongo
WG_MQ_HOST=activemq
WG_MQ_PORT=61616

View File

@ -1,146 +0,0 @@
#!/bin/bash
# Bootstrap the setup of WebGoat for developer use in Linux and Mac machines
# This script will clone the necessary git repositories, call the maven goals
# in the order the are needed and launch tomcat listening on localhost:8080
# Happy hacking !
# Find out what is our terminal size
COLS="$(tput cols)"
if (( COLS <= 0 )) ; then
COLS="${COLUMNS:-80}"
fi
# Colors
ESC_SEQ="\x1b["
COL_RESET=$ESC_SEQ"39;49;00m"
COL_RED=$ESC_SEQ"31;01m"
COL_GREEN=$ESC_SEQ"32;01m"
COL_YELLOW=$ESC_SEQ"33;01m"
COL_BLUE=$ESC_SEQ"34;01m"
COL_MAGENTA=$ESC_SEQ"35;01m"
COL_CYAN=$ESC_SEQ"36;01m"
# Horizontal Rule function
horizontal_rule() {
local WORD
for WORD in "#"
do
hr "$WORD"
done
}
hr() {
local WORD="$1"
if [[ -n "$WORD" ]] ; then
local LINE=''
while (( ${#LINE} < COLS ))
do
LINE="$LINE$WORD"
done
echo -e "${LINE:0:$COLS}"
fi
}
## test if command exists
ftest() {
echo -e "$COL_CYAN info: Checking if ${1} is installed $COL_RESET"
if ! type "${1}" > /dev/null 2>&1; then
return 1
else
return 0
fi
}
## feature tests
features() {
for f in "${@}"; do
ftest "${f}" || {
echo -e >&2 "***$COL_RED ERROR: Missing \`${f}'! Make sure it exists and try again. $COL_RESET"
return 1
}
done
return 0
}
tomcat_started () {
STAT=`netstat -na | grep 8080 | awk '{print $6}'`
if [ "$STAT" = "LISTEN" ]; then
echo -e "$COL_GREEN WebGoat has started successfully! Browse to the following address. $COL_RESET"
echo -e "$COL_CYAN Happy Hacking! $COL_RESET"
return 0
elif [ "$STAT" = "" ]; then
echo -e "$COL_RED WebGoat failed to start up.... please wait run the following command for debugging : $COL_RESET"
echo -e "$COL_MAGENTA mvn -q -file WebGoat/pom.xml -pl webgoat-container tomcat7:run-war"
fi
return 1
}
## main setup
developer_bootstrap() {
horizontal_rule
echo -e "$COL_RED
██╗ ██╗███████╗██████╗ ██████╗ ██████╗ █████╗ ████████╗
██║ ██║██╔════╝██╔══██╗██╔════╝ ██╔═══██╗██╔══██╗╚══██╔══╝
██║ █╗ ██║█████╗ ██████╔╝██║ ███╗██║ ██║███████║ ██║
██║███╗██║██╔══╝ ██╔══██╗██║ ██║██║ ██║██╔══██║ ██║
╚███╔███╔╝███████╗██████╔╝╚██████╔╝╚██████╔╝██║ ██║ ██║
╚══╝╚══╝ ╚══════╝╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝
$COL_RESET"
horizontal_rule
echo -e "Welcome to the WebGoat Developer Bootstrap script for Linux/Mac."
echo -e "Now checking if all the required software to run WebGoat is already installed."
echo -e "FYI: This Developer Bootstrap Script for WebGoat requires: Git, Java JDK and Maven accessible on the path"
## test for require features
features git mvn java || return $?
# Clone WebGoat from github
if [ ! -d "WebGoat" ]; then
echo -e "Cloning the WebGoat container repository"
git clone https://github.com/WebGoat/WebGoat.git
else
horizontal_rule
(
echo -e "$COL_YELLOW The WebGoat container repo has already been clonned before, pulling upstream changes. $COL_RESET"
cd WebGoat || {
echo -e >&2 "$COL_RED *** ERROR: Could not cd into the WebGoat Directory. $COL_RESET"
return 1
}
git pull origin develop
)
fi
# Start the embedded Tomcat server
echo -e "$COL_MAGENTA"
horizontal_rule
horizontal_rule
horizontal_rule
horizontal_rule
echo "$COL_MAGENTA"
echo "$COL_CYAN ***** Starting WebGoat using the embedded Tomcat ***** $COL_RESET"
echo " Please be patient.... The startup of the server takes about 5 seconds..."
echo " WebGoat will be ready for you when you see the following message on the command prompt:"
echo "$COL_YELLOW INFO: Starting ProtocolHandler ["http-bio-8080"] $COL_RESET"
echo "$COL_CYAN When you see the message above, open a web browser and navigate to http://localhost:8080/WebGoat/ $COL_RESET"
echo " To stop the WebGoat and Tomcat Execution execution, press CTRL + C"
echo "$COL_RED If you close this terminal window, Tomcat and WebGoat will stop running $COL_RESET"
echo "$COL_MAGENTA"
horizontal_rule
horizontal_rule
horizontal_rule
horizontal_rule
echo -e "$COL_RESET"
sleep 5
# Starting WebGoat
mvn -q -pl webgoat-container spring-boot:run
}
# Start main script
developer_bootstrap

View File

@ -55,7 +55,7 @@
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
@ -73,6 +73,11 @@
<artifactId>jquery</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>${hsqldb.version}</version>
</dependency>
</dependencies>
<build>

View File

@ -4,10 +4,9 @@ import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
import javax.persistence.Entity;
import javax.persistence.Id;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@ -18,7 +17,7 @@ import java.time.format.DateTimeFormatter;
*/
@Builder
@Data
@Document
@Entity
@NoArgsConstructor
@AllArgsConstructor
public class Email implements Serializable {
@ -29,7 +28,6 @@ public class Email implements Serializable {
private String contents;
private String sender;
private String title;
@Indexed
private String recipient;
public String getSummary() {

View File

@ -1,7 +1,6 @@
package org.owasp.webwolf.mailbox;
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
@ -9,7 +8,7 @@ import java.util.List;
* @author nbaars
* @since 8/17/17.
*/
public interface MailboxRepository extends MongoRepository<Email, ObjectId> {
public interface MailboxRepository extends JpaRepository<Email, String> {
List<Email> findByRecipientOrderByTimeDesc(String recipient);

View File

@ -0,0 +1,47 @@
package org.owasp.webwolf.user;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
/**
* @author nbaars
* @since 3/19/17.
*/
@Controller
@AllArgsConstructor
@Slf4j
public class RegistrationController {
private UserValidator userValidator;
private UserService userService;
private AuthenticationManager authenticationManager;
@GetMapping("/registration")
public String showForm(UserForm userForm) {
return "registration";
}
@PostMapping("/register.mvc")
@SneakyThrows
public String registration(@ModelAttribute("userForm") @Valid UserForm userForm, BindingResult bindingResult, HttpServletRequest request) {
userValidator.validate(userForm, bindingResult);
if (bindingResult.hasErrors()) {
return "registration";
}
userService.addUser(userForm.getUsername(), userForm.getPassword());
request.login(userForm.getUsername(), userForm.getPassword());
return "redirect:/WebWolf/home";
}
}

View File

@ -0,0 +1,28 @@
package org.owasp.webwolf.user;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
/**
* @author nbaars
* @since 3/19/17.
*/
@Getter
@Setter
public class UserForm {
@NotNull
@Size(min=6, max=20)
private String username;
@NotNull
@Size(min=6, max=10)
private String password;
@NotNull
@Size(min=6, max=10)
private String matchingPassword;
@NotNull
private String agree;
}

View File

@ -1,12 +1,12 @@
package org.owasp.webwolf.user;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.jpa.repository.JpaRepository;
/**
* @author nbaars
* @since 3/19/17.
*/
public interface UserRepository extends MongoRepository<WebGoatUser, String> {
public interface UserRepository extends JpaRepository<WebGoatUser, String> {
WebGoatUser findByUsername(String username);
}

View File

@ -27,4 +27,9 @@ public class UserService implements UserDetailsService {
}
public void addUser(String username, String password) {
userRepository.save(new WebGoatUser(username, password));
}
}

View File

@ -0,0 +1,35 @@
package org.owasp.webwolf.user;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
/**
* @author nbaars
* @since 3/19/17.
*/
@Component
@AllArgsConstructor
public class UserValidator implements Validator {
private final UserRepository userRepository;
@Override
public boolean supports(Class<?> aClass) {
return UserForm.class.equals(aClass);
}
@Override
public void validate(Object o, Errors errors) {
UserForm userForm = (UserForm) o;
if (userRepository.findByUsername(userForm.getUsername()) != null) {
errors.rejectValue("username", "username.duplicate");
}
if (!userForm.getMatchingPassword().equals(userForm.getPassword())) {
errors.rejectValue("matchingPassword", "password.diff");
}
}
}

View File

@ -1,13 +1,14 @@
package org.owasp.webwolf.user;
import lombok.Getter;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Transient;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Transient;
import java.util.Collection;
import java.util.Collections;
@ -16,6 +17,7 @@ import java.util.Collections;
* @since 3/19/17.
*/
@Getter
@Entity
public class WebGoatUser implements UserDetails {
public static final String ROLE_USER = "WEBGOAT_USER";

View File

@ -5,6 +5,10 @@ server.session.timeout=6000
server.port=8081
server.session.cookie.name = WEBWOLFSESSION
spring.datasource.url=jdbc:hsqldb:file:${webgoat.server.directory}/data/webwolf
spring.jpa.hibernate.ddl-auto=update
spring.messages.basename=i18n/messages
logging.level.org.springframework=INFO
logging.level.org.springframework.boot.devtools=WARN
logging.level.org.owasp=DEBUG
@ -25,12 +29,9 @@ multipart.location=${java.io.tmpdir}
multipart.max-file-size=1Mb
multipart.max-request-size=1Mb
webgoat.server.directory=${user.home}/.webgoat/
webwolf.fileserver.location=${java.io.tmpdir}/webwolf-fileserver
spring.data.mongodb.host=${WG_MONGO_HOST:}
spring.data.mongodb.port=${WG_MONGO_PORT:27017}
spring.data.mongodb.database=webgoat
spring.jackson.serialization.indent_output=true
spring.jackson.serialization.write-dates-as-timestamps=false

View File

@ -0,0 +1,40 @@
#
# This file is part of WebGoat, an Open Web Application Security Project utility. For details,
# please see http://www.owasp.org/
# <p>
# Copyright (c) 2002 - 2017 Bruce Mayhew
# <p>
# This program is free software; you can redistribute it and/or modify it under the terms of the
# GNU General Public License as published by the Free Software Foundation; either version 2 of the
# License, or (at your option) any later version.
# <p>
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
# <p>
# You should have received a copy of the GNU General Public License along with this program; if
# not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
# <p>
# Getting Source ==============
# <p>
# Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
# projects.
# <p>
#
register.new=Register new user
sign.up=Sign up
register.title=Register
password=Password
password.confirm=Confirm password
username=Username
not.empty=This field is required.
username.size=Please use between 6 and 10 characters.
username.duplicate=User already exists.
password.size=Password should at least contain 6 characters
password.diff=The passwords do not match.

View File

@ -45,6 +45,7 @@
<div class="col-xs-6 col-sm-6 col-md-6">
</div>
</div>
<div><b><a th:href="@{/registration}" th:text="#{register.new}"></a></b></div>
</fieldset>
</form>
</div>

View File

@ -0,0 +1,89 @@
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<div th:replace="fragments/header :: header-css"/>
</head>
<body>
<div th:replace="fragments/header :: header"/>
<div class="container">
<br/><br/>
<fieldset>
<legend th:text="#{register.title}">Please Sign Up</legend>
<form class="form-horizontal" action="#" th:action="@{/register.mvc}" th:object="${userForm}"
method='POST'>
<div class="form-group" th:classappend="${#fields.hasErrors('username')}? 'has-error'">
<label for="username" class="col-sm-2 control-label" th:text="#{username}">Username</label>
<div class="col-sm-4">
<input autofocus="dummy_for_thymeleaf_parser" type="text" class="form-control"
th:field="*{username}"
id="username" placeholder="Username" name='username'/>
</div>
<span th:if="${#fields.hasErrors('username')}" th:errors="*{username}">Username error</span>
</div>
<div class="form-group" th:classappend="${#fields.hasErrors('password')}? 'has-error'">
<label for="password" class="col-sm-2 control-label" th:text="#{password}">Password</label>
<div class="col-sm-4">
<input type="password" class="form-control" id="password" placeholder="Password"
name='password' th:value="*{password}"/>
</div>
<span th:if="${#fields.hasErrors('password')}" th:errors="*{password}">Password error</span>
</div>
<div class="form-group" th:classappend="${#fields.hasErrors('matchingPassword')}? 'has-error'">
<label for="matchingPassword" class="col-sm-2 control-label" th:text="#{password.confirm}">Confirm
password</label>
<div class="col-sm-4">
<input type="password" class="form-control" id="matchingPassword" placeholder="Password"
name='matchingPassword' th:value="*{matchingPassword}"/>
</div>
<span th:if="${#fields.hasErrors('matchingPassword')}"
th:errors="*{matchingPassword}">Password error</span>
</div>
<div class="form-group" th:classappend="${#fields.hasErrors('agree')}? 'has-error'">
<label class="col-sm-2 control-label">Terms of use</label>
<div class="col-sm-6">
<div style="border: 1px solid #e5e5e5; height: 200px; overflow: auto; padding: 10px;">
<p>
While running this program your machine will be extremely
vulnerable to attack. You should disconnect from the Internet while using
this program. WebGoat's default configuration binds to localhost to minimize
the exposure.
</p>
<p>
This program is for educational purposes only. If you attempt
these techniques without authorization, you are very likely to get caught. If
you are caught engaging in unauthorized hacking, most companies will fire you.
Claiming that you were doing security research will not work as that is the
first thing that all hackers claim.
</p>
</div>
</div>
</div>
<div class="form-group" th:classappend="${#fields.hasErrors('agree')}? 'has-error'">
<div class="col-sm-6 col-sm-offset-2">
<div class="checkbox">
<label>
<input type="checkbox" name="agree" value="agree"/>Agree with the terms and
conditions
</label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-6">
<button type="submit" class="btn btn-primary" th:text="#{sign.up}">Sign up</button>
</div>
</div>
</form>
</fieldset>
</div>
</body>
</html>