Fully working WebGoat after migrating to Spring Boot.
This commit is contained in:
parent
ecc8cb391b
commit
8ff02cab6d
@ -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>-->
|
||||
|
@ -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!");
|
||||
}
|
||||
|
||||
/**
|
||||
|
19
webgoat-container/src/main/java/org/owasp/webgoat/Info.java
Normal file
19
webgoat-container/src/main/java/org/owasp/webgoat/Info.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
/**
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
});
|
||||
});
|
@ -0,0 +1,13 @@
|
||||
define(['jquery',
|
||||
'underscore',
|
||||
'backbone'],
|
||||
function ($,
|
||||
_,
|
||||
Backbone) {
|
||||
return Backbone.Model.extend({
|
||||
url: 'service/lessonprogress.mvc',
|
||||
completed: function () {
|
||||
this.fetch();
|
||||
}
|
||||
});
|
||||
});
|
@ -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);
|
||||
}
|
||||
|
||||
});
|
||||
});
|
@ -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);
|
||||
}
|
||||
});
|
||||
});
|
@ -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("");
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
@ -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">×</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}, 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 & Project Lead)</li>
|
||||
<li>Jeff Williams (Author & 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 & 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>
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user