resolving conflicts merge

This commit is contained in:
Jason White 2017-02-16 09:08:19 -05:00
commit d8cc2de080
55 changed files with 16089 additions and 47 deletions

View File

@ -21,7 +21,7 @@ exercises are intended to be used by people to learn about application security
penetration testing techniques. penetration testing techniques.
**WARNING 1:** *While running this program your machine will be extremely **WARNING 1:** *While running this program your machine will be extremely
vulnerable to attack. You should to disconnect from the Internet while using vulnerable to attack. You should disconnect from the Internet while using
this program.* WebGoat's default configuration binds to localhost to minimize this program.* WebGoat's default configuration binds to localhost to minimize
the exposure. the exposure.

View File

@ -166,6 +166,18 @@
</filesets> </filesets>
</configuration> </configuration>
</plugin> </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins> </plugins>
</build> </build>
@ -248,6 +260,12 @@
<version>0.4.10</version> <version>0.4.10</version>
</dependency> </dependency>
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.6</version>
</dependency>
<!-- ************* END spring MVC and related dependencies ************** --> <!-- ************* END spring MVC and related dependencies ************** -->
<!-- ************* START: Dependencies for Unit and Integration Testing ************** --> <!-- ************* START: Dependencies for Unit and Integration Testing ************** -->
<dependency> <dependency>

View File

@ -32,6 +32,7 @@ package org.owasp.webgoat;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import org.owasp.webgoat.i18n.Messages; import org.owasp.webgoat.i18n.Messages;
import org.owasp.webgoat.i18n.PluginMessages;
import org.owasp.webgoat.session.Course; import org.owasp.webgoat.session.Course;
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.Autowired;
@ -117,8 +118,13 @@ public class MvcConfiguration extends WebMvcConfigurerAdapter {
} }
@Bean @Bean
public Messages messageSource() { public PluginMessages pluginMessages(Messages messages) {
Messages messages = new Messages(localeResolver()); return new PluginMessages(messages);
}
@Bean
public Messages messageSource(LocaleResolver localeResolver) {
Messages messages = new Messages(localeResolver);
messages.setBasename("classpath:/i18n/messages"); messages.setBasename("classpath:/i18n/messages");
return messages; return messages;
} }

View File

@ -34,6 +34,7 @@ import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.Context; import org.apache.catalina.Context;
import org.owasp.webgoat.i18n.PluginMessages;
import org.owasp.webgoat.plugins.PluginClassLoader; import org.owasp.webgoat.plugins.PluginClassLoader;
import org.owasp.webgoat.plugins.PluginEndpointPublisher; import org.owasp.webgoat.plugins.PluginEndpointPublisher;
import org.owasp.webgoat.plugins.PluginsExtractor; import org.owasp.webgoat.plugins.PluginsExtractor;
@ -91,8 +92,8 @@ public class WebGoat extends SpringBootServletInitializer {
} }
@Bean @Bean
public PluginsExtractor pluginsLoader(@Qualifier("pluginTargetDirectory") File pluginTargetDirectory, PluginClassLoader classLoader) { public PluginsExtractor pluginsLoader(@Qualifier("pluginTargetDirectory") File pluginTargetDirectory, PluginClassLoader classLoader, PluginMessages messages) {
return new PluginsExtractor(pluginTargetDirectory, classLoader); return new PluginsExtractor(pluginTargetDirectory, classLoader, messages);
} }
@Bean @Bean

View File

