diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/session/UserSessionData.java b/webgoat-container/src/main/java/org/owasp/webgoat/session/UserSessionData.java
index e5546c2ba..1e1229e40 100644
--- a/webgoat-container/src/main/java/org/owasp/webgoat/session/UserSessionData.java
+++ b/webgoat-container/src/main/java/org/owasp/webgoat/session/UserSessionData.java
@@ -18,6 +18,10 @@ public class UserSessionData {
//GETTERS & SETTERS
public Object getValue(String key) {
+ if (!userSessionData.containsKey(key)) {
+ return null;
+ }
+ // else
return userSessionData.get(key);
}
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 dd278c7cc..ec1667826 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
@@ -54,7 +54,7 @@ define(['jquery',
webgoat.customjs.jquery = $; //passing jquery into custom js scope ... still klunky, but works for now
webgoat.customjs.jqueryVuln = $vuln;
- // temporary shim to support dom-xss lesson
+ // temporary shim to support dom-xss assignment
webgoat.customjs.phoneHome = function (e) {
console.log('phoneHome invoked');
console.log(arguments.callee);
@@ -97,6 +97,11 @@ define(['jquery',
this.menuController.updateMenu(name);
},
+ testRoute: function (param) {
+ this.lessonController.testHandler(param);
+ //this.menuController.updateMenu(name);
+ },
+
welcomeRoute: function () {
render();
this.lessonController.loadWelcome();
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 07e9eb177..7f478dab2 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
@@ -114,7 +114,9 @@ define(['jquery',
this.renderFeedback(data.feedback);
this.renderOutput(data.output || "");
- if (data.assignmentCompleted) {
+ //TODO: refactor back assignmentCompleted in Java
+ if (data.lessonCompleted || data.assignmentCompleted) {
+
this.markAssignmentComplete();
this.trigger('assignment:complete');
} else {
diff --git a/webgoat-lessons/command-injection/pom.xml b/webgoat-lessons/command-injection/pom.xml
new file mode 100644
index 000000000..313061c5d
--- /dev/null
+++ b/webgoat-lessons/command-injection/pom.xml
@@ -0,0 +1,34 @@
+
+ 4.0.0
+ http-proxies
+ jar
+
+ org.owasp.webgoat.lesson
+ webgoat-lessons-parent
+ 8.0-SNAPSHOT
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.springframework.security
+ spring-security-test
+ 4.1.3.RELEASE
+ test
+
+
+ junit
+ junit
+ ${junit.version}
+ jar
+ test
+
+
+
+
+
diff --git a/webgoat-lessons/command-injection/src/main/java/org/owasp/webgoat/plugin/CommandInjection.java b/webgoat-lessons/command-injection/src/main/java/org/owasp/webgoat/plugin/CommandInjection.java
new file mode 100644
index 000000000..ad87c7c20
--- /dev/null
+++ b/webgoat-lessons/command-injection/src/main/java/org/owasp/webgoat/plugin/CommandInjection.java
@@ -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/
+ *
+ * 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 October 12, 2016
+ */
+public class HttpProxies extends NewLesson {
+ @Override
+ public Category getDefaultCategory() {
+ return Category.GENERAL;
+ }
+
+ @Override
+ public List getHints() {
+ return Lists.newArrayList();
+ }
+
+ @Override
+ public Integer getDefaultRanking() {
+ return 2;
+ }
+
+ @Override
+ public String getTitle() {
+ return "http-proxies.title";
+ }
+
+ @Override
+ public String getId() {
+ return "HttpProxies";
+ }
+}
diff --git a/webgoat-lessons/command-injection/src/main/java/org/owasp/webgoat/plugin/CommandInjectionExecute.java b/webgoat-lessons/command-injection/src/main/java/org/owasp/webgoat/plugin/CommandInjectionExecute.java
new file mode 100644
index 000000000..ee8f9ef64
--- /dev/null
+++ b/webgoat-lessons/command-injection/src/main/java/org/owasp/webgoat/plugin/CommandInjectionExecute.java
@@ -0,0 +1,58 @@
+package org.owasp.webgoat.plugin;
+
+import org.owasp.webgoat.assignments.AssignmentEndpoint;
+import org.owasp.webgoat.assignments.AssignmentPath;
+import org.owasp.webgoat.assignments.AttackResult;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+
+/**
+ * *************************************************************************************************
+ *
+ *
+ * This file is part of WebGoat, an Open Web Application Security Project
+ * utility. For details, please see http://www.owasp.org/
+ *
+ * Copyright (c) 2002 - 20014 Bruce Mayhew
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Getting Source ==============
+ *
+ * Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository
+ * for free software projects.
+ *
+ * For details, please see http://webgoat.github.io
+ *
+ * @author Bruce Mayhew WebGoat
+ * @created October 28, 2003
+ */
+@AssignmentPath("/HttpProxies/intercept-request")
+public class HttpBasicsInterceptRequest extends AssignmentEndpoint {
+
+ @RequestMapping(method = RequestMethod.GET)
+ public @ResponseBody
+ AttackResult completed(HttpServletRequest request) throws IOException {
+ if (request.getHeader("x-request-intercepted").toLowerCase().equals("true") && request.getParameter("changeMe").equals("Requests are tampered easily")) {
+ return trackProgress(success().feedback("http-proxies.intercept.success").build());
+ } else {
+ return trackProgress(failed().feedback("http-proxies.intercept.failure").build());
+ }
+ }
+}
\ No newline at end of file
diff --git a/webgoat-lessons/command-injection/src/main/resources/plugin/CommandInjection/html/CommandInjection.html b/webgoat-lessons/command-injection/src/main/resources/plugin/CommandInjection/html/CommandInjection.html
new file mode 100644
index 000000000..59113e121
--- /dev/null
+++ b/webgoat-lessons/command-injection/src/main/resources/plugin/CommandInjection/html/CommandInjection.html
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/webgoat-lessons/command-injection/src/main/resources/plugin/CommandInjection/lessonPlans/en/CommandInjection1.adoc b/webgoat-lessons/command-injection/src/main/resources/plugin/CommandInjection/lessonPlans/en/CommandInjection1.adoc
new file mode 100644
index 000000000..6344750d7
--- /dev/null
+++ b/webgoat-lessons/command-injection/src/main/resources/plugin/CommandInjection/lessonPlans/en/CommandInjection1.adoc
@@ -0,0 +1,20 @@
+
+== HTTP Proxy Overview
+
+Many times proxies are used as a way of accessing otehrwise blocked content. A user might connect to server A, which relays content from server B
+ ... Because Server B is blocked wihtin the user's network. That's not the use case we will be dealing with here, but the concept is the same.
+HTTP Proxies receive requesets from a client and relay them. They also typically record them. They act as a man-in-the-middle (keep that in mind if you decide to
+use a proxy server to connect to some other system that is otherwise blocked). We won't get into HTTP vs HTTPS just yet, but that's an important topic in
+relationship to proxies.
+
+=== Proxy Capabilities
+
+Proxies sit between your client and the server the client is talking to. You can record and analyze the requests & responses. You can also use the proxy to
+modify (tamper) the requests and responses. Proxies also have automated or semi-automated functions that allow you to gain efficiency in testing and
+analyzing the security of a website.
+
+=== Other Uses for Proxies
+
+ZAP specifically can also be used in the development process in a CI/CD, DevOps or otherwise automated build/test environment. This lesson does
+not currently have any details on that, but it is worth mentioning. There are a number of examples on the internet of it being integrated into a
+CI/CD with Jenkins, maven or other build processes.
\ No newline at end of file
diff --git a/webgoat-lessons/command-injection/src/main/resources/plugin/i18n/WebGoatLabels.properties b/webgoat-lessons/command-injection/src/main/resources/plugin/i18n/WebGoatLabels.properties
new file mode 100644
index 000000000..2140e3ed4
--- /dev/null
+++ b/webgoat-lessons/command-injection/src/main/resources/plugin/i18n/WebGoatLabels.properties
@@ -0,0 +1,4 @@
+http-proxies.title=HTTP Proxies
+
+http-proxies.intercept.success=Well done, you tampered the request as expected
+http-proxies.intercept.failure=Please try again. Make sure to make all the changes. And case sensitivity may matter ... or not, you never know!
\ No newline at end of file
diff --git a/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson5a.java b/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson5a.java
index 857939090..6b87d7475 100644
--- a/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson5a.java
+++ b/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson5a.java
@@ -4,6 +4,8 @@ package org.owasp.webgoat.plugin;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.assignments.AttackResult;
+import org.owasp.webgoat.session.UserSessionData;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
@@ -47,21 +49,44 @@ import java.io.IOException;
@AssignmentPath("/CrossSiteScripting/attack5a")
public class CrossSiteScriptingLesson5a extends AssignmentEndpoint {
- @RequestMapping(method = RequestMethod.POST)
+ @Autowired
+ UserSessionData userSessionData;
+
+ @RequestMapping(method = RequestMethod.GET)
public @ResponseBody AttackResult completed(@RequestParam Integer QTY1,
@RequestParam Integer QTY2, @RequestParam Integer QTY3,
@RequestParam Integer QTY4, @RequestParam String field1,
@RequestParam Integer field2, HttpServletRequest request)
throws IOException {
- System.out.println("foo");
+ // System.out.println("foo");
// Should add some QTY validation here. Someone could have fun and enter a negative quantity and get merchanidise and a refund :)
double totalSale = QTY1.intValue() * 69.99 + QTY2.intValue() * 27.99 + QTY3.intValue() * 1599.99 + QTY4.intValue() * 299.99;
-
+
+ userSessionData.setValue("xss-reflected1-complete",(Object)"false");
StringBuffer cart = new StringBuffer();
cart.append("Thank you for shopping at WebGoat.
You're support is appreciated
");
cart.append("We have chaged credit card:" + field1 + "
");
cart.append( " -------------------
");
cart.append( " $" + totalSale);
- return trackProgress(failed().output(cart.toString()).build());
+
+ //init state
+ if (userSessionData.getValue("xss-reflected1-complete") == null) {
+ userSessionData.setValue("xss-reflected1-complete",(Object)"false");
+ }
+
+ if (field1.toLowerCase().contains("")) {
+ //return trackProgress()
+ userSessionData.setValue("xss-reflected-5a-complete","true");
+ return trackProgress(success()
+ .feedback("xss-reflected-5a-success")
+ .output(cart.toString())
+ .build());
+ } else {
+ userSessionData.setValue("xss-reflected1-complete","false");
+ return trackProgress(success()
+ .feedback("xss-reflected-5a-failure")
+ .output(cart.toString())
+ .build());
+ }
}
}
\ No newline at end of file
diff --git a/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson5b.java b/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson5b.java
index d09d0daf2..eb609039f 100644
--- a/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson5b.java
+++ b/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson5b.java
@@ -4,7 +4,16 @@ package org.owasp.webgoat.plugin;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentPath;
+import org.owasp.webgoat.assignments.AttackResult;
+import org.owasp.webgoat.session.UserSessionData;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
/***************************************************************************************************
@@ -39,176 +48,27 @@ import org.owasp.webgoat.assignments.AssignmentPath;
*/
@AssignmentPath("/CrossSiteScripting/attack5b")
public class CrossSiteScriptingLesson5b extends AssignmentEndpoint {
-/*
- @RequestMapping(method = RequestMethod.POST)
- public @ResponseBody AttackResult completed(@RequestParam String userid, HttpServletRequest request) throws IOException {
- return injectableQuery(userid);
-
- }
- protected AttackResult injectableQuery(String accountName)
- {
- try
- {
- Connection connection = DatabaseUtilities.getConnection(getWebSession());
- String query = "SELECT * FROM user_data WHERE userid = " + accountName;
+ @Autowired
+ UserSessionData userSessionData;
- try
- {
- Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
- ResultSet.CONCUR_READ_ONLY);
- ResultSet results = statement.executeQuery(query);
+ @RequestMapping(method = RequestMethod.POST)
+ public @ResponseBody
+ AttackResult completed(@RequestParam String isReflectedXSS) throws IOException {
+ // init
+ System.out.println(userSessionData.getValue("xss-reflected5a-complete"));
- if ((results != null) && (results.first() == true))
- {
- ResultSetMetaData resultsMetaData = results.getMetaData();
- StringBuffer output = new StringBuffer();
+ //TODO
+// if (null == userSessionData.getValue("xss-reflected5a-complete") || userSessionData.getValue("xss-reflected-5a-complete").equals("false")) {
+// //userSessionData.setValue("xss-reflected1-complete",(Object)"false");
+// return trackProgress(success().feedback("xss-reflected-5b-do5a-first").build());
+// }
- output.append(writeTable(results, resultsMetaData));
- results.last();
-
- // If they get back more than one user they succeeded
- if (results.getRow() >= 6)
- {
- return trackProgress(AttackResult.success("You have succeed: " + output.toString()));
- } else {
- return trackProgress(AttackResult.failed("You are close, try again. " + output.toString()));
- }
-
- }
- else
- {
- return trackProgress(AttackResult.failed("No Results Matched. Try Again. "));
-
-// output.append(getLabelManager().get("NoResultsMatched"));
- }
- } catch (SQLException sqle)
- {
-
- return trackProgress(AttackResult.failed(sqle.getMessage()));
- }
- } catch (Exception e)
- {
- e.printStackTrace();
- return trackProgress(AttackResult.failed( "ErrorGenerating" + this.getClass().getName() + " : " + e.getMessage()));
+ if (isReflectedXSS.toLowerCase().equals("no") || isReflectedXSS.toLowerCase().equals("n")) {
+ //return trackProgress()
+ return trackProgress(success().feedback("xss-reflected-5b-success").build());
+ } else {
+ return trackProgress(success().feedback("xss-reflected-5b-failure").build());
}
}
-
- public String writeTable(ResultSet results, ResultSetMetaData resultsMetaData) throws IOException,
- SQLException
- {
- int numColumns = resultsMetaData.getColumnCount();
- results.beforeFirst();
- StringBuffer t = new StringBuffer();
- t.append("
");
-
- if (results.next())
- {
- for (int i = 1; i < (numColumns + 1); i++)
- {
- t.append(resultsMetaData.getColumnName(i));
- t.append(", ");
- }
-
- t.append("
");
- results.beforeFirst();
-
- while (results.next())
- {
-
- for (int i = 1; i < (numColumns + 1); i++)
- {
- t.append(results.getString(i));
- t.append(", ");
- }
-
- t.append("
");
- }
-
- }
- else
- {
- t.append ("Query Successful; however no data was returned from this query.");
- }
-
- t.append("
");
- return (t.toString());
- }
-//
-// protected Element parameterizedQuery(WebSession s)
-// {
-// ElementContainer ec = new ElementContainer();
-//
-// ec.addElement(getLabelManager().get("StringSqlInjectionSecondStage"));
-// if (s.getParser().getRawParameter(ACCT_NAME, "YOUR_NAME").equals("restart"))
-// {
-// getLessonTracker(s).getLessonProperties().setProperty(STAGE, "1");
-// return (injectableQuery(s));
-// }
-//
-// ec.addElement(new BR());
-//
-// try
-// {
-// Connection connection = DatabaseUtilities.getConnection(s);
-//
-// ec.addElement(makeAccountLine(s));
-//
-// String query = "SELECT * FROM user_data WHERE last_name = ?";
-// ec.addElement(new PRE(query));
-//
-// try
-// {
-// PreparedStatement statement = connection.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE,
-// ResultSet.CONCUR_READ_ONLY);
-// statement.setString(1, accountName);
-// ResultSet results = statement.executeQuery();
-//
-// if ((results != null) && (results.first() == true))
-// {
-// ResultSetMetaData resultsMetaData = results.getMetaData();
-// ec.addElement(DatabaseUtilities.writeTable(results, resultsMetaData));
-// results.last();
-//
-// // If they get back more than one user they succeeded
-// if (results.getRow() >= 6)
-// {
-// makeSuccess(s);
-// }
-// }
-// else
-// {
-// ec.addElement(getLabelManager().get("NoResultsMatched"));
-// }
-// } catch (SQLException sqle)
-// {
-// ec.addElement(new P().addElement(sqle.getMessage()));
-// }
-// } catch (Exception e)
-// {
-// s.setMessage(getLabelManager().get("ErrorGenerating") + this.getClass().getName());
-// e.printStackTrace();
-// }
-//
-// return (ec);
-// }
-//
-// protected Element makeAccountLine(WebSession s)
-// {
-// ElementContainer ec = new ElementContainer();
-// ec.addElement(new P().addElement(getLabelManager().get("EnterLastName")));
-//
-// accountName = s.getParser().getRawParameter(ACCT_NAME, "Your Name");
-// Input input = new Input(Input.TEXT, ACCT_NAME, accountName.toString());
-// ec.addElement(input);
-//
-// Element b = ECSFactory.makeButton(getLabelManager().get("Go!"));
-// ec.addElement(b);
-//
-// return ec;
-//
-// }
-
- */
-
}
diff --git a/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson6a.java b/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson6a.java
index 67b2ab912..4e9e2a372 100644
--- a/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson6a.java
+++ b/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson6a.java
@@ -3,7 +3,15 @@ package org.owasp.webgoat.plugin;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentPath;
+import org.owasp.webgoat.assignments.AttackResult;
+import org.owasp.webgoat.session.UserSessionData;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import java.io.IOException;
/***************************************************************************************************
@@ -38,176 +46,19 @@ import org.owasp.webgoat.assignments.AssignmentPath;
*/
@AssignmentPath("/CrossSiteScripting/attack6a")
public class CrossSiteScriptingLesson6a extends AssignmentEndpoint {
-/*
- @RequestMapping(method = RequestMethod.POST)
- public @ResponseBody AttackResult completed(@RequestParam String userid_6a, HttpServletRequest request) throws IOException {
- return injectableQuery(userid_6a);
- // The answer: Smith' union select userid,user_name, password,cookie,cookie, cookie,userid from user_system_data --
+ @Autowired
+ UserSessionData userSessionData;
- }
+ @RequestMapping(method = RequestMethod.POST)
+ public @ResponseBody
+ AttackResult completed(@RequestParam String DOMTestRoute) throws IOException {
- protected AttackResult injectableQuery(String accountName)
- {
- try
- {
- Connection connection = DatabaseUtilities.getConnection(getWebSession());
- String query = "SELECT * FROM user_data WHERE last_name = '" + accountName + "'";
-
- try
- {
- Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
- ResultSet.CONCUR_READ_ONLY);
- ResultSet results = statement.executeQuery(query);
-
- if ((results != null) && (results.first() == true))
- {
- ResultSetMetaData resultsMetaData = results.getMetaData();
- StringBuffer output = new StringBuffer();
-
- output.append(writeTable(results, resultsMetaData));
- results.last();
-
- // If they get back more than one user they succeeded
- if (results.getRow() >= 6)
- {
- return trackProgress(AttackResult.success("You have succeed: " + output.toString()));
- } else {
- return trackProgress(AttackResult.failed("You are close, try again. " + output.toString()));
- }
-
- }
- else
- {
- return trackProgress(AttackResult.failed("No Results Matched. Try Again. "));
-
- }
- } catch (SQLException sqle)
- {
-
- return trackProgress(AttackResult.failed(sqle.getMessage()));
- }
- } catch (Exception e)
- {
- e.printStackTrace();
- return trackProgress(AttackResult.failed( "ErrorGenerating" + this.getClass().getName() + " : " + e.getMessage()));
+ if (DOMTestRoute.equals("start.mvc#test/")) {
+ //return trackProgress()
+ return trackProgress(success().feedback("xss-reflected-6a-success").build());
+ } else {
+ return trackProgress(failed().feedback("xss-reflected-6a-failure").build());
}
}
-
- public String writeTable(ResultSet results, ResultSetMetaData resultsMetaData) throws IOException,
- SQLException
- {
- int numColumns = resultsMetaData.getColumnCount();
- results.beforeFirst();
- StringBuffer t = new StringBuffer();
- t.append("");
-
- if (results.next())
- {
- for (int i = 1; i < (numColumns + 1); i++)
- {
- t.append(resultsMetaData.getColumnName(i));
- t.append(", ");
- }
-
- t.append("
");
- results.beforeFirst();
-
- while (results.next())
- {
-
- for (int i = 1; i < (numColumns + 1); i++)
- {
- t.append(results.getString(i));
- t.append(", ");
- }
-
- t.append("
");
- }
-
- }
- else
- {
- t.append ("Query Successful; however no data was returned from this query.");
- }
-
- t.append("
");
- return (t.toString());
- }
-//
-// protected Element parameterizedQuery(WebSession s)
-// {
-// ElementContainer ec = new ElementContainer();
-//
-// ec.addElement(getLabelManager().get("StringSqlInjectionSecondStage"));
-// if (s.getParser().getRawParameter(ACCT_NAME, "YOUR_NAME").equals("restart"))
-// {
-// getLessonTracker(s).getLessonProperties().setProperty(STAGE, "1");
-// return (injectableQuery(s));
-// }
-//
-// ec.addElement(new BR());
-//
-// try
-// {
-// Connection connection = DatabaseUtilities.getConnection(s);
-//
-// ec.addElement(makeAccountLine(s));
-//
-// String query = "SELECT * FROM user_data WHERE last_name = ?";
-// ec.addElement(new PRE(query));
-//
-// try
-// {
-// PreparedStatement statement = connection.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE,
-// ResultSet.CONCUR_READ_ONLY);
-// statement.setString(1, accountName);
-// ResultSet results = statement.executeQuery();
-//
-// if ((results != null) && (results.first() == true))
-// {
-// ResultSetMetaData resultsMetaData = results.getMetaData();
-// ec.addElement(DatabaseUtilities.writeTable(results, resultsMetaData));
-// results.last();
-//
-// // If they get back more than one user they succeeded
-// if (results.getRow() >= 6)
-// {
-// makeSuccess(s);
-// }
-// }
-// else
-// {
-// ec.addElement(getLabelManager().get("NoResultsMatched"));
-// }
-// } catch (SQLException sqle)
-// {
-// ec.addElement(new P().addElement(sqle.getMessage()));
-// }
-// } catch (Exception e)
-// {
-// s.setMessage(getLabelManager().get("ErrorGenerating") + this.getClass().getName());
-// e.printStackTrace();
-// }
-//
-// return (ec);
-// }
-//
-// protected Element makeAccountLine(WebSession s)
-// {
-// ElementContainer ec = new ElementContainer();
-// ec.addElement(new P().addElement(getLabelManager().get("EnterLastName")));
-//
-// accountName = s.getParser().getRawParameter(ACCT_NAME, "Your Name");
-// Input input = new Input(Input.TEXT, ACCT_NAME, accountName.toString());
-// ec.addElement(input);
-//
-// Element b = ECSFactory.makeButton(getLabelManager().get("Go!"));
-// ec.addElement(b);
-//
-// return ec;
-//
-// }
-
-*/
}
diff --git a/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson6b.java b/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson6b.java
deleted file mode 100644
index d58cbe90a..000000000
--- a/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson6b.java
+++ /dev/null
@@ -1,95 +0,0 @@
-
-package org.owasp.webgoat.plugin;
-
-import org.owasp.webgoat.assignments.AssignmentEndpoint;
-import org.owasp.webgoat.assignments.AssignmentPath;
-import org.owasp.webgoat.assignments.AttackResult;
-import org.owasp.webgoat.session.DatabaseUtilities;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.ResponseBody;
-
-import javax.servlet.http.HttpServletRequest;
-import java.io.IOException;
-import java.sql.Connection;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-
-
-
-/***************************************************************************************************
- *
- *
- * 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 WebGoat
- * @created October 28, 2003
- */
-@AssignmentPath("/CrossSiteScripting/attack6b")
-public class CrossSiteScriptingLesson6b extends AssignmentEndpoint {
-
- @RequestMapping(method = RequestMethod.POST)
- public @ResponseBody AttackResult completed(@RequestParam String userid_6b, HttpServletRequest request) throws IOException {
- if (userid_6b.toString().equals(getPassword())) {
- return trackProgress(success().build());
- } else {
- return trackProgress(failed().build());
- }
- }
-
- protected String getPassword()
- {
-
- String password="dave";
- try
- {
- Connection connection = DatabaseUtilities.getConnection(getWebSession());
- String query = "SELECT password FROM user_system_data WHERE user_name = 'dave'";
-
- try
- {
- Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
- ResultSet.CONCUR_READ_ONLY);
- ResultSet results = statement.executeQuery(query);
-
- if ((results != null) && (results.first() == true))
- {
- password = results.getString("password");
- }
- } catch (SQLException sqle)
- {
- sqle.printStackTrace();
- // do nothing
- }
- } catch (Exception e)
- {
- e.printStackTrace();
- // do nothing
- }
- return (password);
- }
-}
diff --git a/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/DOMCrossSiteScripting.java b/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/DOMCrossSiteScripting.java
index 0acb4e38b..c4ceea5b4 100644
--- a/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/DOMCrossSiteScripting.java
+++ b/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/DOMCrossSiteScripting.java
@@ -19,17 +19,17 @@ public class DOMCrossSiteScripting extends AssignmentEndpoint {
@RequestMapping(method = RequestMethod.POST)
public @ResponseBody
AttackResult completed(@RequestParam Integer param1,
- @RequestParam Integer param2, HttpServletRequest request)
- throws IOException {
-
+ @RequestParam Integer param2, HttpServletRequest request) throws IOException {
if (param1 == 42 && param2 == 24 && request.getHeader("webgoat-requested-by").equals("dom-xss-vuln")) {
+ System.out.println("DOM-XSS successful");
return trackProgress(success().build());
} else {
return trackProgress(failed().build());
}
}
}
-
+// something like ... http://localhost:8080/WebGoat/start.mvc#test/testParam=foobar&_someVar=234902384lotslsfjdOf9889080GarbageHere%3Cscript%3Ewebgoat.customjs.phoneHome();%3C%2Fscript%3E
+// or http://localhost:8080/WebGoat/start.mvc#test/testParam=foobar&_someVar=234902384lotslsfjdOf9889080GarbageHere".
\ No newline at end of file
diff --git a/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content5b.adoc b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content5b.adoc
index f4e3b0570..477752127 100644
--- a/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content5b.adoc
+++ b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content5b.adoc
@@ -1,4 +1,5 @@
== Was it Really Reflected XSS?
-Now, was the last attack truly reflected XSS?
+You should have been able to execute script with the last example. Was it truly reflected XSS?
+
diff --git a/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content5c.adoc b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content5c.adoc
new file mode 100644
index 000000000..ffc47194a
--- /dev/null
+++ b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content5c.adoc
@@ -0,0 +1,9 @@
+== Was it Really Reflected XSS?
+
+The last example was not truly reflected XSS ... Why you say?
+# Can you execute it by changing the URL? (No)
+# If you do follow the actual payload in a new tab, does it execute the script? (No ... go ahead and give it a try)
+
+The reason for #2 is that the response type
+
+
diff --git a/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content6.adoc b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content6.adoc
index eaa6c8884..1445c3baf 100644
--- a/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content6.adoc
+++ b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content6.adoc
@@ -1,10 +1,12 @@
== DOM-Based XSS Scenario
+DOM-based XSS is similar to reflected. The difference is that the payload will never go to the server, but will only ever be processed by the client.
+
* Attacker sends a malicious URL to victim
-* Victim clicks on the link that loads malicious web page
-* The malicious web page's JavaScript opens a local web page on the victims machine that contains an attack
-* The local page executes attack in the computer’s local zone
+* Victim clicks on the link
+* That link may load a malicious web page or a web page they use (are logged into?) that has a vulnerable route/handler
+* If it's a malicious web page, it may use it's own JavaScript to attack another page/url with a vulnerable route/handler
+* The vulnerable page renders the payload and executes attack in the user's context on that page/site
* Attacker’s malicious script may run commands with the privileges of local account
-*Victim does not realize attack occurred*
-
+*Victim does not realize attack occurred* ... Malicious attackers don't use <script>alert('xss')</ script>
\ No newline at end of file
diff --git a/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content6a.adoc b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content6a.adoc
index 1726ff547..9d4ce0689 100644
--- a/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content6a.adoc
+++ b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content6a.adoc
@@ -1,3 +1,12 @@
== Try It! DOM-Based XSS
-Need A Lesson
+For this, you'll want to look for some 'test' code in the route handlers (javascript/backbone). Sometimes, test code gets left in.
+(Often times test code is very simple and lacks security or any quality controls!).
+
+Your objective is to find the route and exploit it. First though ... what is the base route? As an example, look at the URL for this lesson ...
+it should look something like /WebGoat/start.mvc#lesson/CrossSiteScripting.lesson/5 (although maybe slightly different). The 'base route' in this case is:
+*start.mvc#lesson/*
+
+The *CrossSiteScripting.lesson/5* after that are parameters that are processed by javascript route handler.
+
+So, what is test route for this test code?
diff --git a/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/i18n/WebGoatLabels.properties b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/i18n/WebGoatLabels.properties
index 2b0bc8c70..af10c440a 100644
--- a/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/i18n/WebGoatLabels.properties
+++ b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/i18n/WebGoatLabels.properties
@@ -1,10 +1,10 @@
-#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:
-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"
-SqlStringInjectionHint3=Compound SQL statements can be made by joining multiple tests with keywords like AND and OR. Try appending a SQL statement that always resolves to true
-SqlStringInjectionHint4=Try entering [ smith' OR '1' = '1 ].
+# XSS success, failure messages and hints
+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.
+xss-reflected-5b-failure=Nope, pretty easy to guess now though.
+xss-reflected-6a-success=Correct! Now, see if you can send in an exploit to that route in the next assignment.
+xss-reflected-6a-failure=No, look at the example. Check the GoatRouter.js file. It should be pretty easy to determine.
+xss.lesson1.failure=Are you sure? Try using a tab from a different site.
-xss.lesson1.failure=Are you sure? Try using a tab from a different site.
\ No newline at end of file
+#xss-reflected-5b-do5a-first=Do the reflected xss attack prior to this, then come back and answer this.
\ No newline at end of file