Fully working WebGoat after migrating to Spring Boot.

This commit is contained in:
Nanne Baars 2016-04-08 18:06:13 +02:00
parent ecc8cb391b
commit 8ff02cab6d
26 changed files with 413 additions and 394 deletions

View File

@ -231,6 +231,11 @@
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!--<dependency>-->
<!--<groupId>org.springframework.boot</groupId>-->
<!--<artifactId>spring-boot-devtools</artifactId>-->

View File

@ -91,6 +91,13 @@ public class HammerHead extends HttpServlet {
*/
private WebgoatContext webgoatContext = null;
public HammerHead(WebgoatContext context) {
this.webgoatContext = context;
}
//TODO_NB
public HammerHead() {}
/**
* {@inheritDoc}
*
@ -186,7 +193,8 @@ public class HammerHead extends HttpServlet {
String viewPage = getViewPage(mySession);
logger.debug("Forwarding to view: " + viewPage);
logger.debug("Screen: " + screen);
request.getRequestDispatcher(viewPage).forward(request, response);
response.sendRedirect("startlesson.mvc");
// request.getRequestDispatcher(viewPage).forward(request, response);
} catch (Throwable t) {
logger.error("Error handling request", t); screen = new ErrorScreen(mySession, t);
} finally {
@ -242,8 +250,6 @@ public class HammerHead extends HttpServlet {
httpDateFormat = new SimpleDateFormat("EEE, dd MMM yyyyy HH:mm:ss z", Locale.US);
httpDateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
propertiesPath = getServletContext().getRealPath("/WEB-INF/webgoat.properties");
webgoatContext = new WebgoatContext(this);
logger.info("Browse to http://localhost:8080/WebGoat and happy hacking!");
}
/**

View File

@ -0,0 +1,19 @@
package org.owasp.webgoat;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class Info {
public static class Information {
}
@Bean(name = "information")
public Information information() {
return null;
}
}

View File

@ -1,191 +0,0 @@
package org.owasp.webgoat;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.session.Course;
import org.owasp.webgoat.session.WebSession;
/**
* *************************************************************************************************
*
*
* 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.
*
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @since October 28, 2003
* @version $Id: $Id
*/
public class LessonSource extends HammerHead {
/**
*
*/
private static final long serialVersionUID = 2588430536196446145L;
/**
* Description of the Field
*/
public final static String START_SOURCE_SKIP = "START_OMIT_SOURCE";
/** Constant <code>END_SOURCE_SKIP="END_OMIT_SOURCE"</code> */
public final static String END_SOURCE_SKIP = "END_OMIT_SOURCE";
/**
* {@inheritDoc}
*
* Description of the Method
* @exception IOException Description of the Exception
* @exception ServletException Description of the Exception
*/
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
String source = null;
try {
// System.out.println( "Entering doPost: " );
// System.out.println( " - request " + request);
// System.out.println( " - principle: " + request.getUserPrincipal()
// );
// setCacheHeaders(response, 0);
WebSession session = (WebSession) request.getSession(true).getAttribute(WebSession.SESSION);
// FIXME: Too much in this call.
session.update(request, response, this.getServletName());
boolean showSolution = session.getParser().getBooleanParameter("solution", false);
boolean showSource = session.getParser().getBooleanParameter("source", false);
if (showSolution) {
// Get the Java solution of the lesson.
source = getSolution(session);
int scr = session.getCurrentScreen();
Course course = session.getCourse();
AbstractLesson lesson = course.getLesson(session, scr, AbstractLesson.USER_ROLE);
lesson.getLessonTracker(session).setViewedSolution(true);
} else if (showSource) {
// Get the Java source of the lesson. FIXME: Not needed
source = getSource(session);
int scr = session.getCurrentScreen();
Course course = session.getCourse();
AbstractLesson lesson = course.getLesson(session, scr, AbstractLesson.USER_ROLE);
lesson.getLessonTracker(session).setViewedSource(true);
}
} catch (Throwable t) {
t.printStackTrace();
log("ERROR: " + t);
} finally {
try {
this.writeSource(source, response);
} catch (Throwable thr) {
thr.printStackTrace();
log(request, "Could not write error screen: " + thr.getMessage());
}
// System.out.println( "Leaving doPost: " );
}
}
/**
* Description of the Method
*
* @param s Description of the Parameter
* @return Description of the Return Value
*/
protected String getSource(WebSession s) {
String source = null;
int scr = s.getCurrentScreen();
Course course = s.getCourse();
if (s.isUser() || s.isChallenge()) {
AbstractLesson lesson = course.getLesson(s, scr, AbstractLesson.USER_ROLE);
if (lesson != null) {
source = lesson.getSource(s);
}
}
if (source == null) {
return "Source code is not available. Contact "
+ s.getWebgoatContext().getFeedbackAddressHTML();
}
return (source.replaceAll("(?s)" + START_SOURCE_SKIP + ".*" + END_SOURCE_SKIP,
"Code Section Deliberately Omitted"));
}
/**
* <p>getSolution.</p>
*
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
* @return a {@link java.lang.String} object.
*/
protected String getSolution(WebSession s) {
String source = null;
int scr = s.getCurrentScreen();
Course course = s.getCourse();
if (s.isUser() || s.isChallenge()) {
AbstractLesson lesson = course.getLesson(s, scr, AbstractLesson.USER_ROLE);
if (lesson != null) {
source = lesson.getSolution(s);
}
}
if (source == null) {
return "Solution is not available. Contact "
+ s.getWebgoatContext().getFeedbackAddressHTML();
}
return (source);
}
/**
* Description of the Method
*
* @param s Description of the Parameter
* @param response Description of the Parameter
* @exception IOException Description of the Exception
* @throws java.io.IOException if any.
*/
protected void writeSource(String s, HttpServletResponse response) throws IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
if (s == null) {
s = new String();
}
out.print(s);
out.close();
}
}