@ -25,7 +25,7 @@
package org.owasp.webgoat.assignments; package org.owasp.webgoat.assignments;
import lombok.Getter; import lombok.Getter;
import org.owasp.webgoat.i18n.Messages; import org.owasp.webgoat.i18n.PluginMessages;
import org.owasp.webgoat.session.UserSessionData; import org.owasp.webgoat.session.UserSessionData;
import org.owasp.webgoat.session.UserTracker; import org.owasp.webgoat.session.UserTracker;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
@ -50,7 +50,7 @@ public abstract class AssignmentEndpoint extends Endpoint {
private UserSessionData userSessionData; private UserSessionData userSessionData;
@Getter @Getter
@Autowired @Autowired
private Messages messages; private PluginMessages messages;
//// TODO: 11/13/2016 events better fit? //// TODO: 11/13/2016 events better fit?
protected AttackResult trackProgress(AttackResult attackResult) { protected AttackResult trackProgress(AttackResult attackResult) {

View File

@ -27,7 +27,7 @@ package org.owasp.webgoat.assignments;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import org.owasp.webgoat.i18n.Messages; import org.owasp.webgoat.i18n.PluginMessages;
@AllArgsConstructor @AllArgsConstructor
public class AttackResult { public class AttackResult {
@ -35,13 +35,13 @@ public class AttackResult {
public static class AttackResultBuilder { public static class AttackResultBuilder {
private boolean lessonCompleted; private boolean lessonCompleted;
private Messages messages; private PluginMessages messages;
private Object[] feedbackArgs; private Object[] feedbackArgs;
private String feedbackResourceBundleKey; private String feedbackResourceBundleKey;
private String output; private String output;
private Object[] outputArgs; private Object[] outputArgs;
public AttackResultBuilder(Messages messages) { public AttackResultBuilder(PluginMessages messages) {
this.messages = messages; this.messages = messages;
} }
@ -84,7 +84,7 @@ public class AttackResult {
private String output; private String output;
public static AttackResultBuilder builder(Messages messages) { public static AttackResultBuilder builder(PluginMessages messages) {
return new AttackResultBuilder(messages); return new AttackResultBuilder(messages);
} }

View File

@ -46,6 +46,7 @@ public class Messages extends ReloadableResourceBundleMessageSource {
/** /**
* Gets all messages for presented Locale. * Gets all messages for presented Locale.
*
* @return all messages * @return all messages
*/ */
public Properties getMessages() { public Properties getMessages() {
@ -60,8 +61,10 @@ public class Messages extends ReloadableResourceBundleMessageSource {
return super.getMessage(code, args, defaultValue, resolveLocale()); return super.getMessage(code, args, defaultValue, resolveLocale());
} }
private Locale resolveLocale() { protected Locale resolveLocale() {
return localeResolver.resolveLocale(((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest()); return localeResolver.resolveLocale(((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest());
} }
} }

View File

@ -0,0 +1,80 @@
/*
* 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 - 2017 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>
*/
package org.owasp.webgoat.i18n;
import lombok.SneakyThrows;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.UrlResource;
import java.io.File;
import java.util.Properties;
/**
* Message resource bundle for plugins. The files is created after startup during the init of the plugins so we
* need to load this file through a ResourceLoader instead of location on the classpath.
*
* @author nbaars
* @date 2/4/17
*/
public class PluginMessages extends ReloadableResourceBundleMessageSource {
private Messages messages;
public PluginMessages(Messages messages) {
this.messages = messages;
this.setParentMessageSource(messages);
}
public Properties getMessages() {
return getMergedProperties(messages.resolveLocale()).getProperties();
}
public String getMessage(String code, Object... args) {
return getMessage(code, args, messages.resolveLocale());
}
public String getMessage(String code, String defaultValue, Object... args) {
return super.getMessage(code, args, defaultValue, messages.resolveLocale());
}
public void addPluginMessageBundles(final File i18nPluginDirectory) {
this.setBasename("WebGoatLabels");
this.setResourceLoader(new ResourceLoader() {
@Override
@SneakyThrows
public Resource getResource(String location) {
return new UrlResource(new File(i18nPluginDirectory, location).toURI());
}
@Override
public ClassLoader getClassLoader() {
return Thread.currentThread().getContextClassLoader();
}
});
}
}

View File

@ -55,6 +55,7 @@ public enum Category {
PARAMETER_TAMPERING("Parameter Tampering", new Integer(1700)), PARAMETER_TAMPERING("Parameter Tampering", new Integer(1700)),
SESSION_MANAGEMENT("Session Management Flaws", new Integer(1800)), SESSION_MANAGEMENT("Session Management Flaws", new Integer(1800)),
WEB_SERVICES("Web Services", new Integer(1900)), WEB_SERVICES("Web Services", new Integer(1900)),
VULNERABLE_COMPONENTS("Vulnerable Components - A9", new Integer(1950)),
ADMIN_FUNCTIONS("Admin Functions", new Integer(2000)), ADMIN_FUNCTIONS("Admin Functions", new Integer(2000)),
CHALLENGE("Challenge", new Integer(3000)); CHALLENGE("Challenge", new Integer(3000));

View File

@ -24,49 +24,49 @@
*/ */
package org.owasp.webgoat.plugins; package org.owasp.webgoat.plugins;
import com.google.common.primitives.Bytes;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.nio.file.Files; import java.io.InputStream;
import java.nio.file.Path;
import java.util.Properties; import java.util.Properties;
import java.util.stream.Stream; import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import static com.google.common.io.Files.createParentDirs;
/** /**
* Merges the main message.properties with the plugins WebGoatLabels * Merges the main message.properties with the plugins WebGoatLabels
*/ */
public class MessagePropertiesMerger { public class MessagePropertyMerger {
private final File targetDirectory; private final File targetDirectory;
public MessagePropertiesMerger(File targetDirectory) { public MessagePropertyMerger(File targetDirectory) {
this.targetDirectory = targetDirectory; this.targetDirectory = targetDirectory;
} }
@SneakyThrows @SneakyThrows
public void mergeAllLanguage() { public void merge(ZipFile zipFile, ZipEntry zipEntry) {
try(Stream<Path> paths = Files.walk(new File(targetDirectory, "plugin/i18n/").toPath())) { Properties messageProperties = new Properties();
paths.filter(Files::isRegularFile).forEach(filePath -> merge(filePath)); try (InputStream zis = zipFile.getInputStream(zipEntry)) {
messageProperties.load(zis);
}
Properties messagesFromHome = new Properties();
File pluginMessageFiles = new File(targetDirectory, zipEntry.getName());
if (pluginMessageFiles.exists()) {
try (FileInputStream fis = new FileInputStream(pluginMessageFiles)) {
messagesFromHome.load(fis);
}
}
messageProperties.putAll(messagesFromHome);
createParentDirs(pluginMessageFiles);
try (FileOutputStream fos = new FileOutputStream(pluginMessageFiles)) {
messageProperties.store(fos, "Plugin message properties");
} }
} }
@SneakyThrows
public void merge(Path propertyFile) {
Properties messageProperties = new Properties();
String messagePropertyFileName = propertyFile.getFileName().toString().replace("WebGoatLabels", "messages");
messageProperties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("i18n/" + messagePropertyFileName));
preparePropertyFile(propertyFile);
messageProperties.load(new FileInputStream(propertyFile.toFile()));
messageProperties.store(new FileOutputStream(new File(Thread.currentThread().getContextClassLoader().getResource("i18n/" + messagePropertyFileName).toURI())), "WebGoat message properties");
}
@SneakyThrows
private void preparePropertyFile(Path propertyFile) {
byte[] lines = Files.readAllBytes(propertyFile);
lines = Bytes.concat(lines, System.lineSeparator().getBytes());
Files.write(propertyFile, lines);
}
} }

View File

@ -71,6 +71,9 @@ public class PluginExtractor {
throws IOException { throws IOException {
if (zipEntry.getName().endsWith(".properties")) { if (zipEntry.getName().endsWith(".properties")) {
final File targetFile = new File(targetDirectory, zipEntry.getName()); final File targetFile = new File(targetDirectory, zipEntry.getName());
if ("WebGoatLabels.properties".equals(targetFile.getName())) {
new MessagePropertyMerger(targetDirectory).merge(zipFile, zipEntry);
}
copyFile(zipFile, zipEntry, targetFile, true); copyFile(zipFile, zipEntry, targetFile, true);
return true; return true;
} }
@ -99,6 +102,7 @@ public class PluginExtractor {
return targetFile; return targetFile;
} }
/** /**
* <p>Getter for the field <code>classes</code>.</p> * <p>Getter for the field <code>classes</code>.</p>
* *

View File

@ -3,6 +3,7 @@ package org.owasp.webgoat.plugins;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import org.owasp.webgoat.i18n.PluginMessages;
import org.springframework.util.ResourceUtils; import org.springframework.util.ResourceUtils;
import java.io.*; import java.io.*;
@ -28,10 +29,12 @@ public class PluginsExtractor {
private static final int BUFFER_SIZE = 32 * 1024; private static final int BUFFER_SIZE = 32 * 1024;
private final File pluginTargetDirectory; private final File pluginTargetDirectory;
private final PluginClassLoader classLoader; private final PluginClassLoader classLoader;
private final PluginMessages messages;
public PluginsExtractor(File pluginTargetDirectory, PluginClassLoader pluginClassLoader) { public PluginsExtractor(File pluginTargetDirectory, PluginClassLoader pluginClassLoader, PluginMessages messages) {
this.classLoader = pluginClassLoader; this.classLoader = pluginClassLoader;
this.pluginTargetDirectory = pluginTargetDirectory; this.pluginTargetDirectory = pluginTargetDirectory;
this.messages = messages;
} }
/** /**
@ -137,7 +140,7 @@ public class PluginsExtractor {
plugin.getOriginationJar()); plugin.getOriginationJar());
} }
} }
new MessagePropertiesMerger(pluginTargetDirectory).mergeAllLanguage(); messages.addPluginMessageBundles(new File(pluginTargetDirectory, "plugin/i18n"));
return plugins; return plugins;
} finally { } finally {
executorService.shutdown(); executorService.shutdown();

View File

@ -31,6 +31,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.i18n.Messages; import org.owasp.webgoat.i18n.Messages;
import org.owasp.webgoat.i18n.PluginMessages;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
@ -60,6 +61,7 @@ public class LabelService {
public static final String URL_LABELS_MVC = "/service/labels.mvc"; public static final String URL_LABELS_MVC = "/service/labels.mvc";
private LocaleResolver localeResolver; private LocaleResolver localeResolver;
private Messages messages; private Messages messages;
private PluginMessages pluginMessages;
/** /**
* We use Springs session locale resolver which also gives us the option to change the local later on. For * We use Springs session locale resolver which also gives us the option to change the local later on. For
@ -82,6 +84,9 @@ public class LabelService {
((SessionLocaleResolver)localeResolver).setDefaultLocale(locale); ((SessionLocaleResolver)localeResolver).setDefaultLocale(locale);
log.debug("Language provided: {} leads to Locale: {}", lang, locale); log.debug("Language provided: {} leads to Locale: {}", lang, locale);
} }
return new ResponseEntity<>(messages.getMessages(), HttpStatus.OK); Properties allProperties = new Properties();
allProperties.putAll(messages.getMessages());
allProperties.putAll(pluginMessages.getMessages());
return new ResponseEntity<>(allProperties, HttpStatus.OK);
} }
} }

View File

@ -1,5 +1,6 @@
define(['jquery', define(['jquery',
'libs/jquery-vuln', 'libs/jquery-vuln',
'jqueryui',
'underscore', 'underscore',
'backbone', 'backbone',
'goatApp/controller/LessonController', 'goatApp/controller/LessonController',
@ -10,6 +11,7 @@ define(['jquery',
'goatApp/view/TitleView' 'goatApp/view/TitleView'
], function ($, ], function ($,
$vuln, $vuln,
jqueryui,
_, _,
Backbone, Backbone,
LessonController, LessonController,

File diff suppressed because it is too large Load Diff

View File

@ -14,6 +14,7 @@ require.config({
baseUrl: "js/", baseUrl: "js/",
paths: { paths: {
jquery: 'libs/jquery-2.2.4.min', jquery: 'libs/jquery-2.2.4.min',
jqueryui: 'libs/jquery-ui-1.10.4',
underscore: 'libs/underscore-min', underscore: 'libs/underscore-min',
backbone: 'libs/backbone-min', backbone: 'libs/backbone-min',
text: 'libs/text', text: 'libs/text',
@ -27,6 +28,10 @@ require.config({
}, },
shim: { shim: {
"jqueryui": {
exports:"$",
deps: ['jquery']
},
underscore: { underscore: {
exports: "_" exports: "_"
}, },
@ -37,6 +42,6 @@ require.config({
} }
}); });
require(['jquery','libs/jquery-base','libs/jquery-vuln','underscore','backbone','goatApp/goatApp'], function($,jqueryBase,jqueryVuln,_,Backbone,Goat){ require(['jquery','libs/jquery-base','libs/jquery-vuln','jqueryui', 'underscore','backbone','goatApp/goatApp'], function($,jqueryBase,jqueryVuln,jqueryui,_,Backbone,Goat){
Goat.initApp(); Goat.initApp();
}); });

View File

@ -94,7 +94,7 @@
<!--<i class="fa fa-users"></i>--> <!--<i class="fa fa-users"></i>-->
<!--</button>--> <!--</button>-->
</div> </div>
<button type="button" id="about-button" class="btn btn-default right_nav_button" title="#{about}" <button type="button" id="about-button" class="btn btn-default right_nav_button" th:title="#{about}"
data-toggle="modal" data-target="#about-modal"> data-toggle="modal" data-target="#about-modal">
<i class="fa fa-info"></i> <i class="fa fa-info"></i>
</button> </button>

View File

@ -0,0 +1,74 @@
/*
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
* <p>
* Copyright (c) 2002 - 2017 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>
*/
package org.owasp.webgoat.assignments;
import org.mockito.Mock;
import org.owasp.webgoat.i18n.Messages;
import org.owasp.webgoat.i18n.PluginMessages;
import org.owasp.webgoat.session.UserSessionData;
import org.owasp.webgoat.session.UserTracker;
import org.owasp.webgoat.session.WebSession;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.web.servlet.LocaleResolver;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;
public class AssignmentEndpointTest {
@Mock
protected UserTracker userTracker;
@Mock
protected WebSession webSession;
@Mock
protected UserSessionData userSessionData;
protected Messages messages = new Messages(new LocaleResolver() {
@Override
public Locale resolveLocale(HttpServletRequest request) {
return Locale.ENGLISH;
}
@Override
public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {
}}){
@Override
protected Locale resolveLocale() {
return Locale.ENGLISH;
}
};
protected PluginMessages pluginMessages = new PluginMessages(messages);
public void init(AssignmentEndpoint a) {
messages.setBasenames("classpath:/i18n/messages", "classpath:/plugin/i18n/WebGoatLabels");
ReflectionTestUtils.setField(a, "userTracker", userTracker);
ReflectionTestUtils.setField(a, "userSessionData", userSessionData);
ReflectionTestUtils.setField(a, "webSession", webSession);
ReflectionTestUtils.setField(a, "messages", pluginMessages);
}
}

View File

@ -58,7 +58,7 @@ public class HttpBasicsLesson extends AssignmentEndpoint {
.feedbackArgs(new StringBuffer(person).reverse().toString()) .feedbackArgs(new StringBuffer(person).reverse().toString())
.build()); .build());
} else { } else {
return trackProgress(failed().feedback("http-basics.close").build()); return trackProgress(failed().feedback("http-basics.empty").build());
} }
} }
} }

View File

@ -10,5 +10,6 @@ http-basics.hints.http_basic_quiz.2=Try to intercept the request with <a href='h
http-basics.reversed=The server has reversed your name: {0} http-basics.reversed=The server has reversed your name: {0}
http-basics.close=Try again: but this time enter a value before hitting go.
http-basics.incorrect=You are close, try again: the HTTP Command is incorrect. http-basics.incorrect=You are close, try again: the HTTP Command is incorrect.
http-basics.magic=You are close, try again: the magic number is incorrect. http-basics.magic=You are close, try again: the magic number is incorrect.

View File

@ -9,4 +9,26 @@
<version>8.0-SNAPSHOT</version> <version>8.0-SNAPSHOT</version>
</parent> </parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<version>4.1.3.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<type>jar</type>
<scope>test</scope>
</dependency>
</dependencies>
</project> </project>

View File

@ -0,0 +1,73 @@
/*
* 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 - 2017 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>
*/
package org.owasp.webgoat.plugin;
import org.hamcrest.CoreMatchers;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;
import org.owasp.webgoat.assignments.AssignmentEndpointTest;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
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.setup.MockMvcBuilders.standaloneSetup;
@RunWith(MockitoJUnitRunner.class)
public class HttpBasicsInterceptRequestTest extends AssignmentEndpointTest {
private MockMvc mockMvc;
@Before
public void setup() {
HttpBasicsInterceptRequest httpBasicsInterceptRequest = new HttpBasicsInterceptRequest();
init(httpBasicsInterceptRequest);
this.mockMvc = standaloneSetup(httpBasicsInterceptRequest).build();
}
@Test
public void success() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/HttpProxies/intercept-request")
.header("x-request-intercepted", "true")
.param("changeMe", "Requests are tampered easily"))
.andExpect(status().isOk()).andDo(MockMvcResultHandlers.print())
.andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("http-proxies.intercept.success"))))
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(true)));
}
@Test
public void failure() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/HttpProxies/intercept-request")
.header("x-request-intercepted", "false")
.param("changeMe", "Requests are tampered easily"))
.andExpect(status().isOk()).andDo(MockMvcResultHandlers.print())
.andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("http-proxies.intercept.failure"))))
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false)));
}
}

