Lesson overview

This commit is contained in:
Nanne Baars 2016-11-29 20:25:00 +01:00
parent df29b36389
commit 1a854a500e
45 changed files with 705 additions and 345 deletions

View File

@ -32,9 +32,9 @@ package org.owasp.webgoat;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.owasp.webgoat.plugins.Plugin;
import org.owasp.webgoat.plugins.PluginClassLoader;
import org.owasp.webgoat.plugins.PluginEndpointPublisher;
import org.owasp.webgoat.plugins.PluginsExtractor;
import org.owasp.webgoat.plugins.PluginsLoader;
import org.owasp.webgoat.session.Course;
import org.owasp.webgoat.session.UserTracker;
@ -51,7 +51,6 @@ import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import java.io.File;
import java.util.List;
@SpringBootApplication
@Slf4j
@ -77,8 +76,8 @@ public class WebGoat extends SpringBootServletInitializer {
}
@Bean
public PluginsLoader pluginsLoader(@Qualifier("pluginTargetDirectory") File pluginTargetDirectory, PluginClassLoader classLoader) {
return new PluginsLoader(pluginTargetDirectory, classLoader);
public PluginsExtractor pluginsLoader(@Qualifier("pluginTargetDirectory") File pluginTargetDirectory, PluginClassLoader classLoader) {
return new PluginsExtractor(pluginTargetDirectory, classLoader);
}
@Bean
@ -88,27 +87,16 @@ public class WebGoat extends SpringBootServletInitializer {
}
@Bean
public Course course(PluginsLoader pluginsLoader, PluginEndpointPublisher pluginEndpointPublisher) {
Course course = new Course();
List<Plugin> plugins = pluginsLoader.loadPlugins();
if (plugins.isEmpty()) {
log.error("No lessons found if you downloaded an official release of WebGoat please take the time to");
log.error("create a new issue at https://github.com/WebGoat/WebGoat/issues/new");
log.error("For developers run 'mvn package' first from the root directory.");
log.error("Stopping WebGoat...");
System.exit(1); //we always run standalone
}
course.createLessonsFromPlugins(plugins);
plugins.forEach(p -> pluginEndpointPublisher.publish(p));
return course;
public Course course(PluginsExtractor extractor, PluginEndpointPublisher pluginEndpointPublisher) {
return new PluginsLoader(extractor, pluginEndpointPublisher).loadPlugins();
}
@Bean
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
@SneakyThrows
public UserTracker userTracker(@Value("${webgoat.user.directory}") final String webgoatHome, WebSession webSession) {
UserTracker userTracker = new UserTracker(webgoatHome, webSession.getUserName());
public UserTracker userTracker(@Value("${webgoat.user.directory}") final String webgoatHome,
@Value("${webgoat.tracker.overwrite:false}") final boolean overwrite, WebSession webSession) {
UserTracker userTracker = new UserTracker(webgoatHome, webSession.getUserName(), overwrite);
userTracker.load();
return userTracker;
}

View File

@ -0,0 +1,65 @@
/**
* ************************************************************************************************
* 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 - 20014 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>
*/
package org.owasp.webgoat.endpoints;
import org.owasp.webgoat.lessons.AttackResult;
import org.owasp.webgoat.session.UserTracker;
import org.owasp.webgoat.session.WebSession;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Each lesson can define an endpoint which can support the lesson. So for example if you create a lesson which uses JavaScript and
* needs to call out to the server to fetch data you can define an endpoint in that lesson. WebGoat will pick up this endpoint and
* Spring will publish it.
* </p>
* Extend this class and implement the met
* </p>
* Note: each subclass should declare this annotation otherwise the WebGoat framework cannot find your endpoint.
*/
public abstract class AssignmentEndpoint extends Endpoint {
@Autowired
private UserTracker userTracker;
@Autowired
private WebSession webSession;
//// TODO: 11/13/2016 events better fit?
protected AttackResult trackProgress(AttackResult attackResult) {
if (attackResult.assignmentSolved()) {
userTracker.assignmentSolved(webSession.getCurrentLesson(), this.getClass().getSimpleName());
} else {
userTracker.assignmentFailed(webSession.getCurrentLesson());
}
return attackResult;
}
protected WebSession getWebSession() {
return webSession;
}
}

View File

@ -1,4 +1,4 @@
package org.owasp.webgoat.lessons;
package org.owasp.webgoat.endpoints;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

View File

@ -44,9 +44,9 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
private Integer ranking;
@Setter
@Getter
private List<Class<Assignment>> assignments;
@Setter
private List<Assignment> assignments;
/**
* Constructor for the Lesson object

View File

@ -1,3 +1,10 @@
package org.owasp.webgoat.lessons;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.io.Serializable;
/**
* ************************************************************************************************
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
@ -22,44 +29,16 @@
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
* <p>
*
* @author nbaars
* @version $Id: $Id
* @since November 25, 2016
*/
package org.owasp.webgoat.lessons;
@AllArgsConstructor
@Getter
public class Assignment implements Serializable {
import org.owasp.webgoat.lessons.model.AttackResult;
import org.owasp.webgoat.session.UserTracker;
import org.owasp.webgoat.session.WebSession;
import org.springframework.beans.factory.annotation.Autowired;
private final String name;
/**
* Each lesson can define an endpoint which can support the lesson. So for example if you create a lesson which uses JavaScript and
* needs to call out to the server to fetch data you can define an endpoint in that lesson. WebGoat will pick up this endpoint and
* Spring will publish it.
* </p>
* Extend this class and implement the met
* </p>
* Note: each subclass should declare this annotation otherwise the WebGoat framework cannot find your endpoint.
*/
public abstract class Assignment extends Endpoint {
@Autowired
private UserTracker userTracker;
@Autowired
private WebSession webSession;
//// TODO: 11/13/2016 events better fit?
protected AttackResult trackProgress(AttackResult attackResult) {
if (attackResult.assignmentSolved()) {
userTracker.assignmentSolved(webSession.getCurrentLesson(), this);
} else {
userTracker.assignmentFailed(webSession.getCurrentLesson());
}
return attackResult;
}
protected WebSession getWebSession() {
return webSession;
}
}

View File

@ -1,4 +1,4 @@
package org.owasp.webgoat.lessons.model;
package org.owasp.webgoat.lessons;
import lombok.Getter;

View File

@ -24,7 +24,7 @@
* projects.
*
*/
package org.owasp.webgoat.lessons.model;
package org.owasp.webgoat.lessons;
/**
* <p>Hint class.</p>

View File

@ -1,7 +1,6 @@
package org.owasp.webgoat.lessons.model;
package org.owasp.webgoat.lessons;
import lombok.Getter;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.session.WebSession;
/**

View File

@ -27,7 +27,7 @@
* https://github.com/WebGoat/WebGoat, a repository for free software projects.
*
*/
package org.owasp.webgoat.lessons.model;
package org.owasp.webgoat.lessons;
import java.util.ArrayList;
import java.util.List;
@ -105,7 +105,7 @@ public class LessonMenuItem {
/**
* <p>addChild.</p>
*
* @param child a {@link org.owasp.webgoat.lessons.model.LessonMenuItem} object.
* @param child a {@link LessonMenuItem} object.
*/
public void addChild(LessonMenuItem child) {
children.add(child);

View File

@ -25,7 +25,7 @@
*
*/
package org.owasp.webgoat.lessons.model;
package org.owasp.webgoat.lessons;
/**
* <p>LessonMenuItemType class.</p>

View File

@ -27,7 +27,7 @@
* for free software projects.
*
*/
package org.owasp.webgoat.lessons.model;
package org.owasp.webgoat.lessons;
/**
* <p>RequestParameter class.</p>

View File

@ -3,9 +3,10 @@ package org.owasp.webgoat.plugins;
import com.google.common.base.Optional;
import com.google.common.collect.Lists;
import lombok.Getter;
import org.owasp.webgoat.endpoints.AssignmentEndpoint;
import org.owasp.webgoat.endpoints.Endpoint;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.lessons.Assignment;
import org.owasp.webgoat.lessons.Endpoint;
import org.owasp.webgoat.lessons.NewLesson;
import org.springframework.util.StringUtils;
@ -13,6 +14,7 @@ import java.io.File;
import java.nio.file.Path;
import java.util.List;
import static java.util.stream.Collectors.toList;
import static org.owasp.webgoat.plugins.PluginFileUtils.fileEndsWith;
/**
@ -27,7 +29,9 @@ public class Plugin {
private final String originationJar;
private PluginClassLoader classLoader;
private Class<NewLesson> newLesson;
private List<Class<Assignment>> assignments = Lists.newArrayList();
@Getter
private List<Class<AssignmentEndpoint>> assignments = Lists.newArrayList();
@Getter
private List<Class<Endpoint>> endpoints = Lists.newArrayList();
private List<File> pluginFiles = Lists.newArrayList();
@ -36,14 +40,6 @@ public class Plugin {
this.originationJar = originatingJar;
}
public List<Class<Assignment>> getAssignments() {
return this.assignments;
}
public List<Class<Endpoint>> getEndpoints() {
return this.endpoints;
}
/**
* <p>findLesson.</p>
*
@ -75,11 +71,12 @@ public class Plugin {
try {
Class clazz = classLoader.loadClass(realClassName);
if (Assignment.class.isAssignableFrom(clazz)) {
if (AssignmentEndpoint.class.isAssignableFrom(clazz)) {
this.assignments.add(clazz);
} else if (Endpoint.class.isAssignableFrom(clazz)) {
this.endpoints.add(clazz);
}
} else
if (Endpoint.class.isAssignableFrom(clazz)) {
this.endpoints.add(clazz);
}
} catch (ClassNotFoundException ce) {
throw new PluginLoadingFailure("Class " + realClassName + " listed in jar but unable to load the class.", ce);
}
@ -106,8 +103,8 @@ public class Plugin {
try {
if (newLesson != null) {
AbstractLesson lesson = newLesson.newInstance();
lesson.setAssignments(this.assignments);
return Optional.of(newLesson.newInstance());
lesson.setAssignments(createAssignment(assignments));
return Optional.of(lesson);
}
} catch (IllegalAccessException | InstantiationException e) {
throw new PluginLoadingFailure("Unable to instantiate the lesson " + newLesson.getName(), e);
@ -116,4 +113,9 @@ public class Plugin {
}
private List<Assignment> createAssignment(List<Class<AssignmentEndpoint>> endpoints) {
return endpoints.stream().map(e -> new Assignment(e.getSimpleName())).collect(toList());
}
}

View File

@ -0,0 +1,173 @@
package org.owasp.webgoat.plugins;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.owasp.webgoat.i18n.LabelProvider;
import org.springframework.util.ResourceUtils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Enumeration;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
/**
* <p>PluginsLoader class.</p>
*
* @author dm
* @version $Id: $Id
*/
@Slf4j
public class PluginsExtractor {
private static final String WEBGOAT_PLUGIN_EXTENSION = "jar";
private static final int BUFFER_SIZE = 32 * 1024;
private final File pluginTargetDirectory;
private final PluginClassLoader classLoader;
public PluginsExtractor(File pluginTargetDirectory, PluginClassLoader pluginClassLoader) {
this.classLoader = pluginClassLoader;
this.pluginTargetDirectory = pluginTargetDirectory;
}
/**
* <p>loadPlugins.</p>
*
* @return a {@link java.util.List} object.
*/
public List<Plugin> loadPlugins() {
List<Plugin> plugins = Lists.newArrayList();
try {
URL location = this.getClass().getProtectionDomain().getCodeSource().getLocation();
log.trace("Determining whether we run as standalone jar or as directory...");
if (ResourceUtils.isFileURL(location)) {
log.trace("Running from directory, copying lessons from {}", location.toString());
extractToTargetDirectoryFromExplodedDirectory(ResourceUtils.getFile(location));
} else {
log.trace("Running from standalone jar, extracting lessons from {}", location.toString());
extractToTargetDirectoryFromJarFile(ResourceUtils.getFile(ResourceUtils.extractJarFileURL(location)));
}
List<URL> jars = listJars();
plugins = processPlugins(jars);
} catch (Exception e) {
log.error("Loading plugins failed", e);
}
return plugins;
}
private void extractToTargetDirectoryFromJarFile(File jarFile) throws IOException {
ZipFile jar = new ZipFile(jarFile);
Enumeration<? extends ZipEntry> entries = jar.entries();
while (entries.hasMoreElements()) {
ZipEntry zipEntry = entries.nextElement();
if (zipEntry.getName().contains("plugin_lessons") && zipEntry.getName().endsWith(".jar")) {
unpack(jar, zipEntry);
}
}
}
private void unpack(ZipFile jar, ZipEntry zipEntry) throws IOException {
try (InputStream inputStream = jar.getInputStream(zipEntry)) {
String name = zipEntry.getName();
if (name.lastIndexOf("/") != -1) {
name = name.substring(name.lastIndexOf("/") + 1);
}
try (OutputStream outputStream = new FileOutputStream(new File(pluginTargetDirectory, name))) {
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead = -1;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.flush();
}
}
log.trace("Extracting {} to {}", jar.getName(), pluginTargetDirectory);
}
private void extractToTargetDirectoryFromExplodedDirectory(File directory) throws IOException {
Files.walkFileTree(directory.toPath(), new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
if (dir.endsWith("plugin_lessons")) {
log.trace("Copying {} to {}", dir.toString(), pluginTargetDirectory);
FileUtils.copyDirectory(dir.toFile(), pluginTargetDirectory);
}
return FileVisitResult.CONTINUE;
}
});
}
private List<URL> listJars() throws Exception {
final List<URL> jars = Lists.newArrayList();
Files.walkFileTree(Paths.get(pluginTargetDirectory.toURI()), new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
if (PluginFileUtils.fileEndsWith(file, WEBGOAT_PLUGIN_EXTENSION)) {
jars.add(file.toUri().toURL());
log.trace("Found jar file at location: {}", file.toString());
}
return FileVisitResult.CONTINUE;
}
});
return jars;
}
private List<Plugin> processPlugins(List<URL> jars) throws Exception {
final ExecutorService executorService = Executors.newFixedThreadPool(10);
try {
final List<Plugin> plugins = Lists.newArrayList();
final CompletionService<Plugin> completionService = new ExecutorCompletionService<>(executorService);
final List<Callable<Plugin>> callables = extractJars(jars);
callables.forEach(s -> completionService.submit(s));
int n = callables.size();
for (int i = 0; i < n; i++) {
Plugin plugin = completionService.take().get();
if (plugin.getLesson().isPresent()) {
log.trace("Plugin jar '{}' contains a lesson, loading into WebGoat...", plugin.getOriginationJar());
plugins.add(plugin);
} else {
log.trace("Plugin jar: '{}' does not contain a lesson not processing as a plugin (can be a utility jar)",
plugin.getOriginationJar());
}
}
LabelProvider.updatePluginResources(
pluginTargetDirectory.toPath().resolve("plugin/i18n/WebGoatLabels.properties"));
return plugins;
} finally {
executorService.shutdown();
}
}
private List<Callable<Plugin>> extractJars(List<URL> jars) {
List<Callable<Plugin>> extractorCallables = Lists.newArrayList();
for (final URL jar : jars) {
classLoader.addURL(jar);
extractorCallables.add(() -> {
PluginExtractor extractor = new PluginExtractor();
return extractor.extractJarFile(ResourceUtils.getFile(jar), pluginTargetDirectory, classLoader);
});
}
return extractorCallables;
}
}

View File

@ -1,173 +1,72 @@
package org.owasp.webgoat.plugins;
import com.google.common.collect.Lists;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.owasp.webgoat.i18n.LabelProvider;
import org.springframework.util.ResourceUtils;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.lessons.NewLesson;
import org.owasp.webgoat.session.Course;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Enumeration;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
/**
* <p>PluginsLoader class.</p>
* ************************************************************************************************
* 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 - 20014 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>
*
* @author dm
* @author nbaars
* @version $Id: $Id
* @since November 25, 2016
*/
@AllArgsConstructor
@Slf4j
public class PluginsLoader {
private static final String WEBGOAT_PLUGIN_EXTENSION = "jar";
private static final int BUFFER_SIZE = 32 * 1024;
private final File pluginTargetDirectory;
private final PluginClassLoader classLoader;
public PluginsLoader(File pluginTargetDirectory, PluginClassLoader pluginClassLoader) {
this.classLoader = pluginClassLoader;
this.pluginTargetDirectory = pluginTargetDirectory;
}
private final PluginsExtractor extractor;
private final PluginEndpointPublisher pluginEndpointPublisher;
/**
* <p>loadPlugins.</p>
*
* @return a {@link java.util.List} object.
* <p>createLessonsFromPlugins.</p>
*/
public List<Plugin> loadPlugins() {
List<Plugin> plugins = Lists.newArrayList();
try {
URL location = this.getClass().getProtectionDomain().getCodeSource().getLocation();
log.trace("Determining whether we run as standalone jar or as directory...");
if (ResourceUtils.isFileURL(location)) {
log.trace("Running from directory, copying lessons from {}", location.toString());
extractToTargetDirectoryFromExplodedDirectory(ResourceUtils.getFile(location));
} else {
log.trace("Running from standalone jar, extracting lessons from {}", location.toString());
extractToTargetDirectoryFromJarFile(ResourceUtils.getFile(ResourceUtils.extractJarFileURL(location)));
}
List<URL> jars = listJars();
plugins = processPlugins(jars);
} catch (Exception e) {
log.error("Loading plugins failed", e);
}
return plugins;
}
private void extractToTargetDirectoryFromJarFile(File jarFile) throws IOException {
ZipFile jar = new ZipFile(jarFile);
Enumeration<? extends ZipEntry> entries = jar.entries();
while (entries.hasMoreElements()) {
ZipEntry zipEntry = entries.nextElement();
if (zipEntry.getName().contains("plugin_lessons") && zipEntry.getName().endsWith(".jar")) {
unpack(jar, zipEntry);
public Course loadPlugins() {
List<AbstractLesson> lessons = Lists.newArrayList();
for (Plugin plugin : extractor.loadPlugins()) {
try {
NewLesson lesson = (NewLesson) plugin.getLesson().get();
lessons.add(lesson);
pluginEndpointPublisher.publish(plugin);
} catch (Exception e) {
log.error("Error in loadLessons: ", e);
}
}
}
private void unpack(ZipFile jar, ZipEntry zipEntry) throws IOException {
try (InputStream inputStream = jar.getInputStream(zipEntry)) {
String name = zipEntry.getName();
if (name.lastIndexOf("/") != -1) {
name = name.substring(name.lastIndexOf("/") + 1);
}
try (OutputStream outputStream = new FileOutputStream(new File(pluginTargetDirectory, name))) {
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead = -1;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.flush();
}
if (lessons.isEmpty()) {
log.error("No lessons found if you downloaded an official release of WebGoat please take the time to");
log.error("create a new issue at https://github.com/WebGoat/WebGoat/issues/new");
log.error("For developers run 'mvn package' first from the root directory.");
log.error("Stopping WebGoat...");
System.exit(1); //we always run standalone
}
log.trace("Extracting {} to {}", jar.getName(), pluginTargetDirectory);
return new Course(lessons);
}
private void extractToTargetDirectoryFromExplodedDirectory(File directory) throws IOException {
Files.walkFileTree(directory.toPath(), new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
if (dir.endsWith("plugin_lessons")) {
log.trace("Copying {} to {}", dir.toString(), pluginTargetDirectory);
FileUtils.copyDirectory(dir.toFile(), pluginTargetDirectory);
}
return FileVisitResult.CONTINUE;
}
});
}
private List<URL> listJars() throws Exception {
final List<URL> jars = Lists.newArrayList();
Files.walkFileTree(Paths.get(pluginTargetDirectory.toURI()), new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
if (PluginFileUtils.fileEndsWith(file, WEBGOAT_PLUGIN_EXTENSION)) {
jars.add(file.toUri().toURL());
log.trace("Found jar file at location: {}", file.toString());
}
return FileVisitResult.CONTINUE;
}
});
return jars;
}
private List<Plugin> processPlugins(List<URL> jars) throws Exception {
final ExecutorService executorService = Executors.newFixedThreadPool(10);
try {
final List<Plugin> plugins = Lists.newArrayList();
final CompletionService<Plugin> completionService = new ExecutorCompletionService<>(executorService);
final List<Callable<Plugin>> callables = extractJars(jars);
callables.forEach(s -> completionService.submit(s));
int n = callables.size();
for (int i = 0; i < n; i++) {
Plugin plugin = completionService.take().get();
if (plugin.getLesson().isPresent()) {
log.trace("Plugin jar '{}' contains a lesson, loading into WebGoat...", plugin.getOriginationJar());
plugins.add(plugin);
} else {
log.trace("Plugin jar: '{}' does not contain a lesson not processing as a plugin (can be a utility jar)",
plugin.getOriginationJar());
}
}
LabelProvider.updatePluginResources(
pluginTargetDirectory.toPath().resolve("plugin/i18n/WebGoatLabels.properties"));
return plugins;
} finally {
executorService.shutdown();
}
}
private List<Callable<Plugin>> extractJars(List<URL> jars) {
List<Callable<Plugin>> extractorCallables = Lists.newArrayList();
for (final URL jar : jars) {
classLoader.addURL(jar);
extractorCallables.add(() -> {
PluginExtractor extractor = new PluginExtractor();
return extractor.extractJarFile(ResourceUtils.getFile(jar), pluginTargetDirectory, classLoader);
});
}
return extractorCallables;
}
}

View File

@ -6,7 +6,7 @@
package org.owasp.webgoat.service;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.lessons.model.Hint;
import org.owasp.webgoat.lessons.Hint;
import org.owasp.webgoat.session.WebSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

View File

@ -1,6 +1,6 @@
package org.owasp.webgoat.service;
import org.owasp.webgoat.lessons.model.LessonInfoModel;
import org.owasp.webgoat.lessons.LessonInfoModel;
import org.owasp.webgoat.session.WebSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@ -24,7 +24,7 @@ public class LessonInfoService {
/**
* <p>getLessonInfo.</p>
*
* @return a {@link org.owasp.webgoat.lessons.model.LessonInfoModel} object.
* @return a {@link LessonInfoModel} object.
*/
@RequestMapping(path = "/service/lessoninfo.mvc", produces = "application/json")
public @ResponseBody

View File

@ -31,8 +31,8 @@ package org.owasp.webgoat.service;
import lombok.AllArgsConstructor;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.lessons.model.LessonMenuItem;
import org.owasp.webgoat.lessons.model.LessonMenuItemType;
import org.owasp.webgoat.lessons.LessonMenuItem;
import org.owasp.webgoat.lessons.LessonMenuItemType;
import org.owasp.webgoat.session.Course;
import org.owasp.webgoat.session.LessonTracker;
import org.owasp.webgoat.session.UserTracker;

View File

@ -1,9 +1,13 @@
package org.owasp.webgoat.service;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.owasp.webgoat.i18n.LabelManager;
import org.owasp.webgoat.lessons.model.LessonInfoModel;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.lessons.Assignment;
import org.owasp.webgoat.lessons.LessonInfoModel;
import org.owasp.webgoat.session.LessonTracker;
import org.owasp.webgoat.session.UserTracker;
import org.owasp.webgoat.session.WebSession;
@ -11,6 +15,8 @@ import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@ -47,4 +53,38 @@ public class LessonProgressService {
json.put("successMessage", successMessage);
return json;
}
/**
* Endpoint for fetching the complete lesson overview which informs the user about whether all the assignments are solved.
* Used as the last page of the lesson to generate a lesson overview.
*
* @return list of assignments
*/
@RequestMapping(value = "/service/lessonoverview.mvc", produces = "application/json")
@ResponseBody
public List<LessonOverview> lessonOverview() {
AbstractLesson currentLesson = webSession.getCurrentLesson();
LessonTracker lessonTracker = userTracker.getLessonTracker(currentLesson);
return toJson(lessonTracker.getLessonOverview());
}
private List<LessonOverview> toJson(Map<Assignment, Boolean> map) {
ArrayList<LessonOverview> result = Lists.newArrayList();
for (Map.Entry<Assignment, Boolean> entry : map.entrySet()) {
result.add(new LessonOverview(entry.getKey(), entry.getValue()));
}
return result;
}
@AllArgsConstructor
@Getter
//Jackson does not really like returning a map of <Assignment, Boolean> directly, see http://stackoverflow.com/questions/11628698/can-we-make-object-as-key-in-map-when-using-json
//so creating intermediate object is the easiest solution
private static class LessonOverview {
private Assignment assignment;
private Boolean solved;
}
}

View File

@ -30,7 +30,7 @@
package org.owasp.webgoat.service;
import com.google.common.collect.Lists;
import org.owasp.webgoat.lessons.model.RequestParameter;
import org.owasp.webgoat.lessons.RequestParameter;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

View File

@ -1,10 +1,9 @@
package org.owasp.webgoat.session;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.lessons.NewLesson;
import org.owasp.webgoat.plugins.Plugin;
import java.util.LinkedList;
import java.util.List;
@ -42,6 +41,7 @@ import static java.util.stream.Collectors.toList;
* @since October 28, 2003
*/
@Slf4j
@AllArgsConstructor
public class Course {
private List<AbstractLesson> lessons = new LinkedList<>();
@ -89,18 +89,5 @@ public class Course {
this.lessons = lessons;
}
/**
* <p>createLessonsFromPlugins.</p>
*/
public void createLessonsFromPlugins(List<Plugin> plugins) {
for (Plugin plugin : plugins) {
try {
NewLesson lesson = (NewLesson) plugin.getLesson().get();
lesson.setAssignments(plugin.getAssignments());
lessons.add(lesson);
} catch (Exception e) {
log.error("Error in loadLessons: ", e);
}
}
}
}

View File

@ -1,11 +1,16 @@
package org.owasp.webgoat.session;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import lombok.Getter;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.lessons.Assignment;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
@ -42,12 +47,17 @@ import java.util.stream.Collectors;
*/
public class LessonTracker implements Serializable {
private static final long serialVersionUID = 5410058267505412928L;
private final List<String> assignments;
private final Set<String> solvedAssignments = Sets.newHashSet();
private final Set<Assignment> solvedAssignments = Sets.newHashSet();
private final List<Assignment> allAssignments = Lists.newArrayList();
@Getter
private int numberOfAttempts = 0;
public LessonTracker(AbstractLesson lesson) {
this.assignments = lesson.getAssignments().stream().map(a -> a.getSimpleName()).collect(Collectors.toList());
allAssignments.addAll(lesson.getAssignments());
}
public Optional<Assignment> getAssignment(String name) {
return allAssignments.stream().filter(a -> a.getName().equals(name)).findFirst();
}
/**
@ -56,14 +66,14 @@ public class LessonTracker implements Serializable {
* @param solvedAssignment the assignment which the user solved
*/
public void assignmentSolved(String solvedAssignment) {
solvedAssignments.add(solvedAssignment);
getAssignment(solvedAssignment).ifPresent(a -> solvedAssignments.add(a));
}
/**
* @return did they user solved all assignments for the lesson?
* @return did they user solved all solvedAssignments for the lesson?
*/
public boolean isLessonSolved() {
return solvedAssignments.size() == assignments.size();
return allAssignments.size() == solvedAssignments.size();
}
/**
@ -79,4 +89,16 @@ public class LessonTracker implements Serializable {
void reset() {
solvedAssignments.clear();
}
/**
* @return list containing all the assignments solved or not
*/
public Map<Assignment, Boolean> getLessonOverview() {
List<Assignment> notSolved = allAssignments.stream()
.filter(i -> !solvedAssignments.contains(i))
.collect(Collectors.toList());
Map<Assignment, Boolean> overview = notSolved.stream().collect(Collectors.toMap(a -> a, b -> false));
overview.putAll(solvedAssignments.stream().collect(Collectors.toMap(a -> a, b -> true)));
return overview;
}
}

View File

@ -1,10 +1,9 @@
package org.owasp.webgoat.session;
import com.google.common.collect.Maps;
import lombok.SneakyThrows;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.lessons.Assignment;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.SerializationUtils;
@ -47,11 +46,13 @@ public class UserTracker {
private final String webgoatHome;
private final String user;
private final boolean overwrite;
private Map<String, LessonTracker> storage = new HashMap<>();
public UserTracker(@Value("${webgoat.user.directory}") final String webgoatHome, final String user) {
public UserTracker(final String webgoatHome, final String user, final boolean overwrite) {
this.webgoatHome = webgoatHome;
this.user = user;
this.overwrite = overwrite;
}
/**
@ -69,10 +70,10 @@ public class UserTracker {
return lessonTracker;
}
public void assignmentSolved(AbstractLesson lesson, Assignment assignment) {
public void assignmentSolved(AbstractLesson lesson, String assignmentName) {
LessonTracker lessonTracker = getLessonTracker(lesson);
lessonTracker.incrementAttempts();
lessonTracker.assignmentSolved(assignment.getClass().getSimpleName());
lessonTracker.assignmentSolved(assignmentName);
save();
}
@ -85,7 +86,9 @@ public class UserTracker {
@SneakyThrows
public void load() {
File file = new File(webgoatHome, user + ".progress");
if (file.exists() && file.isFile()) {
if (overwrite) {
this.storage = Maps.newHashMap();
} else if (file.exists() && file.isFile()) {
this.storage = (Map<String, LessonTracker>) SerializationUtils.deserialize(FileCopyUtils.copyToByteArray(file));
}
}

View File

@ -6,7 +6,7 @@ server.port=8080
logging.level.org.springframework=WARN
logging.level.org.springframework.boot.devtools=DEBUG
logging.level.org.springframework.boot.devtools=WARN
logging.level.org.owasp=DEBUG
logging.level.org.owasp.webgoat=TRACE
@ -14,9 +14,10 @@ spring.thymeleaf.cache=false
spring.thymeleaf.content-type=text/html
security.enable-csrf=false
spring.devtools.restart.enabled=true
spring.devtools.restart.enabled=false
webgoat.tracker.overwrite=true
webgoat.user.directory=${user.home}/.webgoat/
webgoat.build.version=@project.version@
webgoat.build.number=@build.number@

View File

@ -0,0 +1,89 @@
package org.owasp.webgoat.service;
import org.assertj.core.util.Maps;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.owasp.webgoat.i18n.LabelManager;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.lessons.Assignment;
import org.owasp.webgoat.session.LessonTracker;
import org.owasp.webgoat.session.UserTracker;
import org.owasp.webgoat.session.WebSession;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import static org.hamcrest.CoreMatchers.is;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* ************************************************************************************************
* 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 - 20014 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>
*
* @author nbaars
* @version $Id: $Id
* @since November 25, 2016
*/
@RunWith(MockitoJUnitRunner.class)
public class LessonProgressServiceTest {
private MockMvc mockMvc;
@Mock
private AbstractLesson lesson;
@Mock
private UserTracker userTracker;
@Mock
private LessonTracker lessonTracker;
@Mock
private WebSession websession;
@Mock
private LabelManager labelManager;
@Before
public void setup() {
Assignment assignment = new Assignment("test");
when(userTracker.getLessonTracker(any())).thenReturn(lessonTracker);
when(websession.getCurrentLesson()).thenReturn(lesson);
when(lessonTracker.getLessonOverview()).thenReturn(Maps.newHashMap(assignment, true));
this.mockMvc = MockMvcBuilders.standaloneSetup(new LessonProgressService(labelManager, userTracker, websession)).build();
}
@Test
public void jsonLessonOverview() throws Exception {
this.mockMvc.perform(MockMvcRequestBuilders.get("/service/lessonoverview.mvc").accept(MediaType.APPLICATION_JSON_VALUE))
.andExpect(status().isOk())
.andExpect(jsonPath("$[0].assignment.name", is("test")))
.andExpect(jsonPath("$[0].solved", is(true)));
}
}

View File

@ -0,0 +1,34 @@
package org.owasp.webgoat.session;
/**
* ************************************************************************************************
* 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 - 20014 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>
*
* @author nbaars
* @version $Id: $Id
* @since November 26, 2016
*/
public class CourseTest {
}

View File

@ -0,0 +1,73 @@
package org.owasp.webgoat.session;
import com.google.common.collect.Lists;
import org.junit.Test;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.lessons.Assignment;
import java.util.List;
import java.util.Map;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
/**
* ************************************************************************************************
* 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 - 20014 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>
*
* @author nbaars
* @version $Id: $Id
* @since November 25, 2016
*/
public class LessonTrackerTest {
@Test
public void allAssignmentsSolvedShouldMarkLessonAsComplete() {
AbstractLesson lesson = mock(AbstractLesson.class);
when(lesson.getAssignments()).thenReturn(Lists.newArrayList(new Assignment("assignment")));
LessonTracker lessonTracker = new LessonTracker(lesson);
lessonTracker.assignmentSolved("assignment");
assertTrue(lessonTracker.isLessonSolved());
}
@Test
public void noAssignmentsSolvedShouldMarkLessonAsInComplete() {
AbstractLesson lesson = mock(AbstractLesson.class);
Assignment a1 = new Assignment("a1");
Assignment a2 = new Assignment("a2");
List<Assignment> assignments = Lists.newArrayList(a1, a2);
when(lesson.getAssignments()).thenReturn(assignments);
LessonTracker lessonTracker = new LessonTracker(lesson);
lessonTracker.assignmentSolved("a1");
Map<Assignment, Boolean> lessonOverview = lessonTracker.getLessonOverview();
assertThat(lessonOverview.get(a1)).isTrue();
assertThat(lessonOverview.get(a2)).isFalse();
}
}

View File

@ -3,15 +3,14 @@ package org.owasp.webgoat.session;
import com.google.common.collect.Lists;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.lessons.Assignment;
import java.io.File;
import java.io.IOException;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
/**
@ -55,17 +54,38 @@ public class UserTrackerTest {
@Test
public void writeAndRead() {
UserTracker userTracker = new UserTracker(home.getParent(), "test");
AbstractLesson abstractLesson = Mockito.mock(AbstractLesson.class);
Assignment assignment = Mockito.mock(Assignment.class);
when(abstractLesson.getAssignments()).thenReturn((List)Lists.newArrayList(assignment.getClass()));
userTracker.getLessonTracker(abstractLesson);
userTracker.assignmentSolved(abstractLesson, assignment);
UserTracker userTracker = new UserTracker(home.getParent(), "test", false);
AbstractLesson lesson = mock(AbstractLesson.class);
when(lesson.getAssignments()).thenReturn(Lists.newArrayList(new Assignment("assignment")));
userTracker.getLessonTracker(lesson);
userTracker.assignmentSolved(lesson, lesson.getAssignments().get(0).getName());
userTracker = new UserTracker(home.getParent(), "test");
userTracker = new UserTracker(home.getParent(), "test", false);
userTracker.load();
assertThat(userTracker.getLessonTracker(abstractLesson).isLessonSolved()).isTrue();
assertThat(userTracker.getLessonTracker(lesson).isLessonSolved()).isTrue();
}
@Test
public void assignmentFailedShouldIncrementAttempts() {
UserTracker userTracker = new UserTracker(home.getParent(), "test", false);
AbstractLesson lesson = mock(AbstractLesson.class);
when(lesson.getAssignments()).thenReturn(Lists.newArrayList(new Assignment("assignment")));
userTracker.getLessonTracker(lesson);
userTracker.assignmentFailed(lesson);
userTracker.assignmentFailed(lesson);
}
assertThat(userTracker.getLessonTracker(lesson).getNumberOfAttempts()).isEqualTo(2);
}
@Test
public void resetShouldClearSolvedAssignment() {
UserTracker userTracker = new UserTracker(home.getParent(), "test", false);
AbstractLesson lesson = mock(AbstractLesson.class);
when(lesson.getAssignments()).thenReturn(Lists.newArrayList(new Assignment("assignment")));
userTracker.assignmentSolved(lesson, "assignment");
assertThat(userTracker.getLessonTracker(lesson).isLessonSolved()).isTrue();
userTracker.reset(lesson);
assertThat(userTracker.getLessonTracker(lesson).isLessonSolved()).isFalse();
}
}

View File

@ -1,7 +1,7 @@
package org.owasp.webgoat.plugin;
import org.owasp.webgoat.lessons.Assignment;
import org.owasp.webgoat.lessons.model.AttackResult;
import org.owasp.webgoat.endpoints.AssignmentEndpoint;
import org.owasp.webgoat.lessons.AttackResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
@ -38,7 +38,7 @@ import java.io.IOException;
* @version $Id: $Id
* @since August 11, 2016
*/
public class Attack extends Assignment {
public class Attack extends AssignmentEndpoint {
@RequestMapping(method = RequestMethod.POST)
public @ResponseBody AttackResult completed(@RequestParam String answer) throws IOException {

View File

@ -6,7 +6,7 @@ package org.owasp.webgoat.plugin;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.owasp.webgoat.lessons.Endpoint;
import org.owasp.webgoat.endpoints.Endpoint;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.w3c.dom.Node;

View File

@ -2,17 +2,11 @@
package org.owasp.webgoat.plugin;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import javax.servlet.http.HttpServletRequest;
import org.owasp.webgoat.lessons.Assignment;
import org.owasp.webgoat.lessons.model.AttackResult;
import org.owasp.webgoat.session.DatabaseUtilities;
import org.owasp.webgoat.endpoints.AssignmentEndpoint;
import org.owasp.webgoat.lessons.AttackResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
@ -50,7 +44,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003
*/
public class CrossSiteScriptingLesson1 extends Assignment {
public class CrossSiteScriptingLesson1 extends AssignmentEndpoint {
@RequestMapping(method = RequestMethod.POST)
public @ResponseBody AttackResult completed(@RequestParam String answer_xss_1, HttpServletRequest request) throws IOException {

View File

@ -2,17 +2,11 @@
package org.owasp.webgoat.plugin;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import javax.servlet.http.HttpServletRequest;
import org.owasp.webgoat.lessons.Assignment;
import org.owasp.webgoat.lessons.model.AttackResult;
import org.owasp.webgoat.session.DatabaseUtilities;
import org.owasp.webgoat.endpoints.AssignmentEndpoint;
import org.owasp.webgoat.lessons.AttackResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
@ -50,7 +44,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003
*/
public class CrossSiteScriptingLesson5a extends Assignment {
public class CrossSiteScriptingLesson5a extends AssignmentEndpoint {
@RequestMapping(method = RequestMethod.POST)
public @ResponseBody AttackResult completed(@RequestParam Integer QTY1,

View File

@ -11,8 +11,8 @@ import java.sql.Statement;
import javax.servlet.http.HttpServletRequest;
import org.owasp.webgoat.lessons.Assignment;
import org.owasp.webgoat.lessons.model.AttackResult;
import org.owasp.webgoat.endpoints.AssignmentEndpoint;
import org.owasp.webgoat.lessons.AttackResult;
import org.owasp.webgoat.session.DatabaseUtilities;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@ -51,7 +51,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003
*/
public class CrossSiteScriptingLesson5b extends Assignment {
public class CrossSiteScriptingLesson5b extends AssignmentEndpoint {
@RequestMapping(method = RequestMethod.POST)
public @ResponseBody AttackResult completed(@RequestParam String userid, HttpServletRequest request) throws IOException {

View File

@ -10,8 +10,8 @@ import java.sql.Statement;
import javax.servlet.http.HttpServletRequest;
import org.owasp.webgoat.lessons.Assignment;
import org.owasp.webgoat.lessons.model.AttackResult;
import org.owasp.webgoat.endpoints.AssignmentEndpoint;
import org.owasp.webgoat.lessons.AttackResult;
import org.owasp.webgoat.session.DatabaseUtilities;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@ -50,7 +50,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003
*/
public class CrossSiteScriptingLesson6a extends Assignment {
public class CrossSiteScriptingLesson6a extends AssignmentEndpoint {
@RequestMapping(method = RequestMethod.POST)
public @ResponseBody AttackResult completed(@RequestParam String userid_6a, HttpServletRequest request) throws IOException {

View File

@ -4,14 +4,13 @@ package org.owasp.webgoat.plugin;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import javax.servlet.http.HttpServletRequest;
import org.owasp.webgoat.lessons.Assignment;
import org.owasp.webgoat.lessons.model.AttackResult;
import org.owasp.webgoat.endpoints.AssignmentEndpoint;
import org.owasp.webgoat.lessons.AttackResult;
import org.owasp.webgoat.session.DatabaseUtilities;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@ -50,7 +49,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003
*/
public class CrossSiteScriptingLesson6b extends Assignment {
public class CrossSiteScriptingLesson6b extends AssignmentEndpoint {
@RequestMapping(method = RequestMethod.POST)
public @ResponseBody AttackResult completed(@RequestParam String userid_6b, HttpServletRequest request) throws IOException {

View File

@ -1,7 +1,7 @@
package org.owasp.webgoat.plugin;
import org.owasp.webgoat.lessons.Assignment;
import org.owasp.webgoat.lessons.model.AttackResult;
import org.owasp.webgoat.endpoints.AssignmentEndpoint;
import org.owasp.webgoat.lessons.AttackResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
@ -13,7 +13,7 @@ import java.io.IOException;
/**
* Created by jason on 11/23/16.
*/
public class DOMCrossSiteScripting extends Assignment {
public class DOMCrossSiteScripting extends AssignmentEndpoint {
@RequestMapping(method = RequestMethod.POST)
public @ResponseBody
AttackResult completed(@RequestParam Integer param1,

View File

@ -1,7 +1,7 @@
package org.owasp.webgoat.plugin;
import org.owasp.webgoat.lessons.Assignment;
import org.owasp.webgoat.lessons.model.AttackResult;
import org.owasp.webgoat.endpoints.AssignmentEndpoint;
import org.owasp.webgoat.lessons.AttackResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
@ -44,7 +44,7 @@ import java.io.IOException;
* @created October 28, 2003
*/
public class HttpBasicsLesson extends Assignment {
public class HttpBasicsLesson extends AssignmentEndpoint {
@RequestMapping(method = RequestMethod.POST)
public @ResponseBody AttackResult completed(@RequestParam String person, HttpServletRequest request) throws IOException {

View File

@ -1,7 +1,7 @@
package org.owasp.webgoat.plugin;
import org.owasp.webgoat.lessons.Assignment;
import org.owasp.webgoat.lessons.model.AttackResult;
import org.owasp.webgoat.endpoints.AssignmentEndpoint;
import org.owasp.webgoat.lessons.AttackResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
@ -44,7 +44,7 @@ import java.io.IOException;
* @created October 28, 2003
*/
public class HttpBasicsQuiz extends Assignment {
public class HttpBasicsQuiz extends AssignmentEndpoint {
@RequestMapping(method = RequestMethod.POST)
public @ResponseBody AttackResult completed(@RequestParam String answer, @RequestParam String magic_answer, @RequestParam String magic_num, HttpServletRequest request) throws IOException {

View File

@ -10,8 +10,8 @@ import java.sql.Statement;
import javax.servlet.http.HttpServletRequest;
import org.owasp.webgoat.lessons.Assignment;
import org.owasp.webgoat.lessons.model.AttackResult;
import org.owasp.webgoat.endpoints.AssignmentEndpoint;
import org.owasp.webgoat.lessons.AttackResult;
import org.owasp.webgoat.session.DatabaseUtilities;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@ -50,7 +50,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003
*/
public class SqlInjectionLesson5a extends Assignment {
public class SqlInjectionLesson5a extends AssignmentEndpoint {
@RequestMapping(method = RequestMethod.POST)
public @ResponseBody AttackResult completed(@RequestParam String account, HttpServletRequest request) throws IOException {

View File

@ -11,8 +11,8 @@ import java.sql.Statement;
import javax.servlet.http.HttpServletRequest;
import org.owasp.webgoat.lessons.Assignment;
import org.owasp.webgoat.lessons.model.AttackResult;
import org.owasp.webgoat.endpoints.AssignmentEndpoint;
import org.owasp.webgoat.lessons.AttackResult;
import org.owasp.webgoat.session.DatabaseUtilities;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@ -51,7 +51,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003
*/
public class SqlInjectionLesson5b extends Assignment {
public class SqlInjectionLesson5b extends AssignmentEndpoint {
@RequestMapping(method = RequestMethod.POST)
public @ResponseBody AttackResult completed(@RequestParam String userid, HttpServletRequest request) throws IOException {

View File

@ -10,8 +10,8 @@ import java.sql.Statement;
import javax.servlet.http.HttpServletRequest;
import org.owasp.webgoat.lessons.Assignment;
import org.owasp.webgoat.lessons.model.AttackResult;
import org.owasp.webgoat.endpoints.AssignmentEndpoint;
import org.owasp.webgoat.lessons.AttackResult;
import org.owasp.webgoat.session.DatabaseUtilities;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@ -50,7 +50,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003
*/
public class SqlInjectionLesson6a extends Assignment {
public class SqlInjectionLesson6a extends AssignmentEndpoint {
@RequestMapping(method = RequestMethod.POST)
public @ResponseBody AttackResult completed(@RequestParam String userid_6a, HttpServletRequest request) throws IOException {

View File

@ -4,14 +4,13 @@ package org.owasp.webgoat.plugin;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import javax.servlet.http.HttpServletRequest;
import org.owasp.webgoat.lessons.Assignment;
import org.owasp.webgoat.lessons.model.AttackResult;
import org.owasp.webgoat.endpoints.AssignmentEndpoint;
import org.owasp.webgoat.lessons.AttackResult;
import org.owasp.webgoat.session.DatabaseUtilities;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@ -50,7 +49,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003
*/
public class SqlInjectionLesson6b extends Assignment {
public class SqlInjectionLesson6b extends AssignmentEndpoint {
@RequestMapping(method = RequestMethod.POST)
public @ResponseBody AttackResult completed(@RequestParam String userid_6b, HttpServletRequest request) throws IOException {

View File

@ -2,8 +2,8 @@ package org.owasp.webgoat.plugin;
import com.google.common.base.Joiner;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.owasp.webgoat.lessons.Assignment;
import org.owasp.webgoat.lessons.model.AttackResult;
import org.owasp.webgoat.endpoints.AssignmentEndpoint;
import org.owasp.webgoat.lessons.AttackResult;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
@ -46,7 +46,7 @@ import static org.owasp.webgoat.plugin.SimpleXXE.parseXml;
* @version $Id: $Id
* @since November 18, 2016
*/
public class BlindSendFileAssignment extends Assignment {
public class BlindSendFileAssignment extends AssignmentEndpoint {
@Override
public String getPath() {

View File

@ -1,8 +1,8 @@
package org.owasp.webgoat.plugin;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.owasp.webgoat.lessons.Assignment;
import org.owasp.webgoat.lessons.model.AttackResult;
import org.owasp.webgoat.endpoints.AssignmentEndpoint;
import org.owasp.webgoat.lessons.AttackResult;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
@ -44,7 +44,7 @@ import static org.owasp.webgoat.plugin.SimpleXXE.parseXml;
* @version $Id: $Id
* @since November 17, 2016
*/
public class ContentTypeAssignment extends Assignment {
public class ContentTypeAssignment extends AssignmentEndpoint {
@Override
public String getPath() {

View File

@ -1,7 +1,7 @@
package org.owasp.webgoat.plugin;
import lombok.extern.slf4j.Slf4j;
import org.owasp.webgoat.lessons.Endpoint;
import org.owasp.webgoat.endpoints.Endpoint;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

View File

@ -1,8 +1,8 @@
package org.owasp.webgoat.plugin;
import org.apache.commons.exec.OS;
import org.owasp.webgoat.lessons.Assignment;
import org.owasp.webgoat.lessons.model.AttackResult;
import org.owasp.webgoat.endpoints.AssignmentEndpoint;
import org.owasp.webgoat.lessons.AttackResult;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
@ -44,7 +44,7 @@ import java.io.StringReader;
* @version $Id: $Id
* @since November 17, 2016
*/
public class SimpleXXE extends Assignment {
public class SimpleXXE extends AssignmentEndpoint {
private final static String[] DEFAULT_LINUX_DIRECTORIES = {"usr", "opt", "var"};
private final static String[] DEFAULT_WINDOWS_DIRECTORIES = {"Windows", "Program Files (x86)", "Program Files"};