XSS lesson updates
This commit is contained in:
@ -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. <br />You're support is appreciated<hr />");
|
||||
cart.append("<p>We have chaged credit card:" + field1 + "<br />");
|
||||
cart.append( " ------------------- <br />");
|
||||
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("<script>alert('my javascript here')</script>")) {
|
||||
//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());
|
||||
}
|
||||
}
|
||||
}
|
@ -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("<p>");
|
||||
|
||||
if (results.next())
|
||||
{
|
||||
for (int i = 1; i < (numColumns + 1); i++)
|
||||
{
|
||||
t.append(resultsMetaData.getColumnName(i));
|
||||
t.append(", ");
|
||||
}
|
||||
|
||||
t.append("<br />");
|
||||
results.beforeFirst();
|
||||
|
||||
while (results.next())
|
||||
{
|
||||
|
||||
for (int i = 1; i < (numColumns + 1); i++)
|
||||
{
|
||||
t.append(results.getString(i));
|
||||
t.append(", ");
|
||||
}
|
||||
|
||||
t.append("<br />");
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
t.append ("Query Successful; however no data was returned from this query.");
|
||||
}
|
||||
|
||||
t.append("</p>");
|
||||
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;
|
||||
//
|
||||
// }
|
||||
|
||||
*/
|
||||
|
||||
}
|
||||
|
@ -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("<p>");
|
||||
|
||||
if (results.next())
|
||||
{
|
||||
for (int i = 1; i < (numColumns + 1); i++)
|
||||
{
|
||||
t.append(resultsMetaData.getColumnName(i));
|
||||
t.append(", ");
|
||||
}
|
||||
|
||||
t.append("<br />");
|
||||
results.beforeFirst();
|
||||
|
||||
while (results.next())
|
||||
{
|
||||
|
||||
for (int i = 1; i < (numColumns + 1); i++)
|
||||
{
|
||||
t.append(results.getString(i));
|
||||
t.append(", ");
|
||||
}
|
||||
|
||||
t.append("<br />");
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
t.append ("Query Successful; however no data was returned from this query.");
|
||||
}
|
||||
|
||||
t.append("</p>");
|
||||
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;
|
||||
//
|
||||
// }
|
||||
|
||||
*/
|
||||
|
||||
}
|
||||
|
@ -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 <a href="http://code.google.com/p/webgoat">WebGoat</a>
|
||||
* @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);
|
||||
}
|
||||
}
|
@ -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<script>webgoat.customjs.phoneHome();<%2Fscript>
|
||||
|
||||
|
||||
|
||||
|
@ -78,7 +78,7 @@
|
||||
<!-- you can write your own custom forms, but standard form submission will take you to your endpoint and outside of the WebGoat framework -->
|
||||
<!-- of course, you can write your own ajax submission /handling in your own javascript if you like -->
|
||||
<form class="attack-form" accept-charset="UNKNOWN"
|
||||
method="POST" name="form"
|
||||
method="GET" name="xss-5a"
|
||||
action="/WebGoat/CrossSiteScripting/attack5a"
|
||||
enctype="application/json;charset=UTF-8">
|
||||
<hr width="90%" />
|
||||
@ -161,11 +161,27 @@
|
||||
<div class="attack-output"></div>
|
||||
<!-- ... of course, you can move them if you want to, but that will not look consistent to other lessons -->
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:CrossSiteScripting_content5b.adoc"></div>
|
||||
<div class="attack-container">
|
||||
<form class="attack-form" accept-charset="UNKNOWN"
|
||||
method="POST" name="xss-5b"
|
||||
action="/WebGoat/CrossSiteScripting/attack5b"
|
||||
enctype="application/json;charset=UTF-8">
|
||||
<input size="4" value="" name="isReflectedXSS" type="text" />
|
||||
<input type="submit" name="reflectedXssSubmit" value="Submit"/>
|
||||
</form>
|
||||
<!-- do not remove the two following div's, this is where your feedback/output will land -->
|
||||
<div class="attack-feedback"></div>
|
||||
<div class="attack-output"></div>
|
||||
<!-- ... of course, you can move them if you want to, but that will not look consistent to other lessons -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="lesson-page-wrapper">
|
||||
<!-- reuse this lesson-page-wrapper block for each 'page' of content in your lesson -->
|
||||
<!-- include content here, or can be placed in another location. Content will be presented via asciidocs files,
|
||||
which you put in src/main/resources/plugin/lessonplans/{lang}/{fileName}.adoc -->
|
||||
<div class="adoc-content" th:replace="doc:CrossSiteScripting_content6.adoc"></div>
|
||||
</div>
|
||||
<div class="lesson-page-wrapper">
|
||||
@ -180,18 +196,11 @@
|
||||
<!-- you can write your own custom forms, but standard form submission will take you to your endpoint and outside of the WebGoat framework -->
|
||||
<!-- of course, you can write your own ajax submission /handling in your own javascript if you like -->
|
||||
<form class="attack-form" accept-charset="UNKNOWN"
|
||||
method="POST" name="form"
|
||||
method="POST" name="DOMTestRoute"
|
||||
action="/WebGoat/CrossSiteScripting/attack6a"
|
||||
enctype="application/json;charset=UTF-8">
|
||||
<table>
|
||||
<tr>
|
||||
<td>Name:</td>
|
||||
<td><input name="userid_6a" value="" type="TEXT" /></td>
|
||||
<td><input
|
||||
name="Get Account Info" value="Get Account Info" type="SUBMIT"/></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
<input name="DOMTestRoute" value="" type="TEXT" />
|
||||
<input name="SubmitTestRoute" value="Submit" type="SUBMIT"/>
|
||||
</form>
|
||||
<!-- do not remove the two following div's, this is where your feedback/output will land -->
|
||||
<div class="attack-feedback"></div>
|
||||
|
@ -1,14 +1,21 @@
|
||||
== What is XSS
|
||||
|
||||
NEED DEFINITION.
|
||||
Cross-site script (also commonly known as XSS) is a vulnerability/flaw that combines ...
|
||||
# the allowance of html/script tags as input that are ...
|
||||
# rendred into a browser without encoding or sanitization
|
||||
|
||||
==== Cross site scripting (XSS) is the most prevalent and pernicious web application security issue
|
||||
=== Cross site scripting (XSS) is the most prevalent and pernicious web application security issue
|
||||
|
||||
==== XSS flaws occur whenever an application takes user originated data and sends it to a web browser without validation or encoding
|
||||
While there is a simple well-known defense for this attack, there are still many instances of it on the web. In terms of fixing it,
|
||||
coverage of fixes also tends to be a problem. We'll talk more about the defense in a little bit.
|
||||
|
||||
=== XSS allows attackers to execute script in the victim’s browser and take over the user’s browser using scripting malware
|
||||
=== XSS has a significant impact
|
||||
|
||||
==== Examples:
|
||||
Especially as 'Rich Internet Applications' are more and more common place, privileged function calls linked to via javascript may be compromised.
|
||||
And if not properly protected, sensitive data (such as your authentication cookies) can be stolen and used for someone else's purpose.
|
||||
|
||||
|
||||
==== Quick examples:
|
||||
* From the browser address bar (chrome, Firefox)
|
||||
+
|
||||
----
|
||||
@ -22,4 +29,5 @@ javascript:alert(document.cookie);
|
||||
----
|
||||
|
||||
== Try It! Using Chrome or Firefox
|
||||
Type in `javascript:alert(document.cookie);` in the URL bar. If you /cut/paste you'll need to add the `javascript:` back in. Try it on a different tab.
|
||||
Type in `javascript:alert(document.cookie);` in the URL bar. *NOTE:* If you /cut/paste you'll need to add the `javascript:` back in.
|
||||
Try it on a different tab (with WebGoat open in that tab).
|
||||
|
@ -11,7 +11,7 @@
|
||||
* Insertion of hostile and inappropriate content
|
||||
+
|
||||
----
|
||||
<img src=“http://pornsite.com/image.jpg/>
|
||||
<img src=“http://malicious.site.com/image.jpg/>
|
||||
“>GoodYear recommends buying BridgeStone tires…
|
||||
----
|
||||
|
||||
|
@ -2,13 +2,14 @@
|
||||
|
||||
=== Reflected
|
||||
* Malicious content from a user request is displayed to the user in a web browser
|
||||
* Malicious content is written into the page via server code
|
||||
* Malicious content is written into the page after from server response
|
||||
* Social engineering is required
|
||||
* Runs with browser privileges inherited from user in browser
|
||||
|
||||
=== Local: DOM-based
|
||||
=== DOM-based (also technically reflected)
|
||||
* Malicious content from a user request is used by client-side scripts to write HTML to it own page
|
||||
* Similar to reflected XSS
|
||||
* Runs with browser privileges
|
||||
* Runs with browser privileges inherited from user in browser
|
||||
|
||||
=== Stored or Persistent
|
||||
* Malicious content is stored on the server ( in a database, file system, or other object ) and later displayed to users in a web browser
|
||||
|
@ -2,5 +2,7 @@
|
||||
|
||||
Identify which field is susceptible to XSS
|
||||
|
||||
It is always a good practice to validate all input on the server side. XSS can occur when unvalidated user input is used in an HTTP response. In a reflected XSS attack, an attacker can craft a URL with the attack script and post it to another website, email it, or otherwise get a victim to click on it.
|
||||
It is always a good practice to validate all input on the server side. XSS can occur when unvalidated user input is used in an HTTP response.
|
||||
In a reflected XSS attack, an attacker can craft a URL with the attack script and post it to another website, email it, or otherwise get a victim to click on it.
|
||||
|
||||
Make sure to include in your attack payload "<script>alert('my javascript here')</script>".
|
@ -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?
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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>
|
@ -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?
|
||||
|
@ -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:<br><br> "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 <ul><li>The script was not triggered by the URL/QueryString</li><li>Even if you use the attack URL in a new tab, it won't execute (becuase of response type). Try it if you like.</li></ul>
|
||||
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.
|
||||
#xss-reflected-5b-do5a-first=Do the reflected xss attack prior to this, then come back and answer this.
|
Reference in New Issue
Block a user