View File

@ -21,6 +21,7 @@
<module>sql-injection</module> <module>sql-injection</module>
<module>xxe</module> <module>xxe</module>
<module>idor</module> <module>idor</module>
<module>vulnerable-components</module>
</modules> </modules>
<dependencies> <dependencies>
@ -36,6 +37,37 @@
<artifactId>commons-exec</artifactId> <artifactId>commons-exec</artifactId>
<version>1.3</version> <version>1.3</version>
</dependency> </dependency>
<dependency>
<groupId>org.owasp.webgoat</groupId>
<artifactId>webgoat-container</artifactId>
<version>${project.version}</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<type>jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>1.10.19</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<version>4.1.3.RELEASE</version>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
<dependencyManagement> <dependencyManagement>
<dependencies> <dependencies>

View File

@ -8,11 +8,11 @@ SqlStringInjectionHint3=Compound SQL statements can be made by joining multiple
SqlStringInjectionHint4=Try entering [ smith' OR '1' = '1 ]. SqlStringInjectionHint4=Try entering [ smith' OR '1' = '1 ].
sql-injection.5a.success=You have succeed: sql-injection.5a.success=You have succeed: {0}
sql-injection.5a.no.results=No results matched. Try Again. sql-injection.5a.no.results=No results matched. Try Again.
sql-injection.5b.success=You have succeed: sql-injection.5b.success=You have succeed: {0}
sql-injection.5b.no.results=No results matched. Try Again. sql-injection.5b.no.results=No results matched. Try Again.
sql-injection.6b.success=You have succeed: sql-injection.6b.success=You have succeed: {0}
sql-injection.6b.no.results=No results matched. Try Again. sql-injection.6b.no.results=No results matched. Try Again.

