Added some files required to build OWASP release.

Modified License text and format to reflect GPL license.
Reformatted most of the code.

git-svn-id: http://webgoat.googlecode.com/svn/trunk@60 4033779f-a91e-0410-96ef-6bf7bf53c507
This commit is contained in:
mayhew64
2007-01-16 14:56:40 +00:00
parent 036964495b
commit fd9b60f98e
110 changed files with 23099 additions and 17996 deletions

View File

@ -25,434 +25,516 @@ import org.owasp.webgoat.session.Screen;
import org.owasp.webgoat.session.UserTracker;
import org.owasp.webgoat.session.WebSession;
/**
* Copyright (c) 2002 Free Software Foundation developed under the custody of the Open Web
* Application Security Project (http://www.owasp.org) This software package is published by OWASP
* under the GPL. You should read and accept the LICENSE before you use, modify and/or redistribute
* this software.
*
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @created October 28, 2003
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
*
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003
*/
public class HammerHead extends HttpServlet
{
/**
* Description of the Field
*/
protected static SimpleDateFormat httpDateFormat;
/**
* Description of the Field
*/
protected WebSession mySession;
/**
* Set the session timeout to be 2 days
*/
private final static int sessionTimeoutSeconds = 60 * 60 * 24 * 2;
//private final static int sessionTimeoutSeconds = 1;
/**
* Description of the Field
*/
protected static SimpleDateFormat httpDateFormat;
/**
* Properties file path
*/
public static String propertiesPath = null;
/**
* Description of the Field
*/
protected WebSession mySession;
/**
* 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 doGet( HttpServletRequest request, HttpServletResponse response ) throws IOException, ServletException
/**
* Set the session timeout to be 2 days
*/
private final static int sessionTimeoutSeconds = 60 * 60 * 24 * 2;
// private final static int sessionTimeoutSeconds = 1;
/**
* Properties file path
*/
public static String propertiesPath = null;
/**
* 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 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;
try
{
doPost( request, response );
}
// System.out.println( "HH Entering doPost: " );
// 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;
/**
* 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;
// 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;
try
// if the screen parameter exists, the screen was visited via
// the menu categories,
// we won't count these as visits. The user may be able to
// manipulate the counts
// by specifying the screen parameter using a proxy. Good for
// them!
String fromMenus = mySession.getParser().getRawParameter(
WebSession.SCREEN, null);
if (fromMenus == null)
{
// if the show source parameter exists, don't add the visit
fromMenus = mySession.getParser().getRawParameter(
WebSession.SHOW, null);
if (fromMenus == null)
{
//System.out.println( "HH Entering doPost: " );
//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;
// if the screen parameter exists, the screen was visited via the menu categories,
// we won't count these as visits. The user may be able to manipulate the counts
// by specifying the screen parameter using a proxy. Good for them!
String fromMenus = mySession.getParser().getRawParameter( WebSession.SCREEN, null );
if ( fromMenus == null )
{
// if the show source parameter exists, don't add the visit
fromMenus = mySession.getParser().getRawParameter( WebSession.SHOW, null );
if ( fromMenus == null )
{
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);
screen.getLessonTracker(mySession).incrementNumVisits();
}
catch ( Throwable t )
}
// 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(screen, response);
}
catch (Throwable thr)
{
thr.printStackTrace();
log(request, "Could not write error screen: "
+ thr.getMessage());
}
// 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 session
* Description of the Parameter
*/
private void dumpSession(HttpSession session)
{
Enumeration enumerator = session.getAttributeNames();
while (enumerator.hasMoreElements())
{
String name = (String) enumerator.nextElement();
Object value = session.getAttribute(name);
System.out.println("Name: " + name);
System.out.println("Value: " + value);
}
}
/**
* 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(
"." + System.getProperty("file.separator") + "WEB-INF"
+ "/webgoat.properties");
}
/**
* 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 getCategories()
{
Course course = mySession.getCourse();
// May need to clone the List before returning it.
// return new ArrayList(course.getCategories());
return course.getCategories();
}
/*
* 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())
{
t.printStackTrace();
log( "ERROR: " + t );
screen = new ErrorScreen( mySession, t );
// If admin was hacked, let the user see some of the
// admin screens
lesson = course.getLesson(s, scr,
AbstractLesson.HACKED_ADMIN_ROLE);
}
finally
if (lesson != null)
{
try
{
this.writeScreen( screen, response );
}
catch ( Throwable thr )
{
thr.printStackTrace();
log( request, "Could not write error screen: " + thr.getMessage() );
}
//System.out.println( "HH Leaving doPost: " );
}
}
screen = lesson;
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 session Description of the Parameter
*/
private void dumpSession( HttpSession session )
{
Enumeration enumerator = session.getAttributeNames();
// 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.
while ( enumerator.hasMoreElements() )
{
String name = (String) enumerator.nextElement();
Object value = session.getAttribute( name );
System.out.println( "Name: " + name );
System.out.println( "Value: " + value );
}
}
s.setHasHackableAdmin(screen.getRole());
/**
* 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(
"." + System.getProperty("file.separator")+ "WEB-INF" + "/webgoat.properties");
}
/**
* 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 getCategories()
{
Course course = mySession.getCourse();
// May need to clone the List before returning it.
//return new ArrayList(course.getCategories());
return course.getCategories();
}
/*
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" );
}
}
}
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 )
{
response.setHeader( "Pragma", "no-cache" );
response.setHeader( "Cache-Control", "no-cache" );
response.setHeader( "Expires", formatHttpDate( new Date() ) );
lesson.handleRequest(s);
s.setCurrentMenu(lesson.getCategory().getRanking());
}
else
{
Date expiryDate = new Date( System.currentTimeMillis() + expiry );
response.setHeader( "Expires", formatHttpDate( expiryDate ) );
screen = new ErrorScreen(s,
"Invalid screen requested. Try: http://localhost/WebGoat/attack");
}
}
}
/**
* 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
else if (s.isAdmin())
{
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 )
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)
{
session = (WebSession) o;
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
{
// Create new custom session and save it in the HTTP session
//System.out.println( "HH Creating new WebSession: " );
session = new WebSession( this, context );
hs.setAttribute( WebSession.SESSION, session );
// reset timeout
hs.setMaxInactiveInterval( sessionTimeoutSeconds );
screen = new ErrorScreen(
s,
"Invalid screen requested. Try Setting Admin to false or Try: http://localhost/WebGoat/attack");
}
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
* @param response Description of the Parameter
* @exception IOException Description of the Exception
*/
protected void writeScreen( Screen s, HttpServletResponse response ) throws IOException
/**
* 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)
{
response.setContentType( "text/html" );
PrintWriter out = response.getWriter();
if ( s == null )
{
s = new ErrorScreen( mySession, "Page to display was null" );
}
// set the content-length of the response.
// Trying to avoid chunked-encoding. (Aspect required)
response.setContentLength( s.getContentLength() );
response.setHeader("Content-Length",s.getContentLength()+"");
s.output( out );
out.close();
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", formatHttpDate(new Date()));
}
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(this, 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(Screen s, HttpServletResponse response)
throws IOException
{
response.setContentType("text/html");
PrintWriter out = response.getWriter();
if (s == null)
{
s = new ErrorScreen(mySession, "Page to display was null");
}
// set the content-length of the response.
// Trying to avoid chunked-encoding. (Aspect required)
response.setContentLength(s.getContentLength());
response.setHeader("Content-Length", s.getContentLength() + "");
s.output(out);
out.close();
}
}