package org.owasp.webgoat.lessons; import java.text.DecimalFormat; 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("lessonJS/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("lessonJS/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 DecimalFormat money = new DecimalFormat("$0.00"); String grandTotalString = s.getParser().getStringParameter("GRANDTOT", "0"); float grandTotal = 1; try { grandTotal = money.parse(grandTotalString).floatValue(); } catch (java.text.ParseException e) { try { grandTotal = Float.parseFloat(grandTotalString); } catch (java.lang.NumberFormatException e1) { // eat exception, do not update grandTotal } } 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.00")).setReadOnly(true) .setStyle("border:0px;")).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.00")).setReadOnly(true) .setStyle("border:0px;")).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).setStyle("border:0px;")) .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.00")) .setSize(10).setReadOnly(true).setStyle("border:0px;")) .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).setStyle("border:0px;")) .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.00")) .setSize(10).setReadOnly(true).setStyle("border:0px;")) .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).setStyle("border:0px;")).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.00")) .setSize(10).setReadOnly(true).setStyle("border:0px;")) .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).setStyle("border:0px;")) .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.00")) .setSize(10).setReadOnly(true).setStyle("border:0px;")) .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<String> getHints(WebSession s) { List<String> hints = new ArrayList<String>(); 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 of 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 "Insecure Client Storage"; } public Element getCredits() { return super.getCustomCredits("", ASPECT_LOGO); } }