Adjust lesson template (#704)

* Remove method `getId()` from all lessons as it defaults to the class name

* remove clean up endpoint

* remove unused class `RequestParameter`

* remove unused class `PluginLoadingFailure`

* Move `CourseConfiguration` to lesson package

* Add more content around the lesson template lesson and make it visible as a lesson in WebGoat

* Remove explicit invocation `trackProgress()` inside WebGoat framework so assignments only need to return an `AttackResult`

* Put original solution back as well for SQL string injection

* review comments

* Add
This commit is contained in:
Nanne Baars
2019-11-17 13:39:56 +01:00
committed by René Zubcevic
parent f40b6ffd31
commit 5dd6b31905
139 changed files with 769 additions and 870 deletions

View File

@ -1,27 +0,0 @@
package org.owasp.webgoat;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.FileSystemUtils;
import javax.annotation.PostConstruct;
import java.io.File;
/**
* @author nbaars
* @since 4/15/17.
*/
@Slf4j
@Configuration
@ConditionalOnExpression("'${webgoat.clean}' == 'true'")
public class CleanupLocalProgressFiles {
@Value("${webgoat.server.directory}")
private String webgoatHome;
@PostConstruct
public void clean() {
}
}

View File

@ -29,7 +29,6 @@ import lombok.Getter;
import org.owasp.webgoat.i18n.PluginMessages;
import org.owasp.webgoat.session.UserSessionData;
import org.owasp.webgoat.session.WebSession;
import org.owasp.webgoat.users.UserTracker;
import org.owasp.webgoat.users.UserTrackerRepository;
import org.springframework.beans.factory.annotation.Autowired;
@ -45,20 +44,6 @@ public abstract class AssignmentEndpoint {
@Autowired
private PluginMessages messages;
protected AttackResult trackProgress(AttackResult attackResult) {
UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName());
if (userTracker == null) {
userTracker = new UserTracker(webSession.getUserName());
}
if (attackResult.assignmentSolved()) {
userTracker.assignmentSolved(webSession.getCurrentLesson(), this.getClass().getSimpleName());
} else {
userTracker.assignmentFailed(webSession.getCurrentLesson());
}
userTrackerRepository.save(userTracker);
return attackResult;
}
protected WebSession getWebSession() {
return webSession;
}
@ -76,9 +61,10 @@ public abstract class AssignmentEndpoint {
* Of course you can overwrite these values in a specific lesson
*
* @return a builder for creating a result from a lesson
* @param assignment
*/
protected AttackResult.AttackResultBuilder success() {
return AttackResult.builder(messages).lessonCompleted(true).feedback("assignment.solved");
protected AttackResult.AttackResultBuilder success(AssignmentEndpoint assignment) {
return AttackResult.builder(messages).lessonCompleted(true).feedback("assignment.solved").assignment(assignment);
}
/**
@ -90,12 +76,13 @@ public abstract class AssignmentEndpoint {
* Of course you can overwrite these values in a specific lesson
*
* @return a builder for creating a result from a lesson
* @param assignment
*/
protected AttackResult.AttackResultBuilder failed() {
return AttackResult.builder(messages).lessonCompleted(false).feedback("assignment.not.solved");
protected AttackResult.AttackResultBuilder failed(AssignmentEndpoint assignment) {
return AttackResult.builder(messages).lessonCompleted(false).feedback("assignment.not.solved").assignment(assignment);
}
protected AttackResult.AttackResultBuilder informationMessage() {
return AttackResult.builder(messages).lessonCompleted(false);
protected AttackResult.AttackResultBuilder informationMessage(AssignmentEndpoint assignment) {
return AttackResult.builder(messages).lessonCompleted(false).assignment(assignment);
}
}

View File

@ -29,8 +29,11 @@ import lombok.Getter;
import org.apache.commons.lang3.StringEscapeUtils;
import org.owasp.webgoat.i18n.PluginMessages;
import java.util.Objects;
public class AttackResult {
public static class AttackResultBuilder {
private boolean lessonCompleted;
@ -39,6 +42,7 @@ public class AttackResult {
private String feedbackResourceBundleKey;
private String output;
private Object[] outputArgs;
private AssignmentEndpoint assignment;
public AttackResultBuilder(PluginMessages messages) {
this.messages = messages;
@ -77,7 +81,12 @@ public class AttackResult {
}
public AttackResult build() {
return new AttackResult(lessonCompleted, messages.getMessage(feedbackResourceBundleKey, feedbackArgs), messages.getMessage(output, output, outputArgs));
return new AttackResult(lessonCompleted, messages.getMessage(feedbackResourceBundleKey, feedbackArgs), messages.getMessage(output, output, outputArgs), assignment.getClass().getSimpleName());
}
public AttackResultBuilder assignment(AssignmentEndpoint assignment) {
this.assignment = assignment;
return this;
}
}
@ -87,11 +96,14 @@ public class AttackResult {
private String feedback;
@Getter
private String output;
@Getter
private final String assignment;
public AttackResult(boolean lessonCompleted, String feedback, String output) {
public AttackResult(boolean lessonCompleted, String feedback, String output, String assignment) {
this.lessonCompleted = lessonCompleted;
this.feedback = StringEscapeUtils.escapeJson(feedback);
this.output = StringEscapeUtils.escapeJson(output);
this.assignment = assignment;
}
public static AttackResultBuilder builder(PluginMessages messages) {

View File

@ -0,0 +1,74 @@
/*
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2019 Bruce Mayhew
*
* 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.
*
* 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.
*
* 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.
*
* Getting Source ==============
*
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
*/
package org.owasp.webgoat.assignments;
import org.owasp.webgoat.session.WebSession;
import org.owasp.webgoat.users.UserTracker;
import org.owasp.webgoat.users.UserTrackerRepository;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
@RestControllerAdvice
public class LessonTrackerInterceptor implements ResponseBodyAdvice<Object> {
private UserTrackerRepository userTrackerRepository;
private WebSession webSession;
public LessonTrackerInterceptor(UserTrackerRepository userTrackerRepository, WebSession webSession) {
this.userTrackerRepository = userTrackerRepository;
this.webSession = webSession;
}
@Override
public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> clazz) {
return true;
}
@Override
public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
if (o != null && o instanceof AttackResult) {
trackProgress((AttackResult) o);
}
return o;
}
protected AttackResult trackProgress(AttackResult attackResult) {
UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName());
if (userTracker == null) {
userTracker = new UserTracker(webSession.getUserName());
}
if (attackResult.assignmentSolved()) {
userTracker.assignmentSolved(webSession.getCurrentLesson(), attackResult.getAssignment());
} else {
userTracker.assignmentFailed(webSession.getCurrentLesson());
}
userTrackerRepository.saveAndFlush(userTracker);
return attackResult;
}
}

View File

@ -20,7 +20,7 @@
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
*/
package org.owasp.webgoat.plugins;
package org.owasp.webgoat.lessons;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;

View File

@ -119,5 +119,7 @@ public abstract class Lesson {
return getTitle();
}
public abstract String getId();
public final String getId() {
return this.getClass().getSimpleName();
}
}

View File

@ -1,78 +0,0 @@
/**
* *************************************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 20014 Bruce Mayhew
*
* 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.
*
* 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.
*
* 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.
*
* Getting Source ==============
*
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository
* for free software projects.
*
*/
package org.owasp.webgoat.lessons;
/**
* <p>RequestParameter class.</p>
*
* @author rlawson
* @version $Id: $Id
*/
public class RequestParameter implements Comparable<RequestParameter> {
private final String name;
private final String value;
/**
* <p>Constructor for RequestParameter.</p>
*
* @param name a {@link java.lang.String} object.
* @param value a {@link java.lang.String} object.
*/
public RequestParameter(String name, String value) {
this.name = name;
this.value = value;
}
/**
* <p>Getter for the field <code>name</code>.</p>
*
* @return the name
*/
public String getName() {
return name;
}
/**
* <p>Getter for the field <code>value</code>.</p>
*
* @return the values
*/
public String getValue() {
return value;
}
@Override
public int compareTo(RequestParameter o) {
return this.name.compareTo(o.getName());
}
}

View File

@ -1,29 +0,0 @@
package org.owasp.webgoat.plugins;
/**
* <p>PluginLoadingFailure class.</p>
*
* @version $Id: $Id
* @author dm
*/
public class PluginLoadingFailure extends RuntimeException {
/**
* <p>Constructor for PluginLoadingFailure.</p>
*
* @param message a {@link java.lang.String} object.
*/
public PluginLoadingFailure(String message) {
super(message);
}
/**
* <p>Constructor for PluginLoadingFailure.</p>
*
* @param message a {@link java.lang.String} object.
* @param e a {@link java.lang.Exception} object.
*/
public PluginLoadingFailure(String message, Exception e) {
super(message, e);
}
}