Merge pull request #667 from WebGoat/spring-boot-2

Spring boot 2
This commit is contained in:
Nanne Baars 2019-09-24 17:09:09 +02:00 committed by GitHub
commit 686d8b0c85
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
300 changed files with 5856 additions and 5206 deletions

19
LICENSE.txt Normal file
View File

@ -0,0 +1,19 @@
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.

View File

@ -21,7 +21,7 @@
<parent> <parent>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId> <artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.21.RELEASE</version> <version>2.1.8.RELEASE</version>
</parent> </parent>
<licenses> <licenses>

View File

@ -121,8 +121,7 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.thymeleaf.extras</groupId> <groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId> <artifactId>thymeleaf-extras-springsecurity5</artifactId>
<version>2.1.2.RELEASE</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.hsqldb</groupId> <groupId>org.hsqldb</groupId>

View File

@ -39,12 +39,15 @@ import org.owasp.webgoat.asciidoc.WebGoatVersionMacro;
import org.owasp.webgoat.asciidoc.WebWolfMacro; import org.owasp.webgoat.asciidoc.WebWolfMacro;
import org.owasp.webgoat.asciidoc.WebWolfRootMacro; import org.owasp.webgoat.asciidoc.WebWolfRootMacro;
import org.owasp.webgoat.i18n.Language; import org.owasp.webgoat.i18n.Language;
import org.thymeleaf.TemplateProcessingParameters; import org.thymeleaf.IEngineConfiguration;
import org.thymeleaf.resourceresolver.IResourceResolver; import org.thymeleaf.templateresolver.FileTemplateResolver;
import org.thymeleaf.templateresolver.TemplateResolver; import org.thymeleaf.templateresource.ITemplateResource;
import org.thymeleaf.templateresource.StringTemplateResource;
import java.io.*; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.util.Map; import java.util.Map;
import static org.asciidoctor.Asciidoctor.Factory.create; import static org.asciidoctor.Asciidoctor.Factory.create;
@ -57,7 +60,7 @@ import static org.asciidoctor.Asciidoctor.Factory.create;
* </code> * </code>
*/ */
@Slf4j @Slf4j
public class AsciiDoctorTemplateResolver extends TemplateResolver { public class AsciiDoctorTemplateResolver extends FileTemplateResolver {
private static final Asciidoctor asciidoctor = create(); private static final Asciidoctor asciidoctor = create();
private static final String PREFIX = "doc:"; private static final String PREFIX = "doc:";
@ -65,72 +68,56 @@ public class AsciiDoctorTemplateResolver extends TemplateResolver {
public AsciiDoctorTemplateResolver(Language language) { public AsciiDoctorTemplateResolver(Language language) {
this.language = language; this.language = language;
setResourceResolver(new AdocResourceResolver());
setResolvablePatterns(Sets.newHashSet(PREFIX + "*")); setResolvablePatterns(Sets.newHashSet(PREFIX + "*"));
} }
@Override @Override
protected String computeResourceName(TemplateProcessingParameters params) { protected ITemplateResource computeTemplateResource(IEngineConfiguration configuration, String ownerTemplate, String template, String resourceName, String characterEncoding, Map<String, Object> templateResolutionAttributes) {
String templateName = params.getTemplateName(); var templateName = resourceName.substring(PREFIX.length());
return templateName.substring(PREFIX.length()); try (InputStream is = readInputStreamOrFallbackToEnglish(templateName, language)) {
}
private class AdocResourceResolver implements IResourceResolver {
@Override
public InputStream getResourceAsStream(TemplateProcessingParameters params, String resourceName) {
try (InputStream is = readInputStreamOrFallbackToEnglish(resourceName, language)) {
if (is == null) {
log.warn("Resource name: {} not found, did you add the adoc file?", resourceName);
return new ByteArrayInputStream(new byte[0]);
} else {
StringWriter writer = new StringWriter();
JavaExtensionRegistry extensionRegistry = asciidoctor.javaExtensionRegistry();
extensionRegistry.inlineMacro("webWolfLink", WebWolfMacro.class);
extensionRegistry.inlineMacro("webWolfRootLink", WebWolfRootMacro.class);
extensionRegistry.inlineMacro("webGoatVersion", WebGoatVersionMacro.class);
asciidoctor.convert(new InputStreamReader(is), writer, createAttributes());
return new ByteArrayInputStream(writer.getBuffer().toString().getBytes(StandardCharsets.UTF_8));
}
} catch (IOException e) {
//no html yet
return new ByteArrayInputStream(new byte[0]);
}
}
/**
* The resource name is for example HttpBasics_content1.adoc. This is always located in the following directory:
* <code>plugin/HttpBasics/lessonPlans/en/HttpBasics_content1.adoc</code>
*/
private String computeResourceName(String resourceName, String language) {
return String.format("lessonPlans/%s/%s", language, resourceName);
}
private InputStream readInputStreamOrFallbackToEnglish(String resourceName, Language language) {
InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(computeResourceName(resourceName, language.getLocale().getLanguage()));
if (is == null) { if (is == null) {
is = Thread.currentThread().getContextClassLoader().getResourceAsStream(computeResourceName(resourceName, "en")); log.warn("Resource name: {} not found, did you add the adoc file?", templateName);
return new StringTemplateResource("");
} else {
StringWriter writer = new StringWriter();
JavaExtensionRegistry extensionRegistry = asciidoctor.javaExtensionRegistry();
extensionRegistry.inlineMacro("webWolfLink", WebWolfMacro.class);
extensionRegistry.inlineMacro("webWolfRootLink", WebWolfRootMacro.class);
extensionRegistry.inlineMacro("webGoatVersion", WebGoatVersionMacro.class);
asciidoctor.convert(new InputStreamReader(is), writer, createAttributes());
return new StringTemplateResource(writer.getBuffer().toString());
} }
return is; } catch (IOException e) {
} //no html yet
return new StringTemplateResource("");
private Map<String, Object> createAttributes() {
Map<String, Object> attributes = Maps.newHashMap();
attributes.put("source-highlighter", "coderay");
attributes.put("backend", "xhtml");
Map<String, Object> options = Maps.newHashMap();
options.put("attributes", attributes);
return options;
}
@Override
public String getName() {
return "adocResourceResolver";
} }
} }
/**
* The resource name is for example HttpBasics_content1.adoc. This is always located in the following directory:
* <code>plugin/HttpBasics/lessonPlans/en/HttpBasics_content1.adoc</code>
*/
private String computeResourceName(String resourceName, String language) {
return String.format("lessonPlans/%s/%s", language, resourceName);
}
private InputStream readInputStreamOrFallbackToEnglish(String resourceName, Language language) {
InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(computeResourceName(resourceName, language.getLocale().getLanguage()));
if (is == null) {
is = Thread.currentThread().getContextClassLoader().getResourceAsStream(computeResourceName(resourceName, "en"));
}
return is;
}
private Map<String, Object> createAttributes() {
Map<String, Object> attributes = Maps.newHashMap();
attributes.put("source-highlighter", "coderay");
attributes.put("backend", "xhtml");
Map<String, Object> options = Maps.newHashMap();
options.put("attributes", attributes);
return options;
}
} }

View File

@ -1,47 +1,46 @@
/** /**
************************************************************************************************* * ************************************************************************************************
* * <p>
* * <p>
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/ * please see http://www.owasp.org/
* * <p>
* Copyright (c) 2002 - 20014 Bruce Mayhew * 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 * 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 * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version. * 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 * 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 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details. * General Public License for more details.
* * <p>
* You should have received a copy of the GNU General Public License along with this program; if * 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 * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA. * 02111-1307, USA.
* * <p>
* Getting Source ============== * Getting Source ==============
* * <p>
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software * Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects. * projects.
* *
* @author WebGoat * @author WebGoat
* @since October 28, 2003
* @version $Id: $Id * @version $Id: $Id
* @since October 28, 2003
*/ */
package org.owasp.webgoat; package org.owasp.webgoat;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.google.common.io.ByteStreams; import com.google.common.io.ByteStreams;
import lombok.SneakyThrows;
import org.springframework.core.io.ResourceLoader; import org.springframework.core.io.ResourceLoader;
import org.thymeleaf.TemplateProcessingParameters; import org.thymeleaf.IEngineConfiguration;
import org.thymeleaf.resourceresolver.IResourceResolver; import org.thymeleaf.templateresolver.FileTemplateResolver;
import org.thymeleaf.templateresolver.TemplateResolver; import org.thymeleaf.templateresource.ITemplateResource;
import org.thymeleaf.templateresource.StringTemplateResource;
import java.io.ByteArrayInputStream; import java.io.IOException;
import java.io.File; import java.nio.charset.StandardCharsets;
import java.io.InputStream;
import java.util.Map; import java.util.Map;
/** /**
@ -53,42 +52,29 @@ import java.util.Map;
* *
* Thymeleaf will invoke this resolver based on the prefix and this implementation will resolve the html in the plugins directory * Thymeleaf will invoke this resolver based on the prefix and this implementation will resolve the html in the plugins directory
*/ */
public class LessonTemplateResolver extends TemplateResolver { public class LessonTemplateResolver extends FileTemplateResolver {
private final static String PREFIX = "lesson:"; private final static String PREFIX = "lesson:";
private final File pluginTargetDirectory;
private ResourceLoader resourceLoader; private ResourceLoader resourceLoader;
private Map<String, byte[]> resources = Maps.newHashMap(); private Map<String, byte[]> resources = Maps.newHashMap();
public LessonTemplateResolver(File pluginTargetDirectory, ResourceLoader resourceLoader) { public LessonTemplateResolver(ResourceLoader resourceLoader) {
this.pluginTargetDirectory = pluginTargetDirectory;
this.resourceLoader = resourceLoader; this.resourceLoader = resourceLoader;
setResourceResolver(new LessonResourceResolver());
setResolvablePatterns(Sets.newHashSet(PREFIX + "*")); setResolvablePatterns(Sets.newHashSet(PREFIX + "*"));
} }
@Override @Override
protected String computeResourceName(TemplateProcessingParameters params) { protected ITemplateResource computeTemplateResource(IEngineConfiguration configuration, String ownerTemplate, String template, String resourceName, String characterEncoding, Map<String, Object> templateResolutionAttributes) {
String templateName = params.getTemplateName(); var templateName = resourceName.substring(PREFIX.length());;
return templateName.substring(PREFIX.length()); byte[] resource = resources.get(templateName);
} if (resource == null) {
try {
private class LessonResourceResolver implements IResourceResolver { resource = ByteStreams.toByteArray(resourceLoader.getResource("classpath:/html/" + templateName + ".html").getInputStream());
} catch (IOException e) {
@Override e.printStackTrace();
@SneakyThrows
public InputStream getResourceAsStream(TemplateProcessingParameters params, String resourceName) {
byte[] resource = resources.get(resourceName);
if (resource == null) {
resource = ByteStreams.toByteArray(resourceLoader.getResource("classpath:/html/" + resourceName + ".html").getInputStream());
resources.put(resourceName, resource);
} }
return new ByteArrayInputStream(resource); resources.put(resourceName, resource);
}
@Override
public String getName() {
return "lessonResourceResolver";
} }
return new StringTemplateResource(new String(resource, StandardCharsets.UTF_8));
} }
} }

View File

@ -30,41 +30,38 @@
*/ */
package org.owasp.webgoat; package org.owasp.webgoat;
import com.google.common.collect.Sets;
import org.owasp.webgoat.i18n.Language; import org.owasp.webgoat.i18n.Language;
import org.owasp.webgoat.i18n.Messages; import org.owasp.webgoat.i18n.Messages;
import org.owasp.webgoat.i18n.PluginMessages; import org.owasp.webgoat.i18n.PluginMessages;
import org.owasp.webgoat.session.LabelDebugger; import org.owasp.webgoat.session.LabelDebugger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ResourceLoader; import org.springframework.core.io.ResourceLoader;
import org.springframework.web.servlet.LocaleResolver; import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.i18n.SessionLocaleResolver; import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import org.thymeleaf.extras.springsecurity4.dialect.SpringSecurityDialect; import org.thymeleaf.TemplateEngine;
import org.thymeleaf.spring4.SpringTemplateEngine; import org.thymeleaf.extras.springsecurity5.dialect.SpringSecurityDialect;
import org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver; import org.thymeleaf.spring5.SpringTemplateEngine;
import org.thymeleaf.templateresolver.TemplateResolver; import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver;
import org.thymeleaf.spring5.view.ThymeleafViewResolver;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.templateresolver.ITemplateResolver;
import java.io.File; import java.util.Set;
/** /**
* Configuration for Spring MVC * Configuration for Spring MVC
*/ */
@Configuration @Configuration
public class MvcConfiguration extends WebMvcConfigurerAdapter { public class MvcConfiguration implements WebMvcConfigurer {
private static final String UTF8 = "UTF-8"; private static final String UTF8 = "UTF-8";
@Autowired
@Qualifier("pluginTargetDirectory")
private File pluginTargetDirectory;
@Override @Override
public void addViewControllers(ViewControllerRegistry registry) { public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("login"); registry.addViewController("/login").setViewName("login");
@ -74,13 +71,21 @@ public class MvcConfiguration extends WebMvcConfigurerAdapter {
//registry.addViewController("/list_users").setViewName("list_users"); //registry.addViewController("/list_users").setViewName("list_users");
} }
@Bean
public ViewResolver viewResolver(SpringTemplateEngine thymeleafTemplateEngine) {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(thymeleafTemplateEngine);
resolver.setCharacterEncoding("UTF-8");
return resolver;
}
@Bean @Bean
public TemplateResolver springThymeleafTemplateResolver(ApplicationContext applicationContext) { public ITemplateResolver springThymeleafTemplateResolver(ApplicationContext applicationContext) {
SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver(); SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
resolver.setPrefix("classpath:/templates/"); resolver.setPrefix("classpath:/templates/");
resolver.setSuffix(".html"); resolver.setSuffix(".html");
resolver.setOrder(1); resolver.setTemplateMode(TemplateMode.HTML);
resolver.setOrder(2);
resolver.setCacheable(false); resolver.setCacheable(false);
resolver.setCharacterEncoding(UTF8); resolver.setCharacterEncoding(UTF8);
resolver.setApplicationContext(applicationContext); resolver.setApplicationContext(applicationContext);
@ -89,8 +94,8 @@ public class MvcConfiguration extends WebMvcConfigurerAdapter {
@Bean @Bean
public LessonTemplateResolver lessonTemplateResolver(ResourceLoader resourceLoader) { public LessonTemplateResolver lessonTemplateResolver(ResourceLoader resourceLoader) {
LessonTemplateResolver resolver = new LessonTemplateResolver(pluginTargetDirectory, resourceLoader); LessonTemplateResolver resolver = new LessonTemplateResolver(resourceLoader);
resolver.setOrder(2); resolver.setOrder(0);
resolver.setCacheable(false); resolver.setCacheable(false);
resolver.setCharacterEncoding(UTF8); resolver.setCharacterEncoding(UTF8);
return resolver; return resolver;
@ -100,19 +105,20 @@ public class MvcConfiguration extends WebMvcConfigurerAdapter {
public AsciiDoctorTemplateResolver asciiDoctorTemplateResolver(Language language) { public AsciiDoctorTemplateResolver asciiDoctorTemplateResolver(Language language) {
AsciiDoctorTemplateResolver resolver = new AsciiDoctorTemplateResolver(language); AsciiDoctorTemplateResolver resolver = new AsciiDoctorTemplateResolver(language);
resolver.setCacheable(false); resolver.setCacheable(false);
resolver.setOrder(3); resolver.setOrder(1);
resolver.setCharacterEncoding(UTF8); resolver.setCharacterEncoding(UTF8);
return resolver; return resolver;
} }
@Bean @Bean
public SpringTemplateEngine thymeleafTemplateEngine(TemplateResolver springThymeleafTemplateResolver, public SpringTemplateEngine thymeleafTemplateEngine(ITemplateResolver springThymeleafTemplateResolver,
LessonTemplateResolver lessonTemplateResolver, LessonTemplateResolver lessonTemplateResolver,
AsciiDoctorTemplateResolver asciiDoctorTemplateResolver) { AsciiDoctorTemplateResolver asciiDoctorTemplateResolver) {
SpringTemplateEngine engine = new SpringTemplateEngine(); SpringTemplateEngine engine = new SpringTemplateEngine();
engine.setEnableSpringELCompiler(true);
engine.addDialect(new SpringSecurityDialect()); engine.addDialect(new SpringSecurityDialect());
engine.setTemplateResolvers( engine.setTemplateResolvers(
Sets.newHashSet(springThymeleafTemplateResolver, lessonTemplateResolver, asciiDoctorTemplateResolver)); Set.of(lessonTemplateResolver, asciiDoctorTemplateResolver, springThymeleafTemplateResolver));
return engine; return engine;
} }
@ -123,12 +129,10 @@ public class MvcConfiguration extends WebMvcConfigurerAdapter {
*/ */
@Override @Override
public void addResourceHandlers(ResourceHandlerRegistry registry) { public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/plugin_lessons/**").addResourceLocations("file:///" + pluginTargetDirectory.toString() + "/");
registry.addResourceHandler("/images/**").addResourceLocations("classpath:/images/"); registry.addResourceHandler("/images/**").addResourceLocations("classpath:/images/");
registry.addResourceHandler("/lesson_js/**").addResourceLocations("classpath:/js/"); registry.addResourceHandler("/lesson_js/**").addResourceLocations("classpath:/js/");
registry.addResourceHandler("/lesson_css/**").addResourceLocations("classpath:/css/"); registry.addResourceHandler("/lesson_css/**").addResourceLocations("classpath:/css/");
registry.addResourceHandler("/video/**").addResourceLocations("classpath:/video/"); registry.addResourceHandler("/video/**").addResourceLocations("classpath:/video/");
super.addResourceHandlers(registry);
} }
@Bean @Bean

View File

@ -30,15 +30,11 @@
*/ */
package org.owasp.webgoat; package org.owasp.webgoat;
import org.owasp.webgoat.plugins.PluginEndpointPublisher;
import org.owasp.webgoat.plugins.PluginsLoader;
import org.owasp.webgoat.session.Course;
import org.owasp.webgoat.session.UserSessionData; import org.owasp.webgoat.session.UserSessionData;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
import org.owasp.webgoat.session.WebgoatContext; import org.owasp.webgoat.session.WebgoatContext;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode; import org.springframework.context.annotation.ScopedProxyMode;
@ -66,16 +62,6 @@ public class WebGoat {
return new UserSessionData("test", "data"); return new UserSessionData("test", "data");
} }
@Bean
public PluginEndpointPublisher pluginEndpointPublisher(ApplicationContext applicationContext) {
return new PluginEndpointPublisher(applicationContext);
}
@Bean
public Course course(PluginEndpointPublisher pluginEndpointPublisher) {
return new PluginsLoader(pluginEndpointPublisher).loadPlugins();
}
@Bean @Bean
public RestTemplate restTemplate() { public RestTemplate restTemplate() {
return new RestTemplate(); return new RestTemplate();

View File

@ -35,6 +35,7 @@ import org.owasp.webgoat.users.UserService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.builders.WebSecurity;
@ -42,6 +43,7 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer; import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
/** /**
* Security configuration for WebGoat. * Security configuration for WebGoat.
@ -90,4 +92,16 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
public UserDetailsService userDetailsServiceBean() throws Exception { public UserDetailsService userDetailsServiceBean() throws Exception {
return userDetailsService; return userDetailsService;
} }
@Override
@Bean
protected AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
@SuppressWarnings("deprecation")
@Bean
public NoOpPasswordEncoder passwordEncoder() {
return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
}
} }

View File

@ -27,33 +27,23 @@ package org.owasp.webgoat.assignments;
import lombok.Getter; import lombok.Getter;
import org.owasp.webgoat.i18n.PluginMessages; import org.owasp.webgoat.i18n.PluginMessages;
import org.owasp.webgoat.session.UserSessionData; import org.owasp.webgoat.session.UserSessionData;
import org.owasp.webgoat.session.WebSession;
import org.owasp.webgoat.users.UserTracker; import org.owasp.webgoat.users.UserTracker;
import org.owasp.webgoat.users.UserTrackerRepository; import org.owasp.webgoat.users.UserTrackerRepository;
import org.owasp.webgoat.session.WebSession;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
/** public abstract class AssignmentEndpoint {
* 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 @Autowired
private UserTrackerRepository userTrackerRepository; private UserTrackerRepository userTrackerRepository;
@Autowired @Autowired
private WebSession webSession; private WebSession webSession;
@Autowired @Autowired
private UserSessionData userSessionData; private UserSessionData userSessionData;
@Getter @Getter
@Autowired @Autowired
private PluginMessages messages; private PluginMessages messages;
//// TODO: 11/13/2016 events better fit?
protected AttackResult trackProgress(AttackResult attackResult) { protected AttackResult trackProgress(AttackResult attackResult) {
UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName()); UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName());
if (userTracker == null) { if (userTracker == null) {
@ -69,24 +59,19 @@ public abstract class AssignmentEndpoint extends Endpoint {
} }
protected WebSession getWebSession() { protected WebSession getWebSession() {
return webSession; return webSession;
}
protected UserSessionData getUserSessionData() {
return userSessionData;
} }
@Override protected UserSessionData getUserSessionData() {
public final String getPath() { return userSessionData;
return this.getClass().getAnnotationsByType(AssignmentPath.class)[0].value();
} }
/** /**
* Convenience method for create a successful result: * Convenience method for create a successful result:
* * <p>
* - Assignment is set to solved * - Assignment is set to solved
* - Feedback message is set to 'assignment.solved' * - Feedback message is set to 'assignment.solved'
* * <p>
* Of course you can overwrite these values in a specific lesson * Of course you can overwrite these values in a specific lesson
* *
* @return a builder for creating a result from a lesson * @return a builder for creating a result from a lesson
@ -97,10 +82,10 @@ public abstract class AssignmentEndpoint extends Endpoint {
/** /**
* Convenience method for create a failed result: * Convenience method for create a failed result:
* * <p>
* - Assignment is set to not solved * - Assignment is set to not solved
* - Feedback message is set to 'assignment.not.solved' * - Feedback message is set to 'assignment.not.solved'
* * <p>
* Of course you can overwrite these values in a specific lesson * Of course you can overwrite these values in a specific lesson
* *
* @return a builder for creating a result from a lesson * @return a builder for creating a result from a lesson

View File

@ -1,5 +1,9 @@
package org.owasp.webgoat.assignments; package org.owasp.webgoat.assignments;
import org.springframework.core.annotation.AliasFor;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
@ -10,7 +14,15 @@ import java.lang.annotation.Target;
*/ */
@Target(ElementType.TYPE) @Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
//@RequestMapping
public @interface AssignmentPath { public @interface AssignmentPath {
String value(); // @AliasFor(annotation = RequestMapping.class)
String[] path() default {};
// @AliasFor(annotation = RequestMapping.class)
RequestMethod[] method() default {};
// @AliasFor("path")
String value() default "";
} }

View File

@ -30,7 +30,7 @@
*/ */
package org.owasp.webgoat.controller; package org.owasp.webgoat.controller;
import org.owasp.webgoat.lessons.AbstractLesson; import org.owasp.webgoat.lessons.Lesson;
import org.owasp.webgoat.session.Course; import org.owasp.webgoat.session.Course;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContext;
@ -79,8 +79,8 @@ public class StartLesson {
//GrantedAuthority authority = context.getAuthentication().getAuthorities().iterator().next(); //GrantedAuthority authority = context.getAuthentication().getAuthorities().iterator().next();
String path = request.getRequestURL().toString(); // we now got /a/b/c/AccessControlMatrix.lesson String path = request.getRequestURL().toString(); // we now got /a/b/c/AccessControlMatrix.lesson
String lessonName = path.substring(path.lastIndexOf('/') + 1, path.indexOf(".lesson")); String lessonName = path.substring(path.lastIndexOf('/') + 1, path.indexOf(".lesson"));
List<AbstractLesson> lessons = course.getLessons(); List<? extends Lesson> lessons = course.getLessons();
Optional<AbstractLesson> lesson = lessons.stream() Optional<? extends Lesson> lesson = lessons.stream()
.filter(l -> l.getId().equals(lessonName)) .filter(l -> l.getId().equals(lessonName))
.findFirst(); .findFirst();
ws.setCurrentLesson(lesson.get()); ws.setCurrentLesson(lesson.get());

View File

@ -52,11 +52,14 @@ public class Assignment {
//Hibernate //Hibernate
} }
public Assignment(String name, String path) { public Assignment(String name) {
this(name, path, Lists.newArrayList()); this(name, name, Lists.newArrayList());
} }
public Assignment(String name, String path, List<String> hints) { public Assignment(String name, String path, List<String> hints) {
if (path.equals("") || path.equals("/") || path.equals("/WebGoat/")) {
throw new IllegalStateException("The path of assignment '" + name + "' overrides WebGoat endpoints, please choose a path within the scope of the lesson");
}
this.name = name; this.name = name;
this.path = path; this.path = path;
this.hints = hints; this.hints = hints;

View File

@ -26,8 +26,7 @@
*/ */
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import lombok.Getter; import lombok.Value;
import lombok.Setter;
/** /**
* <p>Hint class.</p> * <p>Hint class.</p>
@ -35,12 +34,9 @@ import lombok.Setter;
* @author rlawson * @author rlawson
* @version $Id: $Id * @version $Id: $Id
*/ */
@Getter @Value
@Setter
public class Hint { public class Hint {
private String hint; private String hint;
private String lesson;
private String assignmentPath; private String assignmentPath;
private int number;
} }

View File

@ -1,63 +1,45 @@
package org.owasp.webgoat.lessons; /*
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
import com.google.common.collect.Lists; *
import lombok.Setter; * Copyright (c) 2002 - 2019 Bruce Mayhew
import org.owasp.webgoat.session.Screen; *
import java.util.List;
/**
* ************************************************************************************************
* <p>
* <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 * 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 * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version. * 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 * 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 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details. * General Public License for more details.
* <p> *
* You should have received a copy of the GNU General Public License along with this program; if * 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 * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA. * 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.
* *
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a> * Getting Source ==============
* @version $Id: $Id *
* @since October 28, 2003 * Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
*/ */
public abstract class AbstractLesson extends Screen implements Comparable<Object> {
package org.owasp.webgoat.lessons;
import lombok.Getter;
import lombok.Setter;
import lombok.Singular;
import java.util.List;
@Getter
@Setter
public abstract class Lesson {
private static int count = 1; private static int count = 1;
private Integer id = null; private Integer id = null;
private Integer ranking;
@Setter
private List<Assignment> assignments; private List<Assignment> assignments;
public List<Assignment> getAssignments() {
if (assignments == null) {
return Lists.newArrayList();
}
return assignments;
}
/** /**
* Constructor for the Lesson object * Constructor for the Lesson object
*/ */
public AbstractLesson() { public Lesson() {
id = ++count; id = ++count;
} }
@ -72,34 +54,6 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
return className.substring(className.lastIndexOf('.') + 1); return className.substring(className.lastIndexOf('.') + 1);
} }
/**
* <p>Setter for the field <code>ranking</code>.</p>
*
* @param ranking a {@link java.lang.Integer} object.
*/
public void setRanking(Integer ranking) {
this.ranking = ranking;
}
/**
* {@inheritDoc}
* <p>
* Description of the Method
*/
public int compareTo(Object obj) {
return this.getRanking().compareTo(((AbstractLesson) obj).getRanking());
}
/**
* {@inheritDoc}
* <p>
* Description of the Method
*/
public boolean equals(Object obj) {
return this.getScreenId() == ((AbstractLesson) obj).getScreenId();
}
/** /**
* Gets the category attribute of the Lesson object * Gets the category attribute of the Lesson object
* *
@ -109,13 +63,6 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
return getDefaultCategory(); return getDefaultCategory();
} }
/**
* <p>getDefaultRanking.</p>
*
* @return a {@link java.lang.Integer} object.
*/
protected abstract Integer getDefaultRanking();
/** /**
* <p>getDefaultCategory.</p> * <p>getDefaultCategory.</p>
* *
@ -123,29 +70,6 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
*/ */
protected abstract Category getDefaultCategory(); protected abstract Category getDefaultCategory();
/**
* <p>getDefaultHidden.</p>
*
* @return a boolean.
*/
protected abstract boolean getDefaultHidden();
/**
* Gets the hintCount attribute of the Lesson object
*
* @return The hintCount value
*/
public int getHintCount() {
return getHints().size();
}
/**
* <p>getHints.</p>
*
* @return a {@link java.util.List} object.
*/
public abstract List<String> getHints();
/** /**
* Gets the title attribute of the HelloScreen object * Gets the title attribute of the HelloScreen object
* *
@ -153,28 +77,6 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
*/ */
public abstract String getTitle(); public abstract String getTitle();
/**
* Gets the ranking attribute of the Lesson object
*
* @return The ranking value
*/
public Integer getRanking() {
if (ranking != null) {
return ranking;
} else {
return getDefaultRanking();
}
}
/**
* Gets the uniqueID attribute of the AbstractLesson object
*
* @return The uniqueID value
*/
public int getScreenId() {
return id.intValue();
}
/** /**
* <p>Returns the default "path" portion of a lesson's URL.</p> * <p>Returns the default "path" portion of a lesson's URL.</p>
* <p> * <p>
@ -218,5 +120,4 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
} }
public abstract String getId(); public abstract String getId();
} }

View File

@ -1,86 +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.
*
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @since October 28, 2003
* @version $Id: $Id
*/
package org.owasp.webgoat.lessons;
//// TODO: 11/8/2016 remove
public abstract class LessonAdapter extends AbstractLesson {
/**
* <p>getDefaultHidden.</p>
*
* @return a boolean.
*/
protected boolean getDefaultHidden() {
return false;
}
/**
* Initiates lesson restart functionality. Lessons should override this for
* lesson specific actions
*/
public void restartLesson() {
// Do Nothing - called when restart lesson is pressed. Each lesson can do something
}
private final static Integer DEFAULT_RANKING = 1000;
/**
* <p>getDefaultRanking.</p>
*
* @return a {@link java.lang.Integer} object.
*/
protected Integer getDefaultRanking() {
return DEFAULT_RANKING;
}
/**
* provide a default submitMethod of lesson does not implement
*
* @return a {@link java.lang.String} object.
*/
public String getSubmitMethod() {
return "GET";
}
/**
* Fill in a descriptive title for this lesson. The title of the lesson.
* This will appear above the control area at the top of the page. This
* field will be rendered as html.
*
* @return The title value
*/
public String getTitle() {
return "Untitled Lesson " + getScreenId();
}
}

View File

@ -0,0 +1,117 @@
/*
* 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.plugins;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentHints;
import org.owasp.webgoat.assignments.AttackResult;
import org.owasp.webgoat.lessons.Lesson;
import org.owasp.webgoat.lessons.Assignment;
import org.owasp.webgoat.session.Course;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.toList;
@Slf4j
@Configuration
public class CourseConfiguration {
private final List<Lesson> lessons;
private final List<AssignmentEndpoint> assignments;
private final Map<String, List<AssignmentEndpoint>> assignmentsByPackage;
public CourseConfiguration(List<Lesson> lessons, List<AssignmentEndpoint> assignments) {
this.lessons = lessons;
this.assignments = assignments;
assignmentsByPackage = this.assignments.stream().collect(groupingBy(a -> a.getClass().getPackageName()));
}
@Bean
public Course course() {
lessons.stream().forEach(l -> l.setAssignments(createAssignment(l)));
return new Course(lessons);
}
private List<Assignment> createAssignment(Lesson lesson) {
var endpoints = assignmentsByPackage.get(lesson.getClass().getPackageName());
if (CollectionUtils.isEmpty(endpoints)) {
log.warn("Lesson: {} has no endpoints, is this intentionally?", lesson.getTitle());
return Lists.newArrayList();
}
return endpoints.stream().map(e -> new Assignment(e.getClass().getSimpleName(), getPath(e.getClass()), getHints(e.getClass()))).collect(toList());
}
private String getPath(Class<? extends AssignmentEndpoint> e) {
for (Method m : e.getMethods()) {
if (m.getReturnType() == AttackResult.class) {
var mapping = getMapping(m);
if (mapping == null) {
log.error("AttackResult method found without mapping in: {}", e.getSimpleName());
} else {
return mapping;
}
}
}
return "none";
}
private String getMapping(Method m) {
String[] paths = null;
//Find the path, either it is @GetMapping("/attack") of GetMapping(path = "/attack") both are valid, we need to consider both
if (m.getAnnotation(RequestMapping.class) != null) {
paths = ArrayUtils.addAll(m.getAnnotation(RequestMapping.class).value(), m.getAnnotation(RequestMapping.class).path());
} else if (m.getAnnotation(PostMapping.class) != null) {
paths = ArrayUtils.addAll(m.getAnnotation(PostMapping.class).value(), m.getAnnotation(PostMapping.class).path());
} else if (m.getAnnotation(GetMapping.class) != null) {
paths = ArrayUtils.addAll(m.getAnnotation(GetMapping.class).value(), m.getAnnotation(GetMapping.class).path());
} else if (m.getAnnotation(PutMapping.class) != null) {
paths = ArrayUtils.addAll(m.getAnnotation(PutMapping.class).value(), m.getAnnotation(PutMapping.class).path());
}
if (paths == null) {
return "";
} else {
return Arrays.stream(paths).filter(path -> !"".equals(path)).findFirst().orElseGet(() -> "");
}
}
private List<String> getHints(Class<? extends AssignmentEndpoint> e) {
if (e.isAnnotationPresent(AssignmentHints.class)) {
return Lists.newArrayList(e.getAnnotationsByType(AssignmentHints.class)[0].value());
}
return Lists.newArrayList();
}
}

View File

@ -1,66 +0,0 @@
package org.owasp.webgoat.plugins;
import lombok.extern.slf4j.Slf4j;
import org.owasp.webgoat.assignments.Endpoint;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
import java.util.List;
/**
* ************************************************************************************************
* 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 October 16, 2016
*/
@Slf4j
public class PluginEndpointPublisher {
private AbstractApplicationContext applicationContext;
public PluginEndpointPublisher(ApplicationContext applicationContext) {
this.applicationContext = (AbstractApplicationContext) applicationContext;
}
public void publish(List<Class<Endpoint>> endpoints) {
endpoints.forEach(e -> publishEndpoint(e));
}
private void publishEndpoint(Class<? extends MvcEndpoint> e) {
try {
BeanDefinition beanDefinition = new RootBeanDefinition(e, Autowire.BY_TYPE.value(), true);
DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getBeanFactory();
beanFactory.registerBeanDefinition(beanDefinition.getBeanClassName(), beanDefinition);
} catch (Exception ex) {
log.error("Failed to register " + e.getSimpleName() + " as endpoint with Spring, skipping...");
}
}
}

View File

@ -1,46 +0,0 @@
package org.owasp.webgoat.plugins;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.Endpoint;
import org.owasp.webgoat.lessons.NewLesson;
import java.net.URL;
import java.util.List;
import java.util.stream.Collectors;
/**
* Plugin resource
*
* @author nbaars
* @since 3/4/17.
*/
@AllArgsConstructor
@Getter
public class PluginResource {
private final URL location;
private final List<Class> classes;
public List<Class> getLessons() {
return classes.stream().filter(c -> c.getSuperclass() == NewLesson.class).collect(Collectors.toList());
}
public List<Class<Endpoint>> getEndpoints() {
return classes.stream().
filter(c -> c.getSuperclass() == AssignmentEndpoint.class || c.getSuperclass() == Endpoint.class).
map(c -> (Class<Endpoint>) c).
collect(Collectors.toList());
}
public List<Class<AssignmentEndpoint>> getAssignments(Class lesson) {
return classes.stream().
filter(c -> c.getSuperclass() == AssignmentEndpoint.class).
filter(c -> c.getPackage().equals(lesson.getPackage())).
map(c -> (Class<AssignmentEndpoint>) c).
collect(Collectors.toList());
}
}

View File

@ -1,134 +0,0 @@
package org.owasp.webgoat.plugins;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentHints;
import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.lessons.Assignment;
import org.owasp.webgoat.lessons.NewLesson;
import org.owasp.webgoat.session.Course;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.filter.RegexPatternTypeFilter;
import java.net.URL;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import static java.util.stream.Collectors.toList;
/**
* ************************************************************************************************
* 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
*/
@AllArgsConstructor
@Slf4j
public class PluginsLoader {
private final PluginEndpointPublisher pluginEndpointPublisher;
/**
* <p>createLessonsFromPlugins.</p>
*/
public Course loadPlugins() {
List<AbstractLesson> lessons = Lists.newArrayList();
for (PluginResource plugin : findPluginResources()) {
try {
plugin.getLessons().forEach(c -> {
NewLesson lesson = null;
try {
lesson = (NewLesson) c.newInstance();
log.trace("Lesson loaded: {}", lesson.getId());
} catch (Exception e) {
log.error("Error while loading:" + c, e);
}
List<Class<AssignmentEndpoint>> assignments = plugin.getAssignments(c);
lesson.setAssignments(createAssignment(assignments));
lessons.add(lesson);
pluginEndpointPublisher.publish(plugin.getEndpoints());
});
} catch (Exception e) {
log.error("Error in loadLessons: ", e);
}
}
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.");
}
return new Course(lessons);
}
private List<Assignment> createAssignment(List<Class<AssignmentEndpoint>> endpoints) {
return endpoints.stream().map(e -> new Assignment(e.getSimpleName(), getPath(e), getHints(e))).collect(toList());
}
private String getPath(Class<AssignmentEndpoint> e) {
return e.getAnnotationsByType(AssignmentPath.class)[0].value();
}
private List<String> getHints(Class<AssignmentEndpoint> e) {
if (e.isAnnotationPresent(AssignmentHints.class)) {
return Lists.newArrayList(e.getAnnotationsByType(AssignmentHints.class)[0].value());
}
return Lists.newArrayList();
}
@SneakyThrows
public List<PluginResource> findPluginResources() {
final ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
provider.addIncludeFilter(new RegexPatternTypeFilter(Pattern.compile(".*")));
final Set<BeanDefinition> classes = provider.findCandidateComponents("org.owasp.webgoat.plugin");
Map<URL, List<Class>> pluginClasses = Maps.newHashMap();
for (BeanDefinition bean : classes) {
Class<?> clazz = Class.forName(bean.getBeanClassName());
URL location = clazz.getProtectionDomain().getCodeSource().getLocation();
List<Class> classFiles = pluginClasses.get(location);
if (classFiles == null) {
classFiles = Lists.newArrayList(clazz);
} else {
classFiles.add(clazz);
}
pluginClasses.put(location, classFiles);
}
return pluginClasses.entrySet().parallelStream()
.map(e -> new PluginResource(e.getKey(), e.getValue()))
.collect(Collectors.toList());
}
}

View File

@ -5,10 +5,9 @@
*/ */
package org.owasp.webgoat.service; package org.owasp.webgoat.service;
import com.google.common.collect.Lists;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.lessons.Assignment; import org.owasp.webgoat.lessons.Assignment;
import org.owasp.webgoat.lessons.Hint; import org.owasp.webgoat.lessons.Hint;
import org.owasp.webgoat.lessons.Lesson;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
@ -41,42 +40,22 @@ public class HintService {
*/ */
@GetMapping(path = URL_HINTS_MVC, produces = "application/json") @GetMapping(path = URL_HINTS_MVC, produces = "application/json")
@ResponseBody @ResponseBody
public List<Hint> showHint() { public List<Hint> getHints() {
AbstractLesson l = webSession.getCurrentLesson(); Lesson l = webSession.getCurrentLesson();
List<Hint> hints = createLessonHints(l); return createAssignmentHints(l);
hints.addAll(createAssignmentHints(l));
return hints;
} }
private List<Hint> createLessonHints(AbstractLesson l) { private List<Hint> createAssignmentHints(Lesson l) {
if ( l != null ) { if (l != null) {
return l.getHints().stream().map(h -> createHint(h, l.getName(), null)).collect(toList()); return l.getAssignments().stream()
.map(a -> createHint(a))
.flatMap(hints -> hints.stream())
.collect(toList());
} }
return Lists.newArrayList(); return List.of();
} }
private List<Hint> createAssignmentHints(AbstractLesson l) { private List<Hint> createHint(Assignment a) {
List<Hint> hints = Lists.newArrayList(); return a.getHints().stream().map(h -> new Hint(h, a.getPath())).collect(toList());
if ( l != null) {
List<Assignment> assignments = l.getAssignments();
assignments.stream().forEach(a -> { a.getHints(); createHints(a, hints);});
}
return hints;
}
private void createHints(Assignment a, List<Hint> hints) {
hints.addAll(a.getHints().stream().map(h -> createHint(h, null, a.getPath())).collect(toList()));
}
private Hint createHint(String hintText, String lesson, String assignmentName) {
Hint hint = new Hint();
hint.setHint(hintText);
if (lesson != null) {
hint.setLesson(lesson);
} else {
hint.setAssignmentPath(assignmentName);
}
return hint;
} }
} }

View File

@ -1,7 +1,7 @@
package org.owasp.webgoat.service; package org.owasp.webgoat.service;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import org.owasp.webgoat.lessons.AbstractLesson; import org.owasp.webgoat.lessons.Lesson;
import org.owasp.webgoat.lessons.LessonInfoModel; import org.owasp.webgoat.lessons.LessonInfoModel;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
@ -29,7 +29,7 @@ public class LessonInfoService {
@RequestMapping(path = "/service/lessoninfo.mvc", produces = "application/json") @RequestMapping(path = "/service/lessoninfo.mvc", produces = "application/json")
public @ResponseBody public @ResponseBody
LessonInfoModel getLessonInfo() { LessonInfoModel getLessonInfo() {
AbstractLesson lesson = webSession.getCurrentLesson(); Lesson lesson = webSession.getCurrentLesson();
return new LessonInfoModel(lesson.getTitle(), false, false, false); return new LessonInfoModel(lesson.getTitle(), false, false, false);
} }

View File

@ -29,7 +29,7 @@
package org.owasp.webgoat.service; package org.owasp.webgoat.service;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import org.owasp.webgoat.lessons.AbstractLesson; import org.owasp.webgoat.lessons.Lesson;
import org.owasp.webgoat.lessons.Category; import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.lessons.LessonMenuItem; import org.owasp.webgoat.lessons.LessonMenuItem;
import org.owasp.webgoat.lessons.LessonMenuItemType; import org.owasp.webgoat.lessons.LessonMenuItemType;
@ -43,7 +43,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -81,13 +80,12 @@ public class LessonMenuService {
categoryItem.setName(category.getName()); categoryItem.setName(category.getName());
categoryItem.setType(LessonMenuItemType.CATEGORY); categoryItem.setType(LessonMenuItemType.CATEGORY);
// check for any lessons for this category // check for any lessons for this category
List<AbstractLesson> lessons = course.getLessons(category); List<Lesson> lessons = course.getLessons(category);
lessons = lessons.stream().sorted(Comparator.comparing(l -> l.getTitle())).collect(Collectors.toList()); lessons = lessons.stream().sorted(Comparator.comparing(l -> l.getTitle())).collect(Collectors.toList());
for (AbstractLesson lesson : lessons) { for (Lesson lesson : lessons) {
LessonMenuItem lessonItem = new LessonMenuItem(); LessonMenuItem lessonItem = new LessonMenuItem();
lessonItem.setName(lesson.getTitle()); lessonItem.setName(lesson.getTitle());
lessonItem.setLink(lesson.getLink()); lessonItem.setLink(lesson.getLink());
lessonItem.setRanking(lesson.getRanking());
lessonItem.setType(LessonMenuItemType.LESSON); lessonItem.setType(LessonMenuItemType.LESSON);
LessonTracker lessonTracker = userTracker.getLessonTracker(lesson); LessonTracker lessonTracker = userTracker.getLessonTracker(lesson);
lessonItem.setComplete(lessonTracker.isLessonSolved()); lessonItem.setComplete(lessonTracker.isLessonSolved());

View File

@ -4,7 +4,7 @@ import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import org.owasp.webgoat.lessons.AbstractLesson; import org.owasp.webgoat.lessons.Lesson;
import org.owasp.webgoat.lessons.Assignment; import org.owasp.webgoat.lessons.Assignment;
import org.owasp.webgoat.lessons.LessonInfoModel; import org.owasp.webgoat.lessons.LessonInfoModel;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
@ -66,7 +66,7 @@ public class LessonProgressService {
@ResponseBody @ResponseBody
public List<LessonOverview> lessonOverview() { public List<LessonOverview> lessonOverview() {
UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName()); UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName());
AbstractLesson currentLesson = webSession.getCurrentLesson(); Lesson currentLesson = webSession.getCurrentLesson();
List<LessonOverview> result = Lists.newArrayList(); List<LessonOverview> result = Lists.newArrayList();
if ( currentLesson != null ) { if ( currentLesson != null ) {
LessonTracker lessonTracker = userTracker.getLessonTracker(currentLesson); LessonTracker lessonTracker = userTracker.getLessonTracker(currentLesson);
@ -76,7 +76,7 @@ public class LessonProgressService {
} }
private List<LessonOverview> toJson(Map<Assignment, Boolean> map) { private List<LessonOverview> toJson(Map<Assignment, Boolean> map) {
ArrayList<LessonOverview> result = Lists.newArrayList(); List<LessonOverview> result = new ArrayList();
for (Map.Entry<Assignment, Boolean> entry : map.entrySet()) { for (Map.Entry<Assignment, Boolean> entry : map.entrySet()) {
result.add(new LessonOverview(entry.getKey(), entry.getValue())); result.add(new LessonOverview(entry.getKey(), entry.getValue()));
} }

View File

@ -1,6 +1,6 @@
package org.owasp.webgoat.service; package org.owasp.webgoat.service;
import org.owasp.webgoat.lessons.AbstractLesson; import org.owasp.webgoat.lessons.Lesson;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
@ -31,7 +31,7 @@ public class LessonTitleService {
public public
@ResponseBody @ResponseBody
String showPlan() { String showPlan() {
AbstractLesson lesson = webSession.getCurrentLesson(); Lesson lesson = webSession.getCurrentLesson();
return lesson != null ? lesson.getTitle() : ""; return lesson != null ? lesson.getTitle() : "";
} }

View File

@ -33,7 +33,7 @@ import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.owasp.webgoat.i18n.PluginMessages; import org.owasp.webgoat.i18n.PluginMessages;
import org.owasp.webgoat.lessons.AbstractLesson; import org.owasp.webgoat.lessons.Lesson;
import org.owasp.webgoat.session.Course; import org.owasp.webgoat.session.Course;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
import org.owasp.webgoat.users.LessonTracker; import org.owasp.webgoat.users.LessonTracker;
@ -67,13 +67,13 @@ public class ReportCardService {
@ResponseBody @ResponseBody
public ReportCard reportCard() { public ReportCard reportCard() {
UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName()); UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName());
List<AbstractLesson> lessons = course.getLessons(); var lessons = course.getLessons();
ReportCard reportCard = new ReportCard(); ReportCard reportCard = new ReportCard();
reportCard.setTotalNumberOfLessons(course.getTotalOfLessons()); reportCard.setTotalNumberOfLessons(course.getTotalOfLessons());
reportCard.setTotalNumberOfAssignments(course.getTotalOfAssignments()); reportCard.setTotalNumberOfAssignments(course.getTotalOfAssignments());
reportCard.setNumberOfAssignmentsSolved(userTracker.numberOfAssignmentsSolved()); reportCard.setNumberOfAssignmentsSolved(userTracker.numberOfAssignmentsSolved());
reportCard.setNumberOfLessonsSolved(userTracker.numberOfLessonsSolved()); reportCard.setNumberOfLessonsSolved(userTracker.numberOfLessonsSolved());
for (AbstractLesson lesson : lessons) { for (Lesson lesson : lessons) {
LessonTracker lessonTracker = userTracker.getLessonTracker(lesson); LessonTracker lessonTracker = userTracker.getLessonTracker(lesson);
LessonStatistics lessonStatistics = new LessonStatistics(); LessonStatistics lessonStatistics = new LessonStatistics();
lessonStatistics.setName(pluginMessages.getMessage(lesson.getTitle())); lessonStatistics.setName(pluginMessages.getMessage(lesson.getTitle()));

View File

@ -25,7 +25,7 @@ package org.owasp.webgoat.service;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.owasp.webgoat.lessons.AbstractLesson; import org.owasp.webgoat.lessons.Lesson;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
import org.owasp.webgoat.users.UserTracker; import org.owasp.webgoat.users.UserTracker;
import org.owasp.webgoat.users.UserTrackerRepository; import org.owasp.webgoat.users.UserTrackerRepository;
@ -56,7 +56,7 @@ public class RestartLessonService {
@RequestMapping(path = "/service/restartlesson.mvc", produces = "text/text") @RequestMapping(path = "/service/restartlesson.mvc", produces = "text/text")
@ResponseStatus(value = HttpStatus.OK) @ResponseStatus(value = HttpStatus.OK)
public void restartLesson() { public void restartLesson() {
AbstractLesson al = webSession.getCurrentLesson(); Lesson al = webSession.getCurrentLesson();
log.debug("Restarting lesson: " + al); log.debug("Restarting lesson: " + al);
UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName()); UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName());

View File

@ -1,11 +1,9 @@
package org.owasp.webgoat.session; package org.owasp.webgoat.session;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.owasp.webgoat.lessons.AbstractLesson; import org.owasp.webgoat.lessons.Lesson;
import org.owasp.webgoat.lessons.Category; import org.owasp.webgoat.lessons.Category;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toList;
@ -41,10 +39,13 @@ import static java.util.stream.Collectors.toList;
* @since October 28, 2003 * @since October 28, 2003
*/ */
@Slf4j @Slf4j
@AllArgsConstructor
public class Course { public class Course {
private List<AbstractLesson> lessons = new LinkedList<>(); private List<? extends Lesson> lessons;
public Course(List<? extends Lesson> lessons) {
this.lessons = lessons;
}
/** /**
* Gets the categories attribute of the Course object * Gets the categories attribute of the Course object
@ -60,7 +61,7 @@ public class Course {
* *
* @return The firstLesson value * @return The firstLesson value
*/ */
public AbstractLesson getFirstLesson() { public Lesson getFirstLesson() {
// Category 0 is the admin function. We want the first real category // Category 0 is the admin function. We want the first real category
// to be returned. This is normally the General category and the Http Basics lesson // to be returned. This is normally the General category and the Http Basics lesson
return getLessons(getCategories().get(0)).get(0); return getLessons(getCategories().get(0)).get(0);
@ -71,7 +72,7 @@ public class Course {
* *
* @return a {@link java.util.List} object. * @return a {@link java.util.List} object.
*/ */
public List<AbstractLesson> getLessons() { public List<? extends Lesson> getLessons() {
return this.lessons; return this.lessons;
} }
@ -81,11 +82,11 @@ public class Course {
* @param category a {@link org.owasp.webgoat.lessons.Category} object. * @param category a {@link org.owasp.webgoat.lessons.Category} object.
* @return a {@link java.util.List} object. * @return a {@link java.util.List} object.
*/ */
public List<AbstractLesson> getLessons(Category category) { public List<Lesson> getLessons(Category category) {
return this.lessons.stream().filter(l -> l.getCategory() == category).sorted().collect(toList()); return this.lessons.stream().filter(l -> l.getCategory() == category).collect(toList());
} }
public void setLessons(List<AbstractLesson> lessons) { public void setLessons(List<Lesson> lessons) {
this.lessons = lessons; this.lessons = lessons;
} }
@ -94,9 +95,6 @@ public class Course {
} }
public int getTotalOfAssignments() { public int getTotalOfAssignments() {
final int[] total = {0}; return this.lessons.stream().reduce(0, (total, lesson) -> lesson.getAssignments().size() + total, Integer::sum);
this.lessons.stream().forEach(l -> total[0] = total[0] + l.getAssignments().size());
return total[0];
} }
} }

View File

@ -1,53 +0,0 @@
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/
*
* 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 Jeff Williams <a href="http://www.aspectsecurity.com">Aspect
* Security</a>
* @since October 28, 2003
* @version $Id: $Id
*/
public abstract class Screen {
/**
* Constructor for the Screen object
*/
public Screen() {
}
/**
* Fill in a descriptive title for this lesson
*
* @return The title value
*/
public abstract String getTitle();
}

View File

@ -1,7 +1,7 @@
package org.owasp.webgoat.session; package org.owasp.webgoat.session;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.owasp.webgoat.lessons.AbstractLesson; import org.owasp.webgoat.lessons.Lesson;
import org.owasp.webgoat.users.WebGoatUser; import org.owasp.webgoat.users.WebGoatUser;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
@ -42,7 +42,7 @@ public class WebSession {
private final WebGoatUser currentUser; private final WebGoatUser currentUser;
private final WebgoatContext webgoatContext; private final WebgoatContext webgoatContext;
private AbstractLesson currentLesson; private Lesson currentLesson;
/** /**
* Constructor for the WebSession object * Constructor for the WebSession object
@ -79,16 +79,16 @@ public class WebSession {
* *
* @param lesson current lesson * @param lesson current lesson
*/ */
public void setCurrentLesson(AbstractLesson lesson) { public void setCurrentLesson(Lesson lesson) {
this.currentLesson = lesson; this.currentLesson = lesson;
} }
/** /**
* <p> getCurrentLesson. </p> * <p> getCurrentLesson. </p>
* *
* @return a {@link org.owasp.webgoat.lessons.AbstractLesson} object. * @return a {@link Lesson} object.
*/ */
public AbstractLesson getCurrentLesson() { public Lesson getCurrentLesson() {
return this.currentLesson; return this.currentLesson;
} }

View File

@ -1,10 +1,9 @@
package org.owasp.webgoat.users; package org.owasp.webgoat.users;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import lombok.Getter; import lombok.Getter;
import org.owasp.webgoat.lessons.AbstractLesson; import org.owasp.webgoat.lessons.Lesson;
import org.owasp.webgoat.lessons.Assignment; import org.owasp.webgoat.lessons.Assignment;
import javax.persistence.*; import javax.persistence.*;
@ -64,9 +63,9 @@ public class LessonTracker {
//JPA //JPA
} }
public LessonTracker(AbstractLesson lesson) { public LessonTracker(Lesson lesson) {
lessonName = lesson.getId(); lessonName = lesson.getId();
allAssignments.addAll(lesson.getAssignments()); allAssignments.addAll(lesson.getAssignments() == null ? List.of() : lesson.getAssignments());
} }
public Optional<Assignment> getAssignment(String name) { public Optional<Assignment> getAssignment(String name) {

View File

@ -1,14 +1,12 @@
package org.owasp.webgoat.users; package org.owasp.webgoat.users;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.owasp.webgoat.lessons.AbstractLesson; import org.owasp.webgoat.lessons.Lesson;
import org.owasp.webgoat.lessons.Assignment; import org.owasp.webgoat.lessons.Assignment;
import javax.persistence.*; import javax.persistence.*;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
@ -69,7 +67,7 @@ public class UserTracker {
* @param lesson the lesson * @param lesson the lesson
* @return a lesson tracker created if not already present * @return a lesson tracker created if not already present
*/ */
public LessonTracker getLessonTracker(AbstractLesson lesson) { public LessonTracker getLessonTracker(Lesson lesson) {
Optional<LessonTracker> lessonTracker = lessonTrackers Optional<LessonTracker> lessonTracker = lessonTrackers
.stream().filter(l -> l.getLessonName().equals(lesson.getId())).findFirst(); .stream().filter(l -> l.getLessonName().equals(lesson.getId())).findFirst();
if (!lessonTracker.isPresent()) { if (!lessonTracker.isPresent()) {
@ -91,18 +89,18 @@ public class UserTracker {
return lessonTrackers.stream().filter(l -> l.getLessonName().equals(id)).findFirst(); return lessonTrackers.stream().filter(l -> l.getLessonName().equals(id)).findFirst();
} }
public void assignmentSolved(AbstractLesson lesson, String assignmentName) { public void assignmentSolved(Lesson lesson, String assignmentName) {
LessonTracker lessonTracker = getLessonTracker(lesson); LessonTracker lessonTracker = getLessonTracker(lesson);
lessonTracker.incrementAttempts(); lessonTracker.incrementAttempts();
lessonTracker.assignmentSolved(assignmentName); lessonTracker.assignmentSolved(assignmentName);
} }
public void assignmentFailed(AbstractLesson lesson) { public void assignmentFailed(Lesson lesson) {
LessonTracker lessonTracker = getLessonTracker(lesson); LessonTracker lessonTracker = getLessonTracker(lesson);
lessonTracker.incrementAttempts(); lessonTracker.incrementAttempts();
} }
public void reset(AbstractLesson al) { public void reset(Lesson al) {
LessonTracker lessonTracker = getLessonTracker(al); LessonTracker lessonTracker = getLessonTracker(al);
lessonTracker.reset(); lessonTracker.reset();
} }

View File

@ -1,7 +1,7 @@
server.error.include-stacktrace=always server.error.include-stacktrace=always
server.error.path=/error.html server.error.path=/error.html
server.session.timeout=600 server.session.timeout=600
server.contextPath=/WebGoat server.servlet.context-path=/WebGoat
server.port=${WEBGOAT_PORT:8080} server.port=${WEBGOAT_PORT:8080}
server.address=${WEBGOAT_HOST:127.0.0.1} server.address=${WEBGOAT_HOST:127.0.0.1}
@ -18,6 +18,11 @@ spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.HSQLDialect spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.HSQLDialect
spring.datasource.driver-class-name=org.hsqldb.jdbc.JDBCDriver spring.datasource.driver-class-name=org.hsqldb.jdbc.JDBCDriver
logging.level.org.thymeleaf=DEBUG
logging.level.org.thymeleaf.TemplateEngine.CONFIG=TRACE
logging.level.org.thymeleaf.TemplateEngine.TIMER=TRACE
logging.level.org.thymeleaf.TemplateEngine.cache.TEMPLATE_CACHE=TRACE
logging.level.org.springframework.web=TRACE
logging.level.org.springframework=INFO logging.level.org.springframework=INFO
logging.level.org.springframework.boot.devtools=INFO logging.level.org.springframework.boot.devtools=INFO
logging.level.org.owasp=DEBUG logging.level.org.owasp=DEBUG
@ -26,7 +31,6 @@ logging.level.org.owasp.webgoat=TRACE
# Needed for creating a vulnerable web application # Needed for creating a vulnerable web application
security.enable-csrf=false security.enable-csrf=false
spring.resources.cache-period=0
spring.thymeleaf.cache=false spring.thymeleaf.cache=false
webgoat.start.hsqldb=true webgoat.start.hsqldb=true

View File

@ -28,15 +28,15 @@
<!-- JS --> <!-- JS -->
<script src="js/modernizr-2.6.2.min.js"/> <script src="js/modernizr-2.6.2.min.js"></script>
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]> <!--[if lt IE 9]>
<script src="js/html5shiv.js"/> <script src="js/html5shiv.js"></script>
<script src="js/respond.min.js"/> <script src="js/respond.min.js"></script>
<![endif]--> <![endif]-->
<!-- Require.js used to load js asynchronously --> <!-- Require.js used to load js asynchronously -->
<script src="js/libs/require.min.js" data-main="js/main.js"/> <script src="js/libs/require.min.js" data-main="js/main.js"></script>
<meta http-equiv="Content-Type" content="text/id; charset=ISO-8859-1"/> <meta http-equiv="Content-Type" content="text/id; charset=ISO-8859-1"/>
<title>WebGoat</title> <title>WebGoat</title>
</head> </head>
@ -67,8 +67,7 @@
<li role="presentation"><a role="menuitem" tabindex="-1" th:href="@{/logout}" <li role="presentation"><a role="menuitem" tabindex="-1" th:href="@{/logout}"
th:text="#{logout}">Logout</a></li> th:text="#{logout}">Logout</a></li>
<li role="presentation" class="divider"></li> <li role="presentation" class="divider"></li>
<li role="presentation" class="disabled"><a role="menuitem" tabindex="-1" href="#">User: <span <li role="presentation" class="disabled"><a role="menuitem" tabindex="-1" href="#">User: <span sec:authentication="name"></span></a>
th:text="${#authentication.name}"></span></a>
</li> </li>
<li role="presentation" class="disabled"><a role="menuitem" tabindex="-1" href="#">Role: <li role="presentation" class="disabled"><a role="menuitem" tabindex="-1" href="#">Role:
<span sec:authorize="hasAuthority('WEBGOAT_USER')">User</span> <span sec:authorize="hasAuthority('WEBGOAT_USER')">User</span>
@ -134,14 +133,14 @@
<div id="lesson-content-wrapper" class="panel"> <div id="lesson-content-wrapper" class="panel">
<div class="" id="error-notification-container"> <div class="" id="error-notification-container">
<div class="" id="error-notification"> <div class="" id="error-notification">
<i class="fa fa-exclamation-circle"/> There was an unexpected error. Please try <i class="fa fa-exclamation-circle"> There was an unexpected error. Please try
again. again.</i>
</div> </div>
</div> </div>
<div class="" id="help-controls"> <div class="" id="help-controls">
<button class="btn btn-primary btn-xs btn-danger help-button" <button class="btn btn-primary btn-xs btn-danger help-button"
id="show-source-button"> id="show-source-button">
<i class="fa fa-code"/> <i class="fa fa-code"></i>
</button> </button>
<button class="btn btn-primary btn-xs btn-danger help-button" <button class="btn btn-primary btn-xs btn-danger help-button"
id="show-hints-button" th:text="#{show.hints}">Show hints id="show-hints-button" th:text="#{show.hints}">Show hints

View File

@ -38,7 +38,8 @@ import org.springframework.web.servlet.i18n.FixedLocaleResolver;
import java.util.Locale; import java.util.Locale;
import static org.mockito.Matchers.anyString; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
public class AssignmentEndpointTest { public class AssignmentEndpointTest {
@ -51,7 +52,7 @@ public class AssignmentEndpointTest {
protected WebSession webSession; protected WebSession webSession;
@Mock @Mock
protected UserSessionData userSessionData; protected UserSessionData userSessionData;
private Language language = new Language(new FixedLocaleResolver()){ private Language language = new Language(new FixedLocaleResolver()) {
@Override @Override
public Locale getLocale() { public Locale getLocale() {
return Locale.ENGLISH; return Locale.ENGLISH;
@ -62,7 +63,6 @@ public class AssignmentEndpointTest {
public void init(AssignmentEndpoint a) { public void init(AssignmentEndpoint a) {
messages.setBasenames("classpath:/i18n/messages", "classpath:/i18n/WebGoatLabels"); messages.setBasenames("classpath:/i18n/messages", "classpath:/i18n/WebGoatLabels");
when(userTrackerRepository.findByUser(anyString())).thenReturn(userTracker);
ReflectionTestUtils.setField(a, "userTrackerRepository", userTrackerRepository); ReflectionTestUtils.setField(a, "userTrackerRepository", userTrackerRepository);
ReflectionTestUtils.setField(a, "userSessionData", userSessionData); ReflectionTestUtils.setField(a, "userSessionData", userSessionData);
ReflectionTestUtils.setField(a, "webSession", webSession); ReflectionTestUtils.setField(a, "webSession", webSession);

View File

@ -6,9 +6,9 @@ import org.owasp.webgoat.i18n.PluginMessages;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
import org.owasp.webgoat.session.WebgoatContext; import org.owasp.webgoat.session.WebgoatContext;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.embedded.LocalServerPort;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.TestPropertySource;
import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MockMvc;
import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.WebApplicationContext;

View File

@ -7,13 +7,15 @@ import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.Mockito; import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner; import org.mockito.junit.MockitoJUnitRunner;
import org.owasp.webgoat.lessons.AbstractLesson; import org.owasp.webgoat.lessons.Lesson;
import org.owasp.webgoat.lessons.Assignment; import org.owasp.webgoat.lessons.Assignment;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import java.util.List;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import static org.owasp.webgoat.service.HintService.URL_HINTS_MVC; import static org.owasp.webgoat.service.HintService.URL_HINTS_MVC;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
@ -28,34 +30,24 @@ public class HintServiceTest {
@Mock @Mock
private WebSession websession; private WebSession websession;
@Mock @Mock
private AbstractLesson lesson; private Lesson lesson;
@Mock
private Assignment assignment;
@Before @Before
public void setup() { public void setup() {
this.mockMvc = standaloneSetup(new HintService(websession)).build(); this.mockMvc = standaloneSetup(new HintService(websession)).build();
} }
@Test
public void onlyHintsOnLesson() throws Exception {
when(lesson.getName()).thenReturn("Test lesson");
when(lesson.getHints()).thenReturn(Lists.newArrayList("hint 1", "hint 2"));
when(websession.getCurrentLesson()).thenReturn(lesson);
mockMvc.perform(MockMvcRequestBuilders.get(URL_HINTS_MVC))
.andExpect(status().isOk())
.andExpect(jsonPath("$[0].hint", CoreMatchers.is("hint 1")))
.andExpect(jsonPath("$[0].lesson", CoreMatchers.is("Test lesson")));
}
@Test @Test
public void hintsPerAssignment() throws Exception { public void hintsPerAssignment() throws Exception {
when(lesson.getName()).thenReturn("Test lesson");
Assignment assignment = Mockito.mock(Assignment.class); Assignment assignment = Mockito.mock(Assignment.class);
when(assignment.getPath()).thenReturn("/HttpBasics/attack1"); when(assignment.getPath()).thenReturn("/HttpBasics/attack1");
when(assignment.getHints()).thenReturn(Lists.newArrayList("hint 1", "hint 2")); when(assignment.getHints()).thenReturn(Lists.newArrayList("hint 1", "hint 2"));
when(lesson.getAssignments()).thenReturn(Lists.newArrayList(assignment)); when(lesson.getAssignments()).thenReturn(Lists.newArrayList(assignment));
when(websession.getCurrentLesson()).thenReturn(lesson); when(websession.getCurrentLesson()).thenReturn(lesson);
mockMvc.perform(MockMvcRequestBuilders.get(URL_HINTS_MVC)) mockMvc.perform(MockMvcRequestBuilders.get(URL_HINTS_MVC))
.andExpect(status().isOk()).andDo(print()) .andExpect(status().isOk())
.andExpect(jsonPath("$[0].hint", CoreMatchers.is("hint 1"))) .andExpect(jsonPath("$[0].hint", CoreMatchers.is("hint 1")))
.andExpect(jsonPath("$[0].assignmentPath", CoreMatchers.is("/HttpBasics/attack1"))); .andExpect(jsonPath("$[0].assignmentPath", CoreMatchers.is("/HttpBasics/attack1")));
} }

View File

@ -4,6 +4,7 @@ import org.hamcrest.CoreMatchers;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.owasp.webgoat.session.Course; import org.owasp.webgoat.session.Course;
import org.owasp.webgoat.users.UserService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.test.mock.mockito.MockBean;
@ -53,6 +54,8 @@ public class LabelServiceTest {
public MockMvc mockMvc; public MockMvc mockMvc;
@MockBean @MockBean
private Course course; private Course course;
@MockBean
private UserService userService;
@Test @Test
@WithMockUser(username = "guest", password = "guest") @WithMockUser(username = "guest", password = "guest")

View File

@ -1,3 +1,24 @@
/*
* 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.service; package org.owasp.webgoat.service;
import com.beust.jcommander.internal.Lists; import com.beust.jcommander.internal.Lists;
@ -7,10 +28,9 @@ import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.Mockito; import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner; import org.mockito.junit.MockitoJUnitRunner;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.lessons.Category; import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.lessons.NewLesson; import org.owasp.webgoat.lessons.Lesson;
import org.owasp.webgoat.session.Course; import org.owasp.webgoat.session.Course;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
import org.owasp.webgoat.users.LessonTracker; import org.owasp.webgoat.users.LessonTracker;
@ -19,8 +39,7 @@ import org.owasp.webgoat.users.UserTrackerRepository;
import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import static org.mockito.Matchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import static org.owasp.webgoat.service.LessonMenuService.URL_LESSONMENU_MVC; import static org.owasp.webgoat.service.LessonMenuService.URL_LESSONMENU_MVC;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
@ -28,13 +47,11 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup; import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;
/**
* @author nbaars
* @since 4/16/17.
*/
@RunWith(MockitoJUnitRunner.class) @RunWith(MockitoJUnitRunner.class)
public class LessonMenuServiceTest { public class LessonMenuServiceTest {
@Mock
private LessonTracker lessonTracker;
@Mock @Mock
private Course course; private Course course;
@Mock @Mock
@ -52,18 +69,15 @@ public class LessonMenuServiceTest {
@Test @Test
public void lessonsShouldBeOrdered() throws Exception { public void lessonsShouldBeOrdered() throws Exception {
NewLesson l1 = Mockito.mock(NewLesson.class); Lesson l1 = Mockito.mock(Lesson.class);
NewLesson l2 = Mockito.mock(NewLesson.class); Lesson l2 = Mockito.mock(Lesson.class);
when(l1.getTitle()).thenReturn("ZA"); when(l1.getTitle()).thenReturn("ZA");
when(l2.getTitle()).thenReturn("AA"); when(l2.getTitle()).thenReturn("AA");
when(l1.getCategory()).thenReturn(Category.ACCESS_CONTROL);
when(l2.getCategory()).thenReturn(Category.ACCESS_CONTROL);
LessonTracker lessonTracker = Mockito.mock(LessonTracker.class);
when(lessonTracker.isLessonSolved()).thenReturn(false); when(lessonTracker.isLessonSolved()).thenReturn(false);
when(course.getLessons(any())).thenReturn(Lists.newArrayList(l1, l2)); when(course.getLessons(any())).thenReturn(Lists.newArrayList(l1, l2));
when(course.getCategories()).thenReturn(Lists.newArrayList(Category.ACCESS_CONTROL)); when(course.getCategories()).thenReturn(Lists.newArrayList(Category.ACCESS_CONTROL));
when(userTracker.getLessonTracker(any(AbstractLesson.class))).thenReturn(lessonTracker); when(userTracker.getLessonTracker(any(Lesson.class))).thenReturn(lessonTracker);
when(userTrackerRepository.findByUser(anyString())).thenReturn(userTracker); when(userTrackerRepository.findByUser(any())).thenReturn(userTracker);
mockMvc.perform(MockMvcRequestBuilders.get(URL_LESSONMENU_MVC)) mockMvc.perform(MockMvcRequestBuilders.get(URL_LESSONMENU_MVC))
.andExpect(status().isOk()) .andExpect(status().isOk())
@ -73,16 +87,13 @@ public class LessonMenuServiceTest {
@Test @Test
public void lessonCompleted() throws Exception { public void lessonCompleted() throws Exception {
NewLesson l1 = Mockito.mock(NewLesson.class); Lesson l1 = Mockito.mock(Lesson.class);
when(l1.getTitle()).thenReturn("ZA"); when(l1.getTitle()).thenReturn("ZA");
when(l1.getCategory()).thenReturn(Category.ACCESS_CONTROL);
LessonTracker lessonTracker = Mockito.mock(LessonTracker.class);
when(lessonTracker.isLessonSolved()).thenReturn(true); when(lessonTracker.isLessonSolved()).thenReturn(true);
when(course.getLessons(any())).thenReturn(Lists.newArrayList(l1)); when(course.getLessons(any())).thenReturn(Lists.newArrayList(l1));
when(course.getCategories()).thenReturn(Lists.newArrayList(Category.ACCESS_CONTROL)); when(course.getCategories()).thenReturn(Lists.newArrayList(Category.ACCESS_CONTROL));
when(userTracker.getLessonTracker(any(AbstractLesson.class))).thenReturn(lessonTracker); when(userTracker.getLessonTracker(any(Lesson.class))).thenReturn(lessonTracker);
when(userTrackerRepository.findByUser(anyString())).thenReturn(userTracker); when(userTrackerRepository.findByUser(any())).thenReturn(userTracker);
mockMvc.perform(MockMvcRequestBuilders.get(URL_LESSONMENU_MVC)) mockMvc.perform(MockMvcRequestBuilders.get(URL_LESSONMENU_MVC))
.andExpect(status().isOk()).andDo(print()) .andExpect(status().isOk()).andDo(print())

View File

@ -6,7 +6,7 @@ import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner; import org.mockito.runners.MockitoJUnitRunner;
import org.owasp.webgoat.lessons.AbstractLesson; import org.owasp.webgoat.lessons.Lesson;
import org.owasp.webgoat.lessons.Assignment; import org.owasp.webgoat.lessons.Assignment;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
import org.owasp.webgoat.users.LessonTracker; import org.owasp.webgoat.users.LessonTracker;
@ -17,9 +17,10 @@ import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import java.util.List;
import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.is;
import static org.mockito.Matchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.when; 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.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@ -59,7 +60,7 @@ public class LessonProgressServiceTest {
private MockMvc mockMvc; private MockMvc mockMvc;
@Mock @Mock
private AbstractLesson lesson; private Lesson lesson;
@Mock @Mock
private UserTracker userTracker; private UserTracker userTracker;
@Mock @Mock
@ -71,9 +72,9 @@ public class LessonProgressServiceTest {
@Before @Before
public void setup() { public void setup() {
Assignment assignment = new Assignment("test", "test"); Assignment assignment = new Assignment("test", "test", List.of());
when(userTrackerRepository.findByUser(anyString())).thenReturn(userTracker); when(userTrackerRepository.findByUser(any())).thenReturn(userTracker);
when(userTracker.getLessonTracker(any(AbstractLesson.class))).thenReturn(lessonTracker); when(userTracker.getLessonTracker(any(Lesson.class))).thenReturn(lessonTracker);
when(websession.getCurrentLesson()).thenReturn(lesson); when(websession.getCurrentLesson()).thenReturn(lesson);
when(lessonTracker.getLessonOverview()).thenReturn(Maps.newHashMap(assignment, true)); when(lessonTracker.getLessonOverview()).thenReturn(Maps.newHashMap(assignment, true));
this.mockMvc = MockMvcBuilders.standaloneSetup(new LessonProgressService(userTrackerRepository, websession)).build(); this.mockMvc = MockMvcBuilders.standaloneSetup(new LessonProgressService(userTrackerRepository, websession)).build();

View File

@ -1,13 +1,12 @@
package org.owasp.webgoat.service; package org.owasp.webgoat.service;
import com.beust.jcommander.internal.Lists;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner; import org.mockito.junit.MockitoJUnitRunner;
import org.owasp.webgoat.i18n.PluginMessages; import org.owasp.webgoat.i18n.PluginMessages;
import org.owasp.webgoat.lessons.AbstractLesson; import org.owasp.webgoat.lessons.Lesson;
import org.owasp.webgoat.session.Course; import org.owasp.webgoat.session.Course;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
import org.owasp.webgoat.users.LessonTracker; import org.owasp.webgoat.users.LessonTracker;
@ -17,9 +16,11 @@ import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import java.util.List;
import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.is;
import static org.mockito.Matchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Matchers.anyString; import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when; 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.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@ -34,7 +35,7 @@ public class ReportCardServiceTest {
@Mock @Mock
private UserTracker userTracker; private UserTracker userTracker;
@Mock @Mock
private AbstractLesson lesson; private Lesson lesson;
@Mock @Mock
private LessonTracker lessonTracker; private LessonTracker lessonTracker;
@Mock @Mock
@ -56,9 +57,9 @@ public class ReportCardServiceTest {
when(lesson.getTitle()).thenReturn("Test"); when(lesson.getTitle()).thenReturn("Test");
when(course.getTotalOfLessons()).thenReturn(1); when(course.getTotalOfLessons()).thenReturn(1);
when(course.getTotalOfAssignments()).thenReturn(10); when(course.getTotalOfAssignments()).thenReturn(10);
when(course.getLessons()).thenReturn(Lists.newArrayList(lesson)); when(course.getLessons()).thenAnswer(x -> List.of(lesson));
when(userTrackerRepository.findByUser(anyString())).thenReturn(userTracker); when(userTrackerRepository.findByUser(any())).thenReturn(userTracker);
when(userTracker.getLessonTracker(any(AbstractLesson.class))).thenReturn(lessonTracker); when(userTracker.getLessonTracker(any(Lesson.class))).thenReturn(lessonTracker);
mockMvc.perform(MockMvcRequestBuilders.get("/service/reportcard.mvc")) mockMvc.perform(MockMvcRequestBuilders.get("/service/reportcard.mvc"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("$.totalNumberOfLessons", is(1))) .andExpect(jsonPath("$.totalNumberOfLessons", is(1)))

View File

@ -31,4 +31,8 @@ package org.owasp.webgoat.session;
*/ */
public class CourseTest { public class CourseTest {
public void number() {
}
} }

View File

@ -2,7 +2,7 @@ package org.owasp.webgoat.session;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import org.junit.Test; import org.junit.Test;
import org.owasp.webgoat.lessons.AbstractLesson; import org.owasp.webgoat.lessons.Lesson;
import org.owasp.webgoat.lessons.Assignment; import org.owasp.webgoat.lessons.Assignment;
import org.owasp.webgoat.users.LessonTracker; import org.owasp.webgoat.users.LessonTracker;
@ -47,8 +47,8 @@ public class LessonTrackerTest {
@Test @Test
public void allAssignmentsSolvedShouldMarkLessonAsComplete() { public void allAssignmentsSolvedShouldMarkLessonAsComplete() {
AbstractLesson lesson = mock(AbstractLesson.class); Lesson lesson = mock(Lesson.class);
when(lesson.getAssignments()).thenReturn(Lists.newArrayList(new Assignment("assignment", ""))); when(lesson.getAssignments()).thenReturn(Lists.newArrayList(new Assignment("assignment", "assignment", List.of(""))));
LessonTracker lessonTracker = new LessonTracker(lesson); LessonTracker lessonTracker = new LessonTracker(lesson);
lessonTracker.assignmentSolved("assignment"); lessonTracker.assignmentSolved("assignment");
@ -57,9 +57,9 @@ public class LessonTrackerTest {
@Test @Test
public void noAssignmentsSolvedShouldMarkLessonAsInComplete() { public void noAssignmentsSolvedShouldMarkLessonAsInComplete() {
AbstractLesson lesson = mock(AbstractLesson.class); Lesson lesson = mock(Lesson.class);
Assignment a1 = new Assignment("a1", "a1"); Assignment a1 = new Assignment("a1");
Assignment a2 = new Assignment("a2", "a2"); Assignment a2 = new Assignment("a2");
List<Assignment> assignments = Lists.newArrayList(a1, a2); List<Assignment> assignments = Lists.newArrayList(a1, a2);
when(lesson.getAssignments()).thenReturn(assignments); when(lesson.getAssignments()).thenReturn(assignments);
LessonTracker lessonTracker = new LessonTracker(lesson); LessonTracker lessonTracker = new LessonTracker(lesson);
@ -72,8 +72,8 @@ public class LessonTrackerTest {
@Test @Test
public void solvingSameAssignmentShouldNotAddItTwice() { public void solvingSameAssignmentShouldNotAddItTwice() {
AbstractLesson lesson = mock(AbstractLesson.class); Lesson lesson = mock(Lesson.class);
Assignment a1 = new Assignment("a1", "a1"); Assignment a1 = new Assignment("a1");
List<Assignment> assignments = Lists.newArrayList(a1); List<Assignment> assignments = Lists.newArrayList(a1);
when(lesson.getAssignments()).thenReturn(assignments); when(lesson.getAssignments()).thenReturn(assignments);
LessonTracker lessonTracker = new LessonTracker(lesson); LessonTracker lessonTracker = new LessonTracker(lesson);

View File

@ -3,7 +3,7 @@ package org.owasp.webgoat.users;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner; import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.core.userdetails.UsernameNotFoundException;
import static org.mockito.Matchers.any; import static org.mockito.Matchers.any;
@ -24,5 +24,4 @@ public class UserServiceTest {
UserService userService = new UserService(userRepository, userTrackerRepository); UserService userService = new UserService(userRepository, userTrackerRepository);
userService.loadUserByUsername("unknown"); userService.loadUserByUsername("unknown");
} }
} }

View File

@ -6,7 +6,7 @@ import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.owasp.webgoat.lessons.Assignment; import org.owasp.webgoat.lessons.Assignment;
import org.owasp.webgoat.lessons.Category; import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.lessons.NewLesson; import org.owasp.webgoat.lessons.Lesson;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.context.junit4.SpringRunner;
@ -17,23 +17,13 @@ import java.util.List;
@RunWith(SpringRunner.class) @RunWith(SpringRunner.class)
public class UserTrackerRepositoryTest { public class UserTrackerRepositoryTest {
private class TestLesson extends NewLesson { private class TestLesson extends Lesson {
@Override @Override
public Category getDefaultCategory() { public Category getDefaultCategory() {
return Category.AJAX_SECURITY; return Category.AJAX_SECURITY;
} }
@Override
public List<String> getHints() {
return Lists.newArrayList();
}
@Override
public Integer getDefaultRanking() {
return 12;
}
@Override @Override
public String getTitle() { public String getTitle() {
return "test"; return "test";

View File

@ -3,7 +3,7 @@ package org.owasp.webgoat.users;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner; import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.validation.BeanPropertyBindingResult; import org.springframework.validation.BeanPropertyBindingResult;
import org.springframework.validation.Errors; import org.springframework.validation.Errors;

View File

@ -40,10 +40,8 @@
<dependency> <dependency>
<groupId>io.rest-assured</groupId> <groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId> <artifactId>rest-assured</artifactId>
<version>4.0.0</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
</dependencies> </dependencies>
<build> <build>

View File

@ -87,7 +87,6 @@ public class GeneralLessonTest extends IntegrationTest {
.get(url("/WebGoat/HttpProxies/intercept-request?changeMe=Requests are tampered easily")).then() .get(url("/WebGoat/HttpProxies/intercept-request?changeMe=Requests are tampered easily")).then()
.statusCode(200).extract().path("lessonCompleted"), CoreMatchers.is(true)); .statusCode(200).extract().path("lessonCompleted"), CoreMatchers.is(true));
checkResults("/HttpProxies/"); checkResults("/HttpProxies/");
} }
@Test @Test

View File

@ -13,7 +13,7 @@ import org.hamcrest.CoreMatchers;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.owasp.webgoat.plugin.JWTSecretKeyEndpoint; import org.owasp.webgoat.jwt.JWTSecretKeyEndpoint;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;

View File

@ -57,8 +57,8 @@ public class PasswordResetLessonTest extends IntegrationTest {
.get(webWolfUrl("WebWolf/requests")) .get(webWolfUrl("WebWolf/requests"))
.then() .then()
.extract().response().getBody().asString(); .extract().response().getBody().asString();
int startIndex = responseBody.lastIndexOf("\"path\" : \"/PasswordReset/reset/reset-password/"); int startIndex = responseBody.lastIndexOf("/PasswordReset/reset/reset-password/");
var link = responseBody.substring(startIndex + "\"path\" : \"/PasswordReset/reset/reset-password/".length(), responseBody.indexOf(",", startIndex) - 1); var link = responseBody.substring(startIndex + "/PasswordReset/reset/reset-password/".length(), responseBody.indexOf(",", startIndex) - 1);
return link; return link;
} }

View File

@ -74,6 +74,7 @@ public class XXETest extends IntegrationTest {
.get(webWolfUrl("/WebWolf/requests")) .get(webWolfUrl("/WebWolf/requests"))
.then() .then()
.extract().response().getBody().asString(); .extract().response().getBody().asString();
result = result.replace("%20", " ");
result = result.substring(result.lastIndexOf("WebGoat 8.0 rocks... ("),result.lastIndexOf("WebGoat 8.0 rocks... (")+33); result = result.substring(result.lastIndexOf("WebGoat 8.0 rocks... ("),result.lastIndexOf("WebGoat 8.0 rocks... (")+33);
return result; return result;
} }

View File

@ -1,8 +1,26 @@
package org.owasp.webgoat.plugin; /*
* 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.
*/
import org.jcodings.util.Hash; package org.owasp.webgoat.auth_bypass;
import org.owasp.webgoat.session.UserSessionData;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -12,10 +30,8 @@ import java.util.Map;
*/ */
public class AccountVerificationHelper { public class AccountVerificationHelper {
//simulating database storage of verification credentials //simulating database storage of verification credentials
private static final Integer verifyUserId = new Integer(1223445); private static final Integer verifyUserId = 1223445;
private static final Map<String,String> userSecQuestions = new HashMap<>(); private static final Map<String,String> userSecQuestions = new HashMap<>();
static { static {
userSecQuestions.put("secQuestion0","Dr. Watson"); userSecQuestions.put("secQuestion0","Dr. Watson");

View File

@ -1,57 +1,39 @@
package org.owasp.webgoat.plugin; /*
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
import com.beust.jcommander.internal.Lists; *
import org.owasp.webgoat.lessons.Category; * Copyright (c) 2002 - 2019 Bruce Mayhew
import org.owasp.webgoat.lessons.NewLesson; *
import java.util.List;
/**
* ************************************************************************************************
* 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 * 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 * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version. * 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 * 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 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details. * General Public License for more details.
* <p> *
* You should have received a copy of the GNU General Public License along with this program; if * 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 * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA. * 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 misfir3 * Getting Source ==============
* @version $Id: $Id *
* @since January 3, 2017 * Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
*/ */
public class AuthBypass extends NewLesson {
package org.owasp.webgoat.auth_bypass;
import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.lessons.Lesson;
import org.springframework.stereotype.Component;
@Component
public class AuthBypass extends Lesson {
@Override @Override
public Category getDefaultCategory() { public Category getDefaultCategory() {
return Category.AUTHENTICATION; return Category.AUTHENTICATION;
} }
@Override
public List<String> getHints() {
return Lists.newArrayList();
}
@Override
public Integer getDefaultRanking() {
return 30;
}
@Override @Override
public String getTitle() { public String getTitle() {
return "auth-bypass.title"; return "auth-bypass.title";

View File

@ -0,0 +1,96 @@
/*
* 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.auth_bypass;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentHints;
import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.assignments.AttackResult;
import org.owasp.webgoat.session.UserSessionData;
import org.owasp.webgoat.session.WebSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by jason on 1/5/17.
*/
@RestController
@AssignmentHints({"auth-bypass.hints.verify.1", "auth-bypass.hints.verify.2", "auth-bypass.hints.verify.3", "auth-bypass.hints.verify.4"})
public class VerifyAccount extends AssignmentEndpoint {
@Autowired
private WebSession webSession;
@Autowired
UserSessionData userSessionData;
@PostMapping(path = "/auth-bypass/verify-account", produces = {"application/json"})
@ResponseBody
public AttackResult completed(@RequestParam String userId, @RequestParam String verifyMethod, HttpServletRequest req) throws ServletException, IOException {
AccountVerificationHelper verificationHelper = new AccountVerificationHelper();
Map<String, String> submittedAnswers = parseSecQuestions(req);
if (verificationHelper.didUserLikelylCheat((HashMap) submittedAnswers)) {
return trackProgress(failed()
.feedback("verify-account.cheated")
.output("Yes, you guessed correctly, but see the feedback message")
.build());
}
// else
if (verificationHelper.verifyAccount(new Integer(userId), (HashMap) submittedAnswers)) {
userSessionData.setValue("account-verified-id", userId);
return trackProgress(success()
.feedback("verify-account.success")
.build());
} else {
return trackProgress(failed()
.feedback("verify-account.failed")
.build());
}
}
private HashMap<String, String> parseSecQuestions(HttpServletRequest req) {
Map<String, String> userAnswers = new HashMap<>();
List<String> paramNames = Collections.list(req.getParameterNames());
for (String paramName : paramNames) {
//String paramName = req.getParameterNames().nextElement();
if (paramName.contains("secQuestion")) {
userAnswers.put(paramName, req.getParameter(paramName));
}
}
return (HashMap) userAnswers;
}
}

View File

@ -1,80 +0,0 @@
package org.owasp.webgoat.plugin;
import com.google.common.collect.Lists;
import org.jcodings.util.Hash;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentHints;
import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.assignments.AttackResult;
import org.owasp.webgoat.session.UserSessionData;
import org.owasp.webgoat.session.WebSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by jason on 1/5/17.
*/
@AssignmentPath("/auth-bypass/verify-account")
@AssignmentHints({"auth-bypass.hints.verify.1", "auth-bypass.hints.verify.2", "auth-bypass.hints.verify.3", "auth-bypass.hints.verify.4"})
public class VerifyAccount extends AssignmentEndpoint {
@Autowired
private WebSession webSession;
@Autowired
UserSessionData userSessionData;
@PostMapping(produces = {"application/json"})
@ResponseBody
public AttackResult completed(@RequestParam String userId, @RequestParam String verifyMethod, HttpServletRequest req) throws ServletException, IOException {
AccountVerificationHelper verificationHelper = new AccountVerificationHelper();
Map<String,String> submittedAnswers = parseSecQuestions(req);
if (verificationHelper.didUserLikelylCheat((HashMap)submittedAnswers)) {
return trackProgress(failed()
.feedback("verify-account.cheated")
.output("Yes, you guessed correcctly,but see the feedback message")
.build());
}
// else
if (verificationHelper.verifyAccount(new Integer(userId),(HashMap)submittedAnswers)) {
userSessionData.setValue("account-verified-id", userId);
return trackProgress(success()
.feedback("verify-account.success")
.build());
} else {
return trackProgress(failed()
.feedback("verify-account.failed")
.build());
}
}
private HashMap<String,String> parseSecQuestions (HttpServletRequest req) {
Map <String,String> userAnswers = new HashMap<>();
List<String> paramNames = Collections.list(req.getParameterNames());
for (String paramName : paramNames) {
//String paramName = req.getParameterNames().nextElement();
if (paramName.contains("secQuestion")) {
userAnswers.put(paramName,req.getParameter(paramName));
}
}
return (HashMap)userAnswers;
}
}

View File

@ -23,7 +23,7 @@
* <p> * <p>
*/ */
package org.owasp.webgoat.plugin; package org.owasp.webgoat.auth_bypass;
import org.hamcrest.CoreMatchers; import org.hamcrest.CoreMatchers;
import org.junit.Before; import org.junit.Before;

View File

@ -0,0 +1,45 @@
/*
* 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.bypass_restrictions;
import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.lessons.Lesson;
import org.springframework.stereotype.Component;
@Component
public class BypassRestrictions extends Lesson {
@Override
public Category getDefaultCategory() {
return Category.CLIENT_SIDE;
}
@Override
public String getTitle() {
return "bypass-restrictions.title";
}
@Override
public String getId() {
return "BypassRestrictions";
}
}

View File

@ -0,0 +1,58 @@
/*
* 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.bypass_restrictions;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AttackResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class BypassRestrictionsFieldRestrictions extends AssignmentEndpoint {
@PostMapping("/BypassRestrictions/FieldRestrictions")
@ResponseBody
public AttackResult completed(@RequestParam String select, @RequestParam String radio, @RequestParam String checkbox, @RequestParam String shortInput) {
if (select.equals("option1") || select.equals("option2")) {
return trackProgress(failed().build());
}
if (radio.equals("option1") || radio.equals("option2")) {
return trackProgress(failed().build());
}
if (checkbox.equals("on") || checkbox.equals("off")) {
return trackProgress(failed().build());
}
if (shortInput.length() <= 5) {
return trackProgress(failed().build());
}
/*if (disabled == null) {
return trackProgress(failed().build());
}
if (submit.toString().equals("submit")) {
return trackProgress(failed().build());
}*/
return trackProgress(success().build());
}
}

View File

@ -0,0 +1,72 @@
/*
* 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.bypass_restrictions;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.assignments.AttackResult;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
@RestController
public class BypassRestrictionsFrontendValidation extends AssignmentEndpoint {
@PostMapping("/BypassRestrictions/frontendValidation")
@ResponseBody
public AttackResult completed(@RequestParam String field1, @RequestParam String field2, @RequestParam String field3, @RequestParam String field4, @RequestParam String field5, @RequestParam String field6, @RequestParam String field7, @RequestParam Integer error) {
String regex1 = "^[a-z]{3}$";
String regex2 = "^[0-9]{3}$";
String regex3 = "^[a-zA-Z0-9 ]*$";
String regex4 = "^(one|two|three|four|five|six|seven|eight|nine)$";
String regex5 = "^\\d{5}$";
String regex6 = "^\\d{5}(-\\d{4})?$";
String regex7 = "^[2-9]\\d{2}-?\\d{3}-?\\d{4}$";
if (error > 0) {
return trackProgress(failed().build());
}
if (field1.matches(regex1)) {
return trackProgress(failed().build());
}
if (field2.matches(regex2)) {
return trackProgress(failed().build());
}
if (field3.matches(regex3)) {
return trackProgress(failed().build());
}
if (field4.matches(regex4)) {
return trackProgress(failed().build());
}
if (field5.matches(regex5)) {
return trackProgress(failed().build());
}
if (field6.matches(regex6)) {
return trackProgress(failed().build());
}
if (field7.matches(regex7)) {
return trackProgress(failed().build());
}
return trackProgress(success().build());
}
}

View File

@ -1,74 +0,0 @@
package org.owasp.webgoat.plugin;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.assignments.AttackResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* *************************************************************************************************
*
*
* 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.
*
* For details, please see http://webgoat.github.io
*
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003
*/
@AssignmentPath("/BypassRestrictions/FieldRestrictions")
public class BypassRestrictionsFieldRestrictions extends AssignmentEndpoint {
@RequestMapping(method = RequestMethod.POST)
public
@ResponseBody
AttackResult completed(@RequestParam String select, @RequestParam String radio, @RequestParam String checkbox, @RequestParam String shortInput) throws IOException {
if (select.toString().equals("option1") || select.toString().equals("option2")) {
return trackProgress(failed().build());
}
if (radio.toString().equals("option1") || radio.toString().equals("option2")) {
return trackProgress(failed().build());
}
if (checkbox.toString().equals("on") || checkbox.toString().equals("off")) {
return trackProgress(failed().build());
}
if (shortInput.toString().length() <= 5) {
return trackProgress(failed().build());
}
/*if (disabled == null) {
return trackProgress(failed().build());
}
if (submit.toString().equals("submit")) {
return trackProgress(failed().build());
}*/
return trackProgress(success().build());
}
}

View File

@ -1,87 +0,0 @@
package org.owasp.webgoat.plugin;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.assignments.AttackResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* *************************************************************************************************
*
*
* 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.
*
* For details, please see http://webgoat.github.io
*
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003
*/
@AssignmentPath("/BypassRestrictions/frontendValidation")
public class BypassRestrictionsFrontendValidation extends AssignmentEndpoint {
@RequestMapping(method = RequestMethod.POST)
public
@ResponseBody
AttackResult completed(@RequestParam String field1, @RequestParam String field2, @RequestParam String field3, @RequestParam String field4, @RequestParam String field5, @RequestParam String field6, @RequestParam String field7, @RequestParam Integer error) throws IOException {
String regex1="^[a-z]{3}$";
String regex2="^[0-9]{3}$";
String regex3="^[a-zA-Z0-9 ]*$";
String regex4="^(one|two|three|four|five|six|seven|eight|nine)$";
String regex5="^\\d{5}$";
String regex6="^\\d{5}(-\\d{4})?$";
String regex7="^[2-9]\\d{2}-?\\d{3}-?\\d{4}$";
if (error>0) {
return trackProgress(failed().build());
}
if (field1.matches(regex1)) {
return trackProgress(failed().build());
}
if (field2.matches(regex2)) {
return trackProgress(failed().build());
}
if (field3.matches(regex3)) {
return trackProgress(failed().build());
}
if (field4.matches(regex4)) {
return trackProgress(failed().build());
}
if (field5.matches(regex5)) {
return trackProgress(failed().build());
}
if (field6.matches(regex6)) {
return trackProgress(failed().build());
}
if (field7.matches(regex7)) {
return trackProgress(failed().build());
}
return trackProgress(success().build());
}
}

View File

@ -1,9 +1,10 @@
package org.owasp.webgoat.plugin; package org.owasp.webgoat.bypass_restrictions;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.owasp.webgoat.plugins.LessonTest; import org.owasp.webgoat.plugins.LessonTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.test.web.servlet.setup.MockMvcBuilders;
@ -20,9 +21,12 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
@RunWith(SpringJUnit4ClassRunner.class) @RunWith(SpringJUnit4ClassRunner.class)
public class BypassRestrictionsFrontendValidationTest extends LessonTest { public class BypassRestrictionsFrontendValidationTest extends LessonTest {
@Autowired
private BypassRestrictions bypassRestrictions;
@Before @Before
public void setup() { public void setup() {
when(webSession.getCurrentLesson()).thenReturn(new BypassRestrictions()); when(webSession.getCurrentLesson()).thenReturn(bypassRestrictions);
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build(); this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
} }

View File

@ -0,0 +1,26 @@
package org.owasp.webgoat.challenges;
import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.lessons.Lesson;
/**
* @author nbaars
* @since 3/21/17.
*/
public class ChallengeIntro extends Lesson {
@Override
public Category getDefaultCategory() {
return Category.CHALLENGE;
}
@Override
public String getTitle() {
return "challenge0.title";
}
@Override
public String getId() {
return "Challenge";
}
}

View File

@ -0,0 +1,44 @@
/*
* 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.challenges;
import lombok.Builder;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* @author nbaars
* @since 8/20/17.
*/
@Builder
@Data
public class Email implements Serializable {
private LocalDateTime time;
private String contents;
private String sender;
private String title;
private String recipient;
}

View File

@ -1,11 +1,32 @@
package org.owasp.webgoat.plugin; /*
* 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.challenges;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.owasp.webgoat.assignments.AttackResult; import org.owasp.webgoat.assignments.AttackResult;
import org.owasp.webgoat.assignments.Endpoint;
import org.owasp.webgoat.i18n.PluginMessages; import org.owasp.webgoat.i18n.PluginMessages;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
import org.owasp.webgoat.users.UserTracker; import org.owasp.webgoat.users.UserTracker;
@ -27,7 +48,7 @@ import java.util.stream.IntStream;
* @since 3/23/17. * @since 3/23/17.
*/ */
@Slf4j @Slf4j
public class Flag extends Endpoint { public class Flag { //extends Endpoint {
public static final Map<Integer, String> FLAGS = Maps.newHashMap(); public static final Map<Integer, String> FLAGS = Maps.newHashMap();
@Autowired @Autowired
@ -48,10 +69,10 @@ public class Flag extends Endpoint {
IntStream.range(1, 10).forEach(i -> FLAGS.put(i, UUID.randomUUID().toString())); IntStream.range(1, 10).forEach(i -> FLAGS.put(i, UUID.randomUUID().toString()));
} }
@Override // @Override
public String getPath() { // public String getPath() {
return "challenge/flag"; // return "challenge/flag";
} // }
@RequestMapping(method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) @RequestMapping(method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody @ResponseBody

View File

@ -0,0 +1,37 @@
/*
* 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.challenges;
/**
* Interface with constants so we can easily change the flags
*
* @author nbaars
* @since 3/23/17.
*/
public interface SolutionConstants {
//TODO should be random generated when starting the server
String PASSWORD = "!!webgoat_admin_1234!!";
String PASSWORD_TOM = "thisisasecretfortomonly";
String ADMIN_PASSWORD_LINK = "375afe1104f4a487a73823c50a9292a2";
}

View File

@ -1,19 +1,14 @@
package org.owasp.webgoat.plugin.challenge1; package org.owasp.webgoat.challenges.challenge1;
import org.owasp.webgoat.assignments.AssignmentEndpoint; import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.assignments.AttackResult; import org.owasp.webgoat.assignments.AttackResult;
import org.owasp.webgoat.plugin.Flag; import org.owasp.webgoat.challenges.Flag;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import static org.owasp.webgoat.plugin.SolutionConstants.PASSWORD; import static org.owasp.webgoat.challenges.SolutionConstants.PASSWORD;
/** /**
* ************************************************************************************************ * ************************************************************************************************
@ -44,13 +39,12 @@ import static org.owasp.webgoat.plugin.SolutionConstants.PASSWORD;
* @version $Id: $Id * @version $Id: $Id
* @since August 11, 2016 * @since August 11, 2016
*/ */
@AssignmentPath("/challenge/1") @RestController
public class Assignment1 extends AssignmentEndpoint { public class Assignment1 extends AssignmentEndpoint {
@RequestMapping(method = RequestMethod.POST) @PostMapping("/challenge/1")
public
@ResponseBody @ResponseBody
AttackResult completed(@RequestParam String username, @RequestParam String password, HttpServletRequest request) throws IOException { public AttackResult completed(@RequestParam String username, @RequestParam String password, HttpServletRequest request) {
boolean ipAddressKnown = true; boolean ipAddressKnown = true;
boolean passwordCorrect = "admin".equals(username) && PASSWORD.equals(password); boolean passwordCorrect = "admin".equals(username) && PASSWORD.equals(password);
if (passwordCorrect && ipAddressKnown) { if (passwordCorrect && ipAddressKnown) {
@ -63,6 +57,5 @@ public class Assignment1 extends AssignmentEndpoint {
public static boolean containsHeader(HttpServletRequest request) { public static boolean containsHeader(HttpServletRequest request) {
return StringUtils.hasText(request.getHeader("X-Forwarded-For")); return StringUtils.hasText(request.getHeader("X-Forwarded-For"));
} }
} }

View File

@ -0,0 +1,28 @@
package org.owasp.webgoat.challenges.challenge1;
import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.lessons.Lesson;
import org.springframework.stereotype.Component;
/**
* @author nbaars
* @since 3/21/17.
*/
@Component
public class Challenge1 extends Lesson {
@Override
public Category getDefaultCategory() {
return Category.CHALLENGE;
}
@Override
public String getTitle() {
return "challenge1.title";
}
@Override
public String getId() {
return "Challenge1";
}
}

View File

@ -1,29 +1,47 @@
package org.owasp.webgoat.plugin.challenge5.challenge6; /*
* 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.challenges.challenge5;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.RandomStringUtils;
import org.owasp.webgoat.assignments.AssignmentEndpoint; import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.assignments.AttackResult; import org.owasp.webgoat.assignments.AttackResult;
import org.owasp.webgoat.plugin.Flag; import org.owasp.webgoat.challenges.Flag;
import org.owasp.webgoat.session.DatabaseUtilities; import org.owasp.webgoat.session.DatabaseUtilities;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.sql.*; import java.sql.*;
import static org.owasp.webgoat.plugin.SolutionConstants.PASSWORD_TOM; import static org.owasp.webgoat.challenges.SolutionConstants.PASSWORD_TOM;
import static org.springframework.web.bind.annotation.RequestMethod.POST;
/** /**
* @author nbaars * @author nbaars
* @since 4/8/17. * @since 4/8/17.
*/ */
@AssignmentPath("/challenge/5") @RestController
@Slf4j @Slf4j
public class Assignment5 extends AssignmentEndpoint { public class Assignment5 extends AssignmentEndpoint {
@ -33,7 +51,7 @@ public class Assignment5 extends AssignmentEndpoint {
@Autowired @Autowired
private WebSession webSession; private WebSession webSession;
@RequestMapping(method = POST) @PostMapping("/challenge/5")
@ResponseBody @ResponseBody
public AttackResult login(@RequestParam String username_login, @RequestParam String password_login) throws Exception { public AttackResult login(@RequestParam String username_login, @RequestParam String password_login) throws Exception {
Connection connection = DatabaseUtilities.getConnection(webSession); Connection connection = DatabaseUtilities.getConnection(webSession);

View File

@ -0,0 +1,50 @@
/*
* 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.challenges.challenge5;
import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.lessons.Lesson;
import org.springframework.stereotype.Component;
/**
* @author nbaars
* @since 3/21/17.
*/
@Component
public class Challenge5 extends Lesson {
@Override
public Category getDefaultCategory() {
return Category.CHALLENGE;
}
@Override
public String getTitle() {
return "challenge5.title";
}
@Override
public String getId() {
return "Challenge5";
}
}

View File

@ -1,30 +1,25 @@
package org.owasp.webgoat.plugin.challenge6; package org.owasp.webgoat.challenges.challenge6;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.RandomStringUtils;
import org.owasp.webgoat.assignments.AssignmentEndpoint; import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.assignments.AttackResult; import org.owasp.webgoat.assignments.AttackResult;
import org.owasp.webgoat.plugin.Flag; import org.owasp.webgoat.challenges.Flag;
import org.owasp.webgoat.session.DatabaseUtilities; import org.owasp.webgoat.session.DatabaseUtilities;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.sql.*; import java.sql.*;
import static org.owasp.webgoat.plugin.SolutionConstants.PASSWORD_TOM; import static org.owasp.webgoat.challenges.SolutionConstants.PASSWORD_TOM;
import static org.springframework.web.bind.annotation.RequestMethod.POST;
/** /**
* @author nbaars * @author nbaars
* @since 4/8/17. * @since 4/8/17.
*/ */
@AssignmentPath("/challenge/6") @RestController
@Slf4j @Slf4j
public class Assignment6 extends AssignmentEndpoint { public class Assignment6 extends AssignmentEndpoint {
@ -38,7 +33,7 @@ public class Assignment6 extends AssignmentEndpoint {
log.info("Challenge 6 tablename is: {}", USERS_TABLE_NAME); log.info("Challenge 6 tablename is: {}", USERS_TABLE_NAME);
} }
@PutMapping //assignment path is bounded to class so we use different http method :-) @PutMapping("/challenge/6") //assignment path is bounded to class so we use different http method :-)
@ResponseBody @ResponseBody
public AttackResult registerNewUser(@RequestParam String username_reg, @RequestParam String email_reg, @RequestParam String password_reg) throws Exception { public AttackResult registerNewUser(@RequestParam String username_reg, @RequestParam String email_reg, @RequestParam String password_reg) throws Exception {
AttackResult attackResult = checkArguments(username_reg, email_reg, password_reg); AttackResult attackResult = checkArguments(username_reg, email_reg, password_reg);
@ -75,7 +70,7 @@ public class Assignment6 extends AssignmentEndpoint {
return null; return null;
} }
@RequestMapping(method = POST) @PostMapping("/challenge/6")
@ResponseBody @ResponseBody
public AttackResult login(@RequestParam String username_login, @RequestParam String password_login) throws Exception { public AttackResult login(@RequestParam String username_login, @RequestParam String password_login) throws Exception {
Connection connection = DatabaseUtilities.getConnection(webSession); Connection connection = DatabaseUtilities.getConnection(webSession);

View File

@ -0,0 +1,28 @@
package org.owasp.webgoat.challenges.challenge6;
import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.lessons.Lesson;
import org.springframework.stereotype.Component;
/**
* @author nbaars
* @since 3/21/17.
*/
@Component
public class Challenge6 extends Lesson {
@Override
public Category getDefaultCategory() {
return Category.CHALLENGE;
}
@Override
public String getTitle() {
return "challenge6.title";
}
@Override
public String getId() {
return "Challenge6";
}
}

View File

@ -1,12 +1,11 @@
package org.owasp.webgoat.plugin.challenge7; package org.owasp.webgoat.challenges.challenge7;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.owasp.webgoat.assignments.AssignmentEndpoint; import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.assignments.AttackResult; import org.owasp.webgoat.assignments.AttackResult;
import org.owasp.webgoat.plugin.Email; import org.owasp.webgoat.challenges.Email;
import org.owasp.webgoat.plugin.SolutionConstants; import org.owasp.webgoat.challenges.SolutionConstants;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.ClassPathResource;
@ -22,15 +21,13 @@ import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import static org.owasp.webgoat.plugin.Flag.FLAGS; import static org.owasp.webgoat.challenges.Flag.FLAGS;
import static org.springframework.web.bind.annotation.RequestMethod.GET;
import static org.springframework.web.bind.annotation.RequestMethod.POST;
/** /**
* @author nbaars * @author nbaars
* @since 4/8/17. * @since 4/8/17.
*/ */
@AssignmentPath("/challenge/7") @RestController
@Slf4j @Slf4j
public class Assignment7 extends AssignmentEndpoint { public class Assignment7 extends AssignmentEndpoint {
@ -48,7 +45,7 @@ public class Assignment7 extends AssignmentEndpoint {
@Value("${webwolf.url.mail}") @Value("${webwolf.url.mail}")
private String webWolfMailURL; private String webWolfMailURL;
@GetMapping("/reset-password/{link}") @GetMapping("/challenge/7/reset-password/{link}")
public ResponseEntity<String> resetPassword(@PathVariable(value = "link") String link) { public ResponseEntity<String> resetPassword(@PathVariable(value = "link") String link) {
if (link.equals(SolutionConstants.ADMIN_PASSWORD_LINK)) { if (link.equals(SolutionConstants.ADMIN_PASSWORD_LINK)) {
return ResponseEntity.accepted().body("<h1>Success!!</h1>" + return ResponseEntity.accepted().body("<h1>Success!!</h1>" +
@ -58,7 +55,7 @@ public class Assignment7 extends AssignmentEndpoint {
return ResponseEntity.status(HttpStatus.I_AM_A_TEAPOT).body("That is not the reset link for admin"); return ResponseEntity.status(HttpStatus.I_AM_A_TEAPOT).body("That is not the reset link for admin");
} }
@RequestMapping(method = POST) @PostMapping("/challenge/7")
@ResponseBody @ResponseBody
public AttackResult sendPasswordResetLink(@RequestParam String email, HttpServletRequest request) throws URISyntaxException { public AttackResult sendPasswordResetLink(@RequestParam String email, HttpServletRequest request) throws URISyntaxException {
if (StringUtils.hasText(email)) { if (StringUtils.hasText(email)) {
@ -77,7 +74,7 @@ public class Assignment7 extends AssignmentEndpoint {
return success().feedback("email.send").feedbackArgs(email).build(); return success().feedback("email.send").feedbackArgs(email).build();
} }
@RequestMapping(method = GET, value = "/.git", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE) @GetMapping(value = "/challenge/7/.git", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
@ResponseBody @ResponseBody
@SneakyThrows @SneakyThrows
public ClassPathResource git() { public ClassPathResource git() {

View File

@ -0,0 +1,28 @@
package org.owasp.webgoat.challenges.challenge7;
import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.lessons.Lesson;
import org.springframework.stereotype.Component;
/**
* @author nbaars
* @since 3/21/17.
*/
@Component
public class Challenge7 extends Lesson {
@Override
public Category getDefaultCategory() {
return Category.CHALLENGE;
}
@Override
public String getTitle() {
return "challenge7.title";
}
@Override
public String getId() {
return "Challenge7";
}
}

View File

@ -1,4 +1,4 @@
package org.owasp.webgoat.plugin.challenge7; package org.owasp.webgoat.challenges.challenge7;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;

View File

@ -1,4 +1,4 @@
package org.owasp.webgoat.plugin.challenge7; package org.owasp.webgoat.challenges.challenge7;
import java.util.Random; import java.util.Random;

View File

@ -1,15 +1,15 @@
package org.owasp.webgoat.plugin.challenge8; package org.owasp.webgoat.challenges.challenge8;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.owasp.webgoat.assignments.AssignmentEndpoint; import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentPath; import org.owasp.webgoat.challenges.Flag;
import org.owasp.webgoat.plugin.Flag;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.HashMap; import java.util.HashMap;
@ -20,7 +20,7 @@ import java.util.stream.Collectors;
* @author nbaars * @author nbaars
* @since 4/8/17. * @since 4/8/17.
*/ */
@AssignmentPath("/challenge/8") @RestController
@Slf4j @Slf4j
public class Assignment8 extends AssignmentEndpoint { public class Assignment8 extends AssignmentEndpoint {
@ -34,7 +34,7 @@ public class Assignment8 extends AssignmentEndpoint {
votes.put(5, 300); votes.put(5, 300);
} }
@GetMapping(value = "/vote/{stars}", produces = MediaType.APPLICATION_JSON_VALUE) @GetMapping(value = "/challenge/8/vote/{stars}", produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody @ResponseBody
public ResponseEntity<?> vote(@PathVariable(value = "stars") int nrOfStars, HttpServletRequest request) { public ResponseEntity<?> vote(@PathVariable(value = "stars") int nrOfStars, HttpServletRequest request) {
//Simple implementation of VERB Based Authentication //Simple implementation of VERB Based Authentication
@ -50,12 +50,12 @@ public class Assignment8 extends AssignmentEndpoint {
return ResponseEntity.ok().header("X-Flag", "Thanks for voting, your flag is: " + Flag.FLAGS.get(8)).build(); return ResponseEntity.ok().header("X-Flag", "Thanks for voting, your flag is: " + Flag.FLAGS.get(8)).build();
} }
@GetMapping("/votes/") @GetMapping("/challenge/8/votes/")
public ResponseEntity<?> getVotes() { public ResponseEntity<?> getVotes() {
return ResponseEntity.ok(votes.entrySet().stream().collect(Collectors.toMap(e -> "" + e.getKey(), e -> e.getValue()))); return ResponseEntity.ok(votes.entrySet().stream().collect(Collectors.toMap(e -> "" + e.getKey(), e -> e.getValue())));
} }
@GetMapping("/votes/average") @GetMapping("/challenge/8/votes/average")
public ResponseEntity<Map<String, Integer>> average() { public ResponseEntity<Map<String, Integer>> average() {
int totalNumberOfVotes = votes.values().stream().mapToInt(i -> i.intValue()).sum(); int totalNumberOfVotes = votes.values().stream().mapToInt(i -> i.intValue()).sum();
int categories = votes.entrySet().stream().mapToInt(e -> e.getKey() * e.getValue()).reduce(0, (a, b) -> a + b); int categories = votes.entrySet().stream().mapToInt(e -> e.getKey() * e.getValue()).reduce(0, (a, b) -> a + b);
@ -63,6 +63,5 @@ public class Assignment8 extends AssignmentEndpoint {
json.put("average", (int) Math.ceil((double) categories / totalNumberOfVotes)); json.put("average", (int) Math.ceil((double) categories / totalNumberOfVotes));
return ResponseEntity.ok(json); return ResponseEntity.ok(json);
} }
} }

View File

@ -0,0 +1,28 @@
package org.owasp.webgoat.challenges.challenge8;
import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.lessons.Lesson;
import org.springframework.stereotype.Component;
/**
* @author nbaars
* @since 3/21/17.
*/
@Component
public class Challenge8 extends Lesson {
@Override
public Category getDefaultCategory() {
return Category.CHALLENGE;
}
@Override
public String getTitle() {
return "challenge8.title";
}
@Override
public String getId() {
return "Challenge8";
}
}

View File

@ -1,39 +0,0 @@
package org.owasp.webgoat.plugin;
import com.google.common.collect.Lists;
import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.lessons.NewLesson;
import java.util.List;
/**
* @author nbaars
* @since 3/21/17.
*/
public class ChallengeIntro extends NewLesson {
@Override
public Category getDefaultCategory() {
return Category.CHALLENGE;
}
@Override
public List<String> getHints() {
return Lists.newArrayList();
}
@Override
public Integer getDefaultRanking() {
return 10;
}
@Override
public String getTitle() {
return "challenge0.title";
}
@Override
public String getId() {
return "Challenge";
}
}

View File

@ -1,22 +0,0 @@
package org.owasp.webgoat.plugin;
import lombok.Builder;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* @author nbaars
* @since 8/20/17.
*/
@Builder
@Data
public class Email implements Serializable {
private LocalDateTime time;
private String contents;
private String sender;
private String title;
private String recipient;
}

View File

@ -1,15 +0,0 @@
package org.owasp.webgoat.plugin;
/**
* Interface with constants so we can easily change the flags
*
* @author nbaars
* @since 3/23/17.
*/
public interface SolutionConstants {
//TODO should be random generated when starting the server
String PASSWORD = "!!webgoat_admin_1234!!";
String PASSWORD_TOM = "thisisasecretfortomonly";
String ADMIN_PASSWORD_LINK = "375afe1104f4a487a73823c50a9292a2";
}

View File

@ -1,39 +0,0 @@
package org.owasp.webgoat.plugin.challenge1;
import com.google.common.collect.Lists;
import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.lessons.NewLesson;
import java.util.List;
/**
* @author nbaars
* @since 3/21/17.
*/
public class Challenge1 extends NewLesson {
@Override
public Category getDefaultCategory() {
return Category.CHALLENGE;
}
@Override
public List<String> getHints() {
return Lists.newArrayList();
}
@Override
public Integer getDefaultRanking() {
return 10;
}
@Override
public String getTitle() {
return "challenge1.title";
}
@Override
public String getId() {
return "Challenge1";
}
}

View File

@ -1,39 +0,0 @@
package org.owasp.webgoat.plugin.challenge5.challenge6;
import com.google.common.collect.Lists;
import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.lessons.NewLesson;
import java.util.List;
/**
* @author nbaars
* @since 3/21/17.
*/
public class Challenge5 extends NewLesson {
@Override
public Category getDefaultCategory() {
return Category.CHALLENGE;
}
@Override
public List<String> getHints() {
return Lists.newArrayList();
}
@Override
public Integer getDefaultRanking() {
return 10;
}
@Override
public String getTitle() {
return "challenge5.title";
}
@Override
public String getId() {
return "Challenge5";
}
}

View File

@ -1,39 +0,0 @@
package org.owasp.webgoat.plugin.challenge6;
import com.google.common.collect.Lists;
import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.lessons.NewLesson;
import java.util.List;
/**
* @author nbaars
* @since 3/21/17.
*/
public class Challenge6 extends NewLesson {
@Override
public Category getDefaultCategory() {
return Category.CHALLENGE;
}
@Override
public List<String> getHints() {
return Lists.newArrayList();
}
@Override
public Integer getDefaultRanking() {
return 10;
}
@Override
public String getTitle() {
return "challenge6.title";
}
@Override
public String getId() {
return "Challenge6";
}
}

View File

@ -1,39 +0,0 @@
package org.owasp.webgoat.plugin.challenge7;
import com.google.common.collect.Lists;
import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.lessons.NewLesson;
import java.util.List;
/**
* @author nbaars
* @since 3/21/17.
*/
public class Challenge7 extends NewLesson {
@Override
public Category getDefaultCategory() {
return Category.CHALLENGE;
}
@Override
public List<String> getHints() {
return Lists.newArrayList();
}
@Override
public Integer getDefaultRanking() {
return 10;
}
@Override
public String getTitle() {
return "challenge7.title";
}
@Override
public String getId() {
return "Challenge7";
}
}

View File

@ -1,39 +0,0 @@
package org.owasp.webgoat.plugin.challenge8;
import com.google.common.collect.Lists;
import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.lessons.NewLesson;
import java.util.List;
/**
* @author nbaars
* @since 3/21/17.
*/
public class Challenge8 extends NewLesson {
@Override
public Category getDefaultCategory() {
return Category.CHALLENGE;
}
@Override
public List<String> getHints() {
return Lists.newArrayList();
}
@Override
public Integer getDefaultRanking() {
return 10;
}
@Override
public String getTitle() {
return "challenge8.title";
}
@Override
public String getId() {
return "Challenge8";
}
}

View File

@ -1,18 +1,40 @@
package org.owasp.webgoat.plugin.challenge1; /*
* 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.challenges;
import org.hamcrest.CoreMatchers; import org.hamcrest.CoreMatchers;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner; import org.mockito.junit.MockitoJUnitRunner;
import org.owasp.webgoat.assignments.AssignmentEndpointTest; import org.owasp.webgoat.assignments.AssignmentEndpointTest;
import org.owasp.webgoat.plugin.Flag; import org.owasp.webgoat.challenges.challenge1.Assignment1;
import org.owasp.webgoat.plugin.SolutionConstants;
import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import java.net.InetAddress; import java.net.InetAddress;
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.jsonPath;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup; import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;

View File

@ -0,0 +1,50 @@
/*
* 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.chrome_dev_tools;
import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.lessons.Lesson;
import org.springframework.stereotype.Component;
/**
* @author TMelzer
* @since 30.11.18
*/
@Component
public class ChromeDevTools extends Lesson {
@Override
public Category getDefaultCategory() {
return Category.GENERAL;
}
@Override
public String getTitle() {
return "chrome-dev-tools.title";
}
@Override
public String getId() {
return "ChromeDevTools";
}
}

View File

@ -0,0 +1,54 @@
/*
* 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.chrome_dev_tools;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.assignments.AttackResult;
import org.owasp.webgoat.session.UserSessionData;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
/**
* This is just a class used to make the the HTTP request.
*
* @author TMelzer
* @since 30.11.18
*/
@RestController
public class NetworkDummy extends AssignmentEndpoint {
@PostMapping("/ChromeDevTools/dummy")
@ResponseBody
public AttackResult completed(@RequestParam String successMessage) {
UserSessionData userSessionData = getUserSessionData();
String answer = (String) userSessionData.getValue("randValue");
if (successMessage != null && successMessage.equals(answer)) {
return trackProgress(success().feedback("xss-dom-message-success").build());
} else {
return trackProgress(failed().feedback("xss-dom-message-failure").build());
}
}
}

View File

@ -0,0 +1,60 @@
/*
* 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.chrome_dev_tools;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentHints;
import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.assignments.AttackResult;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
/**
* Assignment where the user has to look through an HTTP Request
* using the Developer Tools and find a specific number.
*
* @author TMelzer
* @since 30.11.18
*/
@RestController
@AssignmentHints({"networkHint1", "networkHint2"})
public class NetworkLesson extends AssignmentEndpoint {
@PostMapping(value = "/ChromeDevTools/network", params = {"network_num", "number"})
@ResponseBody
public AttackResult completed(@RequestParam String network_num, @RequestParam String number) {
if (network_num.equals(number)) {
return trackProgress(success().feedback("network.success").output("").build());
} else {
return trackProgress(failed().feedback("network.failed").build());
}
}
@PostMapping(path = "/ChromeDevTools/network", params = "networkNum")
@ResponseBody
public ResponseEntity<?> ok(@RequestParam String networkNum) {
return ResponseEntity.ok().build();
}
}

View File

@ -1,39 +0,0 @@
package org.owasp.webgoat.plugin;
import com.beust.jcommander.internal.Lists;
import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.lessons.NewLesson;
import java.util.List;
/**
* @author TMelzer
* @since 30.11.18
*/
public class ChromeDevTools extends NewLesson {
@Override
public Category getDefaultCategory() {
return Category.GENERAL;
}
@Override
public List<String> getHints() {
return Lists.newArrayList();
}
@Override
public Integer getDefaultRanking() {
return 4;
}
@Override
public String getTitle() {
return "chrome-dev-tools.title";
}
@Override
public String getId() {
return "ChromeDevTools";
}
}

View File

@ -1,37 +0,0 @@
package org.owasp.webgoat.plugin;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.assignments.AttackResult;
import org.owasp.webgoat.session.UserSessionData;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.io.IOException;
/**
* This is just a class used to make the the HTTP request.
* @author TMelzer
* @since 30.11.18
*/
@AssignmentPath("/ChromeDevTools/dummy")
public class NetworkDummy extends AssignmentEndpoint {
@RequestMapping(method = RequestMethod.POST)
public
@ResponseBody
AttackResult completed(@RequestParam String successMessage) throws IOException {
UserSessionData userSessionData = getUserSessionData();
String answer = (String) userSessionData.getValue("randValue");
if (successMessage!=null && successMessage.equals(answer)) {
return trackProgress(success().feedback("xss-dom-message-success").build());
} else {
return trackProgress(failed().feedback("xss-dom-message-failure").build());
}
}
}

View File

@ -1,42 +0,0 @@
package org.owasp.webgoat.plugin;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentHints;
import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.assignments.AttackResult;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.io.IOException;
/**
* Assignment where the user has to look through an HTTP Request
* using the Developer Tools and find a specific number.
* @author TMelzer
* @since 30.11.18
*/
@AssignmentPath("/ChromeDevTools/network")
@AssignmentHints({"networkHint1", "networkHint2"})
public class NetworkLesson extends AssignmentEndpoint {
@RequestMapping(method = RequestMethod.POST, params= {"network_num","number"})
public
@ResponseBody
AttackResult completed(@RequestParam String network_num, @RequestParam String number) throws IOException {
if(network_num.equals(number)) {
return trackProgress(success().feedback("network.success").output("").build());
} else {
return trackProgress(failed().feedback("network.failed").build());
}
}
@RequestMapping(method = RequestMethod.POST, params="networkNum")
public
@ResponseBody
ResponseEntity<?> ok(@RequestParam String networkNum) throws IOException {
return ResponseEntity.ok().build();
}
}

View File

@ -1,4 +1,4 @@
package org.owasp.webgoat.plugin; package org.owasp.webgoat.chrome_dev_tools;
import org.hamcrest.Matchers; import org.hamcrest.Matchers;
import org.junit.Before; import org.junit.Before;
@ -17,6 +17,7 @@ import static org.hamcrest.CoreMatchers.is;
import static org.mockito.Mockito.when; 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.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/** /**
* @author Benedikt Stuhrmann * @author Benedikt Stuhrmann
* @since 13/03/19. * @since 13/03/19.
@ -25,18 +26,16 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
public class ChromeDevToolsTest extends LessonTest { public class ChromeDevToolsTest extends LessonTest {
@Autowired @Autowired
private WebgoatContext context; private ChromeDevTools cdt;
@Before @Before
public void setup() { public void setup() {
ChromeDevTools cdt = new ChromeDevTools();
when(webSession.getCurrentLesson()).thenReturn(cdt); when(webSession.getCurrentLesson()).thenReturn(cdt);
when(webSession.getWebgoatContext()).thenReturn(context);
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build(); this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
} }
@Test @Test
public void NetworkAssignmentTest_Success() throws Exception{ public void NetworkAssignmentTest_Success() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.post("/ChromeDevTools/network") mockMvc.perform(MockMvcRequestBuilders.post("/ChromeDevTools/network")
.param("network_num", "123456") .param("network_num", "123456")
.param("number", "123456")) .param("number", "123456"))

View File

@ -0,0 +1,28 @@
package org.owasp.webgoat.cia;
import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.lessons.Lesson;
import org.springframework.stereotype.Component;
/**
* @author BenediktStuhrmann
* @since 11/2/18.
*/
@Component
public class CIA extends Lesson {
@Override
public Category getDefaultCategory() {
return Category.GENERAL;
}
@Override
public String getTitle() {
return "cia.title";
}
@Override
public String getId() {
return "CIA";
}
}

View File

@ -1,13 +1,10 @@
package org.owasp.webgoat.plugin; package org.owasp.webgoat.cia;
import org.owasp.webgoat.assignments.AssignmentEndpoint; import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentPath; import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.assignments.AttackResult; import org.owasp.webgoat.assignments.AttackResult;
import org.owasp.webgoat.session.DatabaseUtilities; import org.owasp.webgoat.session.DatabaseUtilities;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.io.IOException; import java.io.IOException;
import java.sql.Connection; import java.sql.Connection;
@ -15,20 +12,20 @@ import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
@AssignmentPath("/cia/quiz") @RestController
public class CIAQuiz extends AssignmentEndpoint { public class CIAQuiz extends AssignmentEndpoint {
String[] solutions = {"Solution 3", "Solution 1", "Solution 4", "Solution 2"}; String[] solutions = {"Solution 3", "Solution 1", "Solution 4", "Solution 2"};
boolean[] guesses = new boolean[solutions.length]; boolean[] guesses = new boolean[solutions.length];
@RequestMapping(method = RequestMethod.POST) @PostMapping("/cia/quiz")
@ResponseBody @ResponseBody
public AttackResult completed(@RequestParam String[] question_0_solution, @RequestParam String[] question_1_solution, @RequestParam String[] question_2_solution, @RequestParam String[] question_3_solution) throws IOException { public AttackResult completed(@RequestParam String[] question_0_solution, @RequestParam String[] question_1_solution, @RequestParam String[] question_2_solution, @RequestParam String[] question_3_solution) {
int correctAnswers = 0; int correctAnswers = 0;
String[] givenAnswers = {question_0_solution[0], question_1_solution[0], question_2_solution[0], question_3_solution[0]}; String[] givenAnswers = {question_0_solution[0], question_1_solution[0], question_2_solution[0], question_3_solution[0]};
for(int i = 0; i < solutions.length; i++) { for (int i = 0; i < solutions.length; i++) {
if (givenAnswers[i].contains(solutions[i])) { if (givenAnswers[i].contains(solutions[i])) {
// answer correct // answer correct
correctAnswers++; correctAnswers++;
@ -39,14 +36,14 @@ public class CIAQuiz extends AssignmentEndpoint {
} }
} }
if(correctAnswers == solutions.length) { if (correctAnswers == solutions.length) {
return trackProgress(success().build()); return trackProgress(success().build());
} else { } else {
return trackProgress(failed().build()); return trackProgress(failed().build());
} }
} }
@RequestMapping(method = RequestMethod.GET) @GetMapping("/cia/quiz")
@ResponseBody @ResponseBody
public boolean[] getResults() { public boolean[] getResults() {
return this.guesses; return this.guesses;

View File

@ -1,39 +0,0 @@
package org.owasp.webgoat.plugin;
import com.beust.jcommander.internal.Lists;
import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.lessons.NewLesson;
import java.util.List;
/**
* @author BenediktStuhrmann
* @since 11/2/18.
*/
public class CIA extends NewLesson {
@Override
public Category getDefaultCategory() {
return Category.GENERAL;
}
@Override
public List<String> getHints() {
return Lists.newArrayList();
}
@Override
public Integer getDefaultRanking() {
return 3;
}
@Override
public String getTitle() {
return "cia.title";
}
@Override
public String getId() {
return "CIA";
}
}

View File

@ -1,4 +1,4 @@
package org.owasp.webgoat.plugin; package org.owasp.webgoat.cia;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@ -24,13 +24,11 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
public class CIAQuizTest extends LessonTest { public class CIAQuizTest extends LessonTest {
@Autowired @Autowired
private WebgoatContext context; private CIA cia;
@Before @Before
public void setup() { public void setup() {
CIA cia = new CIA();
when(webSession.getCurrentLesson()).thenReturn(cia); when(webSession.getCurrentLesson()).thenReturn(cia);
when(webSession.getWebgoatContext()).thenReturn(context);
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build(); this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
} }

View File

@ -1,10 +1,8 @@
package org.owasp.webgoat.plugin; package org.owasp.webgoat.client_side_filtering;
import com.beust.jcommander.internal.Lists;
import org.owasp.webgoat.lessons.Category; import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.lessons.NewLesson; import org.owasp.webgoat.lessons.Lesson;
import org.springframework.stereotype.Component;
import java.util.List;
/** /**
* ************************************************************************************************ * ************************************************************************************************
@ -35,29 +33,21 @@ import java.util.List;
* @version $Id: $Id * @version $Id: $Id
* @since October 12, 2016 * @since October 12, 2016
*/ */
public class BypassRestrictions extends NewLesson { @Component
public class ClientSideFiltering extends Lesson {
@Override @Override
public Category getDefaultCategory() { public Category getDefaultCategory() {
return Category.CLIENT_SIDE; return Category.CLIENT_SIDE;
} }
@Override
public List<String> getHints() {
return Lists.newArrayList();
}
@Override
public Integer getDefaultRanking() {
return 2;
}
@Override @Override
public String getTitle() { public String getTitle() {
return "bypass-restrictions.title"; return "client.side.filtering.title";
} }
@Override @Override
public String getId() { public String getId() {
return "BypassRestrictions"; return "ClientSideFiltering";
} }
} }

View File

@ -1,53 +1,42 @@
package org.owasp.webgoat.plugin; /*
* 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.client_side_filtering;
import org.owasp.webgoat.assignments.AssignmentEndpoint; import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentHints; import org.owasp.webgoat.assignments.AssignmentHints;
import org.owasp.webgoat.assignments.AssignmentPath; import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.assignments.AttackResult; import org.owasp.webgoat.assignments.AttackResult;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.io.IOException; import java.io.IOException;
/** @RestController
* ************************************************************************************************
* 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 WebGoat
* @version $Id: $Id
* @since August 11, 2016
*/
@AssignmentPath("/clientSideFiltering/attack1")
@AssignmentHints({"ClientSideFilteringHint1", "ClientSideFilteringHint2", "ClientSideFilteringHint3", "ClientSideFilteringHint4"}) @AssignmentHints({"ClientSideFilteringHint1", "ClientSideFilteringHint2", "ClientSideFilteringHint3", "ClientSideFilteringHint4"})
public class ClientSideFilteringAssignment extends AssignmentEndpoint { public class ClientSideFilteringAssignment extends AssignmentEndpoint {
@RequestMapping(method = RequestMethod.POST) @PostMapping("/clientSideFiltering/attack1")
public
@ResponseBody @ResponseBody
AttackResult completed(@RequestParam String answer) throws IOException { public AttackResult completed(@RequestParam String answer) {
return trackProgress("450000".equals(answer) ? return trackProgress("450000".equals(answer) ?
success().feedback("assignment.solved").build() : success().feedback("assignment.solved").build() :
failed().feedback("ClientSideFiltering.incorrect").build()); failed().feedback("ClientSideFiltering.incorrect").build());

View File

@ -0,0 +1,51 @@
/*
* 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.client_side_filtering;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentHints;
import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.assignments.AttackResult;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
/**
* @author nbaars
* @since 4/6/17.
*/
@RestController
@AssignmentHints({"client.side.filtering.free.hint1", "client.side.filtering.free.hint2", "client.side.filtering.free.hint3"})
public class ClientSideFilteringFreeAssignment extends AssignmentEndpoint {
public static final String SUPER_COUPON_CODE = "get_it_for_free";
@PostMapping("/clientSideFiltering/getItForFree")
@ResponseBody
public AttackResult completed(@RequestParam String checkoutCode) {
if (SUPER_COUPON_CODE.equals(checkoutCode)) {
return trackProgress(success().build());
}
return trackProgress(failed().build());
}
}

Some files were not shown because too many files have changed in this diff Show More