diff --git a/.gitignore b/.gitignore index fb3ff0300..917e56a8c 100644 --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,4 @@ webgoat-lessons/**/target **/.DS_Store webgoat-server/mongo-data/* webgoat-lessons/vulnerable-components/dependency-reduced-pom.xml +/.sonatype \ No newline at end of file diff --git a/README.MD b/README.MD index 32bd67755..d0ff4809e 100644 --- a/README.MD +++ b/README.MD @@ -40,6 +40,15 @@ docker pull webgoat/webgoat-8.0 docker run -p 8080:8080 -it webgoat/webgoat-8.0 /home/webgoat/start.sh ``` +If you want to keep the database between Docker sessions you need to map the WebGoat data directory to a +folder on the host system as follows: + +```Shell +docker run -p 8080:8080 -it -v /tmp/webgoat-data:/home/webgoat/.webgoat-${VERSION} webgoat/webgoat-8.0 /home/webgoat/start.sh +``` + +where `${VERSION}` is for example `v8.0.0.M14`. The data will now be stored in `/tmp/webgoat-data` on your host system. + Wait for the Docker container to start, and run `docker ps` to verify it's running. - If you are using `docker-machine`, verify the machine IP using `docker-machine env` diff --git a/docker-compose-postgres.yml b/docker-compose-postgres.yml new file mode 100644 index 000000000..7ecc68403 --- /dev/null +++ b/docker-compose-postgres.yml @@ -0,0 +1,35 @@ +version: '2.0' + +services: + webgoat: + image: webgoat/webgoat-8.0 + user: webgoat + environment: + - WEBWOLF_HOST=webwolf + - spring.datasource.url=jdbc:postgresql://webgoat_db:5432/webgoat + - spring.datasource.username=webgoat + - spring.datasource.password=webgoat + - spring.datasource.driver-class-name=org.postgresql.Driver + - spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL94Dialect + ports: + - "8080:8080" + webwolf: + image: webgoat/webwolf + environment: + - spring.datasource.url=jdbc:postgresql://webgoat_db:5432/webgoat + - spring.datasource.username=webgoat + - spring.datasource.password=webgoat + - spring.datasource.driver-class-name=org.postgresql.Driver + - spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL94Dialect + ports: + - "8081:8081" + db: + container_name: webgoat_db + image: postgres:latest + environment: + - POSTGRES_PASSWORD=webgoat + - POSTGRES_USER=webgoat + - POSTGRES_DB=webgoat + ports: + - "5432:5432" + diff --git a/docker-compose.yml b/docker-compose.yml index 9b0769407..8d2bcdee3 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,15 +1,28 @@ -version: '2.0' +version: '2.1' services: webgoat: - build: webgoat-server/ - command: "sh /home/webgoat/start.sh" + image: webgoat/webgoat-8.0 + environment: + - WEBWOLF_HOST=webwolf + - spring.datasource.url=jdbc:hsqldb:hsql://webgoat_db:9001/webgoat ports: - "8080:8080" - webwolf: - build: webwolf/ - command: "sh /home/webwolf/start.sh" depends_on: - - webgoat + - db + webwolf: + image: webgoat/webwolf + environment: + - spring.datasource.url=jdbc:hsqldb:hsql://webgoat_db:9001/webgoat ports: - - "8081:8081" \ No newline at end of file + - "8081:8081" + depends_on: + - db + db: + image: blacklabelops/hsqldb + container_name: webgoat_db + environment: + - HSQLDB_TRACE=false + - HSQLDB_SILENT=true + - HSQLDB_DATABASE_NAME=webgoat + - HSQLDB_DATABASE_ALIAS=webgoat diff --git a/pom.xml b/pom.xml index 972af72c8..4b75535ed 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.owasp.webgoat webgoat-parent pom - 8.0.0.M3 + v8.0.0.M14 WebGoat Parent Pom Parent Pom for the WebGoat Project. A deliberately insecure Web Application @@ -20,7 +20,7 @@ org.springframework.boot spring-boot-starter-parent - 1.5.9.RELEASE + 1.5.12.RELEASE @@ -135,7 +135,7 @@ 2.2.4 18.0 1.4.190 - 2.3.2 + 2.3.4 1.3.1 2.6.3 2.6.3 diff --git a/scripts/deploy-webgoat.sh b/scripts/deploy-webgoat.sh index 652a0b9b0..b9562d0fa 100644 --- a/scripts/deploy-webgoat.sh +++ b/scripts/deploy-webgoat.sh @@ -17,6 +17,24 @@ elif [ ! -z "${TRAVIS_TAG}" ]; then #elif [ "${BRANCH}" == "develop" ]; then # docker build -f Dockerfile -t $REPO:snapshot . # docker push $REPO +else + echo "Skipping releasing to DockerHub because it is a build of branch ${BRANCH}" +fi + + +export REPO=webgoat/webwolf +cd .. +cd webwolf +ls target/ + +if [ "${BRANCH}" == "master" ] && [ ! -z "${TRAVIS_TAG}" ]; then + # If we push a tag to master this will update the LATEST Docker image and tag with the version number + docker build --build-arg webwolf_version=${TRAVIS_TAG:1} -f Dockerfile -t $REPO:latest -t $REPO:${TRAVIS_TAG} . + docker push $REPO +elif [ ! -z "${TRAVIS_TAG}" ]; then + # Creating a tag build we push it to Docker with that tag + docker build --build-arg webwolf_version=${TRAVIS_TAG:1} -f Dockerfile -t $REPO:${TRAVIS_TAG} -t $REPO:latest . + docker push $REPO else echo "Skipping releasing to DockerHub because it is a build of branch ${BRANCH}" fi \ No newline at end of file diff --git a/webgoat-container/pom.xml b/webgoat-container/pom.xml index d9682cb57..76f86c160 100644 --- a/webgoat-container/pom.xml +++ b/webgoat-container/pom.xml @@ -10,7 +10,7 @@ org.owasp.webgoat webgoat-parent - 8.0.0.M3 + v8.0.0.M14 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 7bb02b98d..ecb80bd43 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/AsciiDoctorTemplateResolver.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/AsciiDoctorTemplateResolver.java @@ -35,6 +35,7 @@ import com.google.common.collect.Sets; import lombok.extern.slf4j.Slf4j; import org.asciidoctor.Asciidoctor; import org.asciidoctor.extension.JavaExtensionRegistry; +import org.owasp.webgoat.asciidoc.WebGoatVersionMacro; import org.owasp.webgoat.asciidoc.WebWolfMacro; import org.owasp.webgoat.i18n.Language; import org.thymeleaf.TemplateProcessingParameters; @@ -86,6 +87,7 @@ public class AsciiDoctorTemplateResolver extends TemplateResolver { StringWriter writer = new StringWriter(); JavaExtensionRegistry extensionRegistry = asciidoctor.javaExtensionRegistry(); extensionRegistry.inlineMacro("webWolfLink", WebWolfMacro.class); + extensionRegistry.inlineMacro("webGoatVersion", WebGoatVersionMacro.class); asciidoctor.convert(new InputStreamReader(is), writer, createAttributes()); return new ByteArrayInputStream(writer.getBuffer().toString().getBytes(UTF_8)); 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 e52cff71a..22f6fa99e 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/MvcConfiguration.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/MvcConfiguration.java @@ -130,6 +130,7 @@ public class MvcConfiguration extends WebMvcConfigurerAdapter { @Bean public PluginMessages pluginMessages(Messages messages, Language language) { PluginMessages pluginMessages = new PluginMessages(messages, language); + pluginMessages.setDefaultEncoding("UTF-8"); pluginMessages.setBasenames("i18n/WebGoatLabels"); return pluginMessages; } @@ -142,6 +143,7 @@ public class MvcConfiguration extends WebMvcConfigurerAdapter { @Bean public Messages messageSource(Language language) { Messages messages = new Messages(language); + messages.setDefaultEncoding("UTF-8"); messages.setBasename("classpath:i18n/messages"); return messages; } diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/asciidoc/WebGoatVersionMacro.java b/webgoat-container/src/main/java/org/owasp/webgoat/asciidoc/WebGoatVersionMacro.java new file mode 100644 index 000000000..f33d06063 --- /dev/null +++ b/webgoat-container/src/main/java/org/owasp/webgoat/asciidoc/WebGoatVersionMacro.java @@ -0,0 +1,23 @@ +package org.owasp.webgoat.asciidoc; + +import org.asciidoctor.ast.AbstractBlock; +import org.asciidoctor.extension.InlineMacroProcessor; +import org.springframework.core.env.Environment; +import org.springframework.util.StringUtils; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; +import java.util.Map; + +public class WebGoatVersionMacro extends InlineMacroProcessor { + + public WebGoatVersionMacro(String macroName, Map config) { + super(macroName, config); + } + + @Override + protected String process(AbstractBlock parent, String target, Map attributes) { + return EnvironmentExposure.getEnv().getProperty("webgoat.build.version"); + } +} diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/asciidoc/WebWolfMacro.java b/webgoat-container/src/main/java/org/owasp/webgoat/asciidoc/WebWolfMacro.java index 88b2ab5fb..7f81d63d1 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/asciidoc/WebWolfMacro.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/asciidoc/WebWolfMacro.java @@ -10,6 +10,12 @@ import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import java.util.Map; +/** + * Usage in asciidoc: + *

+ * webWolfLink:here[] will display a href with here as text + * webWolfLink:landing[noLink] will display the complete url, for example: http://WW_HOST:WW_PORT/landing + */ public class WebWolfMacro extends InlineMacroProcessor { public WebWolfMacro(String macroName, Map config) { @@ -20,9 +26,17 @@ public class WebWolfMacro extends InlineMacroProcessor { protected String process(AbstractBlock parent, String target, Map attributes) { Environment env = EnvironmentExposure.getEnv(); String hostname = determineHost(env.getProperty("webwolf.host"), env.getProperty("webwolf.port")); + + if (displayCompleteLinkNoFormatting(attributes)) { + return hostname + (hostname.endsWith("/") ? "" : "/") + target; + } return "" + target + ""; } + private boolean displayCompleteLinkNoFormatting(Map attributes) { + return attributes.values().stream().filter(a -> a.equals("noLink")).findFirst().isPresent(); + } + /** * Look at the remote address from received from the browser first. This way it will also work if you run * the browser in a Docker container and WebGoat on your local machine. 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 c4713a054..3b02b6129 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 @@ -55,7 +55,7 @@ public abstract class AssignmentEndpoint extends Endpoint { //// TODO: 11/13/2016 events better fit? protected AttackResult trackProgress(AttackResult attackResult) { - UserTracker userTracker = userTrackerRepository.findOne(webSession.getUserName()); + UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName()); if (userTracker == null) { userTracker = new UserTracker(webSession.getUserName()); } 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 41758c742..d9b1f3470 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 @@ -1,11 +1,9 @@ package org.owasp.webgoat.lessons; +import com.google.common.collect.Lists; import lombok.*; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.OneToMany; -import javax.persistence.Transient; +import javax.persistence.*; import java.util.List; /** @@ -37,19 +35,30 @@ import java.util.List; * @version $Id: $Id * @since November 25, 2016 */ -@AllArgsConstructor -@RequiredArgsConstructor -@NoArgsConstructor @Getter @EqualsAndHashCode @Entity public class Assignment { - @NonNull + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; private String name; - @NonNull private String path; @Transient private List hints; + private Assignment() { + //Hibernate + } + + public Assignment(String name, String path) { + this(name, path, Lists.newArrayList()); + } + + public Assignment(String name, String path, List hints) { + this.name = name; + this.path = path; + this.hints = hints; + } } diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonMenuService.java b/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonMenuService.java index 097085c48..c0cfdc107 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonMenuService.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/service/LessonMenuService.java @@ -73,7 +73,7 @@ public class LessonMenuService { List showLeftNav() { List menu = new ArrayList<>(); List categories = course.getCategories(); - UserTracker userTracker = userTrackerRepository.findOne(webSession.getUserName()); + UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName()); for (Category category : categories) { LessonMenuItem categoryItem = new LessonMenuItem(); 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 fb4fe0071..76e6187a5 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 @@ -40,17 +40,19 @@ public class LessonProgressService { @RequestMapping(value = "/service/lessonprogress.mvc", produces = "application/json") @ResponseBody public Map getLessonInfo() { - UserTracker userTracker = userTrackerRepository.findOne(webSession.getUserName()); - LessonTracker lessonTracker = userTracker.getLessonTracker(webSession.getCurrentLesson()); Map json = Maps.newHashMap(); - String successMessage = ""; - boolean lessonCompleted = false; - if (lessonTracker != null) { - lessonCompleted = lessonTracker.isLessonSolved(); - successMessage = "LessonCompleted"; //@todo we still use this?? + UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName()); + if (webSession.getCurrentLesson() != null) { + LessonTracker lessonTracker = userTracker.getLessonTracker(webSession.getCurrentLesson()); + String successMessage = ""; + boolean lessonCompleted = false; + if (lessonTracker != null) { + lessonCompleted = lessonTracker.isLessonSolved(); + successMessage = "LessonCompleted"; //@todo we still use this?? + } + json.put("lessonCompleted", lessonCompleted); + json.put("successMessage", successMessage); } - json.put("lessonCompleted", lessonCompleted); - json.put("successMessage", successMessage); return json; } @@ -63,7 +65,7 @@ public class LessonProgressService { @RequestMapping(value = "/service/lessonoverview.mvc", produces = "application/json") @ResponseBody public List lessonOverview() { - UserTracker userTracker = userTrackerRepository.findOne(webSession.getUserName()); + UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName()); AbstractLesson currentLesson = webSession.getCurrentLesson(); List result = Lists.newArrayList(); if ( currentLesson != null ) { diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/service/ReportCardService.java b/webgoat-container/src/main/java/org/owasp/webgoat/service/ReportCardService.java index 21c8c1f20..0337467b1 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/service/ReportCardService.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/service/ReportCardService.java @@ -32,6 +32,7 @@ import com.google.common.collect.Lists; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.Setter; +import org.owasp.webgoat.i18n.PluginMessages; import org.owasp.webgoat.lessons.AbstractLesson; import org.owasp.webgoat.session.Course; import org.owasp.webgoat.session.WebSession; @@ -57,6 +58,7 @@ public class ReportCardService { private final WebSession webSession; private final UserTrackerRepository userTrackerRepository; private final Course course; + private final PluginMessages pluginMessages; /** * Endpoint which generates the report card for the current use to show the stats on the solved lessons @@ -64,7 +66,7 @@ public class ReportCardService { @GetMapping(path = "/service/reportcard.mvc", produces = "application/json") @ResponseBody public ReportCard reportCard() { - UserTracker userTracker = userTrackerRepository.findOne(webSession.getUserName()); + UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName()); List lessons = course.getLessons(); ReportCard reportCard = new ReportCard(); reportCard.setTotalNumberOfLessons(course.getTotalOfLessons()); @@ -74,7 +76,7 @@ public class ReportCardService { for (AbstractLesson lesson : lessons) { LessonTracker lessonTracker = userTracker.getLessonTracker(lesson); LessonStatistics lessonStatistics = new LessonStatistics(); - lessonStatistics.setName(lesson.getTitle()); + lessonStatistics.setName(pluginMessages.getMessage(lesson.getTitle())); lessonStatistics.setNumberOfAttempts(lessonTracker.getNumberOfAttempts()); lessonStatistics.setSolved(lessonTracker.isLessonSolved()); reportCard.lessonStatistics.add(lessonStatistics); diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/service/RestartLessonService.java b/webgoat-container/src/main/java/org/owasp/webgoat/service/RestartLessonService.java index 4ea036996..b207b4ce1 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/service/RestartLessonService.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/service/RestartLessonService.java @@ -59,7 +59,7 @@ public class RestartLessonService { AbstractLesson al = webSession.getCurrentLesson(); log.debug("Restarting lesson: " + al); - UserTracker userTracker = userTrackerRepository.findOne(webSession.getUserName()); + UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName()); userTracker.reset(al); userTrackerRepository.save(userTracker); } diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/users/LessonTracker.java b/webgoat-container/src/main/java/org/owasp/webgoat/users/LessonTracker.java index 81d5d3b23..7d1d5d859 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/users/LessonTracker.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/users/LessonTracker.java @@ -47,8 +47,11 @@ import java.util.stream.Collectors; */ @Entity public class LessonTracker { - @Getter + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + @Getter private String lessonName; @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) private final Set solvedAssignments = Sets.newHashSet(); diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/users/Scoreboard.java b/webgoat-container/src/main/java/org/owasp/webgoat/users/Scoreboard.java index aa8416d58..0b77b89c6 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/users/Scoreboard.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/users/Scoreboard.java @@ -38,7 +38,7 @@ public class Scoreboard { List allUsers = userRepository.findAll(); List rankings = Lists.newArrayList(); for (WebGoatUser user : allUsers) { - UserTracker userTracker = userTrackerRepository.findOne(user.getUsername()); + UserTracker userTracker = userTrackerRepository.findByUser(user.getUsername()); rankings.add(new Ranking(user.getUsername(), challengesSolved(userTracker))); } return rankings; diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/users/UserTracker.java b/webgoat-container/src/main/java/org/owasp/webgoat/users/UserTracker.java index 64ca5fb9a..1cc4920ea 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/users/UserTracker.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/users/UserTracker.java @@ -50,6 +50,9 @@ import java.util.stream.Collectors; public class UserTracker { @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + @Column(name = "username") private String user; @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) private Set lessonTrackers = Sets.newHashSet(); diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/users/UserTrackerRepository.java b/webgoat-container/src/main/java/org/owasp/webgoat/users/UserTrackerRepository.java index a322f9d8a..efa231d59 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/users/UserTrackerRepository.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/users/UserTrackerRepository.java @@ -8,5 +8,6 @@ import org.springframework.data.jpa.repository.JpaRepository; */ public interface UserTrackerRepository extends JpaRepository { + UserTracker findByUser(String user); } diff --git a/webgoat-container/src/main/resources/application.properties b/webgoat-container/src/main/resources/application.properties index 83de9b5d7..35b177ddd 100644 --- a/webgoat-container/src/main/resources/application.properties +++ b/webgoat-container/src/main/resources/application.properties @@ -3,9 +3,12 @@ server.error.path=/error.html server.session.timeout=600 server.contextPath=/WebGoat server.port=8080 +server.address=127.0.0.1 -spring.datasource.url=jdbc:hsqldb:file:${webgoat.server.directory}/data/webgoat +spring.datasource.url=jdbc:hsqldb:hsql://localhost:9001/webgoat 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.springframework=WARN @@ -19,9 +22,10 @@ security.enable-csrf=false spring.resources.cache-period=0 spring.thymeleaf.cache=false +webgoat.start.hsqldb=true webgoat.clean=false -webgoat.server.directory=${user.home}/.webgoat/ -webgoat.user.directory=${user.home}/.webgoat/ +webgoat.server.directory=${user.home}/.webgoat-${webgoat.build.version}/ +webgoat.user.directory=${user.home}/.webgoat-${webgoat.build.version}/ webgoat.build.version=@project.version@ webgoat.build.number=@build.number@ webgoat.email=webgoat@owasp.org diff --git a/webgoat-container/src/main/resources/static/css/main.css b/webgoat-container/src/main/resources/static/css/main.css index d9347acb8..59f674616 100644 --- a/webgoat-container/src/main/resources/static/css/main.css +++ b/webgoat-container/src/main/resources/static/css/main.css @@ -1066,6 +1066,7 @@ span.show-next-page, span.show-prev-page { /* ATTACK DISPLAY */ .attack-container { + position: relative; background-color: #f1f1f1; border: 2px solid #a66; border-radius: 12px; @@ -1150,4 +1151,16 @@ div.captured-flag { height: 117px; width: 1268px; margin-bottom: 20px; +} + +#content { + position:relative; +} + +.webwolf-enabled { + position:absolute; + top: 10px; + right: 25px; + width: 42px; + height: 47px; } \ No newline at end of file diff --git a/webgoat-container/src/main/resources/static/js/goatApp/model/MenuCollection.js b/webgoat-container/src/main/resources/static/js/goatApp/model/MenuCollection.js index 709c557f7..c4c01c70a 100644 --- a/webgoat-container/src/main/resources/static/js/goatApp/model/MenuCollection.js +++ b/webgoat-container/src/main/resources/static/js/goatApp/model/MenuCollection.js @@ -1,29 +1,33 @@ define(['jquery', - 'underscore', - 'backbone', - 'goatApp/model/MenuModel'], - function($,_,Backbone,MenuModel) { + 'underscore', + 'backbone', + 'goatApp/model/MenuModel'], + function ($, _, Backbone, MenuModel) { - return Backbone.Collection.extend({ - model: MenuModel, - url:'service/lessonmenu.mvc', - initialize: function () { - var self = this; - this.fetch(); - }, + return Backbone.Collection.extend({ + model: MenuModel, + url: 'service/lessonmenu.mvc', - onDataLoaded: function() { - this.trigger('menuData:loaded'); - }, + initialize: function () { + var self = this; + this.fetch(); + setInterval(function () { + this.fetch() + }.bind(this), 5000); + }, - fetch: function() { - var self=this; - Backbone.Collection.prototype.fetch.apply(this,arguments).then( - function(data) { - this.models = data; - self.onDataLoaded(); - } - ); - } - }); -}); \ No newline at end of file + onDataLoaded: function () { + this.trigger('menuData:loaded'); + }, + + fetch: function () { + var self = this; + Backbone.Collection.prototype.fetch.apply(this, arguments).then( + function (data) { + this.models = data; + self.onDataLoaded(); + } + ); + } + }); + }); \ No newline at end of file diff --git a/webgoat-container/src/main/resources/static/js/goatApp/view/GoatRouter.js b/webgoat-container/src/main/resources/static/js/goatApp/view/GoatRouter.js index 54aa52828..84a23334f 100644 --- a/webgoat-container/src/main/resources/static/js/goatApp/view/GoatRouter.js +++ b/webgoat-container/src/main/resources/static/js/goatApp/view/GoatRouter.js @@ -67,7 +67,7 @@ define(['jquery', contentType: 'application/x-www-form-urlencoded; charset=UTF-8', success: function (data) { //devs leave stuff like this in all the time - console.log('phone home said ' + data); + console.log('phone home said ' + JSON.stringify(data)); } }); } diff --git a/webgoat-container/src/main/resources/static/js/goatApp/view/LessonContentView.js b/webgoat-container/src/main/resources/static/js/goatApp/view/LessonContentView.js index 65f45a63e..3fca490f0 100644 --- a/webgoat-container/src/main/resources/static/js/goatApp/view/LessonContentView.js +++ b/webgoat-container/src/main/resources/static/js/goatApp/view/LessonContentView.js @@ -25,6 +25,9 @@ define(['jquery', self.navToPage(page); } }); + setInterval(function () { + this.updatePagination(); + }.bind(this), 5000); }, findPage: function(assignment) { @@ -60,7 +63,9 @@ define(['jquery', }, updatePagination: function() { - this.paginationControlView.updateCollection(); + if ( this.paginationControlView != undefined ) { + this.paginationControlView.updateCollection(); + } }, getCurrentPage: function () { @@ -146,14 +151,23 @@ define(['jquery', return false; }, + removeSlashesFromJSON: function(str) { + // slashes are leftover escapes from JSON serialization by server + // for every two char sequence starting with backslash, + // replace them in the text with second char only + return str.replace(/\\(.)/g, "$1"); + }, + renderFeedback: function(feedback) { - this.$curFeedback.html(polyglot.t(feedback) || ""); + var s = this.removeSlashesFromJSON(feedback); + this.$curFeedback.html(polyglot.t(s) || ""); this.$curFeedback.show(400) }, renderOutput: function(output) { - this.$curOutput.html(polyglot.t(output) || ""); + var s = this.removeSlashesFromJSON(output); + this.$curOutput.html(polyglot.t(s) || ""); this.$curOutput.show(400) }, diff --git a/webgoat-container/src/main/resources/templates/main_new.html b/webgoat-container/src/main/resources/templates/main_new.html index 07f8143c8..eadb722c3 100644 --- a/webgoat-container/src/main/resources/templates/main_new.html +++ b/webgoat-container/src/main/resources/templates/main_new.html @@ -76,24 +76,25 @@

- - -
- + + + diff --git a/webgoat-container/src/test/java/org/owasp/webgoat/assignments/AssignmentEndpointTest.java b/webgoat-container/src/test/java/org/owasp/webgoat/assignments/AssignmentEndpointTest.java index 1f9628fb0..dc0c7a481 100644 --- a/webgoat-container/src/test/java/org/owasp/webgoat/assignments/AssignmentEndpointTest.java +++ b/webgoat-container/src/test/java/org/owasp/webgoat/assignments/AssignmentEndpointTest.java @@ -62,7 +62,7 @@ public class AssignmentEndpointTest { public void init(AssignmentEndpoint a) { messages.setBasenames("classpath:/i18n/messages", "classpath:/i18n/WebGoatLabels"); - when(userTrackerRepository.findOne(anyString())).thenReturn(userTracker); + when(userTrackerRepository.findByUser(anyString())).thenReturn(userTracker); ReflectionTestUtils.setField(a, "userTrackerRepository", userTrackerRepository); ReflectionTestUtils.setField(a, "userSessionData", userSessionData); ReflectionTestUtils.setField(a, "webSession", webSession); diff --git a/webgoat-container/src/test/java/org/owasp/webgoat/service/LessonMenuServiceTest.java b/webgoat-container/src/test/java/org/owasp/webgoat/service/LessonMenuServiceTest.java index d71126d82..196610274 100644 --- a/webgoat-container/src/test/java/org/owasp/webgoat/service/LessonMenuServiceTest.java +++ b/webgoat-container/src/test/java/org/owasp/webgoat/service/LessonMenuServiceTest.java @@ -63,7 +63,7 @@ public class LessonMenuServiceTest { when(course.getLessons(any())).thenReturn(Lists.newArrayList(l1, l2)); when(course.getCategories()).thenReturn(Lists.newArrayList(Category.ACCESS_CONTROL)); when(userTracker.getLessonTracker(any(AbstractLesson.class))).thenReturn(lessonTracker); - when(userTrackerRepository.findOne(anyString())).thenReturn(userTracker); + when(userTrackerRepository.findByUser(anyString())).thenReturn(userTracker); mockMvc.perform(MockMvcRequestBuilders.get(URL_LESSONMENU_MVC)) .andExpect(status().isOk()) @@ -81,7 +81,7 @@ public class LessonMenuServiceTest { when(course.getLessons(any())).thenReturn(Lists.newArrayList(l1)); when(course.getCategories()).thenReturn(Lists.newArrayList(Category.ACCESS_CONTROL)); when(userTracker.getLessonTracker(any(AbstractLesson.class))).thenReturn(lessonTracker); - when(userTrackerRepository.findOne(anyString())).thenReturn(userTracker); + when(userTrackerRepository.findByUser(anyString())).thenReturn(userTracker); mockMvc.perform(MockMvcRequestBuilders.get(URL_LESSONMENU_MVC)) diff --git a/webgoat-container/src/test/java/org/owasp/webgoat/service/LessonProgressServiceTest.java b/webgoat-container/src/test/java/org/owasp/webgoat/service/LessonProgressServiceTest.java index 2ca3e9169..cdab7c84f 100644 --- a/webgoat-container/src/test/java/org/owasp/webgoat/service/LessonProgressServiceTest.java +++ b/webgoat-container/src/test/java/org/owasp/webgoat/service/LessonProgressServiceTest.java @@ -72,7 +72,7 @@ public class LessonProgressServiceTest { @Before public void setup() { Assignment assignment = new Assignment("test", "test"); - when(userTrackerRepository.findOne(anyString())).thenReturn(userTracker); + when(userTrackerRepository.findByUser(anyString())).thenReturn(userTracker); when(userTracker.getLessonTracker(any(AbstractLesson.class))).thenReturn(lessonTracker); when(websession.getCurrentLesson()).thenReturn(lesson); when(lessonTracker.getLessonOverview()).thenReturn(Maps.newHashMap(assignment, true)); diff --git a/webgoat-container/src/test/java/org/owasp/webgoat/service/ReportCardServiceTest.java b/webgoat-container/src/test/java/org/owasp/webgoat/service/ReportCardServiceTest.java index e1b6f639f..f35c4131d 100644 --- a/webgoat-container/src/test/java/org/owasp/webgoat/service/ReportCardServiceTest.java +++ b/webgoat-container/src/test/java/org/owasp/webgoat/service/ReportCardServiceTest.java @@ -6,6 +6,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; +import org.owasp.webgoat.i18n.PluginMessages; import org.owasp.webgoat.lessons.AbstractLesson; import org.owasp.webgoat.session.Course; import org.owasp.webgoat.session.WebSession; @@ -40,10 +41,13 @@ public class ReportCardServiceTest { private UserTrackerRepository userTrackerRepository; @Mock private WebSession websession; + @Mock + private PluginMessages pluginMessages; @Before public void setup() { - this.mockMvc = standaloneSetup(new ReportCardService(websession, userTrackerRepository, course)).build(); + this.mockMvc = standaloneSetup(new ReportCardService(websession, userTrackerRepository, course, pluginMessages)).build(); + when(pluginMessages.getMessage(anyString())).thenReturn("Test"); } @Test @@ -53,7 +57,7 @@ public class ReportCardServiceTest { when(course.getTotalOfLessons()).thenReturn(1); when(course.getTotalOfAssignments()).thenReturn(10); when(course.getLessons()).thenReturn(Lists.newArrayList(lesson)); - when(userTrackerRepository.findOne(anyString())).thenReturn(userTracker); + when(userTrackerRepository.findByUser(anyString())).thenReturn(userTracker); when(userTracker.getLessonTracker(any(AbstractLesson.class))).thenReturn(lessonTracker); mockMvc.perform(MockMvcRequestBuilders.get("/service/reportcard.mvc")) .andExpect(status().isOk()) diff --git a/webgoat-container/src/test/java/org/owasp/webgoat/users/UserTrackerRepositoryTest.java b/webgoat-container/src/test/java/org/owasp/webgoat/users/UserTrackerRepositoryTest.java index 5c8092c13..142a6c8c7 100644 --- a/webgoat-container/src/test/java/org/owasp/webgoat/users/UserTrackerRepositoryTest.java +++ b/webgoat-container/src/test/java/org/owasp/webgoat/users/UserTrackerRepositoryTest.java @@ -62,7 +62,7 @@ public class UserTrackerRepositoryTest { userTrackerRepository.save(userTracker); - userTracker = userTrackerRepository.findOne("test"); + userTracker = userTrackerRepository.findByUser("test"); Assertions.assertThat(userTracker.getLessonTracker("test")).isNotNull(); } @@ -77,7 +77,7 @@ public class UserTrackerRepositoryTest { userTrackerRepository.saveAndFlush(userTracker); - userTracker = userTrackerRepository.findOne("test"); + userTracker = userTrackerRepository.findByUser("test"); Assertions.assertThat(userTracker.numberOfAssignmentsSolved()).isEqualTo(1); } @@ -90,7 +90,7 @@ public class UserTrackerRepositoryTest { userTracker.assignmentFailed(lesson); userTrackerRepository.saveAndFlush(userTracker); - userTracker = userTrackerRepository.findOne("test"); + userTracker = userTrackerRepository.findByUser("test"); userTracker.assignmentFailed(lesson); userTracker.assignmentFailed(lesson); userTrackerRepository.saveAndFlush(userTracker); diff --git a/webgoat-lessons/auth-bypass/pom.xml b/webgoat-lessons/auth-bypass/pom.xml index f0242337f..22253bee4 100644 --- a/webgoat-lessons/auth-bypass/pom.xml +++ b/webgoat-lessons/auth-bypass/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - 8.0.0.M3 + v8.0.0.M14 diff --git a/webgoat-lessons/bypass-restrictions/pom.xml b/webgoat-lessons/bypass-restrictions/pom.xml index 3d05db060..8ae0f4f4c 100755 --- a/webgoat-lessons/bypass-restrictions/pom.xml +++ b/webgoat-lessons/bypass-restrictions/pom.xml @@ -6,6 +6,6 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - 8.0.0.M3 + v8.0.0.M14 diff --git a/webgoat-lessons/challenge/pom.xml b/webgoat-lessons/challenge/pom.xml index a35c0b48a..60639ca63 100644 --- a/webgoat-lessons/challenge/pom.xml +++ b/webgoat-lessons/challenge/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - 8.0.0.M3 + v8.0.0.M14 diff --git a/webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/Flag.java b/webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/Flag.java index fe9d66466..7d5c85967 100644 --- a/webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/Flag.java +++ b/webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/Flag.java @@ -46,7 +46,6 @@ public class Flag extends Endpoint { @PostConstruct public void initFlags() { IntStream.range(1, 10).forEach(i -> FLAGS.put(i, UUID.randomUUID().toString())); - FLAGS.entrySet().stream().forEach(e -> log.debug("Flag {} {}", e.getKey(), e.getValue())); } @Override diff --git a/webgoat-lessons/client-side-filtering/pom.xml b/webgoat-lessons/client-side-filtering/pom.xml index 6c7af20ab..95970426a 100644 --- a/webgoat-lessons/client-side-filtering/pom.xml +++ b/webgoat-lessons/client-side-filtering/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - 8.0.0.M3 + v8.0.0.M14 diff --git a/webgoat-lessons/client-side-filtering/src/main/java/org/owasp/webgoat/plugin/ClientSideFiltering.java b/webgoat-lessons/client-side-filtering/src/main/java/org/owasp/webgoat/plugin/ClientSideFiltering.java index 98a7c4172..84596b1ba 100644 --- a/webgoat-lessons/client-side-filtering/src/main/java/org/owasp/webgoat/plugin/ClientSideFiltering.java +++ b/webgoat-lessons/client-side-filtering/src/main/java/org/owasp/webgoat/plugin/ClientSideFiltering.java @@ -56,7 +56,7 @@ public class ClientSideFiltering extends NewLesson { @Override public String getTitle() { - return "Client side filtering"; + return "client.side.filtering.title"; } @Override diff --git a/webgoat-lessons/client-side-filtering/src/main/resources/i18n/WebGoatLabels.properties b/webgoat-lessons/client-side-filtering/src/main/resources/i18n/WebGoatLabels.properties index a5a163cad..e9a044325 100644 --- a/webgoat-lessons/client-side-filtering/src/main/resources/i18n/WebGoatLabels.properties +++ b/webgoat-lessons/client-side-filtering/src/main/resources/i18n/WebGoatLabels.properties @@ -1,3 +1,4 @@ +client.side.filtering.title=Client side filtering ClientSideFilteringSelectUser=Select user: ClientSideFilteringUserID=User ID ClientSideFilteringFirstName=First Name diff --git a/webgoat-lessons/cross-site-scripting/pom.xml b/webgoat-lessons/cross-site-scripting/pom.xml index e4612dbe3..71723d5b3 100644 --- a/webgoat-lessons/cross-site-scripting/pom.xml +++ b/webgoat-lessons/cross-site-scripting/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - 8.0.0.M3 + v8.0.0.M14 diff --git a/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScripting.java b/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScripting.java index 609fb49cd..c1453a112 100644 --- a/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScripting.java +++ b/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScripting.java @@ -60,7 +60,7 @@ public class CrossSiteScripting extends NewLesson { @Override public String getTitle() { - return "Cross Site Scripting"; + return "xss.title"; } @Override diff --git a/webgoat-lessons/cross-site-scripting/src/main/resources/i18n/WebGoatLabels.properties b/webgoat-lessons/cross-site-scripting/src/main/resources/i18n/WebGoatLabels.properties index 9d3490287..3f6a96ee2 100644 --- a/webgoat-lessons/cross-site-scripting/src/main/resources/i18n/WebGoatLabels.properties +++ b/webgoat-lessons/cross-site-scripting/src/main/resources/i18n/WebGoatLabels.properties @@ -1,4 +1,5 @@ # XSS success, failure messages and hints +xss.title=Cross Site Scripting xss-reflected-5a-success=well done, but alerts aren't very impressive are they? Please continue. xss-reflected-5a-failure=Try again. We do want to see this specific javascript (in case you are trying to do something more fancy) xss-reflected-5b-success=Correct ... because
  • The script was not triggered by the URL/QueryString
  • Even if you use the attack URL in a new tab, it won't execute (becuase of response type). Try it if you like.
diff --git a/webgoat-lessons/csrf/pom.xml b/webgoat-lessons/csrf/pom.xml index f3486e80e..fdc72d3f4 100644 --- a/webgoat-lessons/csrf/pom.xml +++ b/webgoat-lessons/csrf/pom.xml @@ -6,6 +6,6 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - 8.0.0.M3 + v8.0.0.M14 \ No newline at end of file diff --git a/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/CSRFLogin.java b/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/CSRFLogin.java index 97edff2c1..122238bc1 100644 --- a/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/CSRFLogin.java +++ b/webgoat-lessons/csrf/src/main/java/org/owasp/webgoat/plugin/CSRFLogin.java @@ -33,7 +33,7 @@ public class CSRFLogin extends AssignmentEndpoint { } private void markAssignmentSolvedWithRealUser(String username) { - UserTracker userTracker = userTrackerRepository.findOne(username); + UserTracker userTracker = userTrackerRepository.findByUser(username); userTracker.assignmentSolved(getWebSession().getCurrentLesson(), this.getClass().getSimpleName()); userTrackerRepository.save(userTracker); } diff --git a/webgoat-lessons/csrf/src/main/resources/lessonPlans/en/CSRF_ContentType.adoc b/webgoat-lessons/csrf/src/main/resources/lessonPlans/en/CSRF_ContentType.adoc index 3e9f217c6..735e320bc 100644 --- a/webgoat-lessons/csrf/src/main/resources/lessonPlans/en/CSRF_ContentType.adoc +++ b/webgoat-lessons/csrf/src/main/resources/lessonPlans/en/CSRF_ContentType.adoc @@ -8,11 +8,11 @@ In this assignment you need to achieve to POST the following JSON message to our [source] ---- -POST /csrf/feedback HTTP/1.1 +POST /csrf/feedback/message HTTP/1.1 { "name" : "WebGoat", - "email" : "webgoat@webgoat.org" + "email" : "webgoat@webgoat.org", "content" : "WebGoat is the best!!" } ---- diff --git a/webgoat-lessons/html-tampering/pom.xml b/webgoat-lessons/html-tampering/pom.xml index 8c1bd0cc1..f90a5c862 100755 --- a/webgoat-lessons/html-tampering/pom.xml +++ b/webgoat-lessons/html-tampering/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - 8.0.0.M3 + v8.0.0.M14 diff --git a/webgoat-lessons/http-basics/pom.xml b/webgoat-lessons/http-basics/pom.xml index 8186c300a..a77c8e0a0 100644 --- a/webgoat-lessons/http-basics/pom.xml +++ b/webgoat-lessons/http-basics/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - 8.0.0.M3 + v8.0.0.M14 diff --git a/webgoat-lessons/http-basics/src/main/resources/i18n/WebGoatLabels.properties b/webgoat-lessons/http-basics/src/main/resources/i18n/WebGoatLabels.properties index 71209ebca..a99bf8ab6 100644 --- a/webgoat-lessons/http-basics/src/main/resources/i18n/WebGoatLabels.properties +++ b/webgoat-lessons/http-basics/src/main/resources/i18n/WebGoatLabels.properties @@ -8,6 +8,7 @@ http-basics.hints.http_basic_quiz.1=Turn on Show Parameters or other features http-basics.hints.http_basic_quiz.2=Try to intercept the request with OWASP ZAP +http-basics.empty=Try again, name cannot be empty. http-basics.reversed=The server has reversed your name: {0} http-basics.close=Try again: but this time enter a value before hitting go. diff --git a/webgoat-lessons/http-proxies/pom.xml b/webgoat-lessons/http-proxies/pom.xml index ac544a8f7..0c656a7ff 100644 --- a/webgoat-lessons/http-proxies/pom.xml +++ b/webgoat-lessons/http-proxies/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - 8.0.0.M3 + v8.0.0.M14 diff --git a/webgoat-lessons/idor/pom.xml b/webgoat-lessons/idor/pom.xml index a4218f71f..0dd3ab28f 100644 --- a/webgoat-lessons/idor/pom.xml +++ b/webgoat-lessons/idor/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - 8.0.0.M3 + v8.0.0.M14 \ No newline at end of file diff --git a/webgoat-lessons/insecure-login/pom.xml b/webgoat-lessons/insecure-login/pom.xml index b21689b14..4d4d9625c 100755 --- a/webgoat-lessons/insecure-login/pom.xml +++ b/webgoat-lessons/insecure-login/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - 8.0.0.M3 + v8.0.0.M14 diff --git a/webgoat-lessons/jwt/pom.xml b/webgoat-lessons/jwt/pom.xml index f55f51d91..e03c3385e 100644 --- a/webgoat-lessons/jwt/pom.xml +++ b/webgoat-lessons/jwt/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - 8.0.0.M3 + v8.0.0.M14 diff --git a/webgoat-lessons/missing-function-ac/pom.xml b/webgoat-lessons/missing-function-ac/pom.xml index cc0fbffd4..71d667565 100644 --- a/webgoat-lessons/missing-function-ac/pom.xml +++ b/webgoat-lessons/missing-function-ac/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - 8.0.0.M3 + v8.0.0.M14 diff --git a/webgoat-lessons/pom.xml b/webgoat-lessons/pom.xml index 5711263d3..fb6c01861 100644 --- a/webgoat-lessons/pom.xml +++ b/webgoat-lessons/pom.xml @@ -5,12 +5,12 @@ org.owasp.webgoat.lesson webgoat-lessons-parent pom - 8.0.0.M3 + v8.0.0.M14 org.owasp.webgoat webgoat-parent - 8.0.0.M3 + v8.0.0.M14 diff --git a/webgoat-lessons/sql-injection/pom.xml b/webgoat-lessons/sql-injection/pom.xml index 37283bdd5..676c9cc4e 100644 --- a/webgoat-lessons/sql-injection/pom.xml +++ b/webgoat-lessons/sql-injection/pom.xml @@ -6,6 +6,6 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - 8.0.0.M3 + v8.0.0.M14 \ No newline at end of file diff --git a/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/advanced/SqlInjectionAdvanced.java b/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/advanced/SqlInjectionAdvanced.java index 3df685705..5313ac86b 100644 --- a/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/advanced/SqlInjectionAdvanced.java +++ b/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/advanced/SqlInjectionAdvanced.java @@ -53,7 +53,7 @@ public class SqlInjectionAdvanced extends NewLesson { @Override public String getTitle() { - return "SQL Injection (advanced)"; + return "sql.advanced.title"; } @Override diff --git a/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/introduction/SqlInjection.java b/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/introduction/SqlInjection.java index d5df3c88a..63d7b0041 100644 --- a/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/introduction/SqlInjection.java +++ b/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/introduction/SqlInjection.java @@ -60,7 +60,7 @@ public class SqlInjection extends NewLesson { @Override public String getTitle() { - return "SQL Injection"; + return "sql.injection.title"; } @Override diff --git a/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/mitigation/SqlInjectionMitigations.java b/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/mitigation/SqlInjectionMitigations.java index 463c4dfdc..2546bfb7f 100644 --- a/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/mitigation/SqlInjectionMitigations.java +++ b/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/mitigation/SqlInjectionMitigations.java @@ -53,7 +53,7 @@ public class SqlInjectionMitigations extends NewLesson { @Override public String getTitle() { - return "SQL Injection (mitigations)"; + return "sql.mitigation.title"; } @Override diff --git a/webgoat-lessons/sql-injection/src/main/resources/i18n/WebGoatLabels.properties b/webgoat-lessons/sql-injection/src/main/resources/i18n/WebGoatLabels.properties index 8f4c69431..409f69b6f 100644 --- a/webgoat-lessons/sql-injection/src/main/resources/i18n/WebGoatLabels.properties +++ b/webgoat-lessons/sql-injection/src/main/resources/i18n/WebGoatLabels.properties @@ -1,6 +1,12 @@ #StringSqlInjection.java StringSqlInjectionSecondStage=Now that you have successfully performed an SQL injection, try the same type of attack on a parameterized query. Restart the lesson if you wish to return to the injectable query. EnterLastName=Enter your last name: + +sql.injection.title=SQL Injection +sql.mitigation.title=SQL Injection (mitigation) +sql.advanced.title=SQL Injection (advanced) + + NoResultsMatched=No results matched. Try Again. SqlStringInjectionHint1=The application is taking your input and inserting it at the end of a pre-formed SQL command. SqlStringInjectionHint2=This is the code for the query being built and issued by WebGoat:

"SELECT * FROM user_data WHERE last_name = "accountName" diff --git a/webgoat-lessons/vulnerable-components/pom.xml b/webgoat-lessons/vulnerable-components/pom.xml index fa63b8c60..26f718269 100644 --- a/webgoat-lessons/vulnerable-components/pom.xml +++ b/webgoat-lessons/vulnerable-components/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - 8.0.0.M3 + v8.0.0.M14 diff --git a/webgoat-lessons/webgoat-introduction/pom.xml b/webgoat-lessons/webgoat-introduction/pom.xml index e21212549..c4076cf17 100644 --- a/webgoat-lessons/webgoat-introduction/pom.xml +++ b/webgoat-lessons/webgoat-introduction/pom.xml @@ -6,6 +6,6 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - 8.0.0.M3 + v8.0.0.M14 \ No newline at end of file diff --git a/webgoat-lessons/webwolf-introduction/pom.xml b/webgoat-lessons/webwolf-introduction/pom.xml index 395a2423f..b55a6a0eb 100644 --- a/webgoat-lessons/webwolf-introduction/pom.xml +++ b/webgoat-lessons/webwolf-introduction/pom.xml @@ -6,6 +6,6 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - 8.0.0.M3 + v8.0.0.M14 \ No newline at end of file diff --git a/webgoat-lessons/webwolf-introduction/src/main/java/org/owasp/webgoat/plugin/MailAssignment.java b/webgoat-lessons/webwolf-introduction/src/main/java/org/owasp/webgoat/plugin/MailAssignment.java index 54e17a9c2..c10321e74 100644 --- a/webgoat-lessons/webwolf-introduction/src/main/java/org/owasp/webgoat/plugin/MailAssignment.java +++ b/webgoat-lessons/webwolf-introduction/src/main/java/org/owasp/webgoat/plugin/MailAssignment.java @@ -8,6 +8,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.client.RestClientException; import org.springframework.web.client.RestTemplate; import java.time.LocalDateTime; @@ -39,7 +40,11 @@ public class MailAssignment extends AssignmentEndpoint { .contents("This is a test message from WebWolf, your unique code is: " + StringUtils.reverse(username)) .sender("webgoat@owasp.org") .build(); - restTemplate.postForEntity(webWolfURL, mailEvent, Object.class); + try { + restTemplate.postForEntity(webWolfURL, mailEvent, Object.class); + } catch (RestClientException e ) { + return informationMessage().feedback("webwolf.email_failed").output(e.getMessage()).build(); + } return informationMessage().feedback("webwolf.email_send").feedbackArgs(email).build(); } else { return informationMessage().feedback("webwolf.email_mismatch").feedbackArgs(username).build(); diff --git a/webgoat-lessons/webwolf-introduction/src/main/resources/html/WebWolfIntroduction.html b/webgoat-lessons/webwolf-introduction/src/main/resources/html/WebWolfIntroduction.html index fc443b7c7..70586184c 100644 --- a/webgoat-lessons/webwolf-introduction/src/main/resources/html/WebWolfIntroduction.html +++ b/webgoat-lessons/webwolf-introduction/src/main/resources/html/WebWolfIntroduction.html @@ -12,6 +12,7 @@
+
+
Click here to reset your password diff --git a/webgoat-lessons/webwolf-introduction/src/main/resources/i18n/WebGoatLabels.properties b/webgoat-lessons/webwolf-introduction/src/main/resources/i18n/WebGoatLabels.properties index 20947800b..0981f2a08 100644 --- a/webgoat-lessons/webwolf-introduction/src/main/resources/i18n/WebGoatLabels.properties +++ b/webgoat-lessons/webwolf-introduction/src/main/resources/i18n/WebGoatLabels.properties @@ -2,7 +2,7 @@ webwolf.title=WebWolf webwolf.email_send=An email has been send to {0} please check your inbox. webwolf.code_incorrect=That is not the correct code: {0}, please try again. - +webwolf.email_failed=There was an error while sending the e-mail. Is WebWolf running? webwolf.email_mismatch=Of course you can send mail to user {0} however you will not be able to read this e-mail in WebWolf, please use your own username. diff --git a/webgoat-lessons/webwolf-introduction/src/main/resources/images/wolf-enabled.png b/webgoat-lessons/webwolf-introduction/src/main/resources/images/wolf-enabled.png new file mode 100644 index 000000000..d343c07d9 Binary files /dev/null and b/webgoat-lessons/webwolf-introduction/src/main/resources/images/wolf-enabled.png differ diff --git a/webgoat-lessons/webwolf-introduction/src/main/resources/lessonPlans/en/IntroductionWebWolf.adoc b/webgoat-lessons/webwolf-introduction/src/main/resources/lessonPlans/en/IntroductionWebWolf.adoc index 37ee96c81..0bbd39bc1 100644 --- a/webgoat-lessons/webwolf-introduction/src/main/resources/lessonPlans/en/IntroductionWebWolf.adoc +++ b/webgoat-lessons/webwolf-introduction/src/main/resources/lessonPlans/en/IntroductionWebWolf.adoc @@ -1,7 +1,17 @@ == Introducing WebWolf -NOTE: You only need WebWolf if you a lesson specifies you can use it. For a lot of lessons you use WebGoat without -starting WebWolf. +You only need WebWolf if you a lesson specifies you can use it. For a lot of lessons you use WebGoat without +starting WebWolf. If you need to do an exercise with WebWolf make sure it is running along side with WebGoat. Lessons +where you can use WebWolf are marked with the following icon (top right in assignment): + +{nbsp} + +image::images/wolf-enabled.png[width=115,height=128] + +{nbsp} + +Even if the icon the present your are not obliged to use WebWolf, you can also use any intercepting tool you like, like +`netcat` etc. WebWolf is a separate web application which simulates an attackers machine. It makes it possible for us to make a clear distinction between what takes place on the attacked website and the actions you need to do as @@ -20,12 +30,18 @@ are not using the Docker image you will need to download the jar file and start java -jar webwolf-<>.jar ``` -WebWolf is also available as a Docker container: +WebWolf is also available as a Docker container, because it shares the database with WebGoat we first need +to find out the ip address of the Docker container. ``` -docker pull webwolf/webwolf-8.0 -docker run -it 8081:8081 /home/webwolf/run.sh +WEBGOAT_SERVER_ADDRESS=$(docker inspect -f "{{ .NetworkSettings.IPAddress }}" `docker ps | grep webgoat | awk '{print $1}'`) +docker pull webgoat/webwolf +docker run -e webgoat.server.address=${WEBGOAT_SERVER_ADDRESS} -it -p 8081:8081 webgoat/webwolf /home/webwolf/run.sh ``` +Note: if you start WebGoat as standalone application you need to start WebWolf as standalone application as well. If +you start WebGoat as Docker container you need to start WebWolf as Docker container as well. + + This will start the application on port 8081, click webWolfLink:here[] to open WebWolf. First thing you need to do is register a new user within WebWolf. \ No newline at end of file diff --git a/webgoat-lessons/xxe/pom.xml b/webgoat-lessons/xxe/pom.xml index 169b86501..3ac778514 100644 --- a/webgoat-lessons/xxe/pom.xml +++ b/webgoat-lessons/xxe/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat.lesson webgoat-lessons-parent - 8.0.0.M3 + v8.0.0.M14 diff --git a/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/plugin/XXE.java b/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/plugin/XXE.java index 43ebad5ac..b35433e30 100644 --- a/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/plugin/XXE.java +++ b/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/plugin/XXE.java @@ -58,7 +58,7 @@ public class XXE extends NewLesson { @Override public String getTitle() { - return "XXE"; + return "xxe.title"; } @Override diff --git a/webgoat-lessons/xxe/src/main/resources/html/XXE.html b/webgoat-lessons/xxe/src/main/resources/html/XXE.html index 39eadc226..f0706e8e3 100644 --- a/webgoat-lessons/xxe/src/main/resources/html/XXE.html +++ b/webgoat-lessons/xxe/src/main/resources/html/XXE.html @@ -144,6 +144,7 @@
+
# +xxe.title=XXE xxe.simple.output=Welcome {0} you can now login to our website xxe.content.type.feedback.json=You are posting JSON which does not work with a XXE xxe.content.type.feedback.xml=You are posting XML but there is no XXE attack performed diff --git a/webgoat-lessons/xxe/src/main/resources/images/wolf-enabled.png b/webgoat-lessons/xxe/src/main/resources/images/wolf-enabled.png new file mode 100644 index 000000000..d343c07d9 Binary files /dev/null and b/webgoat-lessons/xxe/src/main/resources/images/wolf-enabled.png differ diff --git a/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_blind.adoc b/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_blind.adoc index c8114bc1c..72c9e4886 100644 --- a/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_blind.adoc +++ b/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_blind.adoc @@ -1,4 +1,3 @@ - == Blind XXE In some cases you will see no output because although your attack might have worked the field is not reflected in the output of page. @@ -6,25 +5,25 @@ Or the resource you are trying to read contains illegal XML character which caus Let's start with an example, in this case we reference an external DTD which we control on our own server. As an attacker you have WebWolf under your control (*this can be any server under your control.*), you can for example -use this server to ping it using `http://localhost:8081/ping?text=HelloWorld +use this server to ping it using `webWolfLink:landing[noLink]` How do we use this endpoint to verify whether we can perform XXE? We can again use WebWolf to host a file called `attack.dtd`, create this file with the following contents: -[source] +[source, subs="macros, specialcharacters"] ---- - + ---- Now submit the form change the xml using to: -[source] +[source, subs="macros, specialcharacters"] ---- + %remote; ]> diff --git a/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_blind_assignment.adoc b/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_blind_assignment.adoc index e7adfae9b..dd5ae4194 100644 --- a/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_blind_assignment.adoc +++ b/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_blind_assignment.adoc @@ -9,15 +9,15 @@ DTD. |OS |Location |Linux -|`/home/USER/.webgoat/XXE/secret.txt` +|`/home/USER/.webgoat-webGoatVersion:version[]/XXE/secret.txt` |Windows -|`c:/Users/USER/.webgoat/XXE/secret.txt` +|`c:/Users/USER/.webgoat-webGoatVersion:version[]/XXE/secret.txt` |Docker -|`/home/webgoat/.webgoat/XXE/secret.txt` +|`/home/webgoat/.webgoat-webGoatVersion:version[]/XXE/secret.txt` |=== -Try to upload this file using WebWolf landing page for example: `http://localhost:8081/WebWolf/landing?text=[contents_file]` +Try to upload this file using WebWolf landing page for example: `webWolfLink:landing?text=contents_file[noLink]` (NOTE: this endpoint is under your full control) Once you obtained the contents of the file post it as a new comment on the page and you will solve the lesson. \ No newline at end of file diff --git a/webgoat-server/Dockerfile b/webgoat-server/Dockerfile index 2f1b6f0fd..860bb1b3f 100644 --- a/webgoat-server/Dockerfile +++ b/webgoat-server/Dockerfile @@ -2,13 +2,13 @@ FROM openjdk:8-jre-slim ARG webgoat_version=8.0-SNAPSHOT -RUN useradd --home-dir /home/webgoat --create-home -U webgoat - -RUN apt-get update; apt-get install curl -y - -COPY start.sh /home/webgoat/start.sh -RUN chmod +x /home/webgoat/start.sh +RUN \ + apt-get update && apt-get install && \ + useradd --home-dir /home/webgoat --create-home -U webgoat USER webgoat -RUN cd /home/webgoat/; mkdir -p .webgoat +RUN cd /home/webgoat/; mkdir -p .webgoat-${webgoat_version} COPY target/webgoat-server-${webgoat_version}.jar /home/webgoat/webgoat.jar + +ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/home/webgoat/webgoat.jar", "--server.address=0.0.0.0"] +EXPOSE 8080 \ No newline at end of file diff --git a/webgoat-server/pom.xml b/webgoat-server/pom.xml index 6bec68abb..483c3a0b6 100644 --- a/webgoat-server/pom.xml +++ b/webgoat-server/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat webgoat-parent - 8.0.0.M3 + v8.0.0.M14 @@ -198,6 +198,11 @@ spring-boot-devtools true + + org.postgresql + postgresql + 42.2.2 + diff --git a/webgoat-server/src/main/java/org/owasp/webgoat/HSQLDBDatabaseConfig.java b/webgoat-server/src/main/java/org/owasp/webgoat/HSQLDBDatabaseConfig.java new file mode 100644 index 000000000..fe42f1c97 --- /dev/null +++ b/webgoat-server/src/main/java/org/owasp/webgoat/HSQLDBDatabaseConfig.java @@ -0,0 +1,51 @@ +package org.owasp.webgoat; + +import org.hsqldb.server.Server; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.DependsOn; +import org.springframework.context.annotation.Primary; + +import javax.sql.DataSource; + + +/** + * Rationale for this class: when the HSQLDB is started with jdbc:file:// it is only accessible from within the same + * JVM. This can only be done if you start a standalone HSQLDB. We need both WebWolf and WebGoat to use the same database + */ +@Configuration +@ConditionalOnProperty(prefix = "webgoat.start", name = "hsqldb", havingValue = "true") +public class HSQLDBDatabaseConfig { + + @Value("${hsqldb.port:9001}") + private int hsqldbPort; + + @Bean(initMethod = "start", destroyMethod = "stop") + public Server hsqlStandalone(@Value("${webgoat.server.directory}") String directory, + @Value("${hsqldb.silent:true}") boolean silent, + @Value("${hsqldb.trace:false}") boolean trace) { + + Server server = new Server(); + server.setDatabaseName(0, "webgoat"); + server.setDatabasePath(0, directory + "/data/webgoat"); + server.setDaemon(true); + server.setTrace(trace); + server.setSilent(silent); + server.setPort(hsqldbPort); + return server; + } + + @Primary + @Bean + @DependsOn("hsqlStandalone") + public DataSource dataSource(@Value("${spring.datasource.driver-class-name}") String driverClass, + @Value("${spring.datasource.url}") String url) { + return DataSourceBuilder.create() + .driverClassName(driverClass) + .url(url) + .build(); + } +} diff --git a/webgoat-server/src/main/java/org/owasp/webgoat/StartWebGoat.java b/webgoat-server/src/main/java/org/owasp/webgoat/StartWebGoat.java index a615d5b74..34bde941a 100644 --- a/webgoat-server/src/main/java/org/owasp/webgoat/StartWebGoat.java +++ b/webgoat-server/src/main/java/org/owasp/webgoat/StartWebGoat.java @@ -37,7 +37,4 @@ public class StartWebGoat { public static void main(String[] args) { SpringApplication.run(WebGoat.class, args); } - - - } diff --git a/webgoat-server/start.sh b/webgoat-server/start.sh deleted file mode 100644 index 491a89ef7..000000000 --- a/webgoat-server/start.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -java -jar -Djava.security.egd=file:/dev/./urandom /home/webgoat/webgoat.jar diff --git a/webwolf/Dockerfile b/webwolf/Dockerfile index 162fe5a2c..a591b2ae5 100644 --- a/webwolf/Dockerfile +++ b/webwolf/Dockerfile @@ -2,12 +2,13 @@ FROM openjdk:8-jre-slim ARG webwolf_version=8.0-SNAPSHOT -RUN useradd --home-dir /home/webwolf --create-home -U webwolf - -RUN apt-get update; apt-get install curl -y - -COPY start.sh /home/webwolf/start.sh -RUN chmod +x /home/webwolf/start.sh +RUN \ + apt-get update && apt-get install && \ + useradd --home-dir /home/webwolf --create-home -U webwolf USER webwolf COPY target/webwolf-${webwolf_version}.jar /home/webwolf/webwolf.jar + +ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/home/webwolf/webwolf.jar", "--server.address=0.0.0.0"] + +EXPOSE 8081 diff --git a/webwolf/pom.xml b/webwolf/pom.xml index 6e2ade92b..ee2728a35 100644 --- a/webwolf/pom.xml +++ b/webwolf/pom.xml @@ -6,7 +6,7 @@ org.owasp.webgoat webgoat-parent - 8.0.0.M3 + v8.0.0.M14 @@ -78,6 +78,11 @@ hsqldb ${hsqldb.version} + + org.postgresql + postgresql + 42.2.2 + @@ -85,6 +90,10 @@ spring-boot-starter-test test + + org.springframework.security + spring-security-test + diff --git a/webwolf/src/main/java/org/owasp/webwolf/mailbox/Email.java b/webwolf/src/main/java/org/owasp/webwolf/mailbox/Email.java index d721bc5d5..c97e0ba4e 100644 --- a/webwolf/src/main/java/org/owasp/webwolf/mailbox/Email.java +++ b/webwolf/src/main/java/org/owasp/webwolf/mailbox/Email.java @@ -1,5 +1,8 @@ package org.owasp.webwolf.mailbox; +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; @@ -13,6 +16,8 @@ import java.time.format.DateTimeFormatter; * @since 8/20/17. */ @Data +@Builder +@AllArgsConstructor @Entity @NoArgsConstructor public class Email implements Serializable { @@ -20,7 +25,7 @@ public class Email implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - private LocalDateTime time; + private LocalDateTime time = LocalDateTime.now(); @Column(length = 1024) private String contents; private String sender; @@ -28,7 +33,7 @@ public class Email implements Serializable { private String recipient; public String getSummary() { - return "-" + this.contents.substring(0, 50); + return "-" + this.contents.substring(0, Math.min(50, contents.length())); } public LocalDateTime getTimestamp() { diff --git a/webwolf/src/main/java/org/owasp/webwolf/mailbox/MailboxController.java b/webwolf/src/main/java/org/owasp/webwolf/mailbox/MailboxController.java index 52ec55959..169b5f189 100644 --- a/webwolf/src/main/java/org/owasp/webwolf/mailbox/MailboxController.java +++ b/webwolf/src/main/java/org/owasp/webwolf/mailbox/MailboxController.java @@ -7,6 +7,8 @@ import org.owasp.webwolf.user.WebGoatUser; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -25,12 +27,11 @@ import java.util.concurrent.Callable; @Slf4j public class MailboxController { - private final UserRepository userRepository; private final MailboxRepository mailboxRepository; @GetMapping(value = "/WebWolf/mail") public ModelAndView mail() { - WebGoatUser user = (WebGoatUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + UserDetails user = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); ModelAndView modelAndView = new ModelAndView(); List emails = mailboxRepository.findByRecipientOrderByTimeDesc(user.getUsername()); if (emails != null && !emails.isEmpty()) { @@ -44,13 +45,8 @@ public class MailboxController { @PostMapping(value = "/mail") public Callable> sendEmail(@RequestBody Email email) { return () -> { - if (userRepository.findByUsername(email.getRecipient()) != null) { - mailboxRepository.save(email); - return ResponseEntity.status(HttpStatus.CREATED).build(); - } else { - log.trace("Mail received for unknown user: {}", email.getRecipient()); - return ResponseEntity.notFound().build(); - } + mailboxRepository.save(email); + return ResponseEntity.status(HttpStatus.CREATED).build(); }; } diff --git a/webwolf/src/main/resources/application.properties b/webwolf/src/main/resources/application.properties index b169284c8..2d8f6dded 100644 --- a/webwolf/src/main/resources/application.properties +++ b/webwolf/src/main/resources/application.properties @@ -3,9 +3,11 @@ server.error.path=/error.html server.session.timeout=6000 #server.contextPath=/WebWolf server.port=8081 +server.address=127.0.0.1 server.session.cookie.name = WEBWOLFSESSION -spring.datasource.url=jdbc:hsqldb:file:${webgoat.server.directory}/data/webwolf +spring.datasource.url=jdbc:hsqldb:hsql://${webgoat.server.address:localhost}:9001/webgoat +spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.HSQLDialect spring.jpa.hibernate.ddl-auto=update spring.messages.basename=i18n/messages @@ -29,7 +31,8 @@ multipart.location=${java.io.tmpdir} multipart.max-file-size=1Mb multipart.max-request-size=1Mb -webgoat.server.directory=${user.home}/.webgoat/ +webgoat.build.version=@project.version@ +webgoat.server.directory=${user.home}/.webgoat-${webgoat.build.version}/ webwolf.fileserver.location=${java.io.tmpdir}/webwolf-fileserver spring.jackson.serialization.indent_output=true diff --git a/webwolf/src/main/resources/templates/login.html b/webwolf/src/main/resources/templates/login.html index 755831691..f651a437f 100644 --- a/webwolf/src/main/resources/templates/login.html +++ b/webwolf/src/main/resources/templates/login.html @@ -45,7 +45,7 @@
-
+
diff --git a/webwolf/src/test/java/org/owasp/webwolf/mailbox/MailboxControllerTest.java b/webwolf/src/test/java/org/owasp/webwolf/mailbox/MailboxControllerTest.java new file mode 100644 index 000000000..3c554a68d --- /dev/null +++ b/webwolf/src/test/java/org/owasp/webwolf/mailbox/MailboxControllerTest.java @@ -0,0 +1,98 @@ +package org.owasp.webwolf.mailbox; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.collect.Lists; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.not; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +@RunWith(SpringRunner.class) +@WebMvcTest(MailboxController.class) +public class MailboxControllerTest { + + @Autowired + private MockMvc mvc; + @MockBean + private MailboxRepository mailbox; + @Autowired + private ObjectMapper objectMapper; + + @JsonIgnoreProperties("time") + public static class EmailMixIn { + } + + @Before + public void setup() { + objectMapper.addMixIn(Email.class, EmailMixIn.class); + } + + @Test + @WithMockUser + public void sendingMailShouldStoreIt() throws Exception { + Email email = Email.builder() + .contents("This is a test mail") + .recipient("test1234@webgoat.org") + .sender("hacker@webgoat.org") + .title("Click this mail") + .time(LocalDateTime.now()) + .build(); + this.mvc.perform(post("/mail").contentType(MediaType.APPLICATION_JSON).content(objectMapper.writeValueAsBytes(email))) + .andExpect(status().isOk()); + } + + @Test + @WithMockUser(username = "test1234") + public void userShouldBeAbleToReadOwnEmail() throws Exception { + Email email = Email.builder() + .contents("This is a test mail") + .recipient("test1234@webgoat.org") + .sender("hacker@webgoat.org") + .title("Click this mail") + .time(LocalDateTime.now()) + .build(); + Mockito.when(mailbox.findByRecipientOrderByTimeDesc("test1234")).thenReturn(Lists.newArrayList(email)); + + this.mvc.perform(get("/WebWolf/mail")) + .andExpect(status().isOk()) + .andExpect(view().name("mailbox")) + .andExpect(content().string(containsString("Click this mail"))) + .andExpect(content().string(containsString(DateTimeFormatter.ofPattern("h:mm a").format(email.getTimestamp())))); + } + + @Test + @WithMockUser(username = "test1233") + public void differentUserShouldNotBeAbleToReadOwnEmail() throws Exception { + Email email = Email.builder() + .contents("This is a test mail") + .recipient("test1234@webgoat.org") + .sender("hacker@webgoat.org") + .title("Click this mail") + .time(LocalDateTime.now()) + .build(); + Mockito.when(mailbox.findByRecipientOrderByTimeDesc("test1234")).thenReturn(Lists.newArrayList(email)); + + this.mvc.perform(get("/WebWolf/mail")) + .andExpect(status().isOk()) + .andExpect(view().name("mailbox")) + .andExpect(content().string(not(containsString("Click this mail")))); + } + +} \ No newline at end of file diff --git a/webwolf/start.sh b/webwolf/start.sh deleted file mode 100644 index 746266068..000000000 --- a/webwolf/start.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -java -jar -Djava.security.egd=file:/dev/./urandom /home/webwolf/webwolf.jar