diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/controller/StartLesson.java b/webgoat-container/src/main/java/org/owasp/webgoat/controller/StartLesson.java index 0200e3e10..491e781c8 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/controller/StartLesson.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/controller/StartLesson.java @@ -33,8 +33,9 @@ package org.owasp.webgoat.controller; import org.owasp.webgoat.lessons.AbstractLesson; import org.owasp.webgoat.lessons.RandomLessonAdapter; import org.owasp.webgoat.plugins.YmlBasedLesson; +import org.owasp.webgoat.session.LessonTracker; +import org.owasp.webgoat.session.UserTracker; import org.owasp.webgoat.session.WebSession; -import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; @@ -51,10 +52,6 @@ import java.util.Optional; @Controller public class StartLesson { - //simple filter can be removed after ECS removal - private static final String refactored = "ClientSideFiltering AccessControlMatrix"; - - /** *

start.

* @@ -95,4 +92,33 @@ public class StartLesson { model.addObject("lesson", lesson.get()); return model; } + +//// FIXME: 8/8/2016 duplicate code + @RequestMapping(value = {"*.attack"}, produces = "text/html") + public ModelAndView attack(HttpServletRequest request) { + // I will set here the thymeleaf fragment location based on the resource requested. + ModelAndView model = new ModelAndView(); + SecurityContext context = SecurityContextHolder.getContext(); //TODO this should work with the security roles of Spring + GrantedAuthority authority = context.getAuthentication().getAuthorities().iterator().next(); + String path = request.getServletPath(); // we now got /a/b/c/AccessControlMatrix.lesson + String lessonName = path.substring(path.lastIndexOf('/') + 1, path.indexOf(".attack")); + WebSession ws = (WebSession) request.getSession().getAttribute(WebSession.SESSION); + List lessons = ws.getCourse() + .getLessons(ws, AbstractLesson.USER_ROLE);//TODO this should work with the security roles of Spring + Optional lesson = lessons.stream() + .filter(l -> l.getId().equals(lessonName)) + .findFirst(); + model.setViewName("lesson_content"); + + YmlBasedLesson ymlBasedLesson = (YmlBasedLesson) lesson.get(); + if (ymlBasedLesson.getLessonAttack().attack()) { + UserTracker userTracker = UserTracker.instance(); + LessonTracker lessonTracker = userTracker.getLessonTracker(ws, lesson.get()); + lessonTracker.setCompleted(true); + model.addObject("message", ws.getMessage()); + } + + model.addObject("lesson", lesson.get()); + return model; + } } diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/lessons/Attack.java b/webgoat-container/src/main/java/org/owasp/webgoat/lessons/Attack.java new file mode 100644 index 000000000..fa9b241ad --- /dev/null +++ b/webgoat-container/src/main/java/org/owasp/webgoat/lessons/Attack.java @@ -0,0 +1,35 @@ +package org.owasp.webgoat.lessons; + +/** + * ************************************************************************************************ + * This file is part of WebGoat, an Open Web Application Security Project utility. For details, + * please see http://www.owasp.org/ + *

+ * Copyright (c) 2002 - 20014 Bruce Mayhew + *

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

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

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

+ * Getting Source ============== + *

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

+ * + * @author WebGoat + * @version $Id: $Id + * @since August 08, 2016 + */ +public interface Attack { + + boolean attack(); +} diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/lessons/LessonAdapter.java b/webgoat-container/src/main/java/org/owasp/webgoat/lessons/LessonAdapter.java index 15d83cc09..993c18694 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/lessons/LessonAdapter.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/lessons/LessonAdapter.java @@ -220,6 +220,11 @@ public abstract class LessonAdapter extends AbstractLesson { s.getLessonSession(this).setCurrentLessonScreen(lessonScreen); } + @Override + protected Element makeMessages(WebSession s) { + return super.makeMessages(s); + } + /** *

getSessionAttribute.

* diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/plugins/Plugin.java b/webgoat-container/src/main/java/org/owasp/webgoat/plugins/Plugin.java index 7016bf4bf..9c41d2933 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/plugins/Plugin.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/plugins/Plugin.java @@ -5,6 +5,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import com.google.common.base.Optional; import com.google.common.collect.Lists; +import com.google.common.reflect.ClassPath; import org.apache.commons.io.FileUtils; import org.owasp.webgoat.lessons.AbstractLesson; import org.springframework.util.StringUtils; @@ -84,7 +85,8 @@ public class Plugin { final List hints = (List) lessonYml.get("hints"); final String title = (String) lessonYml.get("title"); final String html = (String) lessonYml.get("id"); - this.ymlBasedLesson = new YmlBasedLesson(category, hints, title, html); + Class attackClazz = findAttack(html); + this.ymlBasedLesson = new YmlBasedLesson(category, hints, title, html, attackClazz); this.lesson = null; } catch (IOException e) { throw new PluginLoadingFailure("Unable to read yml file", e); @@ -94,6 +96,19 @@ public class Plugin { } + private Class findAttack(String id) { + try { + for (final ClassPath.ClassInfo info : ClassPath.from(this.classLoader).getTopLevelClasses()) { + if (info.getName().endsWith(id)) { + return info.load(); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + /** *

loadFiles.

* @@ -152,6 +167,7 @@ public class Plugin { /** * Lesson is optional, it is also possible that the supplied jar contains only helper classes. + * Lesson could be a new lesson (adoc based) or still ECS based. * * @return a {@link com.google.common.base.Optional} object. */ diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/plugins/YmlBasedLesson.java b/webgoat-container/src/main/java/org/owasp/webgoat/plugins/YmlBasedLesson.java index e1498e484..f1d53228d 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/plugins/YmlBasedLesson.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/plugins/YmlBasedLesson.java @@ -1,5 +1,6 @@ package org.owasp.webgoat.plugins; +import org.owasp.webgoat.lessons.Attack; import org.owasp.webgoat.lessons.Category; import org.owasp.webgoat.lessons.LessonAdapter; import org.owasp.webgoat.session.WebSession; @@ -42,12 +43,15 @@ public class YmlBasedLesson extends LessonAdapter { private final List hints; private final String title; private final String id; + private Attack attack; - public YmlBasedLesson(String category, List hints, String title, String id) { + public YmlBasedLesson(String category, List hints, String title, String id, Class attack) { this.category = category; this.hints = hints; this.title = title; this.id = id; + createAttack(attack); + } @Override @@ -74,5 +78,16 @@ public class YmlBasedLesson extends LessonAdapter { return id; } + public Attack getLessonAttack() { + return this.attack; + } + + private void createAttack(Class attack) { + try { + this.attack = (Attack) attack.newInstance(); + } catch (Exception e) { + e.printStackTrace(); + } + } } 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 fedb09450..7fef6a602 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 @@ -39,19 +39,29 @@ define(['jquery', var self = this; // The current LessonAdapter#getLink() generates a hash-mark link. It will not match the mask below. // Besides, the new MVC code registers an event handler that will reload the lesson according to the route. - $.each($('a[href^="attack?"]'),function(i,el) { //FIXME: need to figure out what to do here ... - var url = $(el).attr('href'); - $(el).unbind('click').attr('href','#').attr('link',url); - //TODO pull currentMenuId - $(el).click(function(event) { - event.preventDefault(); - var _url = $(el).attr('link'); - console.log("About to GET " + _url); - $.get(_url) - .done(self.reLoadView.bind(self)) - .fail(function() { alert("failed to GET " + _url); }); - }); + $('form').submit(function(event){ + var url = this.baseURI; + url = url.replace('start.mvc#lesson', ''); + url = url + '.attack'; + $.get(url) + .done(self.reLoadView.bind(self)) + .fail(function() { alert("failed to GET " + url); }); }); + // + // + // $.each($('a[href^="*.attack"]'),function(i,el) { //FIXME: need to figure out what to do here ... + // var url = $(el).attr('href'); + // $(el).unbind('click').attr('href','#').attr('link',url); + // //TODO pull currentMenuId + // $(el).click(function(event) { + // event.preventDefault(); + // var _url = $(el).attr('link'); + // console.log("About to GET " + _url); + // $.get(_url) + // .done(self.reLoadView.bind(self)) + // .fail(function() { alert("failed to GET " + _url); }); + // }); + // }); }, onAttackExecution: function(feedback) {