View File

@ -1,6 +1,7 @@
package org.owasp.webgoat;
import org.owasp.webgoat.session.LabelDebugger;
import org.owasp.webgoat.session.WebgoatContext;
import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -13,7 +14,6 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter
@Configuration
public class MvcConfiguration extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("login");
@ -21,8 +21,13 @@ public class MvcConfiguration extends WebMvcConfigurerAdapter {
}
@Bean
public ServletRegistrationBean servletRegistrationBean() {
return new ServletRegistrationBean(new HammerHead(), "/attack/*");
public ServletRegistrationBean servletRegistrationBean(HammerHead hammerHead) {
return new ServletRegistrationBean(hammerHead, "/attack/*");
}
@Bean
public HammerHead hammerHead(WebgoatContext context) {
return new HammerHead(context);
}
@Bean

View File

@ -5,9 +5,6 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
@SpringBootApplication
public class WebGoat extends SpringBootServletInitializer {
@ -16,12 +13,6 @@ public class WebGoat extends SpringBootServletInitializer {
return application.sources(WebGoat.class);
}
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
super.onStartup(servletContext);
}
public static void main(String[] args) throws Exception {
SpringApplication.run(WebGoat.class, args);
}

View File

@ -14,6 +14,7 @@ import org.apache.commons.lang3.builder.ToStringBuilder;
* @author rlawson
* @version $Id: $Id
*/
//TODO_NB still necessary?
public class Application {
private static final Application INSTANCE = new Application();

View File

@ -5,6 +5,18 @@
*/
package org.owasp.webgoat.application;
import org.owasp.webgoat.lessons.LessonServletMapping;
import org.owasp.webgoat.plugins.PluginsLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletRegistration;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Paths;
@ -16,20 +28,6 @@ import java.util.Set;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletRegistration;
import org.owasp.webgoat.HammerHead;
import org.owasp.webgoat.lessons.LessonServletMapping;
import org.owasp.webgoat.plugins.PluginsLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.filter.AnnotationTypeFilter;
/**
* Web application lifecycle listener.
*
@ -38,7 +36,7 @@ import org.springframework.core.type.filter.AnnotationTypeFilter;
*/
public class WebGoatServletListener implements ServletContextListener {
private static final Logger logger = LoggerFactory.getLogger(HammerHead.class);
private static final Logger logger = LoggerFactory.getLogger(WebGoatServletListener.class);
/** {@inheritDoc} */
@Override

View File

@ -0,0 +1,54 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.owasp.webgoat.controller;
import org.owasp.webgoat.lessons.RandomLessonAdapter;
import org.owasp.webgoat.session.WebSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
/**
* <p>Start class.</p>
*
* @author rlawson
* @version $Id: $Id
*/
@Controller
public class StartLesson {
final Logger logger = LoggerFactory.getLogger(StartLesson.class);
@Autowired
private ServletContext servletContext;
/**
* <p>start.</p>
*
* @param request a {@link HttpServletRequest} object.
* @return a {@link ModelAndView} object.
*/
@RequestMapping(path = "startlesson.mvc", method = {RequestMethod.GET, RequestMethod.POST})
public ModelAndView start(HttpServletRequest request) {
ModelAndView model = new ModelAndView();
WebSession ws = (WebSession) request.getSession().getAttribute(WebSession.SESSION);
model.addObject("has_stages", ws.getCurrentLesson() instanceof RandomLessonAdapter);
model.addObject("course", ws.getCourse());
model.addObject("lesson", ws.getCurrentLesson());
model.addObject("message", ws.getMessage());
model.addObject("instructions", ws.getInstructions());
model.setViewName("lesson_content");
return model;
}
}

View File

@ -10,10 +10,10 @@ import org.apache.ecs.html.Html;
import org.apache.ecs.html.IMG;
import org.apache.ecs.html.PRE;
import org.apache.ecs.html.Title;
import org.owasp.webgoat.session.WebgoatContext;
import org.owasp.webgoat.session.ParameterNotFoundException;
import org.owasp.webgoat.session.Screen;
import org.owasp.webgoat.session.WebSession;
import org.owasp.webgoat.session.WebgoatContext;
import org.owasp.webgoat.session.WebgoatProperties;
import org.owasp.webgoat.util.BeanProvider;
import org.owasp.webgoat.util.LabelManager;

View File

@ -1,10 +1,17 @@
package org.owasp.webgoat.plugins;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.session.WebgoatContext;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.session.WebgoatProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.SimpleBeanDefinitionRegistry;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.type.filter.AssignableTypeFilter;
import org.springframework.core.type.filter.TypeFilter;
import javax.servlet.ServletContext;
import java.io.File;
@ -142,7 +149,9 @@ public class LegacyLoader {
*/
public void loadFiles(ServletContext context, String path) {
logger.debug("Loading files into cache, path: " + path);
Set resourcePaths = context.getResourcePaths(path);
Resource resource = new ClassPathResource("/");
Set resourcePaths = null;
if (resourcePaths == null) {
logger.error("Unable to load file cache for courses, this is probably a bug or configuration issue");
return;
@ -170,15 +179,20 @@ public class LegacyLoader {
* @return a {@link java.util.List} object.
*/
public List<AbstractLesson> loadLessons(WebgoatContext webgoatContext, ServletContext context, String path, WebgoatProperties properties ) {
BeanDefinitionRegistry bdr = new SimpleBeanDefinitionRegistry();
ClassPathBeanDefinitionScanner s = new ClassPathBeanDefinitionScanner(bdr);
loadFiles(context, path);
TypeFilter tf = new AssignableTypeFilter(AbstractLesson.class);
s.addIncludeFilter(tf);
s.setIncludeAnnotationConfig(false);
s.scan("org.owasp.webgoat.lessons.admin");
String[] beanDefinitionNames = bdr.getBeanDefinitionNames();
List<AbstractLesson> lessons = new LinkedList<AbstractLesson>();
for (String file : files) {
String className = getClassFile(file, path);
for (String file : beanDefinitionNames) {
String className = bdr.getBeanDefinition(file).getBeanClassName();
if (className != null && !className.endsWith("_i") && className.startsWith("org.owasp.webgoat.lessons.admin")) {
try {
Class c = Class.forName(className);
Object o = c.newInstance();
@ -201,9 +215,8 @@ public class LegacyLoader {
// can't tell that because it threw the exception. Catch 22
// logger.error("Error in loadLessons: ", e);
}
}
}
loadResources(lessons);
// loadResources(lessons);
return lessons;
}

View File

@ -39,9 +39,6 @@ import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpSession;
import static org.owasp.webgoat.LessonSource.END_SOURCE_SKIP;
import static org.owasp.webgoat.LessonSource.START_SOURCE_SKIP;
/**
* <p>SourceService class.</p>
*
@ -51,6 +48,14 @@ import static org.owasp.webgoat.LessonSource.START_SOURCE_SKIP;
@Controller
public class SourceService extends BaseService {
/**
* Description of the Field
*/
public final static String START_SOURCE_SKIP = "START_OMIT_SOURCE";
/** Constant <code>END_SOURCE_SKIP="END_OMIT_SOURCE"</code> */
public final static String END_SOURCE_SKIP = "END_OMIT_SOURCE";
/**
* Returns source for current attack
*

View File

@ -1,6 +1,12 @@
package org.owasp.webgoat.session;
import org.apache.ecs.MultiPartElement;
import org.apache.ecs.html.B;
import org.apache.ecs.html.TD;
import org.apache.ecs.html.TR;
import org.apache.ecs.html.Table;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
@ -9,11 +15,6 @@ import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import org.apache.ecs.MultiPartElement;
import org.apache.ecs.html.B;
import org.apache.ecs.html.TD;
import org.apache.ecs.html.TR;
import org.apache.ecs.html.Table;
/**

View File

@ -1,5 +1,19 @@
package org.owasp.webgoat.session;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.lessons.RandomLessonAdapter;
import org.owasp.webgoat.lessons.SequentialLessonAdapter;
import org.owasp.webgoat.lessons.model.RequestParameter;
import org.owasp.webgoat.util.BeanProvider;
import org.owasp.webgoat.util.LabelManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.ServletContext;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.security.Principal;
@ -15,19 +29,6 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Vector;
import javax.servlet.ServletContext;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.lessons.RandomLessonAdapter;
import org.owasp.webgoat.lessons.SequentialLessonAdapter;
import org.owasp.webgoat.lessons.model.RequestParameter;
import org.owasp.webgoat.util.BeanProvider;
import org.owasp.webgoat.util.LabelManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* *************************************************************************************************
@ -60,6 +61,10 @@ import org.slf4j.LoggerFactory;
*/
public class WebSession {
/**
* @TODO_NB Spring can take inject this bean bound to a specific scope no longer necessary to bound it to a HTTP session
*/
final Logger logger = LoggerFactory.getLogger(WebSession.class);
/**
@ -521,27 +526,6 @@ public class WebSession {
return params;
}
/**
* <p> getCookies. </p>
*
* @return a {@link java.util.List} object.
*/
public List<Cookie> getCookies() {
List<Cookie> cookies = null;
if (showCookies()) {
cookies = Arrays.asList(request.getCookies());
}
/*
* List cookies = new Vector(); HttpServletRequest request = getRequest(); Cookie[] cookies =
* request.getCookies(); if ( cookies.length == 0 ) { list.addElement( new LI( "No Cookies" ) ); } for ( int i =
* 0; i < cookies.length; i++ ) { Cookie cookie = cookies[i]; cookies.add(cookie); //list.addElement( new LI(
* cookie.getName() + " -> " + cookie.getValue() ) ); }
*/
return cookies;
}
/**
* Gets the cookie attribute of the CookieScreen object
*

View File

@ -2,6 +2,8 @@ package org.owasp.webgoat.session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import javax.servlet.http.HttpServlet;
@ -11,62 +13,20 @@ import javax.servlet.http.HttpServlet;
* @version $Id: $Id
* @author dm
*/
@Configuration
public class WebgoatContext {
final Logger logger = LoggerFactory.getLogger(WebgoatContext.class);
/** Constant <code>DATABASE_CONNECTION_STRING="DatabaseConnectionString"</code> */
public final static String DATABASE_CONNECTION_STRING = "DatabaseConnectionString";
/** Constant <code>DATABASE_DRIVER="DatabaseDriver"</code> */
public final static String DATABASE_DRIVER = "DatabaseDriver";
/** Constant <code>DATABASE_USER="DatabaseUser"</code> */
public final static String DATABASE_USER = "DatabaseUser";
/** Constant <code>DATABASE_PASSWORD="DatabasePassword"</code> */
public final static String DATABASE_PASSWORD = "DatabasePassword";
/** Constant <code>ENTERPRISE="Enterprise"</code> */
public final static String ENTERPRISE = "Enterprise";
/** Constant <code>CODING_EXERCISES="CodingExercises"</code> */
public final static String CODING_EXERCISES = "CodingExercises";
/** Constant <code>SHOWCOOKIES="ShowCookies"</code> */
public final static String SHOWCOOKIES = "ShowCookies";
/** Constant <code>SHOWPARAMS="ShowParams"</code> */
public final static String SHOWPARAMS = "ShowParams";
/** Constant <code>SHOWREQUEST="ShowRequest"</code> */
public final static String SHOWREQUEST = "ShowRequest";
/** Constant <code>SHOWSOURCE="ShowSource"</code> */
public final static String SHOWSOURCE = "ShowSource";
/** Constant <code>SHOWSOLUTION="ShowSolution"</code> */
public final static String SHOWSOLUTION = "ShowSolution";
/** Constant <code>SHOWHINTS="ShowHints"</code> */
public final static String SHOWHINTS = "ShowHints";
/** Constant <code>FEEDBACK_ADDRESS_HTML="FeedbackAddressHTML"</code> */
public final static String FEEDBACK_ADDRESS_HTML = "FeedbackAddressHTML";
/** Constant <code>FEEDBACK_ADDRESS="email"</code> */
public final static String FEEDBACK_ADDRESS = "email";
/** Constant <code>DEBUG="debug"</code> */
public final static String DEBUG = "debug";
/** Constant <code>DEFAULTLANGUAGE="DefaultLanguage"</code> */
public final static String DEFAULTLANGUAGE = "DefaultLanguage";
@Value("${webgoat.database.connection.string}")
private String databaseConnectionString;
private String realConnectionString = null;
@Value("${webgoat.database.driver}")
private String databaseDriver;
private String databaseUser;
@ -87,9 +47,11 @@ public class WebgoatContext {
private boolean codingExercises = false;
private String feedbackAddress = "webgoat@owasp.org";
@Value("${webgoat.feedback.address}")
private String feedbackAddress;
private String feedbackAddressHTML = "<A HREF=mailto:webgoat@owasp.org>webgoat@owasp.org</A>";
@Value("${webgoat.feedback.address.html}")
private String feedbackAddressHTML = "";
private boolean isDebug = false;
@ -101,44 +63,6 @@ public class WebgoatContext {
private java.nio.file.Path pluginDirectory;
/**
* <p>Constructor for WebgoatContext.</p>
*
* @param servlet a {@link javax.servlet.http.HttpServlet} object.
*/
public WebgoatContext(HttpServlet servlet) {
this.servlet = servlet;
databaseConnectionString = getParameter(servlet, DATABASE_CONNECTION_STRING);
databaseDriver = getParameter(servlet, DATABASE_DRIVER);
databaseUser = getParameter(servlet, DATABASE_USER);
databasePassword = getParameter(servlet, DATABASE_PASSWORD);
// initialize from web.xml
showParams = "true".equals(getParameter(servlet, SHOWPARAMS));
showCookies = "true".equals(getParameter(servlet, SHOWCOOKIES));
showSource = "true".equals(getParameter(servlet, SHOWSOURCE));
showSolution = "true".equals(getParameter(servlet, SHOWSOLUTION));
enterprise = "true".equals(getParameter(servlet, ENTERPRISE));
codingExercises = "true".equals(getParameter(servlet, CODING_EXERCISES));
feedbackAddressHTML = getParameter(servlet, FEEDBACK_ADDRESS_HTML) != null ? getParameter(servlet,
FEEDBACK_ADDRESS_HTML)
: feedbackAddressHTML;
feedbackAddress = getParameter(servlet, FEEDBACK_ADDRESS) != null ? getParameter(servlet, FEEDBACK_ADDRESS)
: feedbackAddress;
showRequest = "true".equals(getParameter(servlet, SHOWREQUEST));
isDebug = "true".equals(getParameter(servlet, DEBUG));
servletName = servlet.getServletName();
defaultLanguage = getParameter(servlet, DEFAULTLANGUAGE) != null ? new String(getParameter(servlet, DEFAULTLANGUAGE)) : new String("en");
}
private String getParameter(HttpServlet servlet, String key) {
String value = System.getenv().get(key);
if (value == null) {
value = servlet.getInitParameter(key);
}
return value;
}
/**
* returns the connection string with the real path to the database
* directory inserted at the word PATH

View File

@ -1,10 +1,12 @@
package org.owasp.webgoat.util;
import org.owasp.webgoat.session.WebgoatContext;
import java.util.HashMap;
import java.util.Locale;
import java.util.ResourceBundle;
import org.owasp.webgoat.session.WebgoatContext;
@Deprecated
/**

View File

@ -8,4 +8,15 @@ server.error.include-stacktrace=always
logging.level.org.springframework=DEBUG
logging.level.org.hibernate=ERROR
spring.thymeleaf.cache=false
security.enable-csrf=false
security.enable-csrf=false
webgoat.build.version=@project.version@
webgoat.email=webgoat@owasp.org
webgoat.emaillist=owasp-webgoat@lists.owasp.org
webgoat.feedback.address=webgoat@owasp.org
webgoat.feedback.address.html=<A HREF=mailto:webgoat@owasp.org>webgoat@owasp.org</A>
webgoat.database.driver=org.hsqldb.jdbcDriver
webgoat.database.connection.string=jdbc:hsqldb:mem:test
# TODO_NB
#webgoat.database.connection.string=jdbc:hsqldb:mem:${USER}
webgoat.default.language=en

View File

@ -0,0 +1,39 @@
define([
'backbone'],
function(
Backbone) {
return Backbone.Model.extend({
id: 'label-status',
url: 'service/debug/labels.mvc',
label: '',
labels: {
enable: 'Enable label debugging',
disable: 'Disable label debugging'
},
initialize: function() {
this.load();
},
fetch: function(options) {
options || (options = {});
var data = (options.data || {});
if(this.enabled != undefined) {
options.data = { enabled: !this.enabled };
}
return Backbone.Collection.prototype.fetch.call(this, options);
},
load: function () {
this.fetch().then(this.labelStatusLoaded.bind(this));
},
labelStatusLoaded: function(data) {
this.enabled = data.enabled;
this.label = this.enabled ? this.labels['disable'] : this.labels['enable'];
this.trigger('plugins:loaded', this, data);
}
});
});

View File

@ -0,0 +1,13 @@
define(['jquery',
'underscore',
'backbone'],
function ($,
_,
Backbone) {
return Backbone.Model.extend({
url: 'service/lessonprogress.mvc',
completed: function () {
this.fetch();
}
});
});

View File

@ -0,0 +1,19 @@
define([
'backbone'],
function(
Backbone) {
return Backbone.Model.extend({
url: 'service/reloadplugins.mvc',
id: 'reload-plugins',
label: 'Reload plugins',
load: function () {
this.fetch().then(this.pluginsLoaded.bind(this));
},
pluginsLoaded: function(data) {
this.trigger('plugins:loaded', this, data);
}
});
});

View File

@ -0,0 +1,77 @@
define(['jquery',
'underscore',
'backbone',
'goatApp/model/PluginReloadModel',
'goatApp/model/LabelDebugModel'],
function(
$,
_,
Backbone,
PluginReloadModel,
LabelDebugModel) {
return Backbone.View.extend({
el: '#developer-controls',
onControlClick: function(model) {
$('#' + model.id).find('td').text('Loading...');
model.load();
},
onPluginsLoaded: function(model) {
window.location.href = 'welcome.mvc';
},
onLabelsLoaded: function(model) {
this.models[1] = model;
this.render();
Backbone.history.loadUrl(Backbone.history.getFragment());
},
initialize: function(options) {
this.addMenuListener();
this.models = [new PluginReloadModel(), new LabelDebugModel()];
this.listenTo(this.models[0], 'plugins:loaded', this.onPluginsLoaded);
this.listenTo(this.models[1], 'plugins:loaded', this.onLabelsLoaded);
this.render();
},
addMenuListener: function() {
var showHandler = function(e) {
e.preventDefault();
$('#developer-control-container').show();
$(this).text('Hide developer controls').off().on('click', hideHandler);
};
var hideHandler = function(e) {
e.preventDefault();
$('#developer-control-container').hide();
$(this).text('Show developer controls').off().on('click', showHandler);
};
$('a[href="#developer-controls"]').click(showHandler);
},
render: function() {
this.$el.html('');
var table = $('<table>',{'class':'developer-controls-table table-nonfluid'});
var self = this;
_.each(this.models, function(model) {
var newRow = $('<tr>', { id: model.id });
var headerCell = $('<th>')
var statusCell = $('<td>')
var link = $('<a>', {
'text': model.label,
'title': model.label
});
link.click(_.bind(self.onControlClick, self, model));
newRow.append(headerCell.append(link));
newRow.append(statusCell);
table.append(newRow);
});
this.$el.append(table);
}
});
});

View File

@ -0,0 +1,26 @@
define(['jquery',
'underscore',
'backbone',
'goatApp/model/LessonProgressModel'],
function ($,
_,
Backbone,
LessonProgressModel) {
return Backbone.View.extend({
el: '#lesson-progress',
initialize: function (lessonProgressModel) {
this.model = lessonProgressModel;
if (this.model) {
this.listenTo(this.model, 'change', this.render);
}
},
render: function () {
if (this.model.get("lessonCompleted")) {
this.$el.html(this.model.get('successMessage'));
} else {
this.$el.html("");
}
}
});
});

View File

@ -1,42 +1,46 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<html xmlns:th="http://www.thymeleaf.org">
<div class="modal-content">
<body>
<div th:fragment="about" class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h3 class="modal-title" id="myModalLabel">About WebGoat - Provided by the OWASP Foundation</h3>
</div>
<div class="modal-body modal-scroll">
<p>Thanks for hacking The Goat!</p>
<p>Thanks for hacking The Goat!</p>
<p>WebGoat is a demonstration of common web application flaws. The
associated exercises are intended to provide hands-on experience with
techniques aimed at demonstrating and testing application penetration.
</p>
<p>From the entire WebGoat team, we appreciate your interest and efforts
in making applications not just better, but safer and more secure for
everyone. We, as well as our sacrificial goat, thank you.</p>
<p>
Version: ${version},&nbsp;Build: ${build}
Version: <span th:text="${@environment.getProperty('webgoat.build.version')}"></span>
</p>
<div class="row">
<div class="col-md-6">
<p>Contact us:
<ul>
<li>WebGoat mailing list: ${emailList}</li>
<li>Bruce Mayhew: ${contactEmail}</li>
<li>WebGoat mailing list: <span th:text="${@environment.getProperty('webgoat.emaillist')}"></span></li>
<li>Bruce Mayhew: <span th:text="${@environment.getProperty('webgoat.email')}"></span></li>
</ul>
</p>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<p>WebGoat Authors
<ul>
<li>Bruce Mayhew (Author & Project Lead)</li>
<li>Jeff Williams (Author & Original Idea)</li>
<li>Jason White (Architect)</li>
<li>Nanne Baars (Plugin Architecture)</li>
<li>Bruce Mayhew (Author &amp; Project Lead)</li>
<li>Jeff Williams (Author &amp; Original Idea)</li>
<li>Jason White (Architect)</li>
<li>Nanne Baars (Plugin Architecture)</li>
<li>Richard Lawson (Architect)</li>
</ul>
</p>
@ -44,11 +48,11 @@
<div class="col-md-6">
<p>Active Contributors
<ul>
<li>Nanne Baars (Developer)</li>
<li>Jason White (Developer)</li>
<li>Doug Morato (Developer & CI)</li>
<li>Jeff Wayman (Docs)</li>
<li>Bruce Mayhew (Developer)</li>
<li>Nanne Baars (Developer)</li>
<li>Jason White (Developer)</li>
<li>Doug Morato (Developer &amp; CI)</li>
<li>Jeff Wayman (Docs)</li>
<li>Bruce Mayhew (Developer)</li>
<li>Michael Dever (Developer)</li>
</ul>
</p>
@ -58,18 +62,20 @@
<div class="col-md-6">
<p>WebGoat Design Team (Active)
<ul>
<li>Nanne Baars (Plugin Architecture)</li>
<li>Bruce Mayhew (Goat Herder)</li>
<li>Jeff Wayman (Website and Docs)</li>
<li>Jason White (User Interface)</li>
<li>Nanne Baars (Plugin Architecture)</li>
<li>Bruce Mayhew (Goat Herder)</li>
<li>Jeff Wayman (Website and Docs)</li>
<li>Jason White (User Interface)</li>
</ul>
</p><br/>
<p>Corporate Sponsorship - Companies that have donated significant time to WebGoat development
<ul>
<li>Aspect Security</li>
<li>Ounce Labs</li>
</ul>
</p><br/>
<p>Did we miss you? Our sincere apologies, as we know there have
been many contributors over the years. If your name does not
appear in any of the lists above, please send us a note. We'll
@ -110,3 +116,5 @@
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</body>
</html>

View File

@ -1 +1,9 @@
<h1>Lesson content</h1>
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<div id="lessonInstructions" th:utext="${instructions}"></div>
<div id="message" class="info" th:text="${message}"></div>
<br/>
<div th:utext="${lesson.content}"></div>
</html>

View File

@ -99,12 +99,17 @@
<div class="col-md-8">
<div class="col-md-12" align="left">
<div class="panel" id="help-controls">
<button class="btn btn-primary btn-xs btn-danger help-button" id="show-source-button">Show Source
<button class="btn btn-primary btn-xs btn-danger help-button" id="show-source-button">Show
Source
</button>
<button class="btn btn-primary btn-xs btn-danger help-button" id="show-solution-button">Show Solution
<button class="btn btn-primary btn-xs btn-danger help-button" id="show-solution-button">Show
Solution
</button>
<button class="btn btn-primary btn-xs btn-danger help-button" id="show-plan-button">Show Plan</button>
<button class="btn btn-primary btn-xs btn-danger help-button" id="show-hints-button">Show Hints
<button class="btn btn-primary btn-xs btn-danger help-button" id="show-plan-button">Show
Plan
</button>
<button class="btn btn-primary btn-xs btn-danger help-button" id="show-hints-button">Show
Hints
</button>
<button class="btn btn-xs help-button" id="restart-lesson-button">Restart Lesson</button>
</div>
@ -192,10 +197,7 @@
<!-- About WebGoat Modal -->
<div class="modal" id="about-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<!-- TODO@NB
<jsp:include page="../pages/about.jsp"/> -->
</div>
<div class="modal-content" th:replace="about :: about"></div>
</div>
</div>
</body>

View File

@ -35,9 +35,8 @@
<div class="col-md-6">
<p>WebGoat Authors
<ul>
<li>Bruce Mayhew (Author & Project Lead)</li>
<li>Jeff Williams (Author & Original Idea)</li>
<li>Jason White (Architect)</li>
<li>Bruce Mayhew (Author and Project Lead)</li>
<li>Jeff Williams (Author and Original Idea)</li>
<li>Nanne Baars (Plugin Architecture)</li>
<li>Richard Lawson (Architect)</li>
</ul>
@ -48,7 +47,7 @@
<ul>
<li>Nanne Baars (Developer)</li>
<li>Jason White (Developer)</li>
<li>Doug Morato (Developer & CI)</li>
<li>Doug Morato (Developer and CI)</li>
<li>Jeff Wayman (Docs)</li>
<li>Bruce Mayhew (Developer)</li>
<li>Michael Dever (Developer)</li>
@ -65,13 +64,13 @@
<li>Jeff Wayman (Website and Docs)</li>
<li>Jason White (User Interface)</li>
</ul>
</p><br></br>
</p><br/>
<p>Corporate Sponsorship - Companies that have donated significant time to WebGoat development
<ul>
<li>Aspect Security</li>
<li>Ounce Labs</li>
</ul>
</p><br></br>
</p><br/>
<p>Did we miss you? Our sincere apologies, as we know there have
been many contributors over the years. If your name does not
appear in any of the lists above, please send us a note. We'll