diff --git a/webgoat-lessons/cross-site-scripting/.gitignore b/webgoat-lessons/cross-site-scripting/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/webgoat-lessons/cross-site-scripting/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/webgoat-lessons/cross-site-scripting/.sonatype b/webgoat-lessons/cross-site-scripting/.sonatype new file mode 100644 index 000000000..12d612a2b --- /dev/null +++ b/webgoat-lessons/cross-site-scripting/.sonatype @@ -0,0 +1,3 @@ +#Sonatype CLM +#Tue Oct 11 14:10:26 EDT 2016 +application.id=webgoat diff --git a/webgoat-lessons/cross-site-scripting/pom.xml b/webgoat-lessons/cross-site-scripting/pom.xml new file mode 100644 index 000000000..30c506d29 --- /dev/null +++ b/webgoat-lessons/cross-site-scripting/pom.xml @@ -0,0 +1,35 @@ + + 4.0.0 + cross-site-scripting + jar + + org.owasp.webgoat.lesson + webgoat-lessons-parent + 8.0-SNAPSHOT + + + + + org.asciidoctor + asciidoctor-maven-plugin + 1.5.3 + + + + output-html + generate-resources + + process-asciidoc + + + html + src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/ + + + + + + + + \ No newline at end of file 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 new file mode 100644 index 000000000..609fb49cd --- /dev/null +++ b/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScripting.java @@ -0,0 +1,70 @@ +package org.owasp.webgoat.plugin; + +import java.util.ArrayList; +import java.util.List; + +import org.owasp.webgoat.lessons.Category; +import org.owasp.webgoat.lessons.NewLesson; + +/** + * ************************************************************************************************ + * 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 CrossSiteScripting extends NewLesson { + @Override + public Category getDefaultCategory() { + return Category.XSS; + } + + @Override + public List getHints() { + List hints = new ArrayList(); + +// hints.add(getLabelManager().get("SqlStringInjectionHint1")); +// hints.add(getLabelManager().get("SqlStringInjectionHint2")); +// hints.add(getLabelManager().get("SqlStringInjectionHint3")); +// hints.add(getLabelManager().get("SqlStringInjectionHint4")); + + return hints; + } + + @Override + public Integer getDefaultRanking() { + return 1; + } + + @Override + public String getTitle() { + return "Cross Site Scripting"; + } + + @Override + public String getId() { + return "CrossSiteScripting"; + } +} diff --git a/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson1.java b/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson1.java new file mode 100644 index 000000000..88e975681 --- /dev/null +++ b/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson1.java @@ -0,0 +1,68 @@ + +package org.owasp.webgoat.plugin; + +import java.io.IOException; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Statement; + +import javax.servlet.http.HttpServletRequest; + +import org.owasp.webgoat.lessons.Assignment; +import org.owasp.webgoat.lessons.model.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; + + + +/*************************************************************************************************** + * + * + * 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 + */ +public class CrossSiteScriptingLesson1 extends Assignment { + + @RequestMapping(method = RequestMethod.POST) + public @ResponseBody AttackResult completed(@RequestParam String answer_xss_1, HttpServletRequest request) throws IOException { + if (answer_xss_1.toString().toLowerCase().equals("yes")) { + return trackProgress(AttackResult.success()); + } else { + return trackProgress(AttackResult.failed("Are you sure? Try using a tab from a different site.")); + } + } + + @Override + public String getPath() { + return "/CrossSiteScripting/attack1"; + } +} 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 new file mode 100644 index 000000000..6078f7418 --- /dev/null +++ b/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson5a.java @@ -0,0 +1,230 @@ + +package org.owasp.webgoat.plugin; + +import java.io.IOException; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Statement; + +import javax.servlet.http.HttpServletRequest; + +import org.owasp.webgoat.lessons.Assignment; +import org.owasp.webgoat.lessons.model.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; + + + +/*************************************************************************************************** + * + * + * 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 + */ +public class CrossSiteScriptingLesson5a extends Assignment { + + @RequestMapping(method = RequestMethod.POST) + public @ResponseBody AttackResult completed(@RequestParam String account, HttpServletRequest request) throws IOException { + return injectableQuery(account); + } + + @Override + public String getPath() { + return "/CrossSiteScripting/attack5a"; + } + + + 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())); + } + } + + 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/CrossSiteScriptingLesson5b.java b/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson5b.java new file mode 100644 index 000000000..111830a10 --- /dev/null +++ b/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson5b.java @@ -0,0 +1,234 @@ +package org.owasp.webgoat.plugin; + + + +import java.io.IOException; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Statement; + +import javax.servlet.http.HttpServletRequest; + +import org.owasp.webgoat.lessons.Assignment; +import org.owasp.webgoat.lessons.model.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; + + + +/*************************************************************************************************** + * + * + * 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 + */ +public class CrossSiteScriptingLesson5b extends Assignment { + + @RequestMapping(method = RequestMethod.POST) + public @ResponseBody AttackResult completed(@RequestParam String userid, HttpServletRequest request) throws IOException { + return injectableQuery(userid); + + } + + @Override + public String getPath() { + return "/CrossSiteScripting/attack5b"; + } + + + + protected AttackResult injectableQuery(String accountName) + { + try + { + Connection connection = DatabaseUtilities.getConnection(getWebSession()); + String query = "SELECT * FROM user_data WHERE userid = " + 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. ")); + +// 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())); + } + } + + 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 new file mode 100644 index 000000000..b32eef186 --- /dev/null +++ b/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson6a.java @@ -0,0 +1,232 @@ + +package org.owasp.webgoat.plugin; + +import java.io.IOException; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Statement; + +import javax.servlet.http.HttpServletRequest; + +import org.owasp.webgoat.lessons.Assignment; +import org.owasp.webgoat.lessons.model.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; + + + +/*************************************************************************************************** + * + * + * 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 + */ +public class CrossSiteScriptingLesson6a extends Assignment { + + @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 -- + + } + + @Override + public String getPath() { + return "/CrossSiteScripting/attack6a"; + } + + + 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())); + } + } + + 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 new file mode 100644 index 000000000..c537b395a --- /dev/null +++ b/webgoat-lessons/cross-site-scripting/src/main/java/org/owasp/webgoat/plugin/CrossSiteScriptingLesson6b.java @@ -0,0 +1,101 @@ + +package org.owasp.webgoat.plugin; + +import java.io.IOException; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Statement; + +import javax.servlet.http.HttpServletRequest; + +import org.owasp.webgoat.lessons.Assignment; +import org.owasp.webgoat.lessons.model.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; + + + +/*************************************************************************************************** + * + * + * 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 + */ +public class CrossSiteScriptingLesson6b extends Assignment { + + @RequestMapping(method = RequestMethod.POST) + public @ResponseBody AttackResult completed(@RequestParam String userid_6b, HttpServletRequest request) throws IOException { + if (userid_6b.toString().equals(getPassword())) { + return trackProgress(AttackResult.success()); + } else { + return trackProgress(AttackResult.failed("You are close, try again")); + } + } + + @Override + public String getPath() { + return "/CrossSiteScripting/attack6b"; + } + + + 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/resources/plugin/CrossSiteScripting/html/CrossSiteScripting.html b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/html/CrossSiteScripting.html new file mode 100644 index 000000000..f62b43a90 --- /dev/null +++ b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/html/CrossSiteScripting.html @@ -0,0 +1,331 @@ + + + + +
+ + +
+
+ +
+ + +
+
+ +
+ + + +
+ + + + + + + +
Were the cookies the same on each tab?
+
+
+ +
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+ +
+
+ + +
+
+ +
+ + + +
+
+
+

Shopping Cart

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Shopping Cart Items -- To Buy NowPriceQuantityTotal
Studio RTA - Laptop/Reading Cart with Tilting Surface - + Cherry69.99$0.00
Dynex - Traditional Notebook Case27.99$0.00
Hewlett-Packard - Pavilion Notebook with Intel Centrino1599.99$0.00
3 - Year Performance Service Plan $1000 and Over299.99$0.00
+
+ + + + + + + + + + + + + + + + + + + + + + +
The total charged to your credit card:$0.00
 
Enter your credit card number:
Enter your three digit access code:
+
+
+
+
+ +
+
+ +
+
+
+ + +
+
+
+ + +
+
+ +
+ + + +
+ + + + + + + +
Name:
+
+
+ +
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+ +
+ + +
+ + +
+
+ +
+ + + +
+ + + + + + + + + + + + +
Title:
Message:
+

+ +

+
+
+

Message List

+ + + + + + +
+
+
+ +
+
+ +
+
+ + + +
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + \ No newline at end of file diff --git a/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/images/Reflected-XSS.png b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/images/Reflected-XSS.png new file mode 100644 index 000000000..b6ee5966f Binary files /dev/null and b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/images/Reflected-XSS.png differ diff --git a/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/images/Stored-XSS.png b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/images/Stored-XSS.png new file mode 100644 index 000000000..8c1063658 Binary files /dev/null and b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/images/Stored-XSS.png differ diff --git a/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content1.adoc b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content1.adoc new file mode 100644 index 000000000..694dc74f1 --- /dev/null +++ b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content1.adoc @@ -0,0 +1,25 @@ +== What is XSS + +NEED DEFINITION. + +==== 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 + +=== XSS allows attackers to execute script in the victim’s browser and take over the user’s browser using scripting malware + +==== Examples: +* From the browser address bar (chrome, Firefox) ++ +---- +javascript:alert("XSS Test"); +javascript:alert(document.cookie); +---- +* Any data field that is returned to the client is potentially injectable ++ +---- + +---- + +== 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. diff --git a/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content10.adoc b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content10.adoc new file mode 100644 index 000000000..00d8d60f8 --- /dev/null +++ b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content10.adoc @@ -0,0 +1,24 @@ +== XSS Defense +* HTML entity input encoding +** Converting ‘<‘ and ‘>’ to < and > before storage +* HTML entity output encoding +** Converting ‘<‘ and ‘>’ to < and > before writing +* Input validation +** Positive model to allow valid characters only +** New attacks found everyday +*** negative filter not reliable +* Setting HTTPOnly as a cookie attribute +* Only allow post data to prevent reflected XSS +* Use language specific built-in mechanisms +** Page validation for .NET in web.config ++ +---- +<%page ValidateRequest="true" %> +---- +** Struts ++ +---- + +---- + +*Any problems with these approaches?* diff --git a/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content11.adoc b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content11.adoc new file mode 100644 index 000000000..e5f833af8 --- /dev/null +++ b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content11.adoc @@ -0,0 +1,19 @@ +== Encoding Best Practices +* Not as easy as it may seem +** Web 2.0 apps (social networks, mashups, blogs, feeds, etc.) +** HTML encoding, HTML attribute encoding, JavaScript encoding, URL encoding, … +* Use a proven and tested framework +** The OWASP AntiSamy project (Java & .NET) +*** Very useful in social applications where HTML content is allowed as input from users +*** http://www.owasp.org/index.php/Category:OWASP_AntiSamy_Project +** The OWASP ESAPI (Java, .NET, PHP, Classic ASP, Cold Fusion, Haskell) +*** https://www.owasp.org/index.php/ESAPI +** HTMLPurifier (PHP) +*** http://htmlpurifier.org/ +** Anti-XSS Library from Microsoft +*** Designed specifically for ASP.NET applications +*** http://www.codeplex.com/AntiXSS +* Some light reading: +** http://www.owasp.org/index.php/How_to_perform_HTML_entity_encoding_in_Java +** https://www.owasp.org/index.php?title=XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet + diff --git a/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content12.adoc b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content12.adoc new file mode 100644 index 000000000..c371ae985 --- /dev/null +++ b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content12.adoc @@ -0,0 +1,8 @@ +== The Samy Attack! + +A very interesting XSS exploit. A single flaw led to a massive attack. + +http://web.archive.org/web/20060208182348/namb.la/popular/tech.html + +Only published AFTER MySpace resolved this issue. *He only wanted more friends!* + diff --git a/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content13.adoc b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content13.adoc new file mode 100644 index 000000000..d50c9d29d --- /dev/null +++ b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content13.adoc @@ -0,0 +1,19 @@ +== XSS Phishing Example + +* A search page displays the search string +* Attacker types in: +** ‘String to search”>


+ This feature requires account login:



+ Enter Username:

+ Enter Password:

+


+---- + +*Attacker steals credentials and posts data to attacker site* diff --git a/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content13a.adoc b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content13a.adoc new file mode 100644 index 000000000..442ae92e8 --- /dev/null +++ b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content13a.adoc @@ -0,0 +1,3 @@ +== Try It! XSS Phishing + +Place Holder diff --git a/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content14.adoc b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content14.adoc new file mode 100644 index 000000000..9f0a60ae4 --- /dev/null +++ b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content14.adoc @@ -0,0 +1,13 @@ +== HTTPOnly + +* Disallows access to cookie in most modern browsers +** Even by the website that set the cookie in the first place + +* HTTPOnly Cookies are still accessible through AJAX +** This is accomplished using the XmlHttpRequest object +** Cookie data can still be read from the headers + +* Public web sites that support multiple browsers +* Use a client-side script to determine the browser version for a visitor +* The website can restrict sensitive information to visitors using browsers that mitigate cross site scripting attacks for cookies +* Visitors with browsers that do not support HTTPOnly cookies can be given limited information or functionality along with a request to upgrade their software diff --git a/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content15.adoc b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content15.adoc new file mode 100644 index 000000000..cd99ded59 --- /dev/null +++ b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content15.adoc @@ -0,0 +1,31 @@ +== HTTPOnly Implementation + +* Java has limited support for HTTPOnly ++ +---- +response.setHeader("Set-Cookie", UNIQUE2U + "=" + value + "; HTTPOnly"); +---- +* Draft Servlet 3.0 specification (JSR 315) +** Support in Cookie and SessionCookieConfig + +* ASP.NET 1.1 has no built-in support for HTTPOnly ++ +---- +HttpCookie cookie = new HttpCookie("MyCookie"); +cookie.Value = cookieval; +cookie.Path = FormsAuthentication.FormsCookiePath + "; HTTPOnly"; +context.Response.Cookies.Add(cookie); +---- +* ASP.NET 1.1 EndRequest event listener ++ +---- +private void OnEndRequest(object sender, EventArgs e) +{ + HttpContext context = HttpContext.Current; + foreach (string sCookie in context.Response.Cookies) + { + context.Response.Cookies[sCookie].Path += "; HTTPOnly"; + } +} +--- +* ASP.NET 2.0 has HTTPOnly property in Cookie class diff --git a/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content15a.adoc b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content15a.adoc new file mode 100644 index 000000000..dac394f39 --- /dev/null +++ b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content15a.adoc @@ -0,0 +1,3 @@ +== Try It! HTTPOnly + +Place Holder \ No newline at end of file diff --git a/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content16.adoc b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content16.adoc new file mode 100644 index 000000000..de089b022 --- /dev/null +++ b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content16.adoc @@ -0,0 +1,3 @@ +== Try It! XSS LAB + +Place Holder \ No newline at end of file diff --git a/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content2.adoc b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content2.adoc new file mode 100644 index 000000000..97936b0af --- /dev/null +++ b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content2.adoc @@ -0,0 +1,15 @@ +== Most Common Locations + +* Search fields that echo a search string back to the user + +* Input fields that echo user data + +* Error messages that return user supplied text + +* Hidden fields that contain user supplied data + +* Any page that displays user supplied data +** Message boards +** Free form comments + +* HTTP Headers diff --git a/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content3.adoc b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content3.adoc new file mode 100644 index 000000000..e1ccb70f3 --- /dev/null +++ b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content3.adoc @@ -0,0 +1,19 @@ +== Why Should We Care + +=== XSS attacks may result in +* Stealing session cookies +* Creating false requests +* Creating false fields on a page to collect credentials +* Redirecting your page to a “non-friendly” site +* Creating requests that masquerade as a valid user +* Stealing of confidential information +* Execution of malicious code on an end-user system (active scripting) +* Insertion of hostile and inappropriate content ++ +---- + +“>GoodYear recommends buying BridgeStone tires… +---- + +=== XSS attacks add validity to Phishing attacks +* A valid domain is used in the URL diff --git a/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content4.adoc b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content4.adoc new file mode 100644 index 000000000..6fbfabcd4 --- /dev/null +++ b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content4.adoc @@ -0,0 +1,16 @@ +== Types of XSS + +=== 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 +* Social engineering is required + +=== Local: DOM-based +* 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 + +=== 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 +* Social engineering is not required + diff --git a/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content5.adoc b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content5.adoc new file mode 100644 index 000000000..848f66ff6 --- /dev/null +++ b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content5.adoc @@ -0,0 +1,9 @@ +== Reflected XSS Scenario + +* Attacker sends a malicious URL to victim +* Victim clicks on the link that loads malicious web page +* The malicious script embedded in the URL executes in the victim’s browser +** The script steals sensitive information, like the session id, and releases it to the attacker + +*Victim does not realize attack occurred* + diff --git a/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content5a.adoc b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content5a.adoc new file mode 100644 index 000000000..2e1e65ee2 --- /dev/null +++ b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content5a.adoc @@ -0,0 +1,6 @@ +== Try It! Reflected XSS + +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. + 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 new file mode 100644 index 000000000..eaa6c8884 --- /dev/null +++ b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content6.adoc @@ -0,0 +1,10 @@ +== DOM-Based XSS Scenario + +* 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 +* Attacker’s malicious script may run commands with the privileges of local account + +*Victim does not realize attack occurred* + 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 new file mode 100644 index 000000000..1726ff547 --- /dev/null +++ b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content6a.adoc @@ -0,0 +1,3 @@ +== Try It! DOM-Based XSS + +Need A Lesson diff --git a/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content7.adoc b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content7.adoc new file mode 100644 index 000000000..95ec99a41 --- /dev/null +++ b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content7.adoc @@ -0,0 +1,18 @@ +== DOM-Based XSS Example + +---- + +---- diff --git a/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content8.adoc b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content8.adoc new file mode 100644 index 000000000..6eda0dd78 --- /dev/null +++ b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content8.adoc @@ -0,0 +1,20 @@ +== DOM-based XSS Defense + +* Attacker creates url: ++ +---- +http://mylogin.com/login?error= +---- + +* JavaScript must enforce input validation ++ +---- + if ( errorMsg\[1\].match(/^[ a-zA-Z0-9:-]$/)) + { + document.write(‘some error’); + } + else + { + document.write(''+errorMsg\[1\]+''); + } +---- diff --git a/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content9.adoc b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content9.adoc new file mode 100644 index 000000000..a8ab8936d --- /dev/null +++ b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content9.adoc @@ -0,0 +1,8 @@ +== Stored XSS Scenario +* Attacker posts malicious script to a message board +* Message is stored in a server database +* Victim reads the message +* The malicious script embedded in the message board post executes in the victim’s browser +** The script steals sensitive information, like the session id, and releases it to the attacker + +*Victim does not realize attack occurred* diff --git a/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content9a.adoc b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content9a.adoc new file mode 100644 index 000000000..75fb1bc83 --- /dev/null +++ b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_content9a.adoc @@ -0,0 +1,5 @@ +== Try It! Stored XSS + +Identify which field is susceptible to XSS + +It is always a good practice to scrub all input, especially those inputs that will later be used as parameters to OS commands, scripts, and database queries. It is particularly important for content that will be permanently stored somewhere in the application. Users should not be able to create message content that could cause another user to load an undesireable page or undesireable content when the user's message is retrieved. \ No newline at end of file diff --git a/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_plan.adoc b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_plan.adoc new file mode 100644 index 000000000..4a562e0dc --- /dev/null +++ b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonPlans/en/CrossSiteScripting_plan.adoc @@ -0,0 +1,15 @@ +== Concept + +This lesson describes what is Cross-Site Scripting (XSS) and how it can be manipulated to perform tasks that were not the original intent of the developer. + +== Goals + +* The user should have a basic understand how XSS works. +* The user will understand the best practices for defending against XSS injection attacks +* The user will demonstrate knowledge on: +** Reflected XSS Injection +** Stored XSS Injection +** Dom-Based XSS Injection + + + diff --git a/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonSolutions/en/CrossSiteScripting_solution.adoc b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonSolutions/en/CrossSiteScripting_solution.adoc new file mode 100644 index 000000000..a6293919c --- /dev/null +++ b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonSolutions/en/CrossSiteScripting_solution.adoc @@ -0,0 +1,5 @@ += HTTP Basics + +== Solution + +Solution goes here \ No newline at end of file diff --git a/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonSolutions/html/CrossSiteScripting.html b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonSolutions/html/CrossSiteScripting.html new file mode 100644 index 000000000..42219764e --- /dev/null +++ b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/CrossSiteScripting/lessonSolutions/html/CrossSiteScripting.html @@ -0,0 +1,14 @@ + + + + + + +
+ + +
+
+ + + \ No newline at end of file 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 new file mode 100644 index 000000000..6ad457235 --- /dev/null +++ b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/i18n/WebGoatLabels.properties @@ -0,0 +1,8 @@ +#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 ]. diff --git a/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/i18n/WebGoatLabels_de.properties b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/i18n/WebGoatLabels_de.properties new file mode 100644 index 000000000..7ec3f4462 --- /dev/null +++ b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/i18n/WebGoatLabels_de.properties @@ -0,0 +1,8 @@ +#StringSqlInjection.java +StringSqlInjectionSecondStage=Da sie nun erfolgreich eine SQL Injection durchgef\u00fchrt haben, versuchen Sie denselben Typ von Angriff auf eine parametrisierte Anfrage. Starten Sie Diese Lektion neu, wenn Sie zur verwundbaren SQL Anfrage gelangen m\u00f6chten. + EnterLastName=Geben Sie Ihren Nachnamen ein: +NoResultsMatched=Keine Resultate gefunden, versuchen Sie es erneut +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 ]. diff --git a/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/i18n/WebGoatLabels_fr.properties b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/i18n/WebGoatLabels_fr.properties new file mode 100644 index 000000000..e25a104f7 --- /dev/null +++ b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/i18n/WebGoatLabels_fr.properties @@ -0,0 +1,8 @@ +#StringSqlInjection.java +StringSqlInjectionSecondStage=Maintenant que vous avez r\u00e9alis\u00e9 une injection SQL avec succ\u00e8s, essayer le m\u00eame type d'attaque sur une requ\u00eate param\u00e9tr\u00e9e. Red\u00e9marrez la le\u00e7on si vous souhaitez revenir \u00e0 la requ\u00eate injectable. +EnterLastName=Entrez votre nom : +NoResultsMatched=Aucun r\u00e9sultat correspondant. Essayez encore. +SqlStringInjectionHint1=L'application r\u00e9cup\u00e8re votre saisie et l'ins\u00e8re \u00e0 la fin d'une commande SQL pr\u00e9-form\u00e9e. +SqlStringInjectionHint2=Voici le code de la requ\u00eate assembl\u00e9e et ex\u00e9cut\u00e9e par WebGoat :

"SELECT * FROM user_data WHERE last_name = "accountName" +SqlStringInjectionHint3=Les commandes SQL compos\u00e9es peuvent \u00eatre assembl\u00e9es en associant de multiples conditions au moyen de mots-cl\u00e9 tels que AND et OR. Essayez d'assembler une condition qui sera toujours r\u00e9solue \u00e0 vrai. +SqlStringInjectionHint4=Essayez de saisir [ smith' OR '1' = '1 ]. \ No newline at end of file diff --git a/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/i18n/WebGoatLabels_ru.properties b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/i18n/WebGoatLabels_ru.properties new file mode 100644 index 000000000..073d4a78b --- /dev/null +++ b/webgoat-lessons/cross-site-scripting/src/main/resources/plugin/i18n/WebGoatLabels_ru.properties @@ -0,0 +1,8 @@ +#StringSqlInjection.java +StringSqlInjectionSecondStage=\u0422\u0435\u043f\u0435\u0440\u044c, \u043a\u043e\u0433\u0434\u0430 \u0432\u0430\u043c \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0443\u0434\u0430\u0447\u043d\u043e \u043f\u0440\u043e\u044d\u043a\u0441\u043f\u043b\u0443\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c SQL-\u0438\u043d\u044a\u0435\u043a\u0446\u0438\u044e, \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0438\u0442\u044c \u044d\u0442\u043e \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u043c. \u041d\u0430\u0447\u043d\u0438\u0442\u0435 \u0443\u0440\u043e\u043a \u0437\u0430\u043d\u043e\u0432\u043e \u0435\u0441\u043b\u0438 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0432\u043d\u043e\u0432\u044c \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0435 \u043f\u043e\u043b\u0435. +EnterLastName=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0432\u0430\u0448\u0443 \u0444\u0430\u043c\u0438\u043b\u0438\u044e: +NoResultsMatched=\u041d\u0435\u0442 \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u0439. \u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0441\u043d\u043e\u0432\u0430. +SqlStringInjectionHint1=\u041f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0431\u0435\u0440\u0451\u0442 \u0442\u043e \u0447\u0442\u043e \u0432\u044b \u0432\u0432\u043e\u0434\u0438\u0442\u0435 \u0438 \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0432 \u043a\u043e\u043d\u0435\u0446 \u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e SQL-\u0437\u0430\u043f\u0440\u043e\u0441\u0430. +SqlStringInjectionHint2=\u0412\u043e\u0442 \u043a\u043e\u0434 \u0437\u0430\u043f\u0440\u043e\u0441\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f WebGoat`\u043e\u043c:

"SELECT * FROM user_data WHERE last_name = "accountName" +SqlStringInjectionHint3=\u0426\u0435\u043b\u043e\u0441\u0442\u043d\u043e\u0441\u0442\u044c SQL-\u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0442\u044c \u043f\u0440\u043e\u0432\u0435\u0434\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0442\u0430\u043a\u0438\u0445 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0445 \u0441\u043b\u043e\u0432 \u043a\u0430\u043a AND \u0438 OR. \u041f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0441\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0442\u0430\u043a\u043e\u0435 SQL-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0438\u0441\u0442\u0438\u043d\u0443. +SqlStringInjectionHint4=\u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0432\u0432\u0435\u0441\u0442\u0438 [ smith' OR '1' = '1 ]. \ No newline at end of file diff --git a/webgoat-lessons/pom.xml b/webgoat-lessons/pom.xml index f5ba493a3..43928291d 100644 --- a/webgoat-lessons/pom.xml +++ b/webgoat-lessons/pom.xml @@ -15,6 +15,7 @@ client-side-filtering + cross-site-scripting http-basics sql-injection xxe @@ -66,6 +67,6 @@ - - + + diff --git a/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_plan.adoc b/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_plan.adoc index 27e79e50c..2865b3d81 100644 --- a/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_plan.adoc +++ b/webgoat-lessons/sql-injection/src/main/resources/plugin/SqlInjection/lessonPlans/en/SqlInjection_plan.adoc @@ -1,5 +1,3 @@ -= SQL Injection - == Concept This lesson describes what is Structured Query Language (SQL) and how it can be manipulated to perform tasks that were not the original intent of the developer. @@ -11,5 +9,5 @@ This lesson describes what is Structured Query Language (SQL) and how it can be * The user will demonstrate knowledge on: ** String SQL Injection ** Numeric SQL Injection - +** Combining SQL Injection Techniques