package org.owasp.webgoat.lessons; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.Statement; 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.B; 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.P; import org.apache.ecs.html.TD; import org.apache.ecs.html.TR; import org.apache.ecs.html.Table; import org.apache.ecs.html.TextArea; import org.owasp.webgoat.session.DatabaseUtilities; import org.owasp.webgoat.session.ECSFactory; 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 Sherif Koussa Macadamian Technologies. * */ public class CSRF extends LessonAdapter { private final static String MESSAGE = "message"; private final static int MESSAGE_COL = 3; private final static String NUMBER = "Num"; private final static int NUM_COL = 1; private final static String STANDARD_QUERY = "SELECT * FROM messages"; private final static String TITLE = "title"; private final static int TITLE_COL = 2; private static int count = 1; private final static int USER_COL = 4; // Added by Chuck Willis - used to show user who posted // message private final static IMG MAC_LOGO = new IMG("images/logos/macadamian.gif").setAlt("Macadamian Technologies") .setBorder(0).setHspace(0).setVspace(0); /** * Adds a feature to the Message attribute of the MessageBoardScreen object * * @param s * The feature to be added to the Message attribute */ protected void addMessage(WebSession s) { try { String title = HtmlEncoder.encode(s.getParser().getRawParameter(TITLE, "")); String message = s.getParser().getRawParameter(MESSAGE, ""); Connection connection = DatabaseUtilities.getConnection(s); String query = "INSERT INTO messages VALUES (?, ?, ?, ?, ? )"; PreparedStatement statement = connection.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); statement.setInt(1, count++); statement.setString(2, title); statement.setString(3, message); statement.setString(4, s.getUserName()); statement.setString(5, this.getClass().getName()); statement.execute(); } catch (Exception e) { s.setMessage("Could not add message to database"); } } @Override protected Element createContent(WebSession s) { ElementContainer ec = new ElementContainer(); addMessage(s); ec.addElement(makeInput(s)); ec.addElement(new HR()); ec.addElement(makeCurrent(s)); ec.addElement(new HR()); ec.addElement(makeList(s)); return ec; } /** * Description of the Method * * @param s * Description of the Parameter * @return Description of the Return Value */ protected Element makeInput(WebSession s) { Table t = new Table(0).setCellSpacing(0).setCellPadding(0).setBorder(0); TR row1 = new TR(); TR row2 = new TR(); row1.addElement(new TD(new StringElement("Title: "))); Input inputTitle = new Input(Input.TEXT, TITLE, ""); row1.addElement(new TD(inputTitle)); TD item1 = new TD(); item1.setVAlign("TOP"); item1.addElement(new StringElement("Message: ")); row2.addElement(item1); TD item2 = new TD(); TextArea ta = new TextArea(MESSAGE, 5, 60); item2.addElement(ta); row2.addElement(item2); t.addElement(row1); t.addElement(row2); Element b = ECSFactory.makeButton("Submit"); ElementContainer ec = new ElementContainer(); ec.addElement(t); ec.addElement(new P().addElement(b)); return (ec); } /** * Description of the Method * * @param s * Description of the Parameter * @return Description of the Return Value */ public Element makeList(WebSession s) { Table t = new Table(0).setCellSpacing(0).setCellPadding(0).setBorder(0); try { Connection connection = DatabaseUtilities.getConnection(s); // edit by Chuck Willis - Added logic to associate similar usernames // The idea is that users chuck-1, chuck-2, etc will see each other's messages // but not anyone elses. This allows users to try out XSS to grab another user's // cookies, but not get confused by other users scripts String query = "SELECT * FROM messages WHERE user_name LIKE ? and lesson_type = ?"; PreparedStatement statement = connection.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); statement.setString(1, getNameroot(s.getUserName()) + "%"); statement.setString(2, getClass().getName()); ResultSet results = statement.executeQuery(); if ((results != null) && (results.first() == true)) { results.beforeFirst(); for (int i = 0; results.next(); i++) { String link = "" + results.getString(TITLE_COL) + ""; TD td = new TD().addElement(link); TR tr = new TR().addElement(td); t.addElement(tr); } } } catch (Exception e) { s.setMessage("Error while getting message list."); } ElementContainer ec = new ElementContainer(); ec.addElement(new H1("Message List")); ec.addElement(t); String transferFunds = s.getParser().getRawParameter("transferFunds", ""); if (transferFunds.length() != 0) { makeSuccess(s); } return (ec); } /** * Description of the Method * * @param s * Description of the Parameter * @return Description of the Return Value */ protected Element makeCurrent(WebSession s) { ElementContainer ec = new ElementContainer(); try { int messageNum = s.getParser().getIntParameter(NUMBER, 0); Connection connection = DatabaseUtilities.getConnection(s); String query = "SELECT * FROM messages WHERE user_name LIKE ? and num = ? and lesson_type = ?"; PreparedStatement statement = connection.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); statement.setString(1, getNameroot(s.getUserName()) + "%"); statement.setInt(2, messageNum); statement.setString(3, this.getClass().getName()); ResultSet results = statement.executeQuery(); if ((results != null) && results.first()) { ec.addElement(new H1("Message Contents For: " + results.getString(TITLE_COL))); Table t = new Table(0).setCellSpacing(0).setCellPadding(0).setBorder(0); TR row1 = new TR(new TD(new B(new StringElement("Title:")))); row1.addElement(new TD(new StringElement(results.getString(TITLE_COL)))); t.addElement(row1); String messageData = results.getString(MESSAGE_COL); TR row2 = new TR(new TD(new B(new StringElement("Message:")))); row2.addElement(new TD(new StringElement(messageData))); t.addElement(row2); TR row3 = new TR(new TD(new StringElement("Posted By:"))); row3.addElement(new TD(new StringElement(results.getString(USER_COL)))); t.addElement(row3); ec.addElement(t); } else { if (messageNum != 0) { ec.addElement(new P().addElement("Could not find message " + messageNum)); } } } catch (Exception e) { s.setMessage("Error generating " + this.getClass().getName()); e.printStackTrace(); } return (ec); } @Override protected Category getDefaultCategory() { return Category.XSS; } private final static Integer DEFAULT_RANKING = new Integer(120); @Override protected Integer getDefaultRanking() { return DEFAULT_RANKING; } @Override protected List getHints(WebSession s) { List hints = new ArrayList(); hints.add("Enter some text and try to include an image in there."); hints.add("In order to make the picture almost invisible try to add width=\"1\" and height=\"1\"."); hints.add("The format of an image in html is
<img src=\"[URL]\" width=\"1\" height=\"1\" />
"); hints.add("Include this URL in the message
<img src='" + getLink()
				+ "&transferFunds=5000' width=\"1\" height=\"1\" />
"); return hints; } /** * Gets the title attribute of the MessageBoardScreen object * * @return The title value */ public String getTitle() { return ("Cross Site Request Forgery (CSRF)"); } private static String getNameroot(String name) { String nameroot = name; if (nameroot.indexOf('-') != -1) { nameroot = nameroot.substring(0, nameroot.indexOf('-')); } return nameroot; } public Element getCredits() { return super.getCustomCredits("Created by Sherif Koussa ", MAC_LOGO); } }