View File

@ -0,0 +1 @@
/target/

View File

@ -0,0 +1,24 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>vulnerable-components</artifactId>
<packaging>jar</packaging>
<parent>
<groupId>org.owasp.webgoat.lesson</groupId>
<artifactId>webgoat-lessons-parent</artifactId>
<version>8.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.7</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,22 @@
package org.owasp.webgoat.plugin;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
public class CatchAllConverter implements Converter {
public boolean canConvert(Class clazz) {
return true;
}
public void marshal(Object value, HierarchicalStreamWriter writer, MarshallingContext context) {
}
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
return null;
}
}

View File

@ -0,0 +1,18 @@
package org.owasp.webgoat.plugin;
import com.thoughtworks.xstream.annotations.XStreamAlias;
@XStreamAlias("contact")
public class Contact {
@XStreamAlias("name")
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,30 @@
package org.owasp.webgoat.plugin;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
public class ContactConverter implements Converter {
public boolean canConvert(Class clazz) {
return clazz.equals(Contact.class);
}
public void marshal(Object value, HierarchicalStreamWriter writer, MarshallingContext context) {
Contact contact = (Contact) value;
writer.startNode("name");
writer.setValue(contact.getName());
writer.endNode();
}
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
Contact contact = new Contact();
reader.moveDown();
contact.setName(reader.getValue());
reader.moveUp();
return contact;
}
}

