diff --git a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/Category.java b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/Category.java index 6a0a8a527..f388b7472 100644 --- a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/Category.java +++ b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/Category.java @@ -71,6 +71,8 @@ public class Category implements Comparable public final static Category CODE_QUALITY = new Category("Code Quality", new Integer(70)); + public final static Category CONCURRENCY = new Category("Concurrency", new Integer(80)); + public final static Category CHALLENGE = new Category("Challenge", new Integer(2000)); private static final List categories = new ArrayList(); @@ -97,6 +99,7 @@ public class Category implements Comparable categories.add(ADMIN_FUNCTIONS); categories.add(GENERAL); categories.add(CODE_QUALITY); + categories.add(CONCURRENCY); categories.add(CHALLENGE); } diff --git a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ConcurrencyCart.java b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ConcurrencyCart.java new file mode 100644 index 000000000..3f2a0d381 --- /dev/null +++ b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ConcurrencyCart.java @@ -0,0 +1,572 @@ +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.ECSFactory; +import org.owasp.webgoat.session.WebSession; +import org.owasp.webgoat.session.ParameterNotFoundException; +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 Ryan Knell Aspect Security + * @created July, 23 2007 + */ + +public class ConcurrencyCart extends LessonAdapter +{ + //Shared Variables + private static int total = 0; + private static int runningTOTAL = 0; + private static int subTOTAL = 0; + private static int calcTOTAL = 0; + private static int quantity1 = 1; + private static int quantity2 = 1; + private static int quantity3 = 1; + private static int quantity4 = 1; + private int discount = 0; + + 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)); + + /** + * Description of the Method + * + * @param s Description of the Parameter + * @return Description of the Return Value + */ + + protected Element createContent(WebSession s) + { + ElementContainer ec = null; + + try + { + String submit = s.getParser().getStringParameter("SUBMIT"); + + if("Purchase".equalsIgnoreCase(submit)) + { + updateQuantity(s); + ec = createPurchaseContent(s, quantity1, quantity2, quantity3, quantity4); + } + else if ("Confirm".equalsIgnoreCase(submit)) + { + ec = confirmation(s, quantity1, quantity2, quantity3, quantity4); + + //Discount + discount = 100 - (subTOTAL / runningTOTAL); + + if (calcTOTAL < subTOTAL) + { + //CONGRATS + s.setMessage("Thank you for shopping! You have received a " +discount +"% discount."); + + makeSuccess(s); + } + else + { + //ALMOST + s.setMessage("Almost! You payed too much."); + } + } + else + { + updateQuantity(s); + ec = createShoppingPage(s, quantity1, quantity2, quantity3, quantity4); + } + + } + catch (ParameterNotFoundException pnfe) + { + pnfe.printStackTrace(); + System.out.println("[DEBUG] no action selected, defaulting to createShoppingPage"); + ec = createShoppingPage(s, quantity1, quantity2, quantity3, quantity4); + } + + return ec; + } + + //UPDATE QUANTITY VARIABLES + private void updateQuantity(WebSession s) + { + quantity1 = s.getParser().getIntParameter("QTY1", 1); + quantity2 = s.getParser().getIntParameter("QTY2", 1); + quantity3 = s.getParser().getIntParameter("QTY3", 1); + quantity4 = s.getParser().getIntParameter("QTY4", 1); + } + + /* + ********************************************************************** + ******************* PURCHASING PAGE ********************************** + ********************************************************************** + */ + + private ElementContainer createPurchaseContent(WebSession s, int quantity1, int quantity2, int quantity3, int quantity4) + { + + ElementContainer ec = new ElementContainer(); + runningTOTAL = 0; + + String regex1 = "^[0-9]{3}$";// any three digits + Pattern pattern1 = Pattern.compile(regex1); + + try + { + String param1 = s.getParser().getRawParameter("PAC", "111"); + String param2 = HtmlEncoder.encode(s.getParser().getRawParameter( + "CC", "5321 1337 8888 2007")); + + // test input field1 + if (!pattern1.matcher(param1).matches()) + { + s.setMessage("Error! You entered " + HtmlEncoder.encode(param1) + " instead of your 3 digit code. Please try again."); + } + + ec.addElement(new HR().setWidth("90%")); + ec.addElement(new Center().addElement(new H1().addElement("Confirm your order "))); + Table table = new Table().setCellSpacing(0).setCellPadding(2) + .setBorder(1).setWidth("90%").setAlign("center"); + + if (s.isColor()) + { table.setBorder(1); } + + //Table Setup + TR tr = new TR(); + tr.addElement(new TH().addElement("Shopping Cart Items").setWidth("80%")); + tr.addElement(new TH().addElement("Price:").setWidth("10%")); + tr.addElement(new TH().addElement("Quantity:").setWidth("3%")); + tr.addElement(new TH().addElement("Total").setWidth("7%")); + table.addElement(tr); + + //Item 1 + tr = new TR(); //Create a new table object + tr.addElement(new TD().addElement("Hitachi - 750GB External Hard Drive")); + tr.addElement(new TD().addElement("169.00").setAlign("right")); + tr.addElement(new TD().addElement(String.valueOf(quantity1)).setAlign("center")); + + total = quantity1 * 169; + runningTOTAL += total; + tr.addElement(new TD().addElement("$" + total +".00")); + table.addElement(tr); //Adds table to the HTML + + //Item 2 + tr = new TR(); + tr.addElement(new TD().addElement("Hewlett-Packard - All-in-One Laser Printer")); + tr.addElement(new TD().addElement("299.00").setAlign("right")); + tr.addElement(new TD().addElement(String.valueOf(quantity2)).setAlign("center")); + + total = quantity2 * 299; + runningTOTAL += total; + tr.addElement(new TD().addElement("$" + total +".00")); + table.addElement(tr); + + //Item 3 + tr = new TR(); + tr.addElement(new TD().addElement("Sony - Vaio with Intel® Centrino")); + tr.addElement(new TD().addElement("1799.00").setAlign("right")); + tr.addElement(new TD().addElement(String.valueOf(quantity3)).setAlign("center")); + + total = quantity3 * 1799; + runningTOTAL += total; + tr.addElement(new TD().addElement("$" + total +".00")); + table.addElement(tr); + + //Item 4 + tr = new TR(); + tr.addElement(new TD().addElement("Toshiba - XGA LCD Projector ")); + tr.addElement(new TD().addElement("649.00").setAlign("right")); + tr.addElement(new TD().addElement(String.valueOf(quantity4)).setAlign("center")); + + total = quantity4 * 649; + runningTOTAL += total; + tr.addElement(new TD().addElement("$" + total +".00")); + table.addElement(tr); + + ec.addElement(table); + + table = new Table().setCellSpacing(0).setCellPadding(2).setBorder(0) + .setWidth("90%").setAlign("center"); + + if (s.isColor()) { table.setBorder(1); } + + ec.addElement(new BR()); + + calcTOTAL = runningTOTAL; + + //Total Charged + tr = new TR(); + tr.addElement(new TD().addElement("Sub Total:")); + tr.addElement(new TD().addElement("$" + runningTOTAL +".00").setAlign("right")); + table.addElement(tr); + + tr = new TR(); + tr.addElement(new TD().addElement(" ").setColSpan(2)); + table.addElement(tr); + + //Credit Card Input + tr = new TR(); + tr.addElement(new TD().addElement("Enter your credit card number:")); + tr.addElement(new TD().addElement(new Input(Input.TEXT, "CC", param2)).setAlign("right")); + table.addElement(tr); + + //PAC Input + tr = new TR(); + tr.addElement(new TD().addElement("Enter your three digit access code:")); + tr.addElement(new TD().addElement(new Input(Input.TEXT, "PAC", param1)).setAlign("right")); + table.addElement(tr); + + //Confirm Button + Element b = ECSFactory.makeButton("Confirm"); + tr = new TR(); + tr.addElement(new TD().addElement(b).setColSpan(2).setAlign("right")); + table.addElement(tr); + + //Cancel Button + Element c = ECSFactory.makeButton("Cancel"); + tr = new TR(); + tr.addElement(new TD().addElement(c).setColSpan(2).setAlign("right")); + table.addElement(tr); + + ec.addElement(table); + ec.addElement(new BR()); + + } + catch (Exception e) + { + s.setMessage("Error generating " + this.getClass().getName()); + e.printStackTrace(); + } + + return (ec); + } + + /* + ********************************************************************** + ******************* CONFIRMATION PAGE ******************************** + ********************************************************************** + */ + + private ElementContainer confirmation (WebSession s, int quantity1, int quantity2, int quantity3, int quantity4) + { + ElementContainer ec = new ElementContainer(); + + final String confNumber = "CONC-88"; + + try + { + Thread.sleep(5000); + + ec.addElement(new HR().setWidth("90%")); + ec.addElement(new Center().addElement(new H1().addElement("Thank you for your purchase!"))); + ec.addElement(new Center().addElement(new H1().addElement("Confirmation number: " + confNumber))); + Table table = new Table().setCellSpacing(0).setCellPadding(2) + .setBorder(1).setWidth("90%").setAlign("center"); + + if (s.isColor()) + { table.setBorder(1); } + + //Table Setup + TR tr = new TR(); + tr.addElement(new TH().addElement("Shopping Cart Items").setWidth("80%")); + tr.addElement(new TH().addElement("Price:").setWidth("10%")); + tr.addElement(new TH().addElement("Quantity:").setWidth("3%")); + tr.addElement(new TH().addElement("Total").setWidth("7%")); + table.addElement(tr); + + //Item 1 + tr = new TR(); //Create a new table object + tr.addElement(new TD().addElement("Hitachi - 750GB External Hard Drive")); + tr.addElement(new TD().addElement("169.00").setAlign("right")); + tr.addElement(new TD().addElement(String.valueOf(quantity1)).setAlign("center")); + + total = quantity1 * 169; + tr.addElement(new TD().addElement("$" + total +".00")); + table.addElement(tr); //Adds table to the HTML + + //Item 2 + tr = new TR(); + tr.addElement(new TD().addElement("Hewlett-Packard - All-in-One Laser Printer")); + tr.addElement(new TD().addElement("299.00").setAlign("right")); + tr.addElement(new TD().addElement(String.valueOf(quantity2)).setAlign("center")); + + total = quantity2 * 299; + tr.addElement(new TD().addElement("$" + total +".00")); + table.addElement(tr); + + //Item 3 + tr = new TR(); + tr.addElement(new TD().addElement("Sony - Vaio with Intel® Centrino")); + tr.addElement(new TD().addElement("1799.00").setAlign("right")); + tr.addElement(new TD().addElement(String.valueOf(quantity3)).setAlign("center")); + + total = quantity3 * 1799; + tr.addElement(new TD().addElement("$" + total +".00")); + table.addElement(tr); + + //Item 4 + tr = new TR(); + tr.addElement(new TD().addElement("Toshiba - XGA LCD Projector ")); + tr.addElement(new TD().addElement("649.00").setAlign("right")); + tr.addElement(new TD().addElement(String.valueOf(quantity4)).setAlign("center")); + + total = quantity4 * 649; + tr.addElement(new TD().addElement("$" + total +".00")); + table.addElement(tr); + + ec.addElement(table); + + table = new Table().setCellSpacing(0).setCellPadding(2).setBorder(0) + .setWidth("90%").setAlign("center"); + + if (s.isColor()) + { table.setBorder(1); } + + ec.addElement(new BR()); + + //Total Charged + tr = new TR(); + tr.addElement(new TD().addElement("Total Amount Charged to Your Credit Card:")); + tr.addElement(new TD().addElement("$" + runningTOTAL +".00").setAlign("right")); + table.addElement(tr); + + tr = new TR(); + tr.addElement(new TD().addElement(" ").setColSpan(2)); + table.addElement(tr); + + //Return to Store Button + Element b = ECSFactory.makeButton("Return to Store"); + tr = new TR(); + tr.addElement(new TD().addElement(b).setColSpan(2).setAlign("center")); + table.addElement(tr); + + ec.addElement(table); + ec.addElement(new BR()); + + } + catch (Exception e) + { + s.setMessage("Error generating " + this.getClass().getName()); + e.printStackTrace(); + } + return (ec); + } + + /* + ********************************************************************** + ******************* SHOPPING PAGE ********************************** + ********************************************************************** + */ + + private ElementContainer createShoppingPage(WebSession s, int quantity1, int quantity2, int quantity3, int quantity4) + { + + ElementContainer ec = new ElementContainer(); + subTOTAL = 0; + + try + { + + ec.addElement(new HR().setWidth("90%")); + ec.addElement(new Center().addElement(new H1().addElement("Shopping Cart "))); + Table table = new Table().setCellSpacing(0).setCellPadding(2) + .setBorder(1).setWidth("90%").setAlign("center"); + + if (s.isColor()) + { table.setBorder(1); } + + //Table Setup + TR tr = new TR(); + tr.addElement(new TH().addElement("Shopping Cart Items").setWidth("80%")); + tr.addElement(new TH().addElement("Price:").setWidth("10%")); + tr.addElement(new TH().addElement("Quantity:").setWidth("3%")); + tr.addElement(new TH().addElement("Total").setWidth("7%")); + table.addElement(tr); + + //Item 1 + tr = new TR(); //Create a new table object + tr.addElement(new TD().addElement("Hitachi - 750GB External Hard Drive")); + tr.addElement(new TD().addElement("169.00").setAlign("right")); + tr.addElement(new TD().addElement( + new Input(Input.TEXT, "QTY1", s.getParser() + .getStringParameter("QTY1", "1"))) + .setAlign("right")); + + total = quantity1 * 169; + subTOTAL += total; + tr.addElement(new TD().addElement("$" + total +".00")); + table.addElement(tr); //Adds table to the HTML + + //Item 2 + tr = new TR(); + tr.addElement(new TD().addElement("Hewlett-Packard - All-in-One Laser Printer")); + tr.addElement(new TD().addElement("299.00").setAlign("right")); + tr.addElement(new TD().addElement( + new Input(Input.TEXT, "QTY2", s.getParser() + .getStringParameter("QTY2", "1"))) + .setAlign("right")); + + total = quantity2 * 299; + subTOTAL += total; + tr.addElement(new TD().addElement("$" + total +".00")); + table.addElement(tr); + + //Item 3 + tr = new TR(); + tr.addElement(new TD().addElement("Sony - Vaio with Intel® Centrino")); + tr.addElement(new TD().addElement("1799.00").setAlign("right")); + tr.addElement(new TD().addElement( + new Input(Input.TEXT, "QTY3", s.getParser() + .getStringParameter("QTY3", "1"))) + .setAlign("right")); + + total = quantity3 * 1799; + subTOTAL += total; + tr.addElement(new TD().addElement("$" + total +".00")); + table.addElement(tr); + + //Item 4 + tr = new TR(); + tr.addElement(new TD().addElement("Toshiba - XGA LCD Projector ")); + tr.addElement(new TD().addElement("649.00").setAlign("right")); + tr.addElement(new TD().addElement( + new Input(Input.TEXT, "QTY4", s.getParser() + .getStringParameter("QTY4", "1"))) + .setAlign("right")); + + total = quantity4 * 649; + subTOTAL += total; + tr.addElement(new TD().addElement("$" + total +".00")); + table.addElement(tr); + + ec.addElement(table); + + table = new Table().setCellSpacing(0).setCellPadding(2).setBorder(0) + .setWidth("90%").setAlign("center"); + + if (s.isColor()) + { table.setBorder(1); } + + ec.addElement(new BR()); + + //Purchasing Amount + tr = new TR(); + tr.addElement(new TD().addElement("Sub Total: " +"$" +subTOTAL +".00").setAlign("left")); + table.addElement(tr); + + //Update Button + Element b = ECSFactory.makeButton("Update Cart"); + tr = new TR(); + tr.addElement(new TD().addElement(b).setColSpan(2).setAlign("right")); + table.addElement(tr); + + + tr = new TR(); + tr.addElement(new TD().addElement(" ").setColSpan(2)); + table.addElement(tr); + + //Purchase Button + Element c = ECSFactory.makeButton("Purchase"); + tr = new TR(); + tr.addElement(new TD().addElement(c).setColSpan(2).setAlign("right")); + table.addElement(tr); + + ec.addElement(table); + ec.addElement(new BR()); + + } + catch (Exception e) + { + s.setMessage("Error generating " + this.getClass().getName()); + e.printStackTrace(); + } + return (ec); + } + + /** + * DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + protected Category getDefaultCategory() { return Category.CONCURRENCY; } + + /** + * Gets the hints attribute of the AccessControlScreen object + * + * @return The hints value + */ + protected List getHints(WebSession s) + { + List hints = new ArrayList(); + hints.add("Can you purchase the merchandise in your shopping cart for a lower price?"); + hints.add("Try using another web browser to get a lower price."); + + return hints; + } + + /** + * 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 exploit the concurrency issue which will allow you to purchase merchandise for a lower price."; + 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 "Shopping Cart Concurrency Flaw"; } + + public Element getCredits() { return super.getCustomCredits("", ASPECT_LOGO); } +} \ No newline at end of file diff --git a/ webgoat/main/project/WebContent/lesson_plans/ConcurrencyCart.html b/ webgoat/main/project/WebContent/lesson_plans/ConcurrencyCart.html new file mode 100644 index 000000000..4a2f44b75 --- /dev/null +++ b/ webgoat/main/project/WebContent/lesson_plans/ConcurrencyCart.html @@ -0,0 +1,22 @@ + + + + + + Lesson Plan + + + +
+

Lesson Plan Title: Shopping Cart Concurrency Flaw

+
+ +

Concept / Topic To Teach:

+ + Web applications can handle many HTTP requests simultaneously. Developers often use variables that are not thread safe.  Thread safety means that the fields of an object or class always maintain a valid state when used concurrently by multiple threads. It is often possible to exploit a concurrency bug by loading the same page as another user at the exact same time. Because all threads share the same method area, and the method area is where all class variables are stored, multiple threads can attempt to use the same class variables concurrently.
+ +

General Goal(s):

+For this exercise, your mission is to exploit the concurrency issue which will allow you to purchase merchandise for a lower price. +
+ +