diff --git a/pom.xml b/pom.xml index 7036fabab..9023349dc 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ org.springframework.boot spring-boot-starter-parent - 1.5.21.RELEASE + 2.1.8.RELEASE diff --git a/webgoat-container/pom.xml b/webgoat-container/pom.xml index cf324686b..3067eca8b 100644 --- a/webgoat-container/pom.xml +++ b/webgoat-container/pom.xml @@ -121,8 +121,7 @@ org.thymeleaf.extras - thymeleaf-extras-springsecurity4 - 2.1.2.RELEASE + thymeleaf-extras-springsecurity5 org.hsqldb diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/AsciiDoctorTemplateResolver.java b/webgoat-container/src/main/java/org/owasp/webgoat/AsciiDoctorTemplateResolver.java index e5a4c7da9..8fcaf5635 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/AsciiDoctorTemplateResolver.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/AsciiDoctorTemplateResolver.java @@ -39,12 +39,15 @@ import org.owasp.webgoat.asciidoc.WebGoatVersionMacro; import org.owasp.webgoat.asciidoc.WebWolfMacro; import org.owasp.webgoat.asciidoc.WebWolfRootMacro; import org.owasp.webgoat.i18n.Language; -import org.thymeleaf.TemplateProcessingParameters; -import org.thymeleaf.resourceresolver.IResourceResolver; -import org.thymeleaf.templateresolver.TemplateResolver; +import org.thymeleaf.IEngineConfiguration; +import org.thymeleaf.templateresolver.FileTemplateResolver; +import org.thymeleaf.templateresource.ITemplateResource; +import org.thymeleaf.templateresource.StringTemplateResource; -import java.io.*; -import java.nio.charset.StandardCharsets; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.StringWriter; import java.util.Map; import static org.asciidoctor.Asciidoctor.Factory.create; @@ -57,7 +60,7 @@ import static org.asciidoctor.Asciidoctor.Factory.create; * */ @Slf4j -public class AsciiDoctorTemplateResolver extends TemplateResolver { +public class AsciiDoctorTemplateResolver extends FileTemplateResolver { private static final Asciidoctor asciidoctor = create(); private static final String PREFIX = "doc:"; @@ -65,72 +68,56 @@ public class AsciiDoctorTemplateResolver extends TemplateResolver { public AsciiDoctorTemplateResolver(Language language) { this.language = language; - - setResourceResolver(new AdocResourceResolver()); setResolvablePatterns(Sets.newHashSet(PREFIX + "*")); } @Override - protected String computeResourceName(TemplateProcessingParameters params) { - String templateName = params.getTemplateName(); - return templateName.substring(PREFIX.length()); - } - - 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: - * plugin/HttpBasics/lessonPlans/en/HttpBasics_content1.adoc - */ - 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())); + protected ITemplateResource computeTemplateResource(IEngineConfiguration configuration, String ownerTemplate, String template, String resourceName, String characterEncoding, Map templateResolutionAttributes) { + var templateName = resourceName.substring(PREFIX.length()); + try (InputStream is = readInputStreamOrFallbackToEnglish(templateName, language)) { 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; - } - - private Map createAttributes() { - Map attributes = Maps.newHashMap(); - attributes.put("source-highlighter", "coderay"); - attributes.put("backend", "xhtml"); - - Map options = Maps.newHashMap(); - options.put("attributes", attributes); - - return options; - } - - @Override - public String getName() { - return "adocResourceResolver"; + } catch (IOException e) { + //no html yet + return new StringTemplateResource(""); } } + /** + * The resource name is for example HttpBasics_content1.adoc. This is always located in the following directory: + * plugin/HttpBasics/lessonPlans/en/HttpBasics_content1.adoc + */ + 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 createAttributes() { + Map attributes = Maps.newHashMap(); + attributes.put("source-highlighter", "coderay"); + attributes.put("backend", "xhtml"); + + Map options = Maps.newHashMap(); + options.put("attributes", attributes); + + return options; + } } diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/LessonTemplateResolver.java b/webgoat-container/src/main/java/org/owasp/webgoat/LessonTemplateResolver.java index 14e983a81..c035c58a3 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/LessonTemplateResolver.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/LessonTemplateResolver.java @@ -1,47 +1,46 @@ /** - ************************************************************************************************* - * - * + * ************************************************************************************************ + *

+ *

* 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 WebGoat - * @since October 28, 2003 * @version $Id: $Id + * @since October 28, 2003 */ package org.owasp.webgoat; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.google.common.io.ByteStreams; -import lombok.SneakyThrows; import org.springframework.core.io.ResourceLoader; -import org.thymeleaf.TemplateProcessingParameters; -import org.thymeleaf.resourceresolver.IResourceResolver; -import org.thymeleaf.templateresolver.TemplateResolver; +import org.thymeleaf.IEngineConfiguration; +import org.thymeleaf.templateresolver.FileTemplateResolver; +import org.thymeleaf.templateresource.ITemplateResource; +import org.thymeleaf.templateresource.StringTemplateResource; -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.InputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; 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 */ -public class LessonTemplateResolver extends TemplateResolver { +public class LessonTemplateResolver extends FileTemplateResolver { private final static String PREFIX = "lesson:"; - private final File pluginTargetDirectory; private ResourceLoader resourceLoader; private Map resources = Maps.newHashMap(); - public LessonTemplateResolver(File pluginTargetDirectory, ResourceLoader resourceLoader) { - this.pluginTargetDirectory = pluginTargetDirectory; + public LessonTemplateResolver(ResourceLoader resourceLoader) { this.resourceLoader = resourceLoader; - setResourceResolver(new LessonResourceResolver()); setResolvablePatterns(Sets.newHashSet(PREFIX + "*")); } @Override - protected String computeResourceName(TemplateProcessingParameters params) { - String templateName = params.getTemplateName(); - return templateName.substring(PREFIX.length()); - } - - private class LessonResourceResolver implements IResourceResolver { - - @Override - @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); + protected ITemplateResource computeTemplateResource(IEngineConfiguration configuration, String ownerTemplate, String template, String resourceName, String characterEncoding, Map templateResolutionAttributes) { + var templateName = resourceName.substring(PREFIX.length());; + byte[] resource = resources.get(templateName); + if (resource == null) { + try { + resource = ByteStreams.toByteArray(resourceLoader.getResource("classpath:/html/" + templateName + ".html").getInputStream()); + } catch (IOException e) { + e.printStackTrace(); } - return new ByteArrayInputStream(resource); - } - - @Override - public String getName() { - return "lessonResourceResolver"; + resources.put(resourceName, resource); } + return new StringTemplateResource(new String(resource, StandardCharsets.UTF_8)); } -} +} \ No newline at end of file diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/MvcConfiguration.java b/webgoat-container/src/main/java/org/owasp/webgoat/MvcConfiguration.java index e26aa0b5e..0e2aac9f6 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/MvcConfiguration.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/MvcConfiguration.java @@ -30,41 +30,38 @@ */ package org.owasp.webgoat; -import com.google.common.collect.Sets; import org.owasp.webgoat.i18n.Language; import org.owasp.webgoat.i18n.Messages; import org.owasp.webgoat.i18n.PluginMessages; 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.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ResourceLoader; 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.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.thymeleaf.extras.springsecurity4.dialect.SpringSecurityDialect; -import org.thymeleaf.spring4.SpringTemplateEngine; -import org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver; -import org.thymeleaf.templateresolver.TemplateResolver; +import org.thymeleaf.TemplateEngine; +import org.thymeleaf.extras.springsecurity5.dialect.SpringSecurityDialect; +import org.thymeleaf.spring5.SpringTemplateEngine; +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 -public class MvcConfiguration extends WebMvcConfigurerAdapter { +public class MvcConfiguration implements WebMvcConfigurer { private static final String UTF8 = "UTF-8"; - @Autowired - @Qualifier("pluginTargetDirectory") - private File pluginTargetDirectory; - @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/login").setViewName("login"); @@ -74,13 +71,21 @@ public class MvcConfiguration extends WebMvcConfigurerAdapter { //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 - public TemplateResolver springThymeleafTemplateResolver(ApplicationContext applicationContext) { + public ITemplateResolver springThymeleafTemplateResolver(ApplicationContext applicationContext) { SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver(); resolver.setPrefix("classpath:/templates/"); resolver.setSuffix(".html"); - resolver.setOrder(1); + resolver.setTemplateMode(TemplateMode.HTML); + resolver.setOrder(2); resolver.setCacheable(false); resolver.setCharacterEncoding(UTF8); resolver.setApplicationContext(applicationContext); @@ -89,8 +94,8 @@ public class MvcConfiguration extends WebMvcConfigurerAdapter { @Bean public LessonTemplateResolver lessonTemplateResolver(ResourceLoader resourceLoader) { - LessonTemplateResolver resolver = new LessonTemplateResolver(pluginTargetDirectory, resourceLoader); - resolver.setOrder(2); + LessonTemplateResolver resolver = new LessonTemplateResolver(resourceLoader); + resolver.setOrder(0); resolver.setCacheable(false); resolver.setCharacterEncoding(UTF8); return resolver; @@ -100,19 +105,20 @@ public class MvcConfiguration extends WebMvcConfigurerAdapter { public AsciiDoctorTemplateResolver asciiDoctorTemplateResolver(Language language) { AsciiDoctorTemplateResolver resolver = new AsciiDoctorTemplateResolver(language); resolver.setCacheable(false); - resolver.setOrder(3); + resolver.setOrder(1); resolver.setCharacterEncoding(UTF8); return resolver; } @Bean - public SpringTemplateEngine thymeleafTemplateEngine(TemplateResolver springThymeleafTemplateResolver, + public SpringTemplateEngine thymeleafTemplateEngine(ITemplateResolver springThymeleafTemplateResolver, LessonTemplateResolver lessonTemplateResolver, AsciiDoctorTemplateResolver asciiDoctorTemplateResolver) { SpringTemplateEngine engine = new SpringTemplateEngine(); + engine.setEnableSpringELCompiler(true); engine.addDialect(new SpringSecurityDialect()); engine.setTemplateResolvers( - Sets.newHashSet(springThymeleafTemplateResolver, lessonTemplateResolver, asciiDoctorTemplateResolver)); + Set.of(lessonTemplateResolver, asciiDoctorTemplateResolver, springThymeleafTemplateResolver)); return engine; } @@ -123,12 +129,10 @@ public class MvcConfiguration extends WebMvcConfigurerAdapter { */ @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { - registry.addResourceHandler("/plugin_lessons/**").addResourceLocations("file:///" + pluginTargetDirectory.toString() + "/"); registry.addResourceHandler("/images/**").addResourceLocations("classpath:/images/"); registry.addResourceHandler("/lesson_js/**").addResourceLocations("classpath:/js/"); registry.addResourceHandler("/lesson_css/**").addResourceLocations("classpath:/css/"); registry.addResourceHandler("/video/**").addResourceLocations("classpath:/video/"); - super.addResourceHandlers(registry); } @Bean diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/WebGoat.java b/webgoat-container/src/main/java/org/owasp/webgoat/WebGoat.java index 21838d192..dc0f8bb69 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/WebGoat.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/WebGoat.java @@ -30,15 +30,11 @@ */ 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.WebSession; import org.owasp.webgoat.session.WebgoatContext; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.ScopedProxyMode; @@ -66,16 +62,6 @@ public class WebGoat { 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 public RestTemplate restTemplate() { return new RestTemplate(); diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/WebSecurityConfig.java b/webgoat-container/src/main/java/org/owasp/webgoat/WebSecurityConfig.java index b8b526af8..07ea29f1e 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/WebSecurityConfig.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/WebSecurityConfig.java @@ -35,6 +35,7 @@ import org.owasp.webgoat.users.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; 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.web.builders.HttpSecurity; 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.configurers.ExpressionUrlAuthorizationConfigurer; import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.password.NoOpPasswordEncoder; /** * Security configuration for WebGoat. @@ -90,4 +92,16 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { public UserDetailsService userDetailsServiceBean() throws Exception { return userDetailsService; } + + @Override + @Bean + protected AuthenticationManager authenticationManager() throws Exception { + return super.authenticationManager(); + } + + @SuppressWarnings("deprecation") + @Bean + public NoOpPasswordEncoder passwordEncoder() { + return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance(); + } } \ No newline at end of file diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/assignments/AssignmentEndpoint.java b/webgoat-container/src/main/java/org/owasp/webgoat/assignments/AssignmentEndpoint.java index 3b02b6129..b316f40ee 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/assignments/AssignmentEndpoint.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/assignments/AssignmentEndpoint.java @@ -41,7 +41,8 @@ import org.springframework.beans.factory.annotation.Autowired; *

* Note: each subclass should declare this annotation otherwise the WebGoat framework cannot find your endpoint. */ -public abstract class AssignmentEndpoint extends Endpoint { +//TODO: rename to assignment +public abstract class AssignmentEndpoint { @Autowired private UserTrackerRepository userTrackerRepository; @@ -76,11 +77,6 @@ public abstract class AssignmentEndpoint extends Endpoint { return userSessionData; } - @Override - public final String getPath() { - return this.getClass().getAnnotationsByType(AssignmentPath.class)[0].value(); - } - /** * Convenience method for create a successful result: * diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/assignments/AssignmentPath.java b/webgoat-container/src/main/java/org/owasp/webgoat/assignments/AssignmentPath.java index 9147a1820..25336aa44 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/assignments/AssignmentPath.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/assignments/AssignmentPath.java @@ -1,5 +1,9 @@ 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.Retention; import java.lang.annotation.RetentionPolicy; @@ -10,7 +14,15 @@ import java.lang.annotation.Target; */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) +//@RequestMapping public @interface AssignmentPath { - String value(); + // @AliasFor(annotation = RequestMapping.class) + String[] path() default {}; + + // @AliasFor(annotation = RequestMapping.class) + RequestMethod[] method() default {}; + + // @AliasFor("path") + String value() default ""; } diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/assignments/Endpoint.java b/webgoat-container/src/main/java/org/owasp/webgoat/assignments/Endpoint.java deleted file mode 100644 index 746ac412d..000000000 --- a/webgoat-container/src/main/java/org/owasp/webgoat/assignments/Endpoint.java +++ /dev/null @@ -1,41 +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 - 2017 Bruce Mayhew - *

- * This program is free software; you can redistribute it and/or modify it under the terms of the - * GNU General Public License as published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - *

- * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - *

- * You should have received a copy of the GNU General Public License along with this program; if - * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - *

- * Getting Source ============== - *

- * Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software - * projects. - *

- */ - -package org.owasp.webgoat.assignments; - -import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint; - -public abstract class Endpoint implements MvcEndpoint { - - @Override - public final boolean isSensitive() { - return false; - } - - @Override - public final Class getEndpointType() { - return null; - } -} diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/lessons/Assignment.java b/webgoat-container/src/main/java/org/owasp/webgoat/lessons/Assignment.java index d9b1f3470..7587436a9 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/lessons/Assignment.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/lessons/Assignment.java @@ -52,8 +52,8 @@ public class Assignment { //Hibernate } - public Assignment(String name, String path) { - this(name, path, Lists.newArrayList()); + public Assignment(String name) { + this(name, name, Lists.newArrayList()); } public Assignment(String name, String path, List hints) { diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/plugins/PluginEndpointPublisher.java b/webgoat-container/src/main/java/org/owasp/webgoat/plugins/PluginEndpointPublisher.java deleted file mode 100644 index d3a2a333e..000000000 --- a/webgoat-container/src/main/java/org/owasp/webgoat/plugins/PluginEndpointPublisher.java +++ /dev/null @@ -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/ - *

- * 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 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> endpoints) { - endpoints.forEach(e -> publishEndpoint(e)); - } - - private void publishEndpoint(Class 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..."); - } - } -} diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/plugins/PluginResource.java b/webgoat-container/src/main/java/org/owasp/webgoat/plugins/PluginResource.java index 172b7b965..1acdd6097 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/plugins/PluginResource.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/plugins/PluginResource.java @@ -3,19 +3,12 @@ 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 { @@ -27,13 +20,6 @@ public class PluginResource { return classes.stream().filter(c -> c.getSuperclass() == NewLesson.class).collect(Collectors.toList()); } - public List> getEndpoints() { - return classes.stream(). - filter(c -> c.getSuperclass() == AssignmentEndpoint.class || c.getSuperclass() == Endpoint.class). - map(c -> (Class) c). - collect(Collectors.toList()); - } - public List> getAssignments(Class lesson) { return classes.stream(). filter(c -> c.getSuperclass() == AssignmentEndpoint.class). diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/plugins/PluginsLoader.java b/webgoat-container/src/main/java/org/owasp/webgoat/plugins/PluginsLoader.java index 28437e786..4820453e6 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/plugins/PluginsLoader.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/plugins/PluginsLoader.java @@ -8,14 +8,22 @@ 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.assignments.AttackResult; 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.Bean; import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; +import org.springframework.context.annotation.Configuration; import org.springframework.core.type.filter.RegexPatternTypeFilter; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; import java.net.URL; import java.util.List; import java.util.Map; @@ -56,13 +64,12 @@ import static java.util.stream.Collectors.toList; */ @AllArgsConstructor @Slf4j +@Configuration public class PluginsLoader { - - private final PluginEndpointPublisher pluginEndpointPublisher; - /** *

createLessonsFromPlugins.

*/ + @Bean public Course loadPlugins() { List lessons = Lists.newArrayList(); for (PluginResource plugin : findPluginResources()) { @@ -70,7 +77,7 @@ public class PluginsLoader { plugin.getLessons().forEach(c -> { NewLesson lesson = null; try { - lesson = (NewLesson) c.newInstance(); + lesson = (NewLesson) c.getConstructor().newInstance(); log.trace("Lesson loaded: {}", lesson.getId()); } catch (Exception e) { log.error("Error while loading:" + c, e); @@ -78,7 +85,6 @@ public class PluginsLoader { List> assignments = plugin.getAssignments(c); lesson.setAssignments(createAssignment(assignments)); lessons.add(lesson); - pluginEndpointPublisher.publish(plugin.getEndpoints()); }); } catch (Exception e) { log.error("Error in loadLessons: ", e); @@ -97,7 +103,29 @@ public class PluginsLoader { } private String getPath(Class e) { - return e.getAnnotationsByType(AssignmentPath.class)[0].value(); + for (Method m : e.getMethods()) { + if (m.getReturnType() == AttackResult.class) { + var mapping = m.getAnnotation(RequestMapping.class); + if (mapping == null) { + log.error("AttackResult method found without mapping in: {}", e.getSimpleName()); + } else { + return getMapping(m); + } + } + } + return ""; + } + + private String getMapping(Method m) { + String[] path = null; + if (m.getAnnotation(RequestMapping.class) != null) { + path = m.getAnnotation(RequestMapping.class).path(); + } else if (m.getAnnotation(PostMapping.class) != null) { + path = m.getAnnotation(PostMapping.class).path(); + } else if (m.getAnnotation(GetMapping.class) != null) { + path = m.getAnnotation(GetMapping.class).value(); + } + return path != null && path.length > 0 ? path[0] : ""; } private List getHints(Class e) { @@ -107,8 +135,6 @@ public class PluginsLoader { return Lists.newArrayList(); } - - @SneakyThrows public List findPluginResources() { final ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false); diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonProgressService.java b/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonProgressService.java index 76e6187a5..cba3a1017 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonProgressService.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonProgressService.java @@ -76,7 +76,7 @@ public class LessonProgressService { } private List toJson(Map map) { - ArrayList result = Lists.newArrayList(); + List result = new ArrayList(); for (Map.Entry entry : map.entrySet()) { result.add(new LessonOverview(entry.getKey(), entry.getValue())); } diff --git a/webgoat-container/src/main/resources/application-webgoat.properties b/webgoat-container/src/main/resources/application-webgoat.properties index 2346f3f30..ad5f3cbbb 100644 --- a/webgoat-container/src/main/resources/application-webgoat.properties +++ b/webgoat-container/src/main/resources/application-webgoat.properties @@ -1,7 +1,7 @@ server.error.include-stacktrace=always server.error.path=/error.html server.session.timeout=600 -server.contextPath=/WebGoat +server.servlet.context-path=/WebGoat server.port=${WEBGOAT_PORT:8080} server.address=${WEBGOAT_HOST:127.0.0.1} @@ -17,6 +17,11 @@ spring.jpa.hibernate.ddl-auto=update spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.HSQLDialect 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.boot.devtools=INFO logging.level.org.owasp=DEBUG @@ -25,7 +30,6 @@ logging.level.org.owasp.webgoat=TRACE # Needed for creating a vulnerable web application security.enable-csrf=false -spring.resources.cache-period=0 spring.thymeleaf.cache=false webgoat.start.hsqldb=true diff --git a/webgoat-container/src/main/resources/templates/main_new.html b/webgoat-container/src/main/resources/templates/main_new.html index eadb722c3..edde993ab 100644 --- a/webgoat-container/src/main/resources/templates/main_new.html +++ b/webgoat-container/src/main/resources/templates/main_new.html @@ -28,15 +28,15 @@ - - WebGoat @@ -67,8 +67,7 @@
  • Logout
  • -