Compare commits
6 Commits
Author | SHA1 | Date | |
---|---|---|---|
d3ee9431d8 | |||
4811a9d563 | |||
c6e86861fe | |||
b64aa43760 | |||
dd7f4074cd | |||
8c10000e4e |
19
README.MD
19
README.MD
@ -1,4 +1,4 @@
|
|||||||
# WebGoat: A deliberately insecure Web Application
|
# WebGoat 8: A deliberately insecure Web Application
|
||||||
|
|
||||||
[](https://travis-ci.org/WebGoat/WebGoat)
|
[](https://travis-ci.org/WebGoat/WebGoat)
|
||||||
[](https://coveralls.io/github/WebGoat/WebGoat?branch=master)
|
[](https://coveralls.io/github/WebGoat/WebGoat?branch=master)
|
||||||
@ -6,10 +6,6 @@
|
|||||||
[](https://www.versioneye.com/user/projects/562da95ae346d7000e0369aa)
|
[](https://www.versioneye.com/user/projects/562da95ae346d7000e0369aa)
|
||||||
[](https://www.owasp.org/index.php/OWASP_Project_Inventory#tab=Labs_Projects)
|
[](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
|
# Introduction
|
||||||
|
|
||||||
@ -68,6 +64,11 @@ Download the latest WebWolf release from [https://github.com/WebGoat/WebGoat/rel
|
|||||||
java -jar webgoat-server-<<version>>.jar
|
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
|
## 3. Run from the sources
|
||||||
|
|
||||||
@ -88,20 +89,22 @@ Now let's start by compiling the project.
|
|||||||
|
|
||||||
```Shell
|
```Shell
|
||||||
cd WebGoat
|
cd WebGoat
|
||||||
git checkout develop
|
git checkout <<branch_name>>
|
||||||
mvn clean install
|
mvn clean install
|
||||||
```
|
```
|
||||||
|
|
||||||
Now we are ready to run the project. WebGoat 8.x is using Spring-Boot.
|
Now we are ready to run the project. WebGoat 8.x is using Spring-Boot.
|
||||||
|
|
||||||
```Shell
|
```Shell
|
||||||
mvn -pl webwolf spring-boot:run
|
mvn -pl webgoat-server spring-boot:run
|
||||||
```
|
```
|
||||||
... you should be running webgoat on localhost:8080/WebGoat momentarily
|
... 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
|
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
|
# Vagrant
|
||||||
|
@ -1,34 +1,15 @@
|
|||||||
version: '2.0'
|
version: '2.0'
|
||||||
|
|
||||||
services:
|
services:
|
||||||
mongo:
|
|
||||||
image: mongo:latest
|
|
||||||
expose:
|
|
||||||
- "27017"
|
|
||||||
volumes:
|
|
||||||
- './mongo-data:/data/db'
|
|
||||||
webgoat:
|
webgoat:
|
||||||
build: webgoat-server/
|
build: webgoat-server/
|
||||||
command: "sh /home/webgoat/start.sh"
|
command: "sh /home/webgoat/start.sh"
|
||||||
ports:
|
ports:
|
||||||
- "8080:8080"
|
- "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:
|
webwolf:
|
||||||
build: webwolf/
|
build: webwolf/
|
||||||
command: "sh /home/webwolf/start.sh"
|
command: "sh /home/webwolf/start.sh"
|
||||||
depends_on:
|
depends_on:
|
||||||
- webgoat
|
- webgoat
|
||||||
ports:
|
ports:
|
||||||
- "8081:8081"
|
- "8081:8081"
|
||||||
environment:
|
|
||||||
WG_MONGO_PORT: 27017
|
|
||||||
WG_MONGO_HOST: mongo
|
|
||||||
WG_MQ_HOST: activemq
|
|
||||||
WG_MQ_PORT: 61616
|
|
@ -12,7 +12,7 @@ if [ "${BRANCH}" == "master" ] && [ ! -z "${TRAVIS_TAG}" ]; then
|
|||||||
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} .
|
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 .
|
||||||
|
@ -36,16 +36,6 @@
|
|||||||
|
|
||||||
</profiles>
|
</profiles>
|
||||||
|
|
||||||
<dependencyManagement>
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>de.flapdoodle.embed</groupId>
|
|
||||||
<artifactId>de.flapdoodle.embed.mongo</artifactId>
|
|
||||||
<version>2.0.0</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
</dependencyManagement>
|
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<resources>
|
<resources>
|
||||||
<resource>
|
<resource>
|
||||||
@ -127,7 +117,7 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-data-mongodb</artifactId>
|
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
@ -202,12 +192,6 @@
|
|||||||
<version>${junit.version}</version>
|
<version>${junit.version}</version>
|
||||||
<type>jar</type>
|
<type>jar</type>
|
||||||
</dependency>
|
</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 for Unit and Integration Testing ************** -->
|
||||||
<!-- ************* END: <dependencies> ************** -->
|
<!-- ************* END: <dependencies> ************** -->
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
@ -42,6 +42,7 @@ import org.thymeleaf.templateresolver.TemplateResolver;
|
|||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.apache.commons.lang3.CharEncoding.UTF_8;
|
||||||
import static org.asciidoctor.Asciidoctor.Factory.create;
|
import static org.asciidoctor.Asciidoctor.Factory.create;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -82,7 +83,7 @@ public class AsciiDoctorTemplateResolver extends TemplateResolver {
|
|||||||
} else {
|
} else {
|
||||||
StringWriter writer = new StringWriter();
|
StringWriter writer = new StringWriter();
|
||||||
asciidoctor.convert(new InputStreamReader(is), writer, createAttributes());
|
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) {
|
} catch (IOException e) {
|
||||||
//no html yet
|
//no html yet
|
||||||
|
@ -23,11 +23,5 @@ public class CleanupLocalProgressFiles {
|
|||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void clean() {
|
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,10 @@ package org.owasp.webgoat.lessons;
|
|||||||
|
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.OneToMany;
|
||||||
|
import javax.persistence.Transient;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -38,11 +42,14 @@ import java.util.List;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@Getter
|
@Getter
|
||||||
@EqualsAndHashCode
|
@EqualsAndHashCode
|
||||||
|
@Entity
|
||||||
public class Assignment {
|
public class Assignment {
|
||||||
@NonNull
|
@NonNull
|
||||||
|
@Id
|
||||||
private String name;
|
private String name;
|
||||||
@NonNull
|
@NonNull
|
||||||
private String path;
|
private String path;
|
||||||
|
@Transient
|
||||||
private List<String> hints;
|
private List<String> hints;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import lombok.Getter;
|
|||||||
import org.owasp.webgoat.lessons.AbstractLesson;
|
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||||
import org.owasp.webgoat.lessons.Assignment;
|
import org.owasp.webgoat.lessons.Assignment;
|
||||||
|
|
||||||
|
import javax.persistence.*;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@ -44,16 +45,20 @@ import java.util.stream.Collectors;
|
|||||||
* @version $Id: $Id
|
* @version $Id: $Id
|
||||||
* @since October 29, 2003
|
* @since October 29, 2003
|
||||||
*/
|
*/
|
||||||
|
@Entity
|
||||||
public class LessonTracker {
|
public class LessonTracker {
|
||||||
@Getter
|
@Getter
|
||||||
|
@Id
|
||||||
private String lessonName;
|
private String lessonName;
|
||||||
|
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
|
||||||
private final Set<Assignment> solvedAssignments = Sets.newHashSet();
|
private final Set<Assignment> solvedAssignments = Sets.newHashSet();
|
||||||
|
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
|
||||||
private final List<Assignment> allAssignments = Lists.newArrayList();
|
private final List<Assignment> allAssignments = Lists.newArrayList();
|
||||||
@Getter
|
@Getter
|
||||||
private int numberOfAttempts = 0;
|
private int numberOfAttempts = 0;
|
||||||
|
|
||||||
protected LessonTracker() {
|
private LessonTracker() {
|
||||||
//Mongo
|
//JPA
|
||||||
}
|
}
|
||||||
|
|
||||||
public LessonTracker(AbstractLesson lesson) {
|
public LessonTracker(AbstractLesson lesson) {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package org.owasp.webgoat.users;
|
package org.owasp.webgoat.users;
|
||||||
|
|
||||||
import org.springframework.data.mongodb.repository.MongoRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -8,7 +8,7 @@ import java.util.List;
|
|||||||
* @author nbaars
|
* @author nbaars
|
||||||
* @since 3/19/17.
|
* @since 3/19/17.
|
||||||
*/
|
*/
|
||||||
public interface UserRepository extends MongoRepository<WebGoatUser, String> {
|
public interface UserRepository extends JpaRepository<WebGoatUser, String> {
|
||||||
|
|
||||||
WebGoatUser findByUsername(String username);
|
WebGoatUser findByUsername(String username);
|
||||||
|
|
||||||
|
@ -5,8 +5,8 @@ import com.google.common.collect.Lists;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.owasp.webgoat.lessons.AbstractLesson;
|
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||||
import org.owasp.webgoat.lessons.Assignment;
|
import org.owasp.webgoat.lessons.Assignment;
|
||||||
import org.springframework.data.annotation.Id;
|
|
||||||
|
|
||||||
|
import javax.persistence.*;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@ -44,12 +44,16 @@ import java.util.stream.Collectors;
|
|||||||
* @since October 29, 2003
|
* @since October 29, 2003
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@Entity
|
||||||
public class UserTracker {
|
public class UserTracker {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
private final String user;
|
private String user;
|
||||||
|
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
|
||||||
private List<LessonTracker> lessonTrackers = Lists.newArrayList();
|
private List<LessonTracker> lessonTrackers = Lists.newArrayList();
|
||||||
|
|
||||||
|
private UserTracker() {}
|
||||||
|
|
||||||
public UserTracker(final String user) {
|
public UserTracker(final String user) {
|
||||||
this.user = user;
|
this.user = user;
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
package org.owasp.webgoat.users;
|
package org.owasp.webgoat.users;
|
||||||
|
|
||||||
import org.springframework.data.mongodb.repository.MongoRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author nbaars
|
* @author nbaars
|
||||||
* @since 4/30/17.
|
* @since 4/30/17.
|
||||||
*/
|
*/
|
||||||
public interface UserTrackerRepository extends MongoRepository<UserTracker, String> {
|
public interface UserTrackerRepository extends JpaRepository<UserTracker, String> {
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
package org.owasp.webgoat.users;
|
package org.owasp.webgoat.users;
|
||||||
|
|
||||||
import lombok.Getter;
|
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.GrantedAuthority;
|
||||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||||
import org.springframework.security.core.userdetails.User;
|
import org.springframework.security.core.userdetails.User;
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
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.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
@ -16,6 +17,7 @@ import java.util.Collections;
|
|||||||
* @since 3/19/17.
|
* @since 3/19/17.
|
||||||
*/
|
*/
|
||||||
@Getter
|
@Getter
|
||||||
|
@Entity
|
||||||
public class WebGoatUser implements UserDetails {
|
public class WebGoatUser implements UserDetails {
|
||||||
|
|
||||||
public static final String ROLE_USER = "WEBGOAT_USER";
|
public static final String ROLE_USER = "WEBGOAT_USER";
|
||||||
|
@ -4,6 +4,9 @@ server.session.timeout=600
|
|||||||
server.contextPath=/WebGoat
|
server.contextPath=/WebGoat
|
||||||
server.port=8080
|
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=WARN
|
||||||
logging.level.org.springframework.boot.devtools=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.driver=org.hsqldb.jdbcDriver
|
||||||
webgoat.database.connection.string=jdbc:hsqldb:mem:{USER}
|
webgoat.database.connection.string=jdbc:hsqldb:mem:{USER}
|
||||||
webgoat.default.language=en
|
webgoat.default.language=en
|
||||||
webgoat.embedded.mongo=${WG_INTERNAL_MONGO:true}
|
|
||||||
|
|
||||||
webwolf.host=${WEBWOLF_HOST:localhost}
|
webwolf.host=${WEBWOLF_HOST:localhost}
|
||||||
webwolf.port=${WEBWOLF_PORT:8081}
|
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.indent_output=true
|
||||||
spring.jackson.serialization.write-dates-as-timestamps=false
|
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
|
#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
|
spring.devtools.restart.additional-paths=webgoat-container/src/main/resources/static/js,webgoat-container/src/main/resources/static/css
|
||||||
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
@ -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");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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
|
35
webgoat-images/vagrant-training/Vagrantfile
vendored
Normal file
35
webgoat-images/vagrant-training/Vagrantfile
vendored
Normal 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
|
@ -43,34 +43,13 @@
|
|||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
<type>jar</type>
|
<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>
|
||||||
<!--<dependency>-->
|
|
||||||
<!--<groupId>org.apache.commons</groupId>-->
|
|
||||||
<!--<artifactId>commons-exec</artifactId>-->
|
|
||||||
<!--<version>1.3</version>-->
|
|
||||||
<!--</dependency>-->
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.owasp.webgoat</groupId>
|
<groupId>org.owasp.webgoat</groupId>
|
||||||
<artifactId>webgoat-container</artifactId>
|
<artifactId>webgoat-container</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<classifier>tests</classifier>
|
<classifier>tests</classifier>
|
||||||
<scope>test</scope>
|
<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>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
@ -96,12 +75,6 @@
|
|||||||
<version>4.1.3.RELEASE</version>
|
<version>4.1.3.RELEASE</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>com.github.fakemongo</groupId>
|
|
||||||
<artifactId>fongo</artifactId>
|
|
||||||
<version>2.1.0</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.owasp.encoder</groupId>
|
<groupId>org.owasp.encoder</groupId>
|
||||||
<artifactId>encoder</artifactId>
|
<artifactId>encoder</artifactId>
|
||||||
|
@ -10,7 +10,5 @@ COPY start.sh /home/webgoat/start.sh
|
|||||||
RUN chmod +x /home/webgoat/start.sh
|
RUN chmod +x /home/webgoat/start.sh
|
||||||
|
|
||||||
USER webgoat
|
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
|
RUN cd /home/webgoat/; mkdir -p .webgoat
|
||||||
COPY target/webgoat-server-${webgoat_version}.jar /home/webgoat/webgoat.jar
|
COPY target/webgoat-server-${webgoat_version}.jar /home/webgoat/webgoat.jar
|
||||||
|
@ -90,11 +90,6 @@
|
|||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>de.flapdoodle.embed</groupId>
|
|
||||||
<artifactId>de.flapdoodle.embed.mongo</artifactId>
|
|
||||||
<version>2.0.0</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.owasp.webgoat</groupId>
|
<groupId>org.owasp.webgoat</groupId>
|
||||||
<artifactId>webgoat-container</artifactId>
|
<artifactId>webgoat-container</artifactId>
|
||||||
|
@ -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());
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
WG_MONGO_PORT=27017
|
|
||||||
WG_MONGO_HOST=mongo
|
|
||||||
WG_MQ_HOST=activemq
|
|
||||||
WG_MQ_PORT=61616
|
|
@ -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
|
|
@ -55,7 +55,7 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-data-mongodb</artifactId>
|
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
@ -73,6 +73,11 @@
|
|||||||
<artifactId>jquery</artifactId>
|
<artifactId>jquery</artifactId>
|
||||||
<version>3.2.1</version>
|
<version>3.2.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hsqldb</groupId>
|
||||||
|
<artifactId>hsqldb</artifactId>
|
||||||
|
<version>${hsqldb.version}</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -4,10 +4,9 @@ import lombok.AllArgsConstructor;
|
|||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
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.io.Serializable;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
@ -18,7 +17,7 @@ import java.time.format.DateTimeFormatter;
|
|||||||
*/
|
*/
|
||||||
@Builder
|
@Builder
|
||||||
@Data
|
@Data
|
||||||
@Document
|
@Entity
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class Email implements Serializable {
|
public class Email implements Serializable {
|
||||||
@ -29,7 +28,6 @@ public class Email implements Serializable {
|
|||||||
private String contents;
|
private String contents;
|
||||||
private String sender;
|
private String sender;
|
||||||
private String title;
|
private String title;
|
||||||
@Indexed
|
|
||||||
private String recipient;
|
private String recipient;
|
||||||
|
|
||||||
public String getSummary() {
|
public String getSummary() {
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package org.owasp.webwolf.mailbox;
|
package org.owasp.webwolf.mailbox;
|
||||||
|
|
||||||
import org.bson.types.ObjectId;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
import org.springframework.data.mongodb.repository.MongoRepository;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -9,7 +8,7 @@ import java.util.List;
|
|||||||
* @author nbaars
|
* @author nbaars
|
||||||
* @since 8/17/17.
|
* @since 8/17/17.
|
||||||
*/
|
*/
|
||||||
public interface MailboxRepository extends MongoRepository<Email, ObjectId> {
|
public interface MailboxRepository extends JpaRepository<Email, String> {
|
||||||
|
|
||||||
List<Email> findByRecipientOrderByTimeDesc(String recipient);
|
List<Email> findByRecipientOrderByTimeDesc(String recipient);
|
||||||
|
|
||||||
|
@ -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";
|
||||||
|
}
|
||||||
|
}
|
28
webwolf/src/main/java/org/owasp/webwolf/user/UserForm.java
Normal file
28
webwolf/src/main/java/org/owasp/webwolf/user/UserForm.java
Normal 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;
|
||||||
|
}
|
@ -1,12 +1,12 @@
|
|||||||
package org.owasp.webwolf.user;
|
package org.owasp.webwolf.user;
|
||||||
|
|
||||||
import org.springframework.data.mongodb.repository.MongoRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author nbaars
|
* @author nbaars
|
||||||
* @since 3/19/17.
|
* @since 3/19/17.
|
||||||
*/
|
*/
|
||||||
public interface UserRepository extends MongoRepository<WebGoatUser, String> {
|
public interface UserRepository extends JpaRepository<WebGoatUser, String> {
|
||||||
|
|
||||||
WebGoatUser findByUsername(String username);
|
WebGoatUser findByUsername(String username);
|
||||||
}
|
}
|
||||||
|
@ -27,4 +27,9 @@ public class UserService implements UserDetailsService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void addUser(String username, String password) {
|
||||||
|
userRepository.save(new WebGoatUser(username, password));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,13 +1,14 @@
|
|||||||
package org.owasp.webwolf.user;
|
package org.owasp.webwolf.user;
|
||||||
|
|
||||||
import lombok.Getter;
|
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.GrantedAuthority;
|
||||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||||
import org.springframework.security.core.userdetails.User;
|
import org.springframework.security.core.userdetails.User;
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
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.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
@ -16,6 +17,7 @@ import java.util.Collections;
|
|||||||
* @since 3/19/17.
|
* @since 3/19/17.
|
||||||
*/
|
*/
|
||||||
@Getter
|
@Getter
|
||||||
|
@Entity
|
||||||
public class WebGoatUser implements UserDetails {
|
public class WebGoatUser implements UserDetails {
|
||||||
|
|
||||||
public static final String ROLE_USER = "WEBGOAT_USER";
|
public static final String ROLE_USER = "WEBGOAT_USER";
|
||||||
|
@ -5,6 +5,10 @@ server.session.timeout=6000
|
|||||||
server.port=8081
|
server.port=8081
|
||||||
server.session.cookie.name = WEBWOLFSESSION
|
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=INFO
|
||||||
logging.level.org.springframework.boot.devtools=WARN
|
logging.level.org.springframework.boot.devtools=WARN
|
||||||
logging.level.org.owasp=DEBUG
|
logging.level.org.owasp=DEBUG
|
||||||
@ -25,12 +29,9 @@ multipart.location=${java.io.tmpdir}
|
|||||||
multipart.max-file-size=1Mb
|
multipart.max-file-size=1Mb
|
||||||
multipart.max-request-size=1Mb
|
multipart.max-request-size=1Mb
|
||||||
|
|
||||||
|
webgoat.server.directory=${user.home}/.webgoat/
|
||||||
webwolf.fileserver.location=${java.io.tmpdir}/webwolf-fileserver
|
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.indent_output=true
|
||||||
spring.jackson.serialization.write-dates-as-timestamps=false
|
spring.jackson.serialization.write-dates-as-timestamps=false
|
||||||
|
|
||||||
|
40
webwolf/src/main/resources/i18n/messages.properties
Normal file
40
webwolf/src/main/resources/i18n/messages.properties
Normal 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.
|
@ -45,6 +45,7 @@
|
|||||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div><b><a th:href="@{/registration}" th:text="#{register.new}"></a></b></div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
89
webwolf/src/main/resources/templates/registration.html
Normal file
89
webwolf/src/main/resources/templates/registration.html
Normal 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>
|
Reference in New Issue
Block a user