View File

@ -0,0 +1,63 @@
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;
/**
* ************************************************************************************************
* 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 October 12, 2016
*/
public class VulnerableComponents extends NewLesson {
@Override
public Category getDefaultCategory() {
return Category.VULNERABLE_COMPONENTS;
}
@Override
public List<String> getHints() {
return Lists.newArrayList();
}
@Override
public Integer getDefaultRanking() {
return 1;
}
@Override
public String getTitle() {
return "vulnerable-components.title";
}
@Override
public String getId() {
return "VulnerableComponents";
}
}

View File

@ -0,0 +1,101 @@
package org.owasp.webgoat.plugin;
import java.io.IOException;
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 com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
/**
* *************************************************************************************************
*
*
* 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("/VulnerableComponents/attack1")
//@AssignmentHints({"http-basics.hints.http_basics_lesson.1"})
public class VulnerableComponentsLesson extends AssignmentEndpoint {
@RequestMapping(method = RequestMethod.POST)
public @ResponseBody AttackResult completed(@RequestParam String payload) throws IOException {
XStream xstream = new XStream(new DomDriver());
// xstream.processAnnotations(Contact.class);
// xstream.registerConverter(new ContactConverter());
// xstream.registerConverter(new CatchAllConverter(), XStream.PRIORITY_VERY_LOW);
// Contact c = new Contact();
// c.setName("Alvaro");
// String sc = xstream.toXML(c);
// System.out.println(sc);
// String payload2 = "<sorted-set>" +
// "<string>foo</string>" +
// "<dynamic-proxy>" +
// "<interface>java.lang.Comparable</interface>" +
// "<handler class=\"java.beans.EventHandler\">" +
// " <target class=\"java.lang.ProcessBuilder\">" +
// " <command>" +
// " <string>/Applications/Calculator.app/Contents/MacOS/Calculator</string>" +
// " </command>" +
// " </target>" +
// " <action>start</action>" +
// "</handler>" +
// "</dynamic-proxy>" +
// "</sorted-set>";
try {
// System.out.println("Payload:" + payload);
Contact expl = (Contact) xstream.fromXML(payload);
return trackProgress(success().feedback("vulnerable-components.fromXML").feedbackArgs(expl.toString()).build());
} catch (com.thoughtworks.xstream.converters.ConversionException ex) {
ex.printStackTrace();
if (ex.getMessage().contains("Integer"))
{
return trackProgress(success().feedback("vulnerable-components.success").build());
}
return trackProgress(failed().feedback("vulnerable-components.close").build());
}
}
}

View File

@ -0,0 +1,175 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<link rel="stylesheet" type="text/css" href="http://code.jquery.com/ui/1.9.1/themes/base/jquery-ui.css" />
<div class="lesson-page-wrapper">
<!-- reuse this lesson-page-wrapper block for each 'page' of content in your lesson -->
<!-- include content here, or can be placed in another location. Content will be presented via asciidocs files,
which you put in src/main/resources/plugin/lessonplans/{lang}/{fileName}.adoc -->
<div class="adoc-content" th:replace="doc:VulnerableComponents_plan.adoc"></div>
</div>
<div class="lesson-page-wrapper">
<!-- reuse this lesson-page-wrapper block for each 'page' of content in your lesson -->
<!-- include content here, or can be placed in another location. Content will be presented via asciidocs files,
which you put in src/main/resources/plugin/lessonplans/{lang}/{fileName}.adoc -->
<div class="adoc-content" th:replace="doc:VulnerableComponents_content0.adoc"></div>
</div>
<div class="lesson-page-wrapper">
<!-- reuse this lesson-page-wrapper block for each 'page' of content in your lesson -->
<!-- include content here, or can be placed in another location. Content will be presented via asciidocs files,
which you put in src/main/resources/plugin/lessonplans/{lang}/{fileName}.adoc -->
<div class="adoc-content" th:replace="doc:VulnerableComponents_content1.adoc"></div>
</div>
<div class="lesson-page-wrapper">
<!-- reuse this lesson-page-wrapper block for each 'page' of content in your lesson -->
<!-- include content here, or can be placed in another location. Content will be presented via asciidocs files,
which you put in src/main/resources/plugin/lessonplans/{lang}/{fileName}.adoc -->
<div class="adoc-content" th:replace="doc:VulnerableComponents_content1a.adoc"></div>
</div>
<div class="lesson-page-wrapper">
<!-- reuse this lesson-page-wrapper block for each 'page' of content in your lesson -->
<!-- include content here. Content will be presented via asciidocs files,
which you put in src/main/resources/plugin/lessonplans/{lang}/{fileName}.adoc -->
<div class="adoc-content" th:replace="doc:VulnerableComponents_content2.adoc"></div>
<div class="attack-container">
<!-- using attack-form class on your form, will allow your request to be ajaxified and stay within the display framework for webgoat -->
<div id="lessonContent">
<!-- using attack-form class on your form will allow your request to be ajaxified and stay within the display framework for webgoat -->
<!-- you can write your own custom forms, but standard form submission will take you to your endpoint and outside of the WebGoat framework -->
<!-- of course, you can write your own ajax submission /handling in your own javascript if you like -->
<table>
<tr>
<td>Clicking go will execute a jquery-ui close dialog:</td>
<td><input name="closetext" value="" type="TEXT" /><input
name="SUBMIT" value="Go!" type="SUBMIT" onclick="webgoat.customjs.vuln_jquery_ui()" /></td>
<td></td>
</tr>
</table>
<script th:inline="javascript">
/*<![CDATA[*/
webgoat.customjs.vuln_jquery_ui = function()
{
webgoat.customjs.jquery('#dialog').dialog({ closeText: 'OK<script>alert("XSS")<\/script>' });
};
/*]]>*/
</script>
<div id="dialog" title="jquery-ui-1.10.4">This dialog should have exploited a known flaw in jquery-ui:1.10.4 and allowed a XSS attack to occur</div>
<!-- do not remove the two following div's, this is where your feedback/output will land -->
<div class="attack-feedback"></div>
<div class="attack-output"></div>
<!-- ... of course, you can move them if you want to, but that will not look consistent to other lessons -->
</div>
</div>
<div class="adoc-content" th:replace="doc:VulnerableComponents_content2a.adoc"></div>
<div class="attack-container">
<!-- using attack-form class on your form, will allow your request to be ajaxified and stay within the display framework for webgoat -->
<div id="lessonContent">
<!-- using attack-form class on your form will allow your request to be ajaxified and stay within the display framework for webgoat -->
<!-- you can write your own custom forms, but standard form submission will take you to your endpoint and outside of the WebGoat framework -->
<!-- of course, you can write your own ajax submission /handling in your own javascript if you like -->
<table>
<tr>
<td>Clicking go will execute a jquery-ui close dialog:</td>
<td><input name="closetext" value="" type="TEXT" /><input
name="SUBMIT" value="Go!" type="SUBMIT" onclick="webgoat.customjs.jquery_ui()" /></td>
<td></td>
</tr>
</table>
<script th:inline="javascript">
/*<![CDATA[*/
webgoat.customjs.jquery_ui = function()
{
webgoat.customjs.jquery('#dialog2').dialog({ closeText: 'OK' });
};
/*]]>*/
</script>
<div id="dialog2" title="jquery-ui-1.12.0">This dialog should have prevented the above exploit using the EXACT same code in WebGoat but using a later version of jquery-ui.</div>
<!-- do not remove the two following div's, this is where your feedback/output will land -->
<div class="attack-feedback"></div>
<div class="attack-output"></div>
<!-- ... of course, you can move them if you want to, but that will not look consistent to other lessons -->
</div>
</div>
</div>
<div class="lesson-page-wrapper">
<!-- reuse this lesson-page-wrapper block for each 'page' of content in your lesson -->
<!-- include content here, or can be placed in another location. Content will be presented via asciidocs files,
which you put in src/main/resources/plugin/lessonplans/{lang}/{fileName}.adoc -->
<div class="adoc-content" th:replace="doc:VulnerableComponents_content3.adoc"></div>
</div>
<div class="lesson-page-wrapper">
<!-- reuse this lesson-page-wrapper block for each 'page' of content in your lesson -->
<!-- include content here, or can be placed in another location. Content will be presented via asciidocs files,
which you put in src/main/resources/plugin/lessonplans/{lang}/{fileName}.adoc -->
<div class="adoc-content" th:replace="doc:VulnerableComponents_content4.adoc"></div>
</div>
<div class="lesson-page-wrapper">
<!-- reuse this lesson-page-wrapper block for each 'page' of content in your lesson -->
<!-- include content here, or can be placed in another location. Content will be presented via asciidocs files,
which you put in src/main/resources/plugin/lessonplans/{lang}/{fileName}.adoc -->
<div class="adoc-content" th:replace="doc:VulnerableComponents_content4a.adoc"></div>
</div>
<div class="lesson-page-wrapper">
<!-- reuse this lesson-page-wrapper block for each 'page' of content in your lesson -->
<!-- include content here, or can be placed in another location. Content will be presented via asciidocs files,
which you put in src/main/resources/plugin/lessonplans/{lang}/{fileName}.adoc -->
<div class="adoc-content" th:replace="doc:VulnerableComponents_content4b.adoc"></div>
</div>
<div class="lesson-page-wrapper">
<!-- reuse this lesson-page-wrapper block for each 'page' of content in your lesson -->
<!-- include content here, or can be placed in another location. Content will be presented via asciidocs files,
which you put in src/main/resources/plugin/lessonplans/{lang}/{fileName}.adoc -->
<div class="adoc-content" th:replace="doc:VulnerableComponents_content4c.adoc"></div>
</div>
<div class="lesson-page-wrapper">
<!-- reuse this lesson-page-wrapper block for each 'page' of content in your lesson -->
<!-- include content here, or can be placed in another location. Content will be presented via asciidocs files,
which you put in src/main/resources/plugin/lessonplans/{lang}/{fileName}.adoc -->
<div class="adoc-content" th:replace="doc:VulnerableComponents_content5.adoc"></div>
</div>
<div class="lesson-page-wrapper">
<!-- reuse this lesson-page-wrapper block for each 'page' of content in your lesson -->
<!-- include content here, or can be placed in another location. Content will be presented via asciidocs files,
which you put in src/main/resources/plugin/lessonplans/{lang}/{fileName}.adoc -->
<div class="adoc-content" th:replace="doc:VulnerableComponents_content5a.adoc"></div>
<div class="attack-container">
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<!-- using attack-form class on your form will allow your request to be ajaxified and stay within the display framework for webgoat -->
<!-- you can write your own custom forms, but standard form submission will take you to your endpoint and outside of the WebGoat framework -->
<!-- of course, you can write your own ajax submission /handling in your own javascript if you like -->
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/VulnerableComponents/attack1"
enctype="application/json;charset=UTF-8">
<div id="lessonContent">
<form accept-charset="UNKNOWN" method="POST" name="form"
action="#attack/307/100" enctype="">
<table>
<tr>
<td>Enter the contact's xml representation:</td>
<td><textarea name="payload" value="" type="TEXT" rows="15" cols="60"/></td>
<td><input name="SUBMIT" value="Go!" type="SUBMIT"/></td>
</tr>
</table>
</form>
</div>
</form>
<!-- do not remove the two following div's, this is where your feedback/output will land -->
<div class="attack-feedback"></div>
<div class="attack-output"></div>
<!-- ... of course, you can move them if you want to, but that will not look consistent to other lessons -->
</div>
</div>
<div class="lesson-page-wrapper">
<!-- reuse this lesson-page-wrapper block for each 'page' of content in your lesson -->
<!-- include content here, or can be placed in another location. Content will be presented via asciidocs files,
which you put in src/main/resources/plugin/lessonplans/{lang}/{fileName}.adoc -->
<div class="adoc-content" th:replace="doc:VulnerableComponents_content6.adoc"></div>
</div>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 KiB

View File

@ -0,0 +1,13 @@
== The Open Source Ecosystems
* 10+ Million GitHub code repositories
* 1 Million Sourceforge code repositories
* 2500 public binary repositories
** Some repositories have strict publisher standards
*** Some repositories enforce source code distribution
*** No guarantee the published source code is the source code of the published binary
** Some repositories allow the republishing of a different set of bits for the same version
** Some repositories allow you to remove published artifacts
* Many different packaging systems; even for the same language
* Different coordinates systems and level of granularity

View File

@ -0,0 +1,7 @@
== 2013 OWASP Top 10 - A9
As early as 2013, thought leaders like OWASP have recognized that "WE" need to pay attention to this problem.
image::plugin_lessons/plugin/VulnerableComponents/images/OWASP-2013-A9.png[caption="Figure: ", title="2013 OWASP - Top 10 - A9", alt="A9", width="800", height="500", style="lesson-image" link="https://www.owasp.org/index.php/Top_10_2013-A9-Using_Components_with_Known_Vulnerabilities"]

View File

@ -0,0 +1,11 @@
== Components are everywhere
WebGoat uses almost *200 Java and JavaScript* libraries. Like most Java applications, we use maven to manage our java dependencies and we employ the wild, wild west strategy for managing JavaScript.
=== Vulnerable components in WebGoat?
When this lesson was created WebGoat contained more than a dozen high security risks within it's components. Most of these were not deliberate choices. How are developers supposed to track this information across the hundreds of components?
image::plugin_lessons/plugin/VulnerableComponents/images/WebGoat-Vulns.png[caption="Figure: ", title="WebGoat Security Issues", alt="Security Issues", width="800", height="400", style="lesson-image"]

View File

@ -0,0 +1,6 @@
== The exploit is not always in "your" code
Below is an example of using the same source and different versions of jquery-ui. One is exploitable; one is not.
=== jquery-ui:1.10.4
This example allows the user to specify the content of the "closeText" for the jquery-ui dialog. This is an unlikely development scenario, however the jquery-ui dialog (TBD - show exploit link) does not defend against XSS in the button text of the close dialog.

View File

@ -0,0 +1,4 @@
=== jquery-ui:1.12.0 Not Vulnerable
Using the same WebGoat source code but upgrading the jquery-ui library to a non-vulnerable version eliminates the exploit.

View File

@ -0,0 +1,14 @@
== Knowing the OSS "Bill of Materials" is the starting point
Modern applications are comprised of custom code and many pieces of open source. The developer is normally very knowledgeable about their custom code but less familiar with the potential risk of the libraries/components they use. Think of the bill of materials as the list of ingredients in a recipe.
=== Questions we should know the answer to:
* How do we know what open source components are in our applications?
** How do we know what versions of open source components we are using?
* How do we define the risk of open source components?
* How do we discover the risk of open source components?
** How do we associate a specific risk to a specific version of an open source component?
* How do we know when a component releases a new version?
* How do we know if a new vulnerability is found on what was previously a "good" component?
* How do we know if we are using the authentic version of an open source component?

View File

@ -0,0 +1,9 @@
== How do I generate a Bill of Materials
There are several open source and paid-for solutions that will identify risk in components. There are not many tools that will deliver a complete list of "ingredients" used within an application. OWASP Dependency Check provides the ability to generate a bill of materials and identify potential security risk.
Dependency check uses several pieces of evidence to determine the library names. Below is a snippet of a report:
image::plugin_lessons/plugin/VulnerableComponents/images/OWASP-Dep-Check.png[caption="Figure: ", title="WebGoat Bill of Materials", alt="BoM", width="988", height="515", style="lesson-image"]

View File

@ -0,0 +1,23 @@
== Security Information Overload
=== What's important?
* Is my component exploitable?
* Is my component an authentic copy?
** Do I understand why my component is modified?
=== Security information is scattered everywhere
* Multiple sources of security advisories
** 80,000+ CVEs in the National Vulnerbility Database
** Node Security Project, Metasploit, VulnDB, Snyk, ...
** Thousands of website security advisories, blogs, tweets, ...
* 600,000 GitHub events generated daily
** 700 GitHub security related events
** Release notes, change logs, code comments, ...
=== Summary
* It is not reasonable to expect a developer to continually research each component.
* Developers are not security experts; they already have a day job.

View File

@ -0,0 +1,23 @@
== License Information Overload
=== What's important?
* Can I use this component within the context of distribution of my software?
* Are there license incompatibilities?
* If using a modified component, did I addressed additional license obligations?
=== License information is scattered everywhere
* Projects declare a license:
** In a project metadata file.
** On the project website or source code repository page.
** Using a link to a license file in their own source code repository.
** In a license file within the project source tree.
** In the binary META-INF folder.
* Projects include licenses as headers in the source code.
=== Summary
* It is difficult to determine the scope of a license.
* A project often has license discrepancies.
* Developers are not lawyers .

View File

@ -0,0 +1,20 @@
== Architecture Information
=== What's important?
* Is it old or is it stable
* Was my lack of upgrade a deliberate choice or a lack of knowledge
* Is the project I'm using no longer active
* Is my component unpopular
=== Summary
* It's really difficult to keep components up to dat
For the components analyzed in 25,000 applications it was found that:
* 8% of 2 year old components did not have a newer version
* 23% of 11 year old components did not have a newer version
image::plugin_lessons/plugin/VulnerableComponents/images/Old-Components.png[caption="Figure: ", title="Old Components", alt="Old Components", width="355", height="304", style="lesson-image"]

View File

@ -0,0 +1,13 @@
== Some Examples of OSS Risk
=== Commons Collections
In November of 2015, the Apache Commons Collections component latest release was 8 years old. Commons Collections was considered a reliable and stable component. A researcher found a way to exploit a deserialization issue in Commons Collections resulting in a remote code execution. The next day... *everyone using Commons Collections was in a panic*.
Ref: http://www.pcworld.com/article/3004633/business-security/thousands-of-java-applications-vulnerable-to-nine-month-old-remote-code-execution-exploit.html[Thousands of Java applications vulnerable to nine-month-old remote code execution exploit]
=== Dinis Cruz and pwntester exploit of XStream
XStream, a relatively common XML and JSON parsing library, has a nasty little remote code execution. Ref: http://blog.diniscruz.com/2013/12/xstream-remote-code-execution-exploit.html[Dinis Cruz Blog] https://github.com/pwntester/XStreamPOC[pwntester/XStreamPOC]
You may want to read the article(s) before trying this lesson. Let's see if you can figure out how to exploit this in WebGoat.

View File

@ -0,0 +1,14 @@
== Exploiting http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2013-7285[CVE-2013-7285] (XStream)
WebGoat Sends an XML document to add contacts to a contacts database.
[source,xml]
----
<contact>
<id>1</id>
<firstName>Bruce</firstName>
<lastName>Mayhew</lastName>
<email>webgoat@owasp.org</email>
</contact>
----
For this example, we will let you enter the xml directly versus intercepting the request and modifying the data. You provide the XML representation of a contact and WebGoat will convert it a Contact object using XStream.fromXML(xml).

View File

@ -0,0 +1,16 @@
== Summary
* Open source consumption in modern day applications has increased.
* Open source is obtained from many different repositories with different quality standards.
* Security information on vulnerabilities is scattered everywhere.
* License information is often difficult to validate.
* Most teams don't have a component upgrade strategy.
* *Open source components are the new attack vector.*
== What to do
* Generate a bill of materials.
** Use http://lmgtfy.com/?q=OSS+bill+of+materials[automated tooling]
* Baseline open source consumption in your organization.
* Develop an open source component risk management strategy to mitigate current risk and reduce future risk.

View File

@ -0,0 +1,15 @@
= Vulnerable Components
== Concept
The way we build software has changed. The open source community is maturing and the availability of open source software has become prolific without regard to determining the provenance of the libraries used in our applications. Ref: https://www.sonatype.com/hubfs/SSC/Software_Supply_Chain_Inforgraphic.pdf?t=1485298506170[Software Supply Chain]
image::plugin_lessons/plugin/VulnerableComponents/images/OpenSourceGrowing.png[caption="Figure: ", title="Software Supply Chain", alt="SSC", width="800", height="400", style="lesson-image" link="https://www.sonatype.com/hubfs/SSC/Software_Supply_Chain_Inforgraphic.pdf?t=1485298506170[Software Supply Chain"]
This lesson will walk through the difficulties with managing dependent libraries, the risk of not managing those dependencies, and the difficulty in determining if you are at risk.
== Goals
* Gain awareness that the open source consumed is as important as your own custom code.
* Gain awareness of the management, or lack of management, in our open source component consumption.

View File

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<div class="lesson-page-wrapper">
<!-- reuse this block for each 'page' of content -->
<!-- include content here ... will be first page/tab multiple -->
<div class="adoc-content" th:replace="doc:VulnerableComponents_solution.adoc"></div>
</div>
</html>

View File

@ -0,0 +1,6 @@
vulnerable-components.title=Vulnerable Components
EnterYourName=Enter your Name
Go!=Go!
vulnerable-components.close=Trying to deserialize null object.
vulnerable-components.success=If you are not seeing the application you started; it may be minimized
vulnerable-components.fromXML=You created contact {0}. This means you did not exploit the remote code execution.

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/
* <p>
* Copyright (c) 2002 - 2017 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>
*/
package org.owasp.webgoat.plugin;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;
import org.owasp.webgoat.assignments.AssignmentEndpointTest;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;
/**
* @author nbaars
* @date 2/7/17
*/
@RunWith(MockitoJUnitRunner.class)
public class VulnerableComponentsLessonTest extends AssignmentEndpointTest {
private MockMvc mockMvc;
@Before
public void setup() {
VulnerableComponentsLesson vulnerableComponentsLesson = new VulnerableComponentsLesson();
init(vulnerableComponentsLesson);
this.mockMvc = standaloneSetup(vulnerableComponentsLesson).build();
}
@Test
public void success() throws Exception {
// mockMvc.perform(MockMvcRequestBuilders.post("/VulnerableComponents/attack1").content("Test"))
// .andExpect(status().isOk()).andDo(MockMvcResultHandlers.print())
// .andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("http-proxies.intercept.success"))))
// .andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(true)));
}
}