From 1ce614f7338d22364835a7eeaad4d6d55aa58138 Mon Sep 17 00:00:00 2001 From: "rogan.dawes" Date: Thu, 10 Jan 2008 10:12:31 +0000 Subject: [PATCH] Merge with major changes made by Aspect Several new lessons added git-svn-id: http://webgoat.googlecode.com/svn/trunk@236 4033779f-a91e-0410-96ef-6bf7bf53c507 --- .../ClientSideFiltering.java | 430 ++++++++++++++++++ .../webgoat/lessons/ClientSideValidation.java | 423 +++++++++++++++++ .../org/owasp/webgoat/lessons/DOMXSS.java | 264 +++++++++++ .../owasp/webgoat/lessons/DangerousEval.java | 291 ++++++++++++ .../owasp/webgoat/lessons/ReflectedXSS.java | 12 +- .../org/owasp/webgoat/lessons/TraceXSS.java | 4 +- .../project/WebContent/javascript/DOMXSS.js | 5 + .../javascript/clientSideFiltering.js | 64 +++ .../javascript/clientSideValidation.js | 113 +++++ .../project/WebContent/javascript/escape.js | 6 + .../project/WebContent/javascript/eval.js | 54 +++ .../javascript/instructor/DOMXSS_i.js | 13 + .../lesson_plans/DangerousEval.html | 9 + .../lessons/Ajax/clientSideFiltering.jsp | 114 +++++ .../lessons/Ajax/clientSideValidation.jsp | 30 ++ .../WebContent/lessons/Ajax/employees.xml | 228 ++++++++++ .../project/WebContent/lessons/Ajax/eval.jsp | 37 ++ .../lessons/Ajax/images/lesson1_header.jpg | Bin 0 -> 44854 bytes .../lessons/Ajax/images/lesson1_workspace.jpg | Bin 0 -> 23580 bytes .../Ajax/instructor/clientSideFiltering_i.jsp | 111 +++++ 20 files changed, 2200 insertions(+), 8 deletions(-) create mode 100644 webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ClientSideFiltering/ClientSideFiltering.java create mode 100644 webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ClientSideValidation.java create mode 100644 webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/DOMXSS.java create mode 100644 webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/DangerousEval.java create mode 100644 webgoat/main/project/WebContent/javascript/DOMXSS.js create mode 100644 webgoat/main/project/WebContent/javascript/clientSideFiltering.js create mode 100644 webgoat/main/project/WebContent/javascript/clientSideValidation.js create mode 100644 webgoat/main/project/WebContent/javascript/escape.js create mode 100644 webgoat/main/project/WebContent/javascript/eval.js create mode 100644 webgoat/main/project/WebContent/javascript/instructor/DOMXSS_i.js create mode 100644 webgoat/main/project/WebContent/lesson_plans/DangerousEval.html create mode 100644 webgoat/main/project/WebContent/lessons/Ajax/clientSideFiltering.jsp create mode 100644 webgoat/main/project/WebContent/lessons/Ajax/clientSideValidation.jsp create mode 100644 webgoat/main/project/WebContent/lessons/Ajax/employees.xml create mode 100644 webgoat/main/project/WebContent/lessons/Ajax/eval.jsp create mode 100644 webgoat/main/project/WebContent/lessons/Ajax/images/lesson1_header.jpg create mode 100644 webgoat/main/project/WebContent/lessons/Ajax/images/lesson1_workspace.jpg create mode 100644 webgoat/main/project/WebContent/lessons/Ajax/instructor/clientSideFiltering_i.jsp diff --git a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ClientSideFiltering/ClientSideFiltering.java b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ClientSideFiltering/ClientSideFiltering.java new file mode 100644 index 000000000..c36e33d20 --- /dev/null +++ b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ClientSideFiltering/ClientSideFiltering.java @@ -0,0 +1,430 @@ +package org.owasp.webgoat.lessons.ClientSideFiltering; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.apache.ecs.Element; +import org.apache.ecs.ElementContainer; +import org.apache.ecs.html.A; +import org.apache.ecs.html.BR; +import org.apache.ecs.html.IMG; +import org.apache.ecs.html.Input; +import org.apache.ecs.html.P; +import org.apache.ecs.html.Script; +import org.apache.ecs.html.Select; +import org.apache.ecs.html.TD; +import org.apache.ecs.html.TR; +import org.apache.ecs.html.Table; +import org.owasp.webgoat.lessons.Category; +import org.owasp.webgoat.lessons.SequentialLessonAdapter; +import org.owasp.webgoat.session.ECSFactory; +import org.owasp.webgoat.session.WebSession; + +public class ClientSideFiltering extends SequentialLessonAdapter { + + private final static String ANSWER = "answer"; + + public final static A ASPECT_LOGO = new A().setHref("http://www.aspectsecurity.com").addElement(new IMG("images/logos/aspect.jpg").setAlt("Aspect Security").setBorder(0).setHspace(0).setVspace(0)); + + protected Element createContent(WebSession s) { + return super.createStagedContent(s); + } + + protected Element createMainContent(WebSession s) { + ElementContainer ec = new ElementContainer(); + + try { + + ec.addElement(new Script() + .setSrc("javascript/clientSideFiltering.js")); + + + Input input = new Input(Input.HIDDEN, "userID", 102); + + input.setID("userID"); + + ec.addElement(input); + + + + ec.addElement(new P().addElement("Select user:")); + + ec.addElement(createDropDown()); + + ec.addElement(new P()); + + Table t = new Table().setCellSpacing(0).setCellPadding(2) + .setBorder(1).setWidth("90%").setAlign("center"); + + t.setID("hiddenEmployeeRecords"); + t.setStyle("display: none"); + + ec.addElement(t); + + t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(1) + .setWidth("90%").setAlign("center"); + + TR tr = new TR(); + tr.addElement(new TD().addElement("UserID")); + tr.addElement(new TD().addElement("First Name")); + tr.addElement(new TD().addElement("Last Name")); + tr.addElement(new TD().addElement("SSN")); + tr.addElement(new TD().addElement("Salary")); + t.addElement(tr); + tr = new TR(); + tr.setID("employeeRecord"); + t.addElement(tr); + + ec.addElement(t); + + } catch (Exception e) { + s.setMessage("Error generating " + this.getClass().getName()); + e.printStackTrace(); + } + + return (ec); + } + + /** + * Gets the category attribute of the RoleBasedAccessControl object + * + * @return The category value + */ + + protected ElementContainer doStage1(WebSession s) { + ElementContainer ec = new ElementContainer(); + + StringBuffer answerString = null; + int answer = 0; + + try { + answerString = new StringBuffer(s.getParser().getStringParameter( + ANSWER, "")); + answer = Integer.parseInt(answerString.toString()); + } catch (NumberFormatException e) { + + // e.printStackTrace(); + } + + if (answer == 450000) { + + + getLessonTracker(s).setStage(2); + s.setMessage("Stage 1 completed."); + + // Redirect user to Stage2 content. + ec.addElement(doStage2(s)); + } else { + ec.addElement(stage1Content(s)); + } + + return ec; + + } + + protected Element doStage2(WebSession s){ + ElementContainer ec = new ElementContainer(); + + + + /** + * They pass iff: + * + * 1. If the DOMXSS.js file contains the lines "escapeHTML(name)" + */ + String file = s.getWebResource("lessons/Ajax/clientSideFiltering.jsp"); + String content = getFileContent(file); + + if(content.indexOf("[Managers/Manager/text()") != -1) + { + makeSuccess(s); + ec.addElement(stage2Content(s)); + } + else{ + ec.addElement(stage2Content(s)); + } + + return ec; + } + + protected ElementContainer stage1Content(WebSession s) { + ElementContainer ec = new ElementContainer(); + try { + + ec.addElement(createMainContent(s)); + + ec.addElement(new BR()); + ec.addElement(new BR()); + + Table t1 = new Table().setCellSpacing(0).setCellPadding(2); + + if (s.isColor()) { + t1.setBorder(1); + } + + TR tr = new TR(); + tr.addElement(new TD() + .addElement("What is Neville Bartholomew's salary? ")); + tr.addElement(new TD(new Input(Input.TEXT, ANSWER, ""))); + Element b = ECSFactory.makeButton("Submit Answer"); + tr.addElement(new TD(b).setAlign("LEFT")); + t1.addElement(tr); + + ec.addElement(t1); + + } catch (Exception e) { + s.setMessage("Error generating " + this.getClass().getName()); + e.printStackTrace(); + } + + return ec; + } + + + protected ElementContainer stage2Content(WebSession s) { + ElementContainer ec = new ElementContainer(); + try { + + ec.addElement(createMainContent(s)); + + ec.addElement(new BR()); + ec.addElement(new BR()); + + Table t1 = new Table().setCellSpacing(0).setCellPadding(2); + + if (s.isColor()) { + t1.setBorder(1); + } + + TR tr = new TR(); + /*tr.addElement(new TD() + .addElement("Press 'Submit' when you believe you have completed the lesson.")); + */ + Element b = ECSFactory.makeButton("Click here when you believe you have completed the lesson."); + tr.addElement(new TD(b).setAlign("CENTER")); + t1.addElement(tr); + + ec.addElement(t1); + + } catch (Exception e) { + s.setMessage("Error generating " + this.getClass().getName()); + e.printStackTrace(); + } + + return ec; + } + + + protected Select createDropDown(){ + Select select = new Select("UserSelect"); + + select.setID("UserSelect"); + + org.apache.ecs.html.Option option = new org.apache.ecs.html.Option( + "Choose Employee", "0", "Choose Employee"); + + select.addElement(option); + + option = new org.apache.ecs.html.Option("Larry Stooge", "101", + "Larry Stooge"); + + select.addElement(option); + + option = new org.apache.ecs.html.Option("Moe Stooge", "102", + "Moe Stooge"); + + select.addElement(option); + + option = new org.apache.ecs.html.Option("Curly Stooge", "103", + "Curly Stooge"); + + select.addElement(option); + + option = new org.apache.ecs.html.Option("Eric Walker", "104", + "Eric Walker"); + + select.addElement(option); + + option = new org.apache.ecs.html.Option("Tom Cat", "105", "Tom Cat"); + + select.addElement(option); + + option = new org.apache.ecs.html.Option("Jerry Mouse", "106", + "Jerry Mouse"); + + select.addElement(option); + + option = new org.apache.ecs.html.Option("David Giambi", "107", + "David Giambi"); + + select.addElement(option); + + option = new org.apache.ecs.html.Option("Bruce McGuirre", "108", + "Bruce McGuirre"); + + select.addElement(option); + + option = new org.apache.ecs.html.Option("Sean Livingston", "109", + "Sean Livingston"); + + select.addElement(option); + + option = new org.apache.ecs.html.Option("Joanne McDougal", "110", + "Joanne McDougal"); + + select.addElement(option); + + option = new org.apache.ecs.html.Option("John Wayne", "111", + "John Wayne"); + + select.addElement(option); + + select.setOnChange("selectUser()"); + + select.setOnFocus("fetchUserData()"); + + return select; + + } + + protected Category getDefaultCategory() { + return Category.AJAX_SECURITY; + } + + /** + * Gets the hints attribute of the RoleBasedAccessControl object + * + * @return The hints value + */ + public List getHints(WebSession s) + { + List hints = new ArrayList(); + + + + + + hints.add("The information displayed when an employee is choosen from the drop down menu is stored on the client side."); + + hints.add("Use Firebug to find where the information is stored on the client side."); + + hints.add("Examine the hidden table to see if there is anyone listed who is not in the drop down menu."); + + hints.add("Look in the last row of the hidden table."); + + + hints.add("You can access the server directly here " + + "to see what results are being returned"); + + hints.add("The server uses an XPath query agasinst an XML database."); + + hints.add("The query currently returns all of the contents of the database."); + + hints.add("The query should only return the information of employees who are managed by Moe Stooge, who's userID is 102"); + + + + hints.add("Try using a filter operator."); + + hints.add("your filter operator shoiuld look something like: [Managers/Manager/text()="); + + + return hints; + +} + + public String getInstructions(WebSession s) { + String instructions = ""; + + if (getLessonTracker(s).getStage() == 1) { + instructions = "STAGE 1:\tYou are Moe Stooge, CSO of Goat Hills Bank. " + + "You have access to everyone in the company's information, except the CEO, " + + "Neville Bartholomew. Or at least you shouldn't have access to the CEO's information." + + " For this exercise, " + + "examine the contents of the page to see what extra information you can find."; + } else if (getLessonTracker(s).getStage() == 2) { + instructions = "STAGE 2:\tNow, fix the problem. Modify the server to only return " + + "results that Moe Stooge is allowed to see."; + } + return (instructions); + } + + private final static Integer DEFAULT_RANKING = new Integer(10); + + protected Integer getDefaultRanking() { + return DEFAULT_RANKING; + } + + /** + * Gets the resources attribute of the RoleBasedAccessControl object + * + * @param rl + * Description of the Parameter + * @return The resources value + */ + + /** + * Gets the role attribute of the RoleBasedAccessControl object + * + * @param user + * Description of the Parameter + * @return The role value + */ + + /** + * Gets the title attribute of the AccessControlScreen object + * + * @return The title value + */ + + public String getTitle() { + return ("LAB: Client Side Filtering"); + } + + private String getFileContent(String content) + { + BufferedReader is = null; + StringBuffer sb = new StringBuffer(); + + try + { + is = new BufferedReader(new FileReader(new File(content))); + String s = null; + + while((s = is.readLine()) != null) + { + sb.append(s); + } + } + catch (Exception e) + { + e.printStackTrace(); + } + finally + { + if(is != null) + { + try + { + is.close(); + } + catch (IOException ioe) + { + + } + } + } + + return sb.toString(); + } + + public Element getCredits() + { + return super.getCustomCredits("", ASPECT_LOGO); + } + +} diff --git a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ClientSideValidation.java b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ClientSideValidation.java new file mode 100644 index 000000000..b2ae01ceb --- /dev/null +++ b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ClientSideValidation.java @@ -0,0 +1,423 @@ +package org.owasp.webgoat.lessons; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.ecs.Element; +import org.apache.ecs.ElementContainer; +import org.apache.ecs.html.A; +import org.apache.ecs.html.BR; +import org.apache.ecs.html.Center; +import org.apache.ecs.html.H1; +import org.apache.ecs.html.HR; +import org.apache.ecs.html.IMG; +import org.apache.ecs.html.Input; +import org.apache.ecs.html.Script; +import org.apache.ecs.html.TD; +import org.apache.ecs.html.TH; +import org.apache.ecs.html.TR; +import org.apache.ecs.html.Table; +import org.owasp.webgoat.session.ECSFactory; +import org.owasp.webgoat.session.WebSession; +import org.owasp.webgoat.util.HtmlEncoder; + +public class ClientSideValidation extends SequentialLessonAdapter { + + /** + * Description of the Method + * + * @param s + * Description of the Parameter + * @return Description of the Return Value + */ + + public final static A ASPECT_LOGO = new A().setHref("http://www.aspectsecurity.com").addElement(new IMG("images/logos/aspect.jpg").setAlt("Aspect Security").setBorder(0).setHspace(0).setVspace(0)); + + + private boolean stage1FirstVisit = true; + + private boolean stage2FirstVisit = true; + + protected Element createContent(WebSession s) { + return super.createStagedContent(s); + } + + protected Element doStage1(WebSession s) { + return evalStage1(s); + } + + protected Element doStage2(WebSession s) { + return stage2Content(s); + } + + protected Element evalStage1(WebSession s) { + + ElementContainer ec = new ElementContainer(); + + String param1 = s.getParser().getRawParameter("field1", ""); + + //test success + + if (param1.equalsIgnoreCase("platinum") + || param1.equalsIgnoreCase("gold") + || param1.equalsIgnoreCase("silver") + || param1.equalsIgnoreCase("bronze") + || param1.equalsIgnoreCase("pressone") + || param1.equalsIgnoreCase("presstwo")) { + getLessonTracker(s).setStage(2); + //s.resetHintCount(); + s.setMessage("Stage 1 completed."); + + // Redirect user to Stage2 content. + ec.addElement(doStage2(s)); + + } else { + if (!stage1FirstVisit) { + s.setMessage("Keep looking for the coupon code."); + } + stage1FirstVisit = false; + + ec.addElement(stage1Content(s)); + } + + return ec; + + } + + + protected Element stage1Content(WebSession s) { + + ElementContainer ec = new ElementContainer(); + + try { + + + ec.addElement(new Script() + .setSrc("javascript/clientSideValidation.js")); + + + ec.addElement(new HR().setWidth("90%")); + ec.addElement(new Center().addElement(new H1() + .addElement("Shopping Cart"))); + + ec.addElement(createQtyTable(s)); + + ec.addElement(createTotalTable(s)); + ec.addElement(new BR()); + ec.addElement(new HR().setWidth("90%")); + + + + } catch (Exception e) { + s.setMessage("Error generating " + this.getClass().getName()); + e.printStackTrace(); + } + return (ec); + } + + protected Element stage2Content(WebSession s) { + + ElementContainer ec = new ElementContainer(); + + try { + + ec.addElement(new Script() + .setSrc("javascript/clientSideValidation.js")); + + ec.addElement(new HR().setWidth("90%")); + ec.addElement(new Center().addElement(new H1() + .addElement("Shopping Cart"))); + + ec.addElement(createQtyTable(s)); + + ec.addElement(createTotalTable(s)); + ec.addElement(new BR()); + ec.addElement(new HR().setWidth("90%")); + + // test success + + float grandTotal = s.getParser() + .getFloatParameter("GRANDTOT", 0.0f); + + if (getTotalQty(s) > 0 && grandTotal == 0 && !stage2FirstVisit) { + makeSuccess(s); + } else { + + if (!stage2FirstVisit) { + s.setMessage("Your order isn't free yet."); + } + stage2FirstVisit = false; + } + + } catch (Exception e) { + s.setMessage("Error generating " + this.getClass().getName()); + e.printStackTrace(); + } + return (ec); + } + + protected ElementContainer createTotalTable(WebSession s) { + + ElementContainer ec = new ElementContainer(); + + String param1 = s.getParser().getRawParameter("field1", ""); + String param2 = HtmlEncoder.encode(s.getParser().getRawParameter( + "field2", "4128 3214 0002 1999")); + + Table t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(0) + .setWidth("90%").setAlign("center"); + + if (s.isColor()) { + t.setBorder(1); + } + + ec.addElement(new BR()); + + TR tr = new TR(); + tr.addElement(new TD() + .addElement("Total before coupon is applied:")); + + tr.addElement(new TD().addElement( + new Input(Input.TEXT, "SUBTOT", s.getParser() + .getStringParameter("SUBTOT", "0")).setReadOnly(true)) + .setAlign("right")); + t.addElement(tr); + + tr = new TR(); + tr.addElement(new TD() + .addElement("Total to be charged to your credit card:")); + + tr.addElement(new TD() + .addElement( + new Input(Input.TEXT, "GRANDTOT", s.getParser() + .getStringParameter("GRANDTOT", "0")) + .setReadOnly(true)).setAlign("right")); + t.addElement(tr); + + t.addElement(tr); + + tr = new TR(); + tr.addElement(new TD().addElement(" ").setColSpan(2)); + t.addElement(tr); + tr = new TR(); + tr.addElement(new TD().addElement("Enter your credit card number:")); + tr.addElement(new TD().addElement(new Input(Input.TEXT, "field2", + param2))); + t.addElement(tr); + tr = new TR(); + tr.addElement(new TD().addElement("Enter your coupon code:")); + + Input input = new Input(Input.TEXT, "field1", param1); + input.setOnKeyUp("isValidCoupon(field1.value)"); + tr.addElement(new TD().addElement(input)); + t.addElement(tr); + + Element b = ECSFactory.makeButton("Purchase"); + tr = new TR(); + tr.addElement(new TD().addElement(b).setColSpan(2).setAlign("center")); + t.addElement(tr); + ec.addElement(t); + + return ec; + + } + + protected int getTotalQty(WebSession s) { + + int quantity = 0; + + quantity += s.getParser().getFloatParameter("QTY1", 0.0f); + quantity += s.getParser().getFloatParameter("QTY2", 0.0f); + quantity += s.getParser().getFloatParameter("QTY3", 0.0f); + quantity += s.getParser().getFloatParameter("QTY4", 0.0f); + + return quantity; + } + + protected ElementContainer createQtyTable(WebSession s) { + + ElementContainer ec = new ElementContainer(); + Table t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(1) + .setWidth("90%").setAlign("center"); + + if (s.isColor()) { + t.setBorder(1); + } + + TR tr = new TR(); + tr.addElement(new TH().addElement("Shopping Cart Items -- To Buy Now") + .setWidth("70%")); + tr.addElement(new TH().addElement("Price").setWidth("10%")); + tr.addElement(new TH().addElement("Quantity").setWidth("10%")); + tr.addElement(new TH().addElement("Total").setWidth("10%")); + t.addElement(tr); + + tr = new TR(); + tr + .addElement(new TD() + .addElement("Studio RTA - Laptop/Reading Cart with Tilting Surface - Cherry ")); + + + tr.addElement(new TD().addElement( + new Input(Input.TEXT, "PRC1", s.getParser().getStringParameter( + "PRC1", "69.99")).setSize(10).setReadOnly(true)).setAlign("right")); + + Input input = new Input(Input.TEXT, "QTY1", s.getParser() + .getStringParameter("QTY1", "0")); + + input.setOnKeyUp("updateTotals();"); + input.setOnLoad("updateTotals();"); + input.setSize(10); + + tr.addElement(new TD().addElement(input).setAlign("right")); + + tr.addElement(new TD().addElement( + new Input(Input.TEXT, "TOT1", s.getParser().getStringParameter( + "TOT1", "0")).setSize(10).setReadOnly(true)).setAlign("right")); + + t.addElement(tr); + tr = new TR(); + tr.addElement(new TD().addElement("Dynex - Traditional Notebook Case")); + + tr.addElement(new TD().addElement( + new Input(Input.TEXT, "PRC2", s.getParser().getStringParameter( + "PRC2", "27.99")).setSize(10).setReadOnly(true)).setAlign("right")); + + input = new Input(Input.TEXT, "QTY2", s.getParser().getStringParameter( + "QTY2", "0")); + + input.setOnKeyUp("updateTotals();"); + input.setSize(10); + tr.addElement(new TD().addElement(input).setAlign("right")); + + tr.addElement(new TD().addElement( + new Input(Input.TEXT, "TOT2", s.getParser().getStringParameter( + "TOT2", "0")).setSize(10).setReadOnly(true)).setAlign("right")); + + t.addElement(tr); + tr = new TR(); + tr + .addElement(new TD() + .addElement("Hewlett-Packard - Pavilion Notebook with Intel® Centrino™")); + + + tr.addElement(new TD().addElement( + new Input(Input.TEXT, "PRC3", s.getParser().getStringParameter( + "PRC3", "1599.99")).setSize(10).setReadOnly(true)) + .setAlign("right")); + + input = new Input(Input.TEXT, "QTY3", s.getParser().getStringParameter( + "QTY3", "0")); + + input.setOnKeyUp("updateTotals();"); + input.setSize(10); + tr.addElement(new TD().addElement(input).setAlign("right")); + + + tr.addElement(new TD().addElement( + new Input(Input.TEXT, "TOT3", s.getParser().getStringParameter( + "TOT3", "0")).setSize(10).setReadOnly(true)).setAlign("right")); + + t.addElement(tr); + tr = new TR(); + tr + .addElement(new TD() + .addElement("3 - Year Performance Service Plan $1000 and Over ")); + + + tr + .addElement(new TD().addElement( + new Input(Input.TEXT, "PRC4", s.getParser() + .getStringParameter("PRC4", "299.99")).setSize(10) + .setReadOnly(true)).setAlign("right")); + + input = new Input(Input.TEXT, "QTY4", s.getParser().getStringParameter( + "QTY4", "0")); + + input.setOnKeyUp("updateTotals();"); + input.setSize(10); + tr.addElement(new TD().addElement(input).setAlign("right")); + + + tr.addElement(new TD().addElement( + new Input(Input.TEXT, "TOT4", s.getParser().getStringParameter( + "TOT4", "0")).setSize(10).setReadOnly(true)).setAlign("right")); + + t.addElement(tr); + ec.addElement(t); + return ec; + } + + protected Category getDefaultCategory() { + return Category.AJAX_SECURITY; + } + + /** + * Gets the hints attribute of the AccessControlScreen object + * + * @return The hints value + */ + + + public List getHints(WebSession s) + { + List hints = new ArrayList(); + + + + + hints.add("Use Firebug to examine the JavaScript."); + + hints.add("Using Firebug, you can add breakpoints in the JavaScript."); + + hints.add("Use Firebug to find the array or encrypted coupon codes, and " + + "step through the JavaScript to see the decrypted values."); + + hints.add("You can use Firebug to inspect (and modify) the HTML."); + + hints.add("Use Firebug to remove the 'readonly' attribute from the input next to " + + "'The total charged to your credit card:' and set the value to 0."); + + + + return hints; + + } + + /** + * Gets the instructions attribute of the WeakAccessControl object + * + * @return The instructions value + */ + public String getInstructions(WebSession s) { + String instructions = ""; + + if (getLessonTracker(s).getStage() == 1) { + instructions = "STAGE 1:\tFor this exercise, your mission is to discover a coupon code to receive an unintended discount."; + } + else if (getLessonTracker(s).getStage() == 2) { + instructions = "STAGE 2:\tNow, try to get your entire order for free."; + } + return (instructions); + } + + private final static Integer DEFAULT_RANKING = new Integer(120); + + protected Integer getDefaultRanking() { + return DEFAULT_RANKING; + } + + /** + * Gets the title attribute of the AccessControlScreen object + * + * @return The title value + */ + public String getTitle() { + return "Client Side Validation"; + } + + public Element getCredits() + { + return super.getCustomCredits("", ASPECT_LOGO); + } +} diff --git a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/DOMXSS.java b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/DOMXSS.java new file mode 100644 index 000000000..56c5c9670 --- /dev/null +++ b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/DOMXSS.java @@ -0,0 +1,264 @@ +package org.owasp.webgoat.lessons; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.apache.ecs.Element; +import org.apache.ecs.ElementContainer; +import org.apache.ecs.StringElement; +import org.apache.ecs.html.A; +import org.apache.ecs.html.BR; +import org.apache.ecs.html.H1; +import org.apache.ecs.html.IMG; +import org.apache.ecs.html.Input; +import org.apache.ecs.html.Script; +import org.owasp.webgoat.session.*; + +public class DOMXSS extends SequentialLessonAdapter { + + public final static A ASPECT_LOGO = new A().setHref("http://www.aspectsecurity.com").addElement(new IMG("images/logos/aspect.jpg").setAlt("Aspect Security").setBorder(0).setHspace(0).setVspace(0)); + + + private final static String PERSON = "person"; + + /** + * Description of the Method + * + * @param s Description of the Parameter + * @return Description of the Return Value + */ + protected Element createContent(WebSession s) { + return super.createStagedContent(s); + } + + protected Element doStage1(WebSession s) throws Exception { + ElementContainer ec = new ElementContainer(); + + StringBuffer attackString = new StringBuffer(s.getParser().getStringParameter(PERSON, "")); + + ec.addElement(mainContent(s)); + + if (attackString.toString().toLowerCase().indexOf("img") != -1&& attackString.toString().toLowerCase().indexOf("images/logos/owasp.jpg") != -1) { + getLessonTracker(s).setStage(2); + s.setMessage("Stage 1 completed. "); + } + + return (ec); + } + + protected Element doStage2(WebSession s) throws Exception { + ElementContainer ec = new ElementContainer(); + + StringBuffer attackString = new StringBuffer(s.getParser().getStringParameter(PERSON, "")); + + ec.addElement(mainContent(s)); + + if (attackString.toString().toLowerCase().indexOf("img") != -1 && attackString.toString().toLowerCase().indexOf("onerror") != -1 && attackString.toString().toLowerCase().indexOf("alert") != -1) { + getLessonTracker(s).setStage(3); + s.setMessage("Stage 2 completed. "); + } + + return (ec); + } + + protected Element doStage3(WebSession s) throws Exception { + ElementContainer ec = new ElementContainer(); + + StringBuffer attackString = new StringBuffer(s.getParser().getStringParameter(PERSON, "")); + + ec.addElement(mainContent(s)); + + if (attackString.toString().toLowerCase().indexOf("iframe") != -1 && attackString.toString().toLowerCase().indexOf("javascript:alert") != -1) { + getLessonTracker(s).setStage(4); + s.setMessage("Stage 3 completed."); + } + return (ec); + } + + protected Element doStage4(WebSession s) throws Exception { + ElementContainer ec = new ElementContainer(); + + StringBuffer attackString = new StringBuffer(s.getParser().getStringParameter(PERSON, "")); + + ec.addElement(mainContent(s)); + + if (attackString.toString().toLowerCase().indexOf("please enter your password:") != -1&& attackString.toString().toLowerCase().indexOf("javascript:alert") != -1) { + getLessonTracker(s).setStage(5); + s.setMessage("Stage 4 completed."); + } + + return (ec); + } + + protected Element doStage5(WebSession s) throws Exception { + ElementContainer ec = new ElementContainer(); + + ec.addElement(mainContent(s)); + + /** + * They pass iff: + * + * 1. If the DOMXSS.js file contains the lines "escapeHTML(name)" + */ + String file = s.getWebResource("javascript/DOMXSS.js"); + String content = getFileContent(file); + + if(content.indexOf("escapeHTML(name)") != -1) + { + makeSuccess(s); + } + + return ec; + } + + protected ElementContainer mainContent(WebSession s) { + StringBuffer attackString = null; + + ElementContainer ec = new ElementContainer(); + try { + + ec.addElement(new Script().setSrc("javascript/DOMXSS.js")); + + ec.addElement(new H1().setID("greeting")); + + ec.addElement(new StringElement("Enter your name: ")); + + attackString = new StringBuffer(s.getParser().getStringParameter(PERSON, "")); + + Input input = new Input(Input.TEXT, PERSON, attackString.toString()); + input.setOnKeyUp("displayGreeting(" + PERSON + ".value)"); + ec.addElement(input); + ec.addElement(new BR()); + ec.addElement(new BR()); + + Element b = ECSFactory.makeButton("Submit Solution"); + ec.addElement(b); + } catch (Exception e) { + s.setMessage("Error generating " + this.getClass().getName()); + e.printStackTrace(); + } + return ec; + + } + + /** + * Gets the hints attribute of the HelloScreen object + * + * @return The hints value + */ + public List getHints(WebSession s) { + List hints = new ArrayList(); + + hints.add("Try entering the following: " + "<IMG SRC=\"images/logos/owasp.jpg\"/>"); + + hints.add("Try entering the following: " + "<img src=x onerror=;;alert('XSS') />"); + + hints.add("Try entering the following: " + "<IFRAME SRC=\"javascript:alert('XSS');\"></IFRAME>"); + + hints.add("Try entering the following: " + "Please enter your password:<BR><input type = \"password\" name=\"pass\"/><button " + + "onClick=\"javascript:alert('I have your password: ' + pass.value);\">Submit</button><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR>"); + + + + //Attack Strings: + + // + + // + + // + + //Please enter your password:
















+ + + return hints; + } + + /** + * Gets the ranking attribute of the HelloScreen object + * + * @return The ranking value + */ + private final static Integer DEFAULT_RANKING = new Integer(10); + + protected Integer getDefaultRanking() { + return DEFAULT_RANKING; + } + + protected Category getDefaultCategory() { + return Category.AJAX_SECURITY; + } + + /** + * Gets the title attribute of the HelloScreen object + * + * @return The title value + */ + public String getTitle() { + return ("LAB: DOM-Based cross-site scripting"); + } + + public String getInstructions(WebSession s) { + String instructions = ""; + + if (getLessonTracker(s).getStage() == 1) { + instructions = "STAGE 1:\tFor this exercise, your mission is to deface this website using the image at the following location: OWASP IMAGE"; + } else if (getLessonTracker(s).getStage() == 2) { + instructions = "STAGE 2:\tNow, try to create a pop up using the image tag"; + } else if (getLessonTracker(s).getStage() == 3) { + instructions = "STAGE 3:\tNext, try to create a pop up using the IFRAME tag."; + } else if (getLessonTracker(s).getStage() == 4) { + instructions = "STAGE 4:\tUse the following to create a fake login form:

" + "Please enter your password:<BR><input type = \"password\" name=\"pass\"/><button " + + "onClick=\"javascript:alert('I have your password: ' + pass.value);\">Submit</button><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR>"; + } else if(getLessonTracker(s).getStage() == 5) { + instructions = "STAGE 5:\tPerform client-side HTML entity encoding to mitigate the DOM XSS vulnerability. A utility method is provided for you in WebContent/javascript/escape.js."; + } + return (instructions); + } + + private String getFileContent(String content) + { + BufferedReader is = null; + StringBuffer sb = new StringBuffer(); + + try + { + is = new BufferedReader(new FileReader(new File(content))); + String s = null; + + while((s = is.readLine()) != null) + { + sb.append(s); + } + } + catch (Exception e) + { + e.printStackTrace(); + } + finally + { + if(is != null) + { + try + { + is.close(); + } + catch (IOException ioe) + { + + } + } + } + + return sb.toString(); + } + + public Element getCredits() + { + return super.getCustomCredits("", ASPECT_LOGO); + } +} diff --git a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/DangerousEval.java b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/DangerousEval.java new file mode 100644 index 000000000..a059c6cec --- /dev/null +++ b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/DangerousEval.java @@ -0,0 +1,291 @@ +package org.owasp.webgoat.lessons; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Pattern; + +import org.apache.ecs.Element; +import org.apache.ecs.ElementContainer; +import org.apache.ecs.html.A; +import org.apache.ecs.html.BR; +import org.apache.ecs.html.Center; +import org.apache.ecs.html.H1; +import org.apache.ecs.html.HR; +import org.apache.ecs.html.IMG; +import org.apache.ecs.html.Input; +import org.apache.ecs.html.TD; +import org.apache.ecs.html.TH; +import org.apache.ecs.html.TR; +import org.apache.ecs.html.Table; +import org.owasp.webgoat.session.WebSession; +import org.owasp.webgoat.util.HtmlEncoder; + +/******************************************************************************* + * + * + * This file is part of WebGoat, an Open Web Application Security Project + * utility. For details, please see http://www.owasp.org/ + * + * Copyright (c) 2002 - 2007 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 code.google.com, a repository + * for free software projects. + * + * For details, please see http://code.google.com/p/webgoat/ + * + * @author Eric Sheridan, Aspect Security + * @created October 28, 2003 + */ + +public class DangerousEval extends LessonAdapter +{ + public final static A ASPECT_LOGO = new A().setHref("http://www.aspectsecurity.com").addElement(new IMG("images/logos/aspect.jpg").setAlt("Aspect Security").setBorder(0).setHspace(0).setVspace(0)); + + public final static String PASSED = "__DANGEROUS_EVAL_PASS"; + + /** + * Description of the Method + * + * @param s Description of the Parameter + * @return Description of the Return Value + */ + + protected Element createContent(WebSession s) + { + ElementContainer ec = new ElementContainer(); + String regex1 = "^[0-9]{3}$";// any three digits + Pattern pattern1 = Pattern.compile(regex1); + + try + { + checkSuccess(s); + + String param1 = s.getParser().getRawParameter("field1", "111"); + //String param2 = HtmlEncoder.encode(s.getParser().getRawParameter("field2", "4128 3214 0002 1999")); + float quantity = 1.0f; + float total = 0.0f; + float runningTotal = 0.0f; + + // test input field1 + if (!pattern1.matcher(param1).matches()) + { + if (param1.toLowerCase().indexOf("script") != -1) + { + //makeSuccess(s); + } + + s.setMessage("Whoops! You entered " + HtmlEncoder.encode(param1) + " instead of your three digit code. Please try again."); + } + + // FIXME: encode output of field2, then s.setMessage( field2 ); + ec.addElement(" + /** + * Gets the instructions attribute of the WeakAccessControl object + * + * @return The instructions value + */ + public String getInstructions(WebSession s) + { + String instructions = "For this exercise, your mission is to come up with some input containing a script. You have to try to get this page to reflect that input back to your browser, which will execute the script. In order to pass this lesson, you must 'alert()' document.cookie."; + return (instructions); + } + + private final static Integer DEFAULT_RANKING = new Integer(120); + + protected Integer getDefaultRanking() + { + return DEFAULT_RANKING; + } + + + /** + * Gets the title attribute of the AccessControlScreen object + * + * @return The title value + */ + public String getTitle() + { + return "Dangerous Use of Eval"; + } + + public Element getCredits() + { + return super.getCustomCredits("", ASPECT_LOGO); + } + + /** + * Check to see if JSP says they passed the lesson. + * @param s + */ + private void checkSuccess(WebSession s) + { + javax.servlet.http.HttpSession session = s.getRequest().getSession(); + + if(session.getAttribute(PASSED) != null) + { + makeSuccess(s); + + session.removeAttribute(PASSED); + } + } +} diff --git a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ReflectedXSS.java b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ReflectedXSS.java index 07ffb4023..15523c047 100644 --- a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ReflectedXSS.java +++ b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ReflectedXSS.java @@ -107,8 +107,8 @@ public class ReflectedXSS extends LessonAdapter TR tr = new TR(); tr.addElement(new TH().addElement( "Shopping Cart Items -- To Buy Now").setWidth("80%")); - tr.addElement(new TH().addElement("Price:").setWidth("10%")); - tr.addElement(new TH().addElement("Quantity:").setWidth("3%")); + tr.addElement(new TH().addElement("Price").setWidth("10%")); + tr.addElement(new TH().addElement("Quantity").setWidth("3%")); tr.addElement(new TH().addElement("Total").setWidth("7%")); t.addElement(tr); @@ -121,7 +121,7 @@ public class ReflectedXSS extends LessonAdapter new Input(Input.TEXT, "QTY1", s.getParser() .getStringParameter("QTY1", "1"))) .setAlign("right")); - quantity = s.getParser().getFloatParameter("QTY1", 1.0f); + quantity = s.getParser().getFloatParameter("QTY1", 0.0f); total = quantity * 69.99f; runningTotal += total; tr.addElement(new TD().addElement("$" + total)); @@ -134,7 +134,7 @@ public class ReflectedXSS extends LessonAdapter new Input(Input.TEXT, "QTY2", s.getParser() .getStringParameter("QTY2", "1"))) .setAlign("right")); - quantity = s.getParser().getFloatParameter("QTY2", 1.0f); + quantity = s.getParser().getFloatParameter("QTY2", 0.0f); total = quantity * 27.99f; runningTotal += total; tr.addElement(new TD().addElement("$" + total)); @@ -148,7 +148,7 @@ public class ReflectedXSS extends LessonAdapter new Input(Input.TEXT, "QTY3", s.getParser() .getStringParameter("QTY3", "1"))) .setAlign("right")); - quantity = s.getParser().getFloatParameter("QTY3", 1.0f); + quantity = s.getParser().getFloatParameter("QTY3", 0.0f); total = quantity * 1599.99f; runningTotal += total; tr.addElement(new TD().addElement("$" + total)); @@ -163,7 +163,7 @@ public class ReflectedXSS extends LessonAdapter new Input(Input.TEXT, "QTY4", s.getParser() .getStringParameter("QTY4", "1"))) .setAlign("right")); - quantity = s.getParser().getFloatParameter("QTY4", 1.0f); + quantity = s.getParser().getFloatParameter("QTY4", 0.0f); total = quantity * 299.99f; runningTotal += total; tr.addElement(new TD().addElement("$" + total)); diff --git a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/TraceXSS.java b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/TraceXSS.java index e8e569b78..5202afafb 100644 --- a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/TraceXSS.java +++ b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/TraceXSS.java @@ -109,8 +109,8 @@ public class TraceXSS extends LessonAdapter TR tr = new TR(); tr.addElement(new TH().addElement( "Shopping Cart Items -- To Buy Now").setWidth("80%")); - tr.addElement(new TH().addElement("Price:").setWidth("10%")); - tr.addElement(new TH().addElement("Quantity:").setWidth("3%")); + tr.addElement(new TH().addElement("Price").setWidth("10%")); + tr.addElement(new TH().addElement("Quantity").setWidth("3%")); tr.addElement(new TH().addElement("Total").setWidth("7%")); t.addElement(tr); diff --git a/ webgoat/main/project/WebContent/javascript/DOMXSS.js b/ webgoat/main/project/WebContent/javascript/DOMXSS.js new file mode 100644 index 000000000..9ddb31a10 --- /dev/null +++ b/ webgoat/main/project/WebContent/javascript/DOMXSS.js @@ -0,0 +1,5 @@ +function displayGreeting(name) { + if (name != ''){ + document.getElementById("greeting").innerHTML="Hello, " + name+ "!"; + } +} \ No newline at end of file diff --git a/ webgoat/main/project/WebContent/javascript/clientSideFiltering.js b/ webgoat/main/project/WebContent/javascript/clientSideFiltering.js new file mode 100644 index 000000000..ab0ba775f --- /dev/null +++ b/ webgoat/main/project/WebContent/javascript/clientSideFiltering.js @@ -0,0 +1,64 @@ +var dataFetched = false; + + +function selectUser(){ + + var newEmployeeID = document.getElementById("UserSelect").options[document.getElementById("UserSelect").selectedIndex].value; + + document.getElementById("employeeRecord").innerHTML = document.getElementById(newEmployeeID).innerHTML; + +} + + +function fetchUserData(){ + if(!dataFetched){ + dataFetched = true; + ajaxFunction(document.getElementById("userID").value); + } +} + + + + + +function ajaxFunction(userId) + { + var xmlHttp; + try + { + // Firefox, Opera 8.0+, Safari + xmlHttp=new XMLHttpRequest(); + } + catch (e) + { + // Internet Explorer + try + { + xmlHttp=new ActiveXObject("Msxml2.XMLHTTP"); + } + catch (e) + { + try + { + xmlHttp=new ActiveXObject("Microsoft.XMLHTTP"); + } + catch (e) + { + alert("Your browser does not support AJAX!"); + return false; + } + } + } + xmlHttp.onreadystatechange=function() + { + + var result = xmlHttp.responseText; + if(xmlHttp.readyState==4) + { + document.getElementById("hiddenEmployeeRecords").innerHTML=result + + } + } + xmlHttp.open("GET","lessons/Ajax/clientSideFiltering.jsp?userId=" + userId,true); + xmlHttp.send(null); + } \ No newline at end of file diff --git a/ webgoat/main/project/WebContent/javascript/clientSideValidation.js b/ webgoat/main/project/WebContent/javascript/clientSideValidation.js new file mode 100644 index 000000000..f47c5b83e --- /dev/null +++ b/ webgoat/main/project/WebContent/javascript/clientSideValidation.js @@ -0,0 +1,113 @@ +var coupons = ["nvojubmq", +"emph", +"sfwmjt", +"faopsc", +"fopttfsq", +"pxuttfsq"]; + + +function isValidCoupon(coupon) { + coupon = coupon.toUpperCase(); + for(var i=0; i= 0;i--){ + + for (j = 0;j +

Lesson Plan Title: Dangerous Use of Eval

+ +

Concept / Topic To Teach:

+ +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 this lesson, unvalidated user-supplied data is used in conjunction with a Javascript eval() call. 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. + +

General Goal(s):

+For this exercise, your mission is to come up with some input containing a script. You have to try to get this page to reflect that input back to your browser, which will execute the script. In order to pass this lesson, you must 'alert()' document.cookie. \ No newline at end of file diff --git a/ webgoat/main/project/WebContent/lessons/Ajax/clientSideFiltering.jsp b/ webgoat/main/project/WebContent/lessons/Ajax/clientSideFiltering.jsp new file mode 100644 index 000000000..7155c6c2b --- /dev/null +++ b/ webgoat/main/project/WebContent/lessons/Ajax/clientSideFiltering.jsp @@ -0,0 +1,114 @@ + +<%@ page language="java" contentType="text/html; charset=ISO-8859-1" + pageEncoding="ISO-8859-1"%> + +<%@ page import="java.io.*, javax.xml.xpath.*, org.xml.sax.InputSource,org.w3c.dom.*,org.apache.ecs.html.* " %> + +<% + + String userId = request.getParameter("userID"); + + + NodeList nodes = null; + + + + File d = new File(this.getServletContext().getRealPath("lessons/Ajax/employees.xml")); + + if(d.exists()){ + System.out.print("File does exist"); + } + else{ + System.out.print("File DOES NOT exist"); + } + + System.out.println(d.getAbsolutePath()); + XPathFactory factory = XPathFactory.newInstance(); + XPath xPath = factory.newXPath(); + InputSource inputSource = new InputSource(new FileInputStream(d)); + + + + + + +StringBuffer sb = new StringBuffer(); + +sb.append("/Employees/Employee/UserID | "); +sb.append("/Employees/Employee/FirstName | "); +sb.append("/Employees/Employee/LastName | "); +sb.append("/Employees/Employee/SSN | "); +sb.append("/Employees/Employee/Salary "); + +String expression = sb.toString(); + + + + + + + nodes = (NodeList) xPath.evaluate(expression, inputSource, + XPathConstants.NODESET); + int nodesLength = nodes.getLength(); + + + System.out.println("nodesLength:" + nodesLength); + + TR tr; + + int COLUMNS = 5; + + Table t2 = null; + if (nodesLength > 0) + { + t2 = new Table().setCellSpacing(0).setCellPadding(0).setBorder( + 1).setWidth("90%").setAlign("center"); + tr = new TR(); + tr.addElement(new TD().addElement("UserID")); + tr.addElement(new TD().addElement("First Name")); + tr.addElement(new TD().addElement("Last Name")); + tr.addElement(new TD().addElement("SSN")); + tr.addElement(new TD().addElement("Salary")); + t2.addElement(tr); + } + + + + tr = new TR(); + + for (int i = 0; i < nodesLength; i++) + { + Node node = nodes.item(i); + + if(i%COLUMNS==0){ + tr = new TR(); + tr.setID(node.getTextContent()); + //tr.setStyle("display: none"); + } + + tr.addElement(new TD().addElement(node.getTextContent())); + + if(i%COLUMNS==(COLUMNS-1)){ + t2.addElement(tr); + } + } + + if(t2 != null){ + out.println(t2.toString()); + } + else{ + out.println("No Results"); + } + + + + + + + + + + + +%> + diff --git a/ webgoat/main/project/WebContent/lessons/Ajax/clientSideValidation.jsp b/ webgoat/main/project/WebContent/lessons/Ajax/clientSideValidation.jsp new file mode 100644 index 000000000..a035833c3 --- /dev/null +++ b/ webgoat/main/project/WebContent/lessons/Ajax/clientSideValidation.jsp @@ -0,0 +1,30 @@ +<%@ page language="java" contentType="text/html; charset=ISO-8859-1" + pageEncoding="ISO-8859-1"%> + + + +<% String coupon = request.getParameter("coupon"); + +if (coupon.equalsIgnoreCase("PLATINUM")){ + out.print(".25"); +} +else if (coupon.equalsIgnoreCase("GOLD")){ + out.print(".5"); +} +else if (coupon.equalsIgnoreCase("SILVER")){ + out.print(".75"); +} +else if (coupon.equalsIgnoreCase("BRONZE")){ + out.print(".8"); +} +else if (coupon.equalsIgnoreCase("PRESSONE")){ + out.print(".9"); +} +else if (coupon.equalsIgnoreCase("PRESSTWO")){ + out.print(".95"); +} + + + +%> + diff --git a/ webgoat/main/project/WebContent/lessons/Ajax/employees.xml b/ webgoat/main/project/WebContent/lessons/Ajax/employees.xml new file mode 100644 index 000000000..ce301627f --- /dev/null +++ b/ webgoat/main/project/WebContent/lessons/Ajax/employees.xml @@ -0,0 +1,228 @@ + + + + 101 + Larry + Stooge + 9175 Guilford Rd + New York, NY + 443-689-0192 + 1012000 + 386-09-5451 + 55000 + 2578546969853547 + 5000 + Does not work well with others + Constantly harassing coworkers + 10106 + + 102 + + + + 102 + Moe + Stooge + 3013 AMD Ave + New York, NY + 443-938-5301 + 3082003 + 936-18-4524 + 140000 + NA + 0 + Very dominating over Larry and Curly + Hit Curly over head + 101013 + + 102 + + + + 103 + Curly + Stooge + 1112 Crusoe Lane + New York, NY + 410-667-6654 + 2122001 + 961-08-0047 + 50000 + NA + 0 + Owes three-thousand to company for fradulent purchases + Hit Moe back + 101014 + + 102 + + + + 104 + Eric + Walker + 1160 Prescott Rd + New York, NY + 410-887-1193 + 12152005 + 445-66-5565 + 13000 + NA + 0 + Late. Always needs help. Too intern-ish. + Bothering Larry about webgoat problems + 101013 + + 102 + + + + 105 + Tom + Cat + 2211 HyperThread Rd. + New York, NY + 443-599-0762 + 1011999 + 792-14-6364 + 80000 + 5481360857968521 + 30000 + Co-Owner. + NA + 0 + + 102 + + + + 106 + Jerry + Mouse + 3011 Unix Drive + New York, NY + 443-699-3366 + 1011999 + 858-55-4452 + 70000 + 6981754825013564 + 20000 + Co-Owner. + NA + 0 + + 102 + + + + 107 + David + Giambi + 5132 DIMM Avenue + New York, NY + 610-521-8413 + 5011999 + 439-20-9405 + 100000 + 6981754825018101 + 10000 + Strong work habbit. Questionable ethics. + Hacked into accounting server. Modified personal pay. + 61402 + + 102 + + + + 108 + Bruce + McGuirre + 8899 FreeBSD Drive<script>alert(document.cookie)</script> + New York, NY + 610-282-1103 + 3012000 + 707-95-9482 + 110000 + 6981754825854136 + 30000 + Enjoys watching others struggle in exercises. + Tortuous Boot Camp workout at 5am. Employees felt sick. + 61502 + + 102 + + + + 109 + Sean + Livingston + 6422 dFlyBSD Road + New York, NY + 610-878-9549 + 6012003 + 136-55-1046 + 130000 + 6981754825014510 + 5000 + Has some fascination with Steelers. Go Ravens. + Late to work 30 days in row due to excessive Halo 2 + 72804 + + 102 + + + + 110 + Joanne + McDougal + 5567 Broadband Lane + New York, NY + 610-213-6341 + 1012001 + 789-54-2413 + 90000 + 6981754825081054 + 300 + Finds it necessary to leave early every day. + Used company cc to purchase new car. Limit adjusted. + 112005 + + 102 + + + + 111 + John + Wayne + 129 Third St + New York, NY + 610-213-1134 + 1012001 + 129-69-4572 + 200000 + 4437334565679921 + 300 + + + 112005 + + 102 + + + + 112 + Neville + Bartholomew + 1 Corporate Headquarters + San Jose, CA + 408-587-0024 + 3012000 + 111-111-1111 + 450000 + 4803389267684109 + 300 + + + 112005 + + diff --git a/ webgoat/main/project/WebContent/lessons/Ajax/eval.jsp b/ webgoat/main/project/WebContent/lessons/Ajax/eval.jsp new file mode 100644 index 000000000..d0c083ab3 --- /dev/null +++ b/ webgoat/main/project/WebContent/lessons/Ajax/eval.jsp @@ -0,0 +1,37 @@ +<%@ page language="java" contentType="text/html; charset=ISO-8859-1" import="java.util.regex.*" import="org.owasp.webgoat.lessons.DangerousEval" + pageEncoding="ISO-8859-1"%> +<% +String action = request.getParameter("action"); +String field1 = request.getParameter("field1"); +String field2 = request.getParameter("field2"); +String regex1 = "^[0-9]{3}$";// any three digits +Pattern pattern1 = Pattern.compile(regex1); + +if(action == null) action = "Purchase"; +if(field1 == null) field1 = "123"; +if(field2 == null) field2 = "-1"; + +/** For security reasons, we remove all '<' and '>' characters to prevent XSS **/ +field1.replaceAll("<", ""); +field1.replaceAll(">", ""); +field2.replaceAll("<", ""); +field2.replaceAll(">", ""); + +if("Purchase".equals(action)) +{ + if(!pattern1.matcher(field1).matches()) + { + /** If they supplied the right attack, pass them **/ + if(field1.indexOf("');") != -1 && field1.indexOf("alert") != -1 && field1.indexOf("document.cookie") != -1) + { + session.setAttribute(DangerousEval.PASSED, "true"); + } + + out.write("alert('Whoops: You entered an incorrect access code of \"" + field1 + "\"');"); + } + else + { + out.write("alert('Purchase completed successfully with credit card \"" + field2 + "\" and access code \"" + field1 + "\"');"); + } +} +%> diff --git a/ webgoat/main/project/WebContent/lessons/Ajax/images/lesson1_header.jpg b/ webgoat/main/project/WebContent/lessons/Ajax/images/lesson1_header.jpg new file mode 100644 index 0000000000000000000000000000000000000000..60a809af01cd39c520a84573529811cc745ca362 GIT binary patch literal 44854 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 literal 0 HcmV?d00001 diff --git a/ webgoat/main/project/WebContent/lessons/Ajax/images/lesson1_workspace.jpg b/ webgoat/main/project/WebContent/lessons/Ajax/images/lesson1_workspace.jpg new file mode 100644 index 0000000000000000000000000000000000000000..292d25654bdb690fd67b05bab161168aa66fe990 GIT binary patch literal 23580 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 literal 0 HcmV?d00001 diff --git a/ webgoat/main/project/WebContent/lessons/Ajax/instructor/clientSideFiltering_i.jsp b/ webgoat/main/project/WebContent/lessons/Ajax/instructor/clientSideFiltering_i.jsp new file mode 100644 index 000000000..9de07fcf8 --- /dev/null +++ b/ webgoat/main/project/WebContent/lessons/Ajax/instructor/clientSideFiltering_i.jsp @@ -0,0 +1,111 @@ + +<%@ page language="java" contentType="text/html; charset=ISO-8859-1" + pageEncoding="ISO-8859-1"%> + +<%@ page import="java.io.*, javax.xml.xpath.*, org.xml.sax.InputSource,org.w3c.dom.*,org.apache.ecs.html.* " %> + +<% + +String userId = request.getParameter("userId"); + + + NodeList nodes = null; + + + + File d = new File(this.getServletContext().getRealPath("lessons/Ajax/employees.xml")); + + if(d.exists()){ + System.out.print("File does exist"); + } + else{ + System.out.print("File DOES NOT exist"); + } + + System.out.println(d.getAbsolutePath()); + XPathFactory factory = XPathFactory.newInstance(); + XPath xPath = factory.newXPath(); + InputSource inputSource = new InputSource(new FileInputStream(d)); + + +StringBuffer sb = new StringBuffer(); + +sb.append("/Employees/Employee [Managers/Manager/text()='" + userId + "']/UserID | "); +sb.append("/Employees/Employee [Managers/Manager/text()='" + userId + "']/FirstName | "); +sb.append("/Employees/Employee [Managers/Manager/text()='" + userId + "']/LastName | "); +sb.append("/Employees/Employee [Managers/Manager/text()='" + userId + "']/SSN | "); +sb.append("/Employees/Employee [Managers/Manager/text()='" + userId + "']/Salary "); + +String expression = sb.toString(); + + + + + + + + nodes = (NodeList) xPath.evaluate(expression, inputSource, + XPathConstants.NODESET); + int nodesLength = nodes.getLength(); + + + System.out.println("nodesLength:" + nodesLength); + + TR tr; + + int COLUMNS = 5; + + Table t2 = null; + if (nodesLength > 0) + { + t2 = new Table().setCellSpacing(0).setCellPadding(0).setBorder( + 1).setWidth("90%").setAlign("center"); + tr = new TR(); + tr.addElement(new TD().addElement("UserID")); + tr.addElement(new TD().addElement("First Name")); + tr.addElement(new TD().addElement("Last Name")); + tr.addElement(new TD().addElement("SSN")); + tr.addElement(new TD().addElement("Salary")); + t2.addElement(tr); + } + + + + tr = new TR(); + + for (int i = 0; i < nodesLength; i++) + { + Node node = nodes.item(i); + + if(i%COLUMNS==0){ + tr = new TR(); + tr.setID(node.getTextContent()); + //tr.setStyle("display: none"); + } + + tr.addElement(new TD().addElement(node.getTextContent())); + + if(i%COLUMNS==(COLUMNS-1)){ + t2.addElement(tr); + } + } + + if(t2 != null){ + out.println(t2.toString()); + } + else{ + out.println("No Results"); + } + + + + + + + + + + + +%> +