git-svn-id: http://webgoat.googlecode.com/svn/trunk@6 4033779f-a91e-0410-96ef-6bf7bf53c507
This commit is contained in:
458
webgoat/main/project/org/owasp/webgoat/HammerHead.java
Normal file
458
webgoat/main/project/org/owasp/webgoat/HammerHead.java
Normal file
@ -0,0 +1,458 @@
|
|||||||
|
package org.owasp.webgoat;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServlet;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import javax.servlet.http.HttpSession;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||||
|
import org.owasp.webgoat.lessons.WelcomeScreen;
|
||||||
|
import org.owasp.webgoat.lessons.admin.WelcomeAdminScreen;
|
||||||
|
import org.owasp.webgoat.session.Course;
|
||||||
|
import org.owasp.webgoat.session.ErrorScreen;
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
{
|
||||||
|
//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);
|
||||||
|
}
|
||||||
|
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() )
|
||||||
|
{
|
||||||
|
// 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() ) );
|
||||||
|
}
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
171
webgoat/main/project/org/owasp/webgoat/LessonSource.java
Normal file
171
webgoat/main/project/org/owasp/webgoat/LessonSource.java
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
package org.owasp.webgoat;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import javax.servlet.http.HttpSession;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||||
|
import org.owasp.webgoat.session.Course;
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
public class LessonSource extends HammerHead
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Field
|
||||||
|
*/
|
||||||
|
//protected WebSession tempSession;
|
||||||
|
|
||||||
|
public final static String START_SOURCE_SKIP = "START_OMIT_SOURCE";
|
||||||
|
public final static String END_SOURCE_SKIP = "END_OMIT_SOURCE";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
{
|
||||||
|
String source = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//System.out.println( "Entering doPost: " );
|
||||||
|
//System.out.println( " - request " + request);
|
||||||
|
//System.out.println( " - principle: " + request.getUserPrincipal() );
|
||||||
|
//setCacheHeaders(response, 0);
|
||||||
|
WebSession session = (WebSession) request.getSession( true ).getAttribute( WebSession.SESSION );
|
||||||
|
session.update(request, response, this.getServletName()); // FIXME: Too much in this call.
|
||||||
|
|
||||||
|
// Get the Java source of the lesson. FIXME: Not needed
|
||||||
|
source = getSource( session );
|
||||||
|
|
||||||
|
int scr = session.getCurrentScreen();
|
||||||
|
Course course = session.getCourse();
|
||||||
|
AbstractLesson lesson = course.getLesson( session, scr, AbstractLesson.USER_ROLE );
|
||||||
|
lesson.getLessonTracker( session ).setViewedSource(true);
|
||||||
|
}
|
||||||
|
catch ( Throwable t )
|
||||||
|
{
|
||||||
|
t.printStackTrace();
|
||||||
|
log( "ERROR: " + t );
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
this.writeSource(source, response );
|
||||||
|
}
|
||||||
|
catch ( Throwable thr )
|
||||||
|
{
|
||||||
|
thr.printStackTrace();
|
||||||
|
log( request, "Could not write error screen: " + thr.getMessage() );
|
||||||
|
}
|
||||||
|
//System.out.println( "Leaving doPost: " );
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected WebSession updateSession_DELETEME( HttpServletRequest request, HttpServletResponse response, ServletContext context )
|
||||||
|
{
|
||||||
|
HttpSession hs;
|
||||||
|
hs = request.getSession( true );
|
||||||
|
|
||||||
|
//System.out.println( "Entering Session_id: " + hs.getId() );
|
||||||
|
// dumpSession( hs );
|
||||||
|
|
||||||
|
// Make a temporary session to avoid the concurreny issue
|
||||||
|
// in WebSession
|
||||||
|
WebSession session = new WebSession( this, context );
|
||||||
|
|
||||||
|
WebSession realSession = null;
|
||||||
|
Object o = hs.getAttribute( WebSession.SESSION );
|
||||||
|
|
||||||
|
if ( ( o != null ) && o instanceof WebSession )
|
||||||
|
{
|
||||||
|
realSession = (WebSession) o;
|
||||||
|
}
|
||||||
|
session.setCurrentScreen( realSession.getCurrentScreen());
|
||||||
|
session.setCourse( realSession.getCourse() );
|
||||||
|
session.setRequest( request );
|
||||||
|
|
||||||
|
// to authenticate
|
||||||
|
//System.out.println( "Leaving Session_id: " + hs.getId() );
|
||||||
|
//dumpSession( hs );
|
||||||
|
return ( session );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param s Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
protected String getSource( WebSession s )
|
||||||
|
{
|
||||||
|
|
||||||
|
String source = null;
|
||||||
|
int scr = s.getCurrentScreen();
|
||||||
|
Course course = s.getCourse();
|
||||||
|
|
||||||
|
if ( s.isUser() || s.isChallenge() )
|
||||||
|
{
|
||||||
|
|
||||||
|
AbstractLesson lesson = course.getLesson( s, scr, AbstractLesson.USER_ROLE );
|
||||||
|
|
||||||
|
if ( lesson != null )
|
||||||
|
{
|
||||||
|
source = lesson.getSource(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( source == null )
|
||||||
|
{
|
||||||
|
return "Source code is not available. Contact webgoat@aspectsecurity.com";
|
||||||
|
}
|
||||||
|
return ( source.replaceAll("(?s)" + START_SOURCE_SKIP + ".*" + END_SOURCE_SKIP, "Code Section Deliberately Omitted") );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param s Description of the Parameter
|
||||||
|
* @param response Description of the Parameter
|
||||||
|
* @exception IOException Description of the Exception
|
||||||
|
*/
|
||||||
|
protected void writeSource( String s, HttpServletResponse response ) throws IOException
|
||||||
|
{
|
||||||
|
response.setContentType( "text/html" );
|
||||||
|
|
||||||
|
PrintWriter out = response.getWriter();
|
||||||
|
|
||||||
|
if ( s == null )
|
||||||
|
{
|
||||||
|
s = new String();
|
||||||
|
}
|
||||||
|
|
||||||
|
out.print(s);
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
1024
webgoat/main/project/org/owasp/webgoat/lessons/AbstractLesson.java
Normal file
1024
webgoat/main/project/org/owasp/webgoat/lessons/AbstractLesson.java
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,226 @@
|
|||||||
|
package org.owasp.webgoat.lessons;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
import org.apache.ecs.ElementContainer;
|
||||||
|
import org.apache.ecs.html.P;
|
||||||
|
import org.owasp.webgoat.session.ECSFactory;
|
||||||
|
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 org.owasp.webgoat.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
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class AccessControlMatrix extends LessonAdapter
|
||||||
|
{
|
||||||
|
|
||||||
|
private final static String RESOURCE = "Resource";
|
||||||
|
private final static String USER = "User";
|
||||||
|
private final static String[] resources = {"Public Share", "Time Card Entry", "Performance Review", "Time Card Approval", "Site Manager", "Account Manager"};
|
||||||
|
private final static String[] roles = {"Public", "User", "Manager", "Admin"};
|
||||||
|
private final static String[] users = { "Moe", "Larry", "Curly", "Shemp"};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
{
|
||||||
|
String user = s.getParser().getRawParameter( USER, users[0] );
|
||||||
|
String resource = s.getParser().getRawParameter( RESOURCE, resources[0] );
|
||||||
|
String credentials = getRoles( user ).toString();
|
||||||
|
ec.addElement( new P().addElement( "Change user:" ) );
|
||||||
|
ec.addElement( ECSFactory.makePulldown( USER, users, user, 1 ) );
|
||||||
|
ec.addElement( new P() );
|
||||||
|
|
||||||
|
// 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 ) );
|
||||||
|
ec.addElement( new P().addElement( "Select resource: " ) );
|
||||||
|
ec.addElement( ECSFactory.makePulldown( RESOURCE, resources, resource, 1 ) );
|
||||||
|
|
||||||
|
ec.addElement( new P() );
|
||||||
|
ec.addElement( ECSFactory.makeButton( "Check Access" ) );
|
||||||
|
|
||||||
|
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() );
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( ec );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the category attribute of the RoleBasedAccessControl object
|
||||||
|
*
|
||||||
|
* @return The category value
|
||||||
|
*/
|
||||||
|
|
||||||
|
protected Category getDefaultCategory()
|
||||||
|
{
|
||||||
|
return AbstractLesson.A2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the hints attribute of the RoleBasedAccessControl object
|
||||||
|
*
|
||||||
|
* @return The hints value
|
||||||
|
*/
|
||||||
|
protected List getHints()
|
||||||
|
{
|
||||||
|
List hints = new ArrayList();
|
||||||
|
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." );
|
||||||
|
return hints;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final static Integer DEFAULT_RANKING = new Integer(120);
|
||||||
|
|
||||||
|
protected Integer getDefaultRanking()
|
||||||
|
{
|
||||||
|
return DEFAULT_RANKING;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the resources attribute of the RoleBasedAccessControl object
|
||||||
|
*
|
||||||
|
* @param rl Description of the Parameter
|
||||||
|
* @return The resources value
|
||||||
|
*/
|
||||||
|
private List getResources( List rl )
|
||||||
|
{
|
||||||
|
// return the resources allowed for these roles
|
||||||
|
ArrayList list = new ArrayList();
|
||||||
|
|
||||||
|
if ( rl.contains( roles[0] ) )
|
||||||
|
{
|
||||||
|
list.add( resources[0] );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( rl.contains( roles[1] ) )
|
||||||
|
{
|
||||||
|
list.add( resources[1] );
|
||||||
|
list.add( resources[5] );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( rl.contains( roles[2] ) )
|
||||||
|
{
|
||||||
|
list.add( resources[2] );
|
||||||
|
list.add( resources[3] );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( rl.contains( roles[3] ) )
|
||||||
|
{
|
||||||
|
list.add( resources[4] );
|
||||||
|
list.add( resources[5] );
|
||||||
|
}
|
||||||
|
|
||||||
|
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 )
|
||||||
|
{
|
||||||
|
ArrayList list = new ArrayList();
|
||||||
|
|
||||||
|
if ( user.equals( users[0] ) )
|
||||||
|
{
|
||||||
|
list.add( roles[0] );
|
||||||
|
}
|
||||||
|
else if ( user.equals( users[1] ) )
|
||||||
|
{
|
||||||
|
list.add( roles[1] );
|
||||||
|
list.add( roles[2] );
|
||||||
|
}
|
||||||
|
else if ( user.equals( users[2] ) )
|
||||||
|
{
|
||||||
|
list.add( roles[0] );
|
||||||
|
list.add( roles[2] );
|
||||||
|
}
|
||||||
|
else if ( user.equals( users[3] ) )
|
||||||
|
{
|
||||||
|
list.add( roles[3] );
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the title attribute of the AccessControlScreen object
|
||||||
|
*
|
||||||
|
* @return The title value
|
||||||
|
*/
|
||||||
|
|
||||||
|
public String getTitle()
|
||||||
|
{
|
||||||
|
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));
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 resources = getResources( roles );
|
||||||
|
return ( resources.contains( resource ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,270 @@
|
|||||||
|
package org.owasp.webgoat.lessons;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
import org.apache.ecs.ElementContainer;
|
||||||
|
import org.apache.ecs.StringElement;
|
||||||
|
import org.apache.ecs.html.Input;
|
||||||
|
import org.apache.ecs.html.P;
|
||||||
|
import org.apache.ecs.html.TD;
|
||||||
|
import org.apache.ecs.html.TR;
|
||||||
|
import org.apache.ecs.html.Table;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.session.ECSFactory;
|
||||||
|
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 org.owasp.webgoat.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
|
||||||
|
*/
|
||||||
|
public class BasicAuthentication extends LessonAdapter
|
||||||
|
{
|
||||||
|
|
||||||
|
private static final String EMPTY_STRING = "";
|
||||||
|
private static final String WEBGOAT_BASIC = "webgoat_basic";
|
||||||
|
private static final String AUTHORIZATION = "Authorization";
|
||||||
|
private static final String ORIGINAL_AUTH = "Original_Auth";
|
||||||
|
private static final String ORIGINAL_USER = "Original.user";
|
||||||
|
private static final String BASIC = "basic";
|
||||||
|
private static final String JSESSIONID = "JSESSIONID";
|
||||||
|
private final static String HEADER_NAME = "header";
|
||||||
|
private final static String HEADER_VALUE = "value";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save the session so it can be used in a staged lesson
|
||||||
|
*/
|
||||||
|
private WebSession session = null;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param s Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
protected Element createContent( WebSession s )
|
||||||
|
{
|
||||||
|
session = 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( 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.equals(AUTHORIZATION) &&
|
||||||
|
( headerValue.equals("guest:guest") || headerValue.equals("webgoat:webgoat")))
|
||||||
|
{
|
||||||
|
getLessonTracker(s).setStage(2);
|
||||||
|
return doStage2( s );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( headerName.length() > 0 && !headerName.equals(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 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
|
||||||
|
if ( originalSessionId.equals(s.getCookie(JSESSIONID)) )
|
||||||
|
{
|
||||||
|
// Store the original user name in the "basic" user properties file. We need to use
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
s.setMessage("Congratulations, you have figured out the mechanics of basic authentication." );
|
||||||
|
s.setMessage(" - Now you must try to make WebGoat reauthenticate you as: ");
|
||||||
|
s.setMessage(" - username: basic");
|
||||||
|
s.setMessage(" - password: basic");
|
||||||
|
|
||||||
|
// 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>" +
|
||||||
|
" user name: basic<br> " +
|
||||||
|
" 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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the category attribute of the ForgotPassword object
|
||||||
|
*
|
||||||
|
* @return The category value
|
||||||
|
*/
|
||||||
|
protected Category getDefaultCategory()
|
||||||
|
{
|
||||||
|
|
||||||
|
return AbstractLesson.A3;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the hints attribute of the HelloScreen object
|
||||||
|
*
|
||||||
|
* @return The hints value
|
||||||
|
*/
|
||||||
|
public List getHints()
|
||||||
|
{
|
||||||
|
List hints = new ArrayList();
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private final static Integer DEFAULT_RANKING = new Integer(100);
|
||||||
|
|
||||||
|
protected Integer getDefaultRanking()
|
||||||
|
{
|
||||||
|
return DEFAULT_RANKING;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the title attribute of the HelloScreen object
|
||||||
|
*
|
||||||
|
* @return The title value
|
||||||
|
*/
|
||||||
|
public String getTitle()
|
||||||
|
{
|
||||||
|
return ( "Basic Authentication" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,270 @@
|
|||||||
|
package org.owasp.webgoat.lessons;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
import org.apache.ecs.ElementContainer;
|
||||||
|
import org.apache.ecs.StringElement;
|
||||||
|
import org.apache.ecs.html.Input;
|
||||||
|
import org.apache.ecs.html.P;
|
||||||
|
import org.owasp.webgoat.session.DatabaseUtilities;
|
||||||
|
import org.owasp.webgoat.session.ECSFactory;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2005 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 Chuck Willis <a href="http://www.securityfoundry.com">Chuck's web site</a> (this lesson is heavily based on Jeff Williams' SQL Injection lesson
|
||||||
|
* @created January 14, 2005
|
||||||
|
*/
|
||||||
|
public class BlindSqlInjection extends LessonAdapter
|
||||||
|
{
|
||||||
|
private final static String ACCT_NUM = "account_number";
|
||||||
|
private final static int TARGET_ACCT_NUM = 15613;
|
||||||
|
private static Connection connection = null;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
{
|
||||||
|
if ( connection == null )
|
||||||
|
{
|
||||||
|
connection = DatabaseUtilities.makeConnection( s );
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
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() );
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( ec );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the category attribute of the SqlInjection object
|
||||||
|
*
|
||||||
|
* @return The category value
|
||||||
|
*/
|
||||||
|
public Category getCategory()
|
||||||
|
{
|
||||||
|
return AbstractLesson.A6;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the credits attribute of the AbstractLesson object
|
||||||
|
*
|
||||||
|
* @return The credits value
|
||||||
|
*/
|
||||||
|
public Element getCredits()
|
||||||
|
{
|
||||||
|
return new StringElement("By Chuck Willis (edited 14 Dec 05 - Hints need to updated for non-Windows systems)");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the hints attribute of the DatabaseFieldScreen object
|
||||||
|
*
|
||||||
|
* @return The hints value
|
||||||
|
*/
|
||||||
|
protected List getHints()
|
||||||
|
{
|
||||||
|
List hints = new ArrayList();
|
||||||
|
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>> and < - 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>> and < - 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 that name in the form to pass the lesson.";
|
||||||
|
|
||||||
|
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 ( "How to Perform Blind SQL Injection" );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for the DatabaseFieldScreen object
|
||||||
|
*
|
||||||
|
* @param s Description of the Parameter
|
||||||
|
*/
|
||||||
|
public void handleRequest( WebSession s )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
super.handleRequest( s );
|
||||||
|
|
||||||
|
if ( connection == null )
|
||||||
|
{
|
||||||
|
connection = DatabaseUtilities.makeConnection( s );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
System.out.println( "Exception caught: " + e );
|
||||||
|
e.printStackTrace( System.out );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,86 @@
|
|||||||
|
package org.owasp.webgoat.lessons;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
import org.apache.ecs.StringElement;
|
||||||
|
|
||||||
|
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 org.owasp.webgoat.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
|
||||||
|
*/
|
||||||
|
public class BufferOverflow extends LessonAdapter
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param s Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
protected Element createContent( WebSession 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 AbstractLesson.A5;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the hints attribute of the HelloScreen object
|
||||||
|
*
|
||||||
|
* @return The hints value
|
||||||
|
*/
|
||||||
|
public List getHints()
|
||||||
|
{
|
||||||
|
List hints = new ArrayList();
|
||||||
|
hints.add( "Lesson Hint 1" );
|
||||||
|
hints.add( "Lesson Hint 2" );
|
||||||
|
|
||||||
|
return hints;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private final static Integer DEFAULT_RANKING = new Integer(15);
|
||||||
|
|
||||||
|
protected Integer getDefaultRanking()
|
||||||
|
{
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
51
webgoat/main/project/org/owasp/webgoat/lessons/Category.java
Normal file
51
webgoat/main/project/org/owasp/webgoat/lessons/Category.java
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
package org.owasp.webgoat.lessons;
|
||||||
|
|
||||||
|
public class Category implements Comparable
|
||||||
|
{
|
||||||
|
|
||||||
|
private String category;
|
||||||
|
private Integer ranking;
|
||||||
|
|
||||||
|
public Category( String category, Integer ranking )
|
||||||
|
{
|
||||||
|
this.category = category;
|
||||||
|
this.ranking = ranking;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int compareTo( Object obj )
|
||||||
|
{
|
||||||
|
int value = 1;
|
||||||
|
|
||||||
|
if ( obj instanceof Category )
|
||||||
|
{
|
||||||
|
value = this.getRanking().compareTo( ( (Category) obj ).getRanking() );
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getRanking()
|
||||||
|
{
|
||||||
|
return ranking;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer setRanking( Integer ranking )
|
||||||
|
{
|
||||||
|
return this.ranking = ranking;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName()
|
||||||
|
{
|
||||||
|
return category;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals( Object obj )
|
||||||
|
{
|
||||||
|
return getName().equals( ((Category)obj).getName() );
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,741 @@
|
|||||||
|
package org.owasp.webgoat.lessons;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.ResultSetMetaData;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
import javax.servlet.http.Cookie;
|
||||||
|
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
import org.apache.ecs.ElementContainer;
|
||||||
|
import org.apache.ecs.StringElement;
|
||||||
|
import org.apache.ecs.html.B;
|
||||||
|
import org.apache.ecs.html.BR;
|
||||||
|
import org.apache.ecs.html.Center;
|
||||||
|
import org.apache.ecs.html.H1;
|
||||||
|
import org.apache.ecs.html.HR;
|
||||||
|
import org.apache.ecs.html.Input;
|
||||||
|
import org.apache.ecs.html.P;
|
||||||
|
import org.apache.ecs.html.TD;
|
||||||
|
import org.apache.ecs.html.TH;
|
||||||
|
import org.apache.ecs.html.TR;
|
||||||
|
import org.apache.ecs.html.Table;
|
||||||
|
import org.owasp.webgoat.session.DatabaseUtilities;
|
||||||
|
import org.owasp.webgoat.session.ECSFactory;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
import org.owasp.webgoat.util.Exec;
|
||||||
|
import org.owasp.webgoat.util.ExecResults;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
public class Challenge2Screen extends LessonAdapter
|
||||||
|
{
|
||||||
|
private static final String USER_COOKIE = "user";
|
||||||
|
|
||||||
|
private static final String JSP = ".jsp";
|
||||||
|
|
||||||
|
private static final String WEBGOAT_CHALLENGE = "webgoat_challenge";
|
||||||
|
|
||||||
|
private static final String WEBGOAT_CHALLENGE_JSP = WEBGOAT_CHALLENGE + JSP;
|
||||||
|
|
||||||
|
private static final String PROCEED_TO_NEXT_STAGE = "Proceed to the next stage...";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Field
|
||||||
|
*/
|
||||||
|
protected final static String CREDIT = "Credit";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Field
|
||||||
|
*/
|
||||||
|
protected final static String PROTOCOL = "File";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Field
|
||||||
|
*/
|
||||||
|
protected final static String MESSAGE = "Message";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Field
|
||||||
|
*/
|
||||||
|
protected final static String PARAM = "p";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Field
|
||||||
|
*/
|
||||||
|
protected final static String PASSWORD = "Password";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Field
|
||||||
|
*/
|
||||||
|
protected final static String USER = "s";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Field
|
||||||
|
*/
|
||||||
|
protected final static String USERNAME = "Username";
|
||||||
|
private static Connection connection = null;
|
||||||
|
private String pass = "goodbye";
|
||||||
|
private String user = "youaretheweakestlink";
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine the username and password
|
||||||
|
*
|
||||||
|
* @param s Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
* @exception Exception Description of the Exception
|
||||||
|
*/
|
||||||
|
protected Element doStage1( WebSession s ) throws Exception
|
||||||
|
{
|
||||||
|
setStage( s, 1 );
|
||||||
|
|
||||||
|
String username = s.getParser().getStringParameter( USERNAME, "" );
|
||||||
|
String password = s.getParser().getStringParameter( PASSWORD, "" );
|
||||||
|
|
||||||
|
if ( username.equals( user ) && password.equals( pass ) )
|
||||||
|
{
|
||||||
|
s.setMessage( "Welcome to stage 2 -- get credit card numbers!" );
|
||||||
|
setStage( s, 2 );
|
||||||
|
|
||||||
|
return ( doStage2( s ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
s.setMessage( "Invalid login" );
|
||||||
|
|
||||||
|
ElementContainer ec = new ElementContainer();
|
||||||
|
ec.addElement( makeLogin(s) );
|
||||||
|
|
||||||
|
//<START_OMIT_SOURCE>
|
||||||
|
// these are red herrings for the first stage
|
||||||
|
Input input = new Input( Input.HIDDEN, USER, "White" );
|
||||||
|
ec.addElement( input );
|
||||||
|
|
||||||
|
Cookie newCookie = new Cookie( USER_COOKIE, "White" );
|
||||||
|
s.getResponse().addCookie( newCookie );
|
||||||
|
//<END_OMIT_SOURCE>
|
||||||
|
|
||||||
|
return ( ec );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// get creditcards from database
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param s Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
* @exception Exception Description of the Exception
|
||||||
|
*/
|
||||||
|
protected Element doStage2( WebSession s ) throws Exception
|
||||||
|
{
|
||||||
|
//<START_OMIT_SOURCE>
|
||||||
|
|
||||||
|
Cookie newCookie = new Cookie( USER_COOKIE, "White" );
|
||||||
|
s.getResponse().addCookie( newCookie );
|
||||||
|
|
||||||
|
ElementContainer ec = new ElementContainer();
|
||||||
|
if ( s.getParser().getStringParameter(Input.SUBMIT, "").equals(PROCEED_TO_NEXT_STAGE + "(3)"))
|
||||||
|
{
|
||||||
|
s.setMessage( "Welcome to stage 3 -- deface the site" );
|
||||||
|
setStage( s, 3 );
|
||||||
|
// Reset the defaced webpage so the lesson can start over
|
||||||
|
resetWebPage(s);
|
||||||
|
return doStage3(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( connection == null )
|
||||||
|
{
|
||||||
|
connection = DatabaseUtilities.makeConnection( s );
|
||||||
|
}
|
||||||
|
|
||||||
|
Statement statement3 = connection.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY );
|
||||||
|
// pull the USER_COOKIE from the cookies
|
||||||
|
String user = getCookie(s);
|
||||||
|
String query = "SELECT * FROM user_data WHERE last_name = '" + user +"'";
|
||||||
|
Vector v = new Vector();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ResultSet results = statement3.executeQuery( query );
|
||||||
|
|
||||||
|
while ( results.next() )
|
||||||
|
{
|
||||||
|
String type = results.getString( "cc_type" );
|
||||||
|
String num = results.getString( "cc_number" );
|
||||||
|
v.addElement( type + "-" + num );
|
||||||
|
}
|
||||||
|
if ( v.size() > 2 )
|
||||||
|
{
|
||||||
|
ResultSetMetaData resultsMetaData = results.getMetaData();
|
||||||
|
ec.addElement( DatabaseUtilities.writeTable( results, resultsMetaData ) );
|
||||||
|
ec.addElement(ECSFactory.makeButton(PROCEED_TO_NEXT_STAGE + "(3)"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s.setMessage("Try to get all the credit card numbers");
|
||||||
|
ec.addElement( buildCart(s));
|
||||||
|
|
||||||
|
//Table t = ECSFactory.makeTable( s.isColor(), HtmlColor.ALICEBLUE );
|
||||||
|
Table t = new Table().setCellSpacing( 0 ).setCellPadding( 2 ).setBorder( 0 ).setWidth( "90%" ).setAlign(
|
||||||
|
"center" );
|
||||||
|
|
||||||
|
ec.addElement( new BR() );
|
||||||
|
TR tr = new TR();
|
||||||
|
tr.addElement( new TD().addElement( "Please select credit card for this purchase: " ) );
|
||||||
|
Element p = ECSFactory.makePulldown( CREDIT, v );
|
||||||
|
tr.addElement( new TD().addElement( p ).setAlign( "right" ));
|
||||||
|
t.addElement( tr );
|
||||||
|
|
||||||
|
tr = new TR();
|
||||||
|
Element b = ECSFactory.makeButton( "Buy Now!" );
|
||||||
|
tr.addElement( new TD().addElement( b ) );
|
||||||
|
t.addElement( tr );
|
||||||
|
ec.addElement(t);
|
||||||
|
|
||||||
|
ec.addElement( new BR() );
|
||||||
|
Input input = new Input( Input.HIDDEN, USER, "White" );
|
||||||
|
ec.addElement( input );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
s.setMessage("An error occurred in the woods");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return ( ec );
|
||||||
|
//<END_OMIT_SOURCE>
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param s Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
* @exception Exception Description of the Exception
|
||||||
|
*/
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see lessons.LessonAdapter#doStage3(session.WebSession)
|
||||||
|
*/
|
||||||
|
protected Element doStage3( WebSession s ) throws Exception
|
||||||
|
{
|
||||||
|
//<START_OMIT_SOURCE>
|
||||||
|
|
||||||
|
ElementContainer ec = new ElementContainer();
|
||||||
|
if ( s.getParser().getStringParameter(Input.SUBMIT, "").equals(PROCEED_TO_NEXT_STAGE +"(4)"))
|
||||||
|
{
|
||||||
|
setStage( s, 4 );
|
||||||
|
// Reset the defaced webpage so the lesson can start over
|
||||||
|
resetWebPage(s);
|
||||||
|
return doStage4(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
// execute the possible attack first to determine if site is defaced.
|
||||||
|
ElementContainer netstatResults = getNetstatResults(s);
|
||||||
|
if (isDefaced(s))
|
||||||
|
{
|
||||||
|
ec.addElement( new HR() );
|
||||||
|
s.setMessage( "CONGRATULATIONS - You have defaced the site!" );
|
||||||
|
Table t = new Table().setCellSpacing( 0 ).setCellPadding( 2 ).setWidth("90%").setAlign("center");
|
||||||
|
if ( s.isColor() )
|
||||||
|
{
|
||||||
|
t.setBorder( 1 );
|
||||||
|
}
|
||||||
|
TR tr = new TR();
|
||||||
|
tr.addElement( new TD().setAlign("center").addElement(ECSFactory.makeButton(PROCEED_TO_NEXT_STAGE + "(4)")));
|
||||||
|
t.addElement(tr);
|
||||||
|
tr = new TR();
|
||||||
|
tr.addElement( new TD().addElement( showDefaceAttempt(s) ));
|
||||||
|
t.addElement(tr);
|
||||||
|
ec.addElement( t );
|
||||||
|
return ec;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Setup the screen content
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ec.addElement( new H1("Current Network Status:") );
|
||||||
|
ec.addElement( netstatResults );
|
||||||
|
|
||||||
|
Table t = new Table().setCellSpacing( 0 ).setCellPadding( 2 ).setWidth("90%").setAlign("center");
|
||||||
|
if ( s.isColor() )
|
||||||
|
{
|
||||||
|
t.setBorder( 1 );
|
||||||
|
}
|
||||||
|
String[] list = {"TCP", "TCPv6", "IP", "IPv6", "UDP", "UDPv6"};
|
||||||
|
|
||||||
|
TR tr = new TR();
|
||||||
|
tr.addElement( new TD().addElement( ECSFactory.makeButton( "View Network" )));
|
||||||
|
tr.addElement( new TD().setWidth("35%").addElement( ECSFactory.makePulldown( PROTOCOL, list, "", 5 )));
|
||||||
|
t.addElement(tr);
|
||||||
|
|
||||||
|
ec.addElement( t );
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
ec.addElement( new P().addElement( "Select a message to read from the Message List below" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
ec.addElement( new HR() );
|
||||||
|
Table t = new Table().setCellSpacing( 0 ).setCellPadding( 2 ).setWidth("90%").setAlign("center");
|
||||||
|
if ( s.isColor() )
|
||||||
|
{
|
||||||
|
t.setBorder( 1 );
|
||||||
|
}
|
||||||
|
TR tr = new TR();
|
||||||
|
tr.addElement( new TD().addElement( showDefaceAttempt(s) ));
|
||||||
|
t.addElement(tr);
|
||||||
|
ec.addElement( t );
|
||||||
|
}
|
||||||
|
return ( ec );
|
||||||
|
//<END_OMIT_SOURCE>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private boolean isDefaced(WebSession s)
|
||||||
|
{
|
||||||
|
//<START_OMIT_SOURCE>
|
||||||
|
boolean defaced = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// get current text and compare to the new text
|
||||||
|
String origpath = s.getContext(). getRealPath( WEBGOAT_CHALLENGE + "_" + s.getUserName() + JSP );
|
||||||
|
String masterFilePath = s.getContext().getRealPath( WEBGOAT_CHALLENGE_JSP );
|
||||||
|
String defacedText = getFileText( new BufferedReader( new FileReader( origpath ) ), false );
|
||||||
|
String origText = getFileText( new BufferedReader( new FileReader( masterFilePath ) ), false );
|
||||||
|
|
||||||
|
defaced = ( !origText.equals(defacedText) );
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return defaced;
|
||||||
|
//<END_OMIT_SOURCE>
|
||||||
|
}
|
||||||
|
|
||||||
|
private Element showDefaceAttempt( WebSession s ) throws Exception
|
||||||
|
{
|
||||||
|
ElementContainer ec = new ElementContainer();
|
||||||
|
|
||||||
|
// get current text and compare to the new text
|
||||||
|
String origpath = s.getContext(). getRealPath( WEBGOAT_CHALLENGE + "_" + s.getUserName() + JSP );
|
||||||
|
String defaced = getFileText( new BufferedReader( new FileReader( origpath ) ), false );
|
||||||
|
String origText = getFileText( new BufferedReader( new FileReader( s.getContext(). getRealPath( WEBGOAT_CHALLENGE_JSP ))), false);
|
||||||
|
|
||||||
|
// show webgoat.jsp text
|
||||||
|
ec.addElement( new H1().addElement( "Original Website Text" ) );
|
||||||
|
ec.addElement( new P().addElement( origText ) );
|
||||||
|
ec.addElement( new HR() );
|
||||||
|
ec.addElement( new H1().addElement( "Defaced Website Text" ) );
|
||||||
|
ec.addElement( new P().addElement( defaced ) );
|
||||||
|
ec.addElement( new HR() );
|
||||||
|
|
||||||
|
return ec;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void resetWebPage(WebSession s)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// get current text and compare to the new text
|
||||||
|
String defacedpath = s.getContext(). getRealPath( WEBGOAT_CHALLENGE + "_" + s.getUserName() + JSP );
|
||||||
|
String masterFilePath = s.getContext().getRealPath( WEBGOAT_CHALLENGE_JSP );
|
||||||
|
|
||||||
|
// replace the defaced text with the original
|
||||||
|
File usersFile = new File( defacedpath );
|
||||||
|
FileWriter fw = new FileWriter( usersFile );
|
||||||
|
fw.write( getFileText( new BufferedReader( new FileReader( masterFilePath ) ), false ) );
|
||||||
|
fw.close();
|
||||||
|
// System.out.println("webgoat_guest replaced: " + getFileText( new BufferedReader( new FileReader( defacedpath ) ), false ) );
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Category getDefaultCategory()
|
||||||
|
{
|
||||||
|
return CHALLENGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param s Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
* @exception Exception Description of the Exception
|
||||||
|
*/
|
||||||
|
protected Element doStage4( WebSession s ) throws Exception
|
||||||
|
{
|
||||||
|
makeSuccess( s );
|
||||||
|
ElementContainer ec = new ElementContainer();
|
||||||
|
ec.addElement(new H1().addElement( "Thanks for coming!" ));
|
||||||
|
ec.addElement(new BR());
|
||||||
|
ec.addElement(new H1().addElement( "Please remember that you will be caught and fired if you use these techniques for evil." ));
|
||||||
|
|
||||||
|
return ( ec ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param s Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
* @exception Exception Description of the Exception
|
||||||
|
*/
|
||||||
|
protected Element doStage5( WebSession s ) throws Exception
|
||||||
|
{
|
||||||
|
//<START_OMIT_SOURCE>
|
||||||
|
ElementContainer ec = new ElementContainer();
|
||||||
|
return ( ec );
|
||||||
|
//<END_OMIT_SOURCE>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param s Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
* @exception Exception Description of the Exception
|
||||||
|
*/
|
||||||
|
protected Element doStage6( WebSession s ) throws Exception
|
||||||
|
{
|
||||||
|
return ( new StringElement( "not yet" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the hints attribute of the ChallengeScreen object
|
||||||
|
*
|
||||||
|
* @return The hints value
|
||||||
|
*/
|
||||||
|
protected List getHints(WebSession s)
|
||||||
|
{
|
||||||
|
//<START_OMIT_SOURCE>
|
||||||
|
|
||||||
|
List hints = new ArrayList();
|
||||||
|
hints.add( "You need to gain access to the Java source code for this lesson." );
|
||||||
|
hints.add( "Seriously, no more hints -- it's a CHALLENGE!" );
|
||||||
|
hints.add( "Come on -- give it a rest!" );
|
||||||
|
if (getStage(s) != 1);
|
||||||
|
{
|
||||||
|
hints.add("Persistance is always rewarded");
|
||||||
|
}
|
||||||
|
|
||||||
|
return hints;
|
||||||
|
|
||||||
|
//<END_OMIT_SOURCE>
|
||||||
|
}
|
||||||
|
|
||||||
|
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("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();
|
||||||
|
tr.addElement( new TD().addElement(" ").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, "" );
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the instructions attribute of the ChallengeScreen object
|
||||||
|
*
|
||||||
|
* @return The instructions value
|
||||||
|
*/
|
||||||
|
public String getInstructions(WebSession s)
|
||||||
|
{
|
||||||
|
String instructions = "Your mission is to break the authentication scheme, " +
|
||||||
|
"steal all the credit cards from the database, and then deface the website. " +
|
||||||
|
"You will have to use many of the techniques you have learned in the other lessons. " +
|
||||||
|
"The main webpage for this site is 'webgoat_challenge_<username>.jsp'";
|
||||||
|
|
||||||
|
return ( instructions );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the ranking attribute of the ChallengeScreen object
|
||||||
|
*
|
||||||
|
* @return The ranking value
|
||||||
|
*/
|
||||||
|
protected Integer getDefaultRanking()
|
||||||
|
{
|
||||||
|
return new Integer( 130 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the title attribute of the ChallengeScreen object
|
||||||
|
*
|
||||||
|
* @return The title value
|
||||||
|
*/
|
||||||
|
public String getTitle()
|
||||||
|
{
|
||||||
|
return ( "The CHALLENGE!" );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param text Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
protected ElementContainer getNetstatResults( WebSession s )
|
||||||
|
{
|
||||||
|
//<START_OMIT_SOURCE>
|
||||||
|
|
||||||
|
ElementContainer ec = new ElementContainer();
|
||||||
|
|
||||||
|
Table t = new Table().setCellSpacing( 0 ).setCellPadding( 2 ).setBorder( 1 ).setWidth("90%").setAlign("center");
|
||||||
|
|
||||||
|
if ( s.isColor() )
|
||||||
|
{
|
||||||
|
t.setBorder( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
TR tr = new TR();
|
||||||
|
tr.addElement( new TH().addElement("Protocol").setWidth("7%"));
|
||||||
|
tr.addElement( new TH().addElement("Local Address").setWidth("80%"));
|
||||||
|
tr.addElement( new TH().addElement("Foreign Address").setWidth("10%"));
|
||||||
|
tr.addElement( new TH().addElement("State").setWidth("3%"));
|
||||||
|
t.addElement( tr );
|
||||||
|
|
||||||
|
String protocol = s.getParser().getRawParameter( PROTOCOL, "tcp" );
|
||||||
|
|
||||||
|
String osName = System.getProperty( "os.name" );
|
||||||
|
ExecResults er = null;
|
||||||
|
if ( osName.indexOf( "Windows" ) != -1 )
|
||||||
|
{
|
||||||
|
String cmd = "cmd.exe /c netstat -a -p " + protocol;
|
||||||
|
er = Exec.execSimple( cmd );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
String[] cmd = {"/bin/sh", "-c", "netstat -a -p " + protocol};
|
||||||
|
er = Exec.execSimple( cmd );
|
||||||
|
}
|
||||||
|
|
||||||
|
String results = er.getOutput();
|
||||||
|
StringTokenizer lines = new StringTokenizer( results, "\n");
|
||||||
|
String line = lines.nextToken();
|
||||||
|
//System.out.println(line);
|
||||||
|
int start = 0;
|
||||||
|
while ( start == 0 && lines.hasMoreTokens() )
|
||||||
|
{
|
||||||
|
if (( line.indexOf("Proto") != -1 ) )
|
||||||
|
{
|
||||||
|
start++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
line = lines.nextToken();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while ( start > 0 && lines.hasMoreTokens() )
|
||||||
|
{
|
||||||
|
// in order to avoid a ill-rendered screen when the user performs
|
||||||
|
// command injection, we will wrap the screen at 4 columns
|
||||||
|
int columnCount = 4;
|
||||||
|
tr = new TR();
|
||||||
|
StringTokenizer tokens = new StringTokenizer( lines.nextToken(), "\t ");
|
||||||
|
while( tokens.hasMoreTokens() && columnCount-- > 0 )
|
||||||
|
{
|
||||||
|
tr.addElement( new TD().addElement(tokens.nextToken()));
|
||||||
|
}
|
||||||
|
t.addElement( tr );
|
||||||
|
}
|
||||||
|
// parse the results
|
||||||
|
ec.addElement( t );
|
||||||
|
return ( ec );
|
||||||
|
//<END_OMIT_SOURCE>
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param s Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
protected Element makeClues( WebSession s )
|
||||||
|
{
|
||||||
|
return new StringElement( "Clues not Available :)" );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected Element makeHints( WebSession s )
|
||||||
|
{
|
||||||
|
return new StringElement("Hint: Find the hints");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param s Description of the Parameter
|
||||||
|
* @param message Description of the Parameter
|
||||||
|
*/
|
||||||
|
protected void sendMessage( Socket s, String message )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
OutputStreamWriter osw = new OutputStreamWriter( s.getOutputStream() );
|
||||||
|
osw.write( message );
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
System.out.println( "Couldn't write " + message + " to " + s );
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Element buildCart( WebSession s )
|
||||||
|
{
|
||||||
|
ElementContainer ec = new ElementContainer();
|
||||||
|
|
||||||
|
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("Sympathy Bouquet"));
|
||||||
|
tr.addElement( new TD().addElement("59.99").setAlign("right"));
|
||||||
|
tr.addElement( new TD().addElement(" 1 ").setAlign( "right" ));
|
||||||
|
tr.addElement( new TD().addElement("59.99"));
|
||||||
|
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( "59.99"));
|
||||||
|
t.addElement( tr );
|
||||||
|
|
||||||
|
ec.addElement(t);
|
||||||
|
|
||||||
|
return ( ec );
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canHaveClues()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the cookie attribute of the CookieScreen object
|
||||||
|
*
|
||||||
|
* @param s Description of the Parameter
|
||||||
|
* @return The cookie value
|
||||||
|
*/
|
||||||
|
protected String getCookie( WebSession s )
|
||||||
|
{
|
||||||
|
Cookie[] cookies = s.getRequest().getCookies();
|
||||||
|
|
||||||
|
for ( int i = 0; i < cookies.length; i++ )
|
||||||
|
{
|
||||||
|
if ( cookies[i].getName().equalsIgnoreCase( USER_COOKIE ) )
|
||||||
|
{
|
||||||
|
return ( cookies[i].getValue() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( null );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,299 @@
|
|||||||
|
package org.owasp.webgoat.lessons;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
import org.apache.ecs.ElementContainer;
|
||||||
|
import org.apache.ecs.StringElement;
|
||||||
|
import org.apache.ecs.html.BR;
|
||||||
|
import org.apache.ecs.html.HR;
|
||||||
|
import org.apache.ecs.html.P;
|
||||||
|
import org.apache.ecs.html.PRE;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.session.ECSFactory;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
import org.owasp.webgoat.util.Exec;
|
||||||
|
import org.owasp.webgoat.util.ExecResults;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2002 Free Software Foundation developed under the custody of the Open Web
|
||||||
|
* Application Security Project (http://www.owasp.org) This software package org.owasp.webgoat.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
|
||||||
|
*/
|
||||||
|
public class CommandInjection extends LessonAdapter
|
||||||
|
{
|
||||||
|
private final static String HELP_FILE = "HelpFile";
|
||||||
|
private String osName = System.getProperty( "os.name" );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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();
|
||||||
|
boolean illegalCommand = s.isDefuseOSCommands();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String helpFile = s.getParser().getRawParameter( HELP_FILE, "BasicAuthentication.help" );
|
||||||
|
String safeDirName;
|
||||||
|
if ( s.isDefuseOSCommands() && ( helpFile.indexOf('&') != -1 || helpFile.indexOf(';') != -1) )
|
||||||
|
{
|
||||||
|
int index = helpFile.indexOf('&');
|
||||||
|
if ( index == -1)
|
||||||
|
{
|
||||||
|
index = helpFile.indexOf(';');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (( osName.indexOf( "Windows" ) != -1 &&
|
||||||
|
( helpFile.substring(index + 1).trim().toLowerCase().equals("netstat -a") ||
|
||||||
|
helpFile.substring(index + 1).trim().toLowerCase().equals("dir") ||
|
||||||
|
helpFile.substring(index + 1).trim().toLowerCase().equals("ls") ||
|
||||||
|
helpFile.substring(index + 1).trim().toLowerCase().equals("ifconfig") ||
|
||||||
|
helpFile.substring(index + 1).trim().toLowerCase().equals("ipconfig") )) ||
|
||||||
|
(helpFile.substring(index + 1).trim().toLowerCase().equals("netstat -a #") ||
|
||||||
|
helpFile.substring(index + 1).trim().toLowerCase().equals("dir #") ||
|
||||||
|
helpFile.substring(index + 1).trim().toLowerCase().equals("ls #") ||
|
||||||
|
helpFile.substring(index + 1).trim().toLowerCase().equals("ls -l #") ||
|
||||||
|
helpFile.substring(index + 1).trim().toLowerCase().equals("ifconfig #") ||
|
||||||
|
helpFile.substring(index + 1).trim().toLowerCase().equals("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 ( s.isDefuseOSCommands() && helpFile.indexOf('&') == -1 && helpFile.indexOf(';') == -1 )
|
||||||
|
{
|
||||||
|
if ( helpFile.length() > 0 )
|
||||||
|
{
|
||||||
|
if ( upDirCount( helpFile ) <= 3 )
|
||||||
|
{
|
||||||
|
// FIXME: This value isn't used. What is the goal here?
|
||||||
|
safeDirName = s.getContext().getRealPath("/") + helpFile;
|
||||||
|
illegalCommand = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s.setMessage("It appears that you are on the right track. " +
|
||||||
|
"Commands that may compromise the operating system have been disabled. " +
|
||||||
|
"This lesson is a command injection lesson, not access control.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// No Command entered.
|
||||||
|
illegalCommand = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
File safeDir = new File(s.getContext().getRealPath( "/lesson_plans" ));
|
||||||
|
|
||||||
|
ec.addElement( new StringElement( "You are currently viewing: <b>"
|
||||||
|
+ ( helpFile.toString().length() == 0 ? "<select file from list below>" : helpFile.toString() )
|
||||||
|
+ "</b>") );
|
||||||
|
|
||||||
|
if ( !illegalCommand ) {
|
||||||
|
String results;
|
||||||
|
String fileData = null;
|
||||||
|
helpFile = helpFile.replaceAll("\\.help","\\.html");
|
||||||
|
|
||||||
|
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 )
|
||||||
|
{
|
||||||
|
s.setMessage( "Error generating " + this.getClass().getName() );
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( ec );
|
||||||
|
}
|
||||||
|
|
||||||
|
private String parseResults( String results )
|
||||||
|
{
|
||||||
|
return results.replaceAll("(?s).*Output...\\s","").replaceAll("(?s)Returncode.*","");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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++;
|
||||||
|
startIndex = fileName.indexOf("..", startIndex+1);
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param command Description of the Parameter
|
||||||
|
* @param args Description of the Parameter
|
||||||
|
* @param s Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
private Element exec( WebSession s, String command, String args )
|
||||||
|
{
|
||||||
|
System.out.println("Executing OS command: '" + command + "' with args: '" + args + "'");
|
||||||
|
ExecResults er = Exec.execSimple( command, args );
|
||||||
|
if (( args.indexOf("&" ) != -1 || args.indexOf(";") != -1 ) && !er.getError() )
|
||||||
|
{
|
||||||
|
makeSuccess( s );
|
||||||
|
}
|
||||||
|
PRE p = new PRE().addElement( er.toString() );
|
||||||
|
|
||||||
|
return ( p );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the category attribute of the CommandInjection object
|
||||||
|
*
|
||||||
|
* @return The category value
|
||||||
|
*/
|
||||||
|
protected Category getDefaultCategory()
|
||||||
|
{
|
||||||
|
return AbstractLesson.A6;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the hints attribute of the DirectoryScreen object
|
||||||
|
*
|
||||||
|
* @return The hints value
|
||||||
|
*/
|
||||||
|
protected List getHints()
|
||||||
|
{
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private final static Integer DEFAULT_RANKING = new Integer(40);
|
||||||
|
|
||||||
|
protected Integer getDefaultRanking()
|
||||||
|
{
|
||||||
|
return DEFAULT_RANKING;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the title attribute of the DirectoryScreen object
|
||||||
|
*
|
||||||
|
* @return The title value
|
||||||
|
*/
|
||||||
|
public String getTitle()
|
||||||
|
{
|
||||||
|
return "How to Perform Command Injection";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,355 @@
|
|||||||
|
package org.owasp.webgoat.lessons.CrossSiteScripting;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Hashtable;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.ecs.ElementContainer;
|
||||||
|
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||||
|
import org.owasp.webgoat.lessons.Category;
|
||||||
|
import org.owasp.webgoat.lessons.LessonAdapter;
|
||||||
|
import org.owasp.webgoat.lessons.LessonAction;
|
||||||
|
import org.owasp.webgoat.lessons.RoleBasedAccessControl.DeleteProfile;
|
||||||
|
import org.owasp.webgoat.lessons.RoleBasedAccessControl.ListStaff;
|
||||||
|
import org.owasp.webgoat.lessons.RoleBasedAccessControl.Login;
|
||||||
|
import org.owasp.webgoat.lessons.RoleBasedAccessControl.Logout;
|
||||||
|
import org.owasp.webgoat.lessons.RoleBasedAccessControl.SearchStaff;
|
||||||
|
import org.owasp.webgoat.session.DatabaseUtilities;
|
||||||
|
import org.owasp.webgoat.session.ParameterNotFoundException;
|
||||||
|
import org.owasp.webgoat.session.UnauthenticatedException;
|
||||||
|
import org.owasp.webgoat.session.UnauthorizedException;
|
||||||
|
import org.owasp.webgoat.session.ValidationException;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2006 Free Software Foundation developed under the custody of the Open Web
|
||||||
|
* Application Security Project (http://www.owasp.org) This software package org.owasp.webgoat.is published by OWASP
|
||||||
|
* under the GPL. You should read and accept the LICENSE before you use, modify and/or redistribute
|
||||||
|
* this software.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class CrossSiteScripting extends LessonAdapter
|
||||||
|
{
|
||||||
|
public final static String DESCRIPTION = "description";
|
||||||
|
public final static String DISCIPLINARY_DATE = "disciplinaryDate";
|
||||||
|
public final static String DISCIPLINARY_NOTES = "disciplinaryNotes";
|
||||||
|
public final static String CCN_LIMIT = "ccnLimit";
|
||||||
|
public final static String CCN = "ccn";
|
||||||
|
public final static String SALARY = "salary";
|
||||||
|
public final static String START_DATE = "startDate";
|
||||||
|
public final static String MANAGER = "manager";
|
||||||
|
public final static String ADDRESS1 = "address1";
|
||||||
|
public final static String ADDRESS2 = "address2";
|
||||||
|
public final static String PHONE_NUMBER = "phoneNumber";
|
||||||
|
public final static String TITLE = "title";
|
||||||
|
public final static String SSN = "ssn";
|
||||||
|
public final static String LAST_NAME = "lastName";
|
||||||
|
public final static String FIRST_NAME = "firstName";
|
||||||
|
public final static String PASSWORD = "password";
|
||||||
|
|
||||||
|
public final static String EMPLOYEE_ID = "employee_id";
|
||||||
|
public final static String USER_ID = "user_id";
|
||||||
|
public final static String SEARCHNAME = "search_name";
|
||||||
|
public final static String SEARCHRESULT_ATTRIBUTE_KEY = "SearchResult";
|
||||||
|
public final static String EMPLOYEE_ATTRIBUTE_KEY = "Employee";
|
||||||
|
public final static String STAFF_ATTRIBUTE_KEY = "Staff";
|
||||||
|
|
||||||
|
public final static String LOGIN_ACTION = "Login";
|
||||||
|
public final static String LOGOUT_ACTION = "Logout";
|
||||||
|
public final static String LISTSTAFF_ACTION = "ListStaff";
|
||||||
|
public final static String SEARCHSTAFF_ACTION = "SearchStaff";
|
||||||
|
public final static String FINDPROFILE_ACTION = "FindProfile";
|
||||||
|
public final static String VIEWPROFILE_ACTION = "ViewProfile";
|
||||||
|
public final static String EDITPROFILE_ACTION = "EditProfile";
|
||||||
|
public final static String UPDATEPROFILE_ACTION = "UpdateProfile";
|
||||||
|
public final static String CREATEPROFILE_ACTION = "CreateProfile";
|
||||||
|
public final static String DELETEPROFILE_ACTION = "DeleteProfile";
|
||||||
|
public final static String ERROR_ACTION = "error";
|
||||||
|
|
||||||
|
private final static String LESSON_NAME = "CrossSiteScripting";
|
||||||
|
private final static String JSP_PATH = "/lessons/" + LESSON_NAME + "/";
|
||||||
|
|
||||||
|
private final static Integer DEFAULT_RANKING = new Integer(100);
|
||||||
|
|
||||||
|
private static Connection connection = null;
|
||||||
|
|
||||||
|
private Map lessonFunctions = new Hashtable();
|
||||||
|
|
||||||
|
public static synchronized Connection getConnection(WebSession s)
|
||||||
|
throws SQLException, ClassNotFoundException
|
||||||
|
{
|
||||||
|
if ( connection == null )
|
||||||
|
{
|
||||||
|
connection = DatabaseUtilities.makeConnection( s );
|
||||||
|
}
|
||||||
|
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CrossSiteScripting()
|
||||||
|
{
|
||||||
|
String myClassName = parseClassName(this.getClass().getName());
|
||||||
|
registerAction(new ListStaff(this, myClassName, LISTSTAFF_ACTION));
|
||||||
|
registerAction(new SearchStaff(this, myClassName, SEARCHSTAFF_ACTION));
|
||||||
|
registerAction(new ViewProfile(this, myClassName, VIEWPROFILE_ACTION));
|
||||||
|
registerAction(new EditProfile(this, myClassName, EDITPROFILE_ACTION));
|
||||||
|
registerAction(new EditProfile(this, myClassName, CREATEPROFILE_ACTION));
|
||||||
|
|
||||||
|
// These actions are special in that they chain to other actions.
|
||||||
|
registerAction(new Login(this, myClassName, LOGIN_ACTION, getAction(LISTSTAFF_ACTION)));
|
||||||
|
registerAction(new Logout(this, myClassName, LOGOUT_ACTION, getAction(LOGIN_ACTION)));
|
||||||
|
registerAction(new FindProfile(this, myClassName, FINDPROFILE_ACTION, getAction(VIEWPROFILE_ACTION)));
|
||||||
|
registerAction(new UpdateProfile(this, myClassName, UPDATEPROFILE_ACTION, getAction(VIEWPROFILE_ACTION)));
|
||||||
|
registerAction(new DeleteProfile(this, myClassName, DELETEPROFILE_ACTION, getAction(LISTSTAFF_ACTION)));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the category attribute of the CrossSiteScripting object
|
||||||
|
*
|
||||||
|
* @return The category value
|
||||||
|
*/
|
||||||
|
public Category getDefaultCategory()
|
||||||
|
{
|
||||||
|
return AbstractLesson.A4;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the hints attribute of the DirectoryScreen object
|
||||||
|
*
|
||||||
|
* @return The hints value
|
||||||
|
*/
|
||||||
|
protected List getHints()
|
||||||
|
{
|
||||||
|
List hints = new ArrayList();
|
||||||
|
|
||||||
|
// 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: <script language=\"javascript\" type=\"text/javascript\">alert(\"Ha Ha Ha\");</script> in message fields." );
|
||||||
|
hints.add( "Enter this: <script>alert(\"document.cookie\");</script> in message fields." );
|
||||||
|
|
||||||
|
// Stage 2
|
||||||
|
hints.add( "Many scripts rely on the use of special characters such as: <" );
|
||||||
|
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())
|
||||||
|
{
|
||||||
|
switch (getStage(s))
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
instructions = "Stage " + getStage(s) + ": Execute a Stored Cross Site Scripting (XSS) attack.<br>" +
|
||||||
|
"For this exercise, your mission is to cause the application to serve a script of your making " +
|
||||||
|
" to some other user.";
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
instructions = "Stage " + getStage(s) + ": Block Stored XSS using Input Validation.<br>" +
|
||||||
|
"You will modify the application to perform input validation on the vulnerable input field " +
|
||||||
|
"you just exploited.";
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
instructions = "Stage " + getStage(s) + ": Execute a previously Stored Cross Site Scripting (XSS) attack.<br>" +
|
||||||
|
"The application is still vulnerable to scripts in the database. Trigger a pre-stored " +
|
||||||
|
"script by logging in as employee 'David' and viewing Bruce's profile.";
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
instructions = "Stage " + getStage(s) + ": Block Stored XSS using Output Encoding.<br>" +
|
||||||
|
"Encode data served from the database to the client so that any scripts are rendered harmless.";
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
instructions = "Stage " + getStage(s) + ": Execute a Reflected XSS attack.<br>" +
|
||||||
|
"Your goal here is to craft a link containing a script which the application will " +
|
||||||
|
"serve right back to any client that activates the link.";
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
instructions = "Stage " + getStage(s) + ": Block Reflected XSS using Input Validation.<br>" +
|
||||||
|
"Use the input validation techniques learned ealier in this lesson to close the vulnerability " +
|
||||||
|
"you just exploited.";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Illegal stage value
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return instructions;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected LessonAction getAction(String actionName)
|
||||||
|
{
|
||||||
|
return (LessonAction) 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAuthorized(WebSession s, int userId, String functionId)
|
||||||
|
{
|
||||||
|
//System.out.println("Checking authorization from " + getCurrentAction(s));
|
||||||
|
LessonAction action = (LessonAction) lessonFunctions.get(getCurrentAction(s));
|
||||||
|
return action.isAuthorized(s, userId, functionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getUserId(WebSession s) throws ParameterNotFoundException
|
||||||
|
{
|
||||||
|
LessonAction action = (LessonAction) lessonFunctions.get(getCurrentAction(s));
|
||||||
|
return action.getUserId(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUserName(WebSession s) throws ParameterNotFoundException
|
||||||
|
{
|
||||||
|
LessonAction action = (LessonAction) lessonFunctions.get(getCurrentAction(s));
|
||||||
|
return action.getUserName(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTemplatePage(WebSession s)
|
||||||
|
{
|
||||||
|
return JSP_PATH + LESSON_NAME + ".jsp";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPage(WebSession s)
|
||||||
|
{
|
||||||
|
String page = JSP_PATH + getCurrentAction(s) + ".jsp";
|
||||||
|
//System.out.println("Retrieved sub-view page for " + this.getClass().getName() + " of " + page);
|
||||||
|
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 (XSS)";
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,157 @@
|
|||||||
|
package org.owasp.webgoat.lessons.CrossSiteScripting;
|
||||||
|
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||||
|
import org.owasp.webgoat.lessons.DefaultLessonAction;
|
||||||
|
import org.owasp.webgoat.session.Employee;
|
||||||
|
import org.owasp.webgoat.session.ParameterNotFoundException;
|
||||||
|
import org.owasp.webgoat.session.UnauthenticatedException;
|
||||||
|
import org.owasp.webgoat.session.UnauthorizedException;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
|
||||||
|
public class EditProfile extends DefaultLessonAction
|
||||||
|
{
|
||||||
|
public EditProfile(AbstractLesson 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 = getUserId(s);
|
||||||
|
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 String getNextPage(WebSession s)
|
||||||
|
{
|
||||||
|
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 = ?";
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,209 @@
|
|||||||
|
package org.owasp.webgoat.lessons.CrossSiteScripting;
|
||||||
|
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||||
|
import org.owasp.webgoat.lessons.DefaultLessonAction;
|
||||||
|
import org.owasp.webgoat.lessons.LessonAction;
|
||||||
|
import org.owasp.webgoat.session.Employee;
|
||||||
|
import org.owasp.webgoat.session.ParameterNotFoundException;
|
||||||
|
import org.owasp.webgoat.session.UnauthenticatedException;
|
||||||
|
import org.owasp.webgoat.session.UnauthorizedException;
|
||||||
|
import org.owasp.webgoat.session.ValidationException;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
|
||||||
|
public class FindProfile extends DefaultLessonAction
|
||||||
|
{
|
||||||
|
private LessonAction chainedAction;
|
||||||
|
|
||||||
|
public FindProfile(AbstractLesson 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() + "." + CrossSiteScripting.USER_ID);
|
||||||
|
|
||||||
|
String searchName = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
searchName = getRequestParameter(s, CrossSiteScripting.SEARCHNAME);
|
||||||
|
|
||||||
|
Employee employee = null;
|
||||||
|
|
||||||
|
employee = findEmployeeProfile(s, userId, searchName);
|
||||||
|
if (employee == null)
|
||||||
|
{
|
||||||
|
setSessionAttribute(s, getLessonName() + "." + CrossSiteScripting.SEARCHRESULT_ATTRIBUTE_KEY,
|
||||||
|
"Employee " + searchName + " not found.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ValidationException e)
|
||||||
|
{
|
||||||
|
if (getStage(s) == 6)
|
||||||
|
{
|
||||||
|
s.setMessage("Congratulations. You have successfully completed this lesson");
|
||||||
|
getLesson().getLessonTracker( s ).setCompleted( true );
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getStage(s) == 5)
|
||||||
|
{
|
||||||
|
if (searchName.indexOf("<script>") > -1 && searchName.indexOf("alert") > -1 && searchName.indexOf("</script>") > -1)
|
||||||
|
{
|
||||||
|
s.setMessage( "Welcome to stage 6 - more input validation" );
|
||||||
|
setStage(s, 6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
{
|
||||||
|
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 )
|
||||||
|
{
|
||||||
|
s.setMessage( "Error finding employee profile" );
|
||||||
|
sqle.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
s.setMessage( "Error finding employee profile" );
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return profile;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean foundEmployee(WebSession s)
|
||||||
|
{
|
||||||
|
boolean found = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
getIntRequestAttribute(s, getLessonName() + "." + 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 patterns = new HashMap();
|
||||||
|
static
|
||||||
|
{
|
||||||
|
patterns.put(CrossSiteScripting.SEARCHNAME, Pattern.compile("[a-zA-Z ]{0,20}"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,356 @@
|
|||||||
|
package org.owasp.webgoat.lessons.CrossSiteScripting;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||||
|
import org.owasp.webgoat.lessons.DefaultLessonAction;
|
||||||
|
import org.owasp.webgoat.lessons.LessonAction;
|
||||||
|
import org.owasp.webgoat.session.Employee;
|
||||||
|
import org.owasp.webgoat.session.ParameterNotFoundException;
|
||||||
|
import org.owasp.webgoat.session.ParameterParser;
|
||||||
|
import org.owasp.webgoat.session.UnauthenticatedException;
|
||||||
|
import org.owasp.webgoat.session.UnauthorizedException;
|
||||||
|
import org.owasp.webgoat.session.ValidationException;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
|
||||||
|
public class UpdateProfile extends DefaultLessonAction
|
||||||
|
{
|
||||||
|
private LessonAction chainedAction;
|
||||||
|
|
||||||
|
public UpdateProfile(AbstractLesson 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() + "." + CrossSiteScripting.USER_ID);
|
||||||
|
|
||||||
|
int subjectId = s.getParser().getIntParameter(CrossSiteScripting.EMPLOYEE_ID, 0);
|
||||||
|
|
||||||
|
Employee employee = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
employee = parseEmployeeProfile(subjectId, s);
|
||||||
|
}
|
||||||
|
catch (ValidationException e)
|
||||||
|
{
|
||||||
|
if (getStage(s) == 2)
|
||||||
|
{
|
||||||
|
s.setMessage( "Welcome to stage 3 - demonstrate Stored XSS again" );
|
||||||
|
setStage(s, 3);
|
||||||
|
}
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new UnauthenticatedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Employee parseEmployeeProfile(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 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 = '" + employee.getFirstName() +
|
||||||
|
"', last_name = '" + employee.getLastName() +
|
||||||
|
"', ssn = '" + employee.getSsn() +
|
||||||
|
"', title = '" + employee.getTitle() +
|
||||||
|
"', phone = '" + employee.getPhoneNumber() +
|
||||||
|
"', address1 = '" + employee.getAddress1() +
|
||||||
|
"', address2 = '" + employee.getAddress2() +
|
||||||
|
"', manager = " + employee.getManager() +
|
||||||
|
", start_date = '" + employee.getStartDate() +
|
||||||
|
"', ccn = '" + employee.getCcn() +
|
||||||
|
"', ccn_limit = " + employee.getCcnLimit() +
|
||||||
|
// "', disciplined_date = '" + employee.getDisciplinaryActionDate() +
|
||||||
|
// "', disciplined_notes = '" + employee.getDisciplinaryActionNotes() +
|
||||||
|
", personal_description = '" + employee.getPersonalDescription() +
|
||||||
|
"' WHERE userid = " + subjectId;
|
||||||
|
//System.out.println("Query: " + query);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Statement answer_statement = WebSession.getConnection(s).createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY );
|
||||||
|
answer_statement.executeUpdate( query );
|
||||||
|
}
|
||||||
|
catch ( SQLException sqle )
|
||||||
|
{
|
||||||
|
s.setMessage( "Error updating employee profile" );
|
||||||
|
sqle.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
s.setMessage( "Error updating employee profile" );
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void doChangeEmployeeProfile_BACKUP(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 = '" + employee.getFirstName() +
|
||||||
|
"', last_name = '" + employee.getLastName() +
|
||||||
|
"', ssn = '" + employee.getSsn() +
|
||||||
|
"', title = '" + employee.getTitle() +
|
||||||
|
"', phone = '" + employee.getPhoneNumber() +
|
||||||
|
"', address1 = '" + employee.getAddress1() +
|
||||||
|
"', address2 = '" + employee.getAddress2() +
|
||||||
|
"', manager = " + employee.getManager() +
|
||||||
|
", start_date = '" + employee.getStartDate() +
|
||||||
|
"', ccn = '" + employee.getCcn() +
|
||||||
|
"', ccn_limit = " + employee.getCcnLimit() +
|
||||||
|
// "', disciplined_date = '" + employee.getDisciplinaryActionDate() +
|
||||||
|
// "', disciplined_notes = '" + employee.getDisciplinaryActionNotes() +
|
||||||
|
", personal_description = '" + employee.getPersonalDescription() +
|
||||||
|
"' WHERE userid = " + subjectId;
|
||||||
|
//System.out.println("Query: " + query);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Statement answer_statement = WebSession.getConnection(s).createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY );
|
||||||
|
answer_statement.executeUpdate( query );
|
||||||
|
}
|
||||||
|
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(WebSession s, int userId, Employee employee)
|
||||||
|
throws UnauthorizedException
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// FIXME: Cannot choose the id because we cannot guarantee uniqueness
|
||||||
|
String query = "INSERT INTO employee VALUES ( max(userid)+1, '"
|
||||||
|
+ employee.getFirstName() + "','"
|
||||||
|
+ employee.getLastName() + "','"
|
||||||
|
+ employee.getSsn() + "','"
|
||||||
|
+ employee.getFirstName().toLowerCase() + "','"
|
||||||
|
+ employee.getTitle() + "','"
|
||||||
|
+ employee.getPhoneNumber() + "','"
|
||||||
|
+ employee.getAddress1() + "','"
|
||||||
|
+ employee.getAddress2() + "',"
|
||||||
|
+ employee.getManager() + ",'"
|
||||||
|
+ employee.getStartDate() + "',"
|
||||||
|
+ employee.getSalary() + ",'"
|
||||||
|
+ employee.getCcn() + "',"
|
||||||
|
+ employee.getCcnLimit() + ",'"
|
||||||
|
+ employee.getDisciplinaryActionDate() + "','"
|
||||||
|
+ employee.getDisciplinaryActionNotes() + "','"
|
||||||
|
+ employee.getPersonalDescription()
|
||||||
|
+ "')";
|
||||||
|
|
||||||
|
//System.out.println("Query: " + query);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Statement statement = WebSession.getConnection(s).createStatement();
|
||||||
|
statement.executeUpdate(query);
|
||||||
|
}
|
||||||
|
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
|
||||||
|
String query = "INSERT INTO employee VALUES ( max(userid)+1, '"
|
||||||
|
+ employee.getFirstName() + "','"
|
||||||
|
+ employee.getLastName() + "','"
|
||||||
|
+ employee.getSsn() + "','"
|
||||||
|
+ employee.getFirstName().toLowerCase() + "','"
|
||||||
|
+ employee.getTitle() + "','"
|
||||||
|
+ employee.getPhoneNumber() + "','"
|
||||||
|
+ employee.getAddress1() + "','"
|
||||||
|
+ employee.getAddress2() + "',"
|
||||||
|
+ employee.getManager() + ",'"
|
||||||
|
+ employee.getStartDate() + "',"
|
||||||
|
+ employee.getSalary() + ",'"
|
||||||
|
+ employee.getCcn() + "',"
|
||||||
|
+ employee.getCcnLimit() + ",'"
|
||||||
|
+ employee.getDisciplinaryActionDate() + "','"
|
||||||
|
+ employee.getDisciplinaryActionNotes() + "','"
|
||||||
|
+ employee.getPersonalDescription()
|
||||||
|
+ "')";
|
||||||
|
|
||||||
|
//System.out.println("Query: " + query);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Statement statement = WebSession.getConnection(s).createStatement();
|
||||||
|
statement.executeUpdate(query);
|
||||||
|
}
|
||||||
|
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.
|
||||||
|
*
|
||||||
|
* @param parameter
|
||||||
|
* @param pattern
|
||||||
|
* @return
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,203 @@
|
|||||||
|
package org.owasp.webgoat.lessons.CrossSiteScripting;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||||
|
import org.owasp.webgoat.lessons.DefaultLessonAction;
|
||||||
|
import org.owasp.webgoat.session.Employee;
|
||||||
|
import org.owasp.webgoat.session.ParameterNotFoundException;
|
||||||
|
import org.owasp.webgoat.session.UnauthenticatedException;
|
||||||
|
import org.owasp.webgoat.session.UnauthorizedException;
|
||||||
|
import org.owasp.webgoat.session.ValidationException;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
|
||||||
|
public class ViewProfile extends DefaultLessonAction
|
||||||
|
{
|
||||||
|
public ViewProfile(AbstractLesson lesson, String lessonName, 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() + "." + 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 String getNextPage(WebSession s)
|
||||||
|
{
|
||||||
|
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 = " + 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 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)
|
||||||
|
{
|
||||||
|
switch (getStage(s))
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
String address1 = employee.getAddress1().toLowerCase();
|
||||||
|
if (address1.indexOf("<script>") > -1 && address1.indexOf("alert") > -1 && address1.indexOf("</script>") > -1)
|
||||||
|
{
|
||||||
|
s.setMessage( "Welcome to stage 2 - implement input validation" );
|
||||||
|
setStage(s, 2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
String address2 = employee.getAddress1().toLowerCase();
|
||||||
|
if (address2.indexOf("<script>") > -1 && address2.indexOf("alert") > -1 && address2.indexOf("</script>") > -1)
|
||||||
|
{
|
||||||
|
s.setMessage( "Welcome to stage 4 - implement output encoding" );
|
||||||
|
setStage(s, 4);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
if (employee.getAddress1().toLowerCase().indexOf("<") > -1)
|
||||||
|
{
|
||||||
|
s.setMessage( "Welcome to stage 5 - demonstrate reflected XSS" );
|
||||||
|
setStage(s, 5);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
228
webgoat/main/project/org/owasp/webgoat/lessons/DOS_Login.java
Normal file
228
webgoat/main/project/org/owasp/webgoat/lessons/DOS_Login.java
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
package org.owasp.webgoat.lessons;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.ResultSetMetaData;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
import org.apache.ecs.ElementContainer;
|
||||||
|
import org.apache.ecs.StringElement;
|
||||||
|
import org.apache.ecs.html.H1;
|
||||||
|
import org.apache.ecs.html.H2;
|
||||||
|
import org.apache.ecs.html.Input;
|
||||||
|
import org.apache.ecs.html.P;
|
||||||
|
import org.apache.ecs.html.TD;
|
||||||
|
import org.apache.ecs.html.TR;
|
||||||
|
import org.apache.ecs.html.Table;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.session.DatabaseUtilities;
|
||||||
|
import org.owasp.webgoat.session.ECSFactory;
|
||||||
|
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 org.owasp.webgoat.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
|
||||||
|
*/
|
||||||
|
public class DOS_Login extends LessonAdapter
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Description of the Field
|
||||||
|
*/
|
||||||
|
protected final static String PASSWORD = "Password";
|
||||||
|
/**
|
||||||
|
* Description of the Field
|
||||||
|
*/
|
||||||
|
protected final static String USERNAME = "Username";
|
||||||
|
|
||||||
|
private static Connection connection = null;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
{
|
||||||
|
String username = "";
|
||||||
|
String password = "";
|
||||||
|
username = s.getParser().getRawParameter( USERNAME );
|
||||||
|
password = s.getParser().getRawParameter( PASSWORD );
|
||||||
|
|
||||||
|
// don;t allow user name from other lessons. it would be too simple.
|
||||||
|
if ( username.equals( "jeff" ) || username.equals( "dave" ) )
|
||||||
|
{
|
||||||
|
ec.addElement( new H2( "Login Failed: 'jeff' and 'dave' are not valid for this lesson" ));
|
||||||
|
return ( ec.addElement( makeLogin( s ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Check if the login is valid
|
||||||
|
if ( connection == null )
|
||||||
|
{
|
||||||
|
connection = DatabaseUtilities.makeConnection( s );
|
||||||
|
}
|
||||||
|
|
||||||
|
String query = "SELECT * FROM user_system_data WHERE user_name = '" + username + "' and password = '" + password + "'" ;
|
||||||
|
ec.addElement( new StringElement( query ));
|
||||||
|
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 user they succeeded
|
||||||
|
if ( results.getRow() >= 1 )
|
||||||
|
{
|
||||||
|
// Make sure this isn't data from an sql injected query.
|
||||||
|
if ( results.getString(2).equals( username ) && results.getString(3).equals( password ) )
|
||||||
|
{
|
||||||
|
String insertData1 = "INSERT INTO user_login VALUES ( '" + username + "', '" + s.getUserName() + "' )";
|
||||||
|
statement.executeUpdate( insertData1 );
|
||||||
|
}
|
||||||
|
// check the total count of logins
|
||||||
|
query = "SELECT * FROM user_login WHERE webgoat_user = '" + s.getUserName() + "'" ;
|
||||||
|
results = statement.executeQuery( query );
|
||||||
|
results.last();
|
||||||
|
// If they get back more than one user they succeeded
|
||||||
|
if ( results.getRow() >= 3 )
|
||||||
|
{
|
||||||
|
makeSuccess( s );
|
||||||
|
String deleteData1 = "DELETE from user_login WHERE webgoat_user = '" + s.getUserName() + "'" ;
|
||||||
|
statement.executeUpdate( deleteData1 );
|
||||||
|
return( new H1("Congratulations! Lesson Completed" ));
|
||||||
|
}
|
||||||
|
|
||||||
|
ec.addElement( new H2( "Login Succeeded: Total login count: " + results.getRow() ));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ec.addElement( new H2( "Login Failed"));
|
||||||
|
// check the total count of logins
|
||||||
|
query = "SELECT * FROM user_login WHERE webgoat_user = '" + s.getUserName() + "'" ;
|
||||||
|
results = statement.executeQuery( query );
|
||||||
|
results.last();
|
||||||
|
ec.addElement( new H2( "Successfull login count: " + results.getRow() ));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( SQLException sqle )
|
||||||
|
{
|
||||||
|
ec.addElement( new P().addElement( sqle.getMessage() ) );
|
||||||
|
sqle.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
s.setMessage( "Error generating " + this.getClass().getName() );
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( ec.addElement( makeLogin( s ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the category attribute of the WeakAuthenticationCookie object
|
||||||
|
*
|
||||||
|
* @return The category value
|
||||||
|
*/
|
||||||
|
protected Category getDefaultCategory()
|
||||||
|
{
|
||||||
|
return AbstractLesson.A9;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the hints attribute of the CookieScreen object
|
||||||
|
*
|
||||||
|
* @return The hints value
|
||||||
|
*/
|
||||||
|
protected List getHints()
|
||||||
|
{
|
||||||
|
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 "dont_care' or '1' = '1" 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();
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,362 @@
|
|||||||
|
package org.owasp.webgoat.lessons;
|
||||||
|
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.lessons.RoleBasedAccessControl.RoleBasedAccessControl;
|
||||||
|
import org.owasp.webgoat.session.ParameterNotFoundException;
|
||||||
|
import org.owasp.webgoat.session.UnauthenticatedException;
|
||||||
|
import org.owasp.webgoat.session.UnauthorizedException;
|
||||||
|
import org.owasp.webgoat.session.ValidationException;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
|
||||||
|
public abstract class DefaultLessonAction implements LessonAction
|
||||||
|
{
|
||||||
|
// FIXME: We could parse this class name to get defaults for these fields.
|
||||||
|
private String lessonName;
|
||||||
|
private String actionName;
|
||||||
|
|
||||||
|
private AbstractLesson lesson;
|
||||||
|
|
||||||
|
public DefaultLessonAction(AbstractLesson lesson, String lessonName, String actionName)
|
||||||
|
{
|
||||||
|
this.lesson = lesson;
|
||||||
|
this.lessonName = lessonName;
|
||||||
|
this.actionName = actionName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleRequest( WebSession s )
|
||||||
|
throws ParameterNotFoundException, UnauthenticatedException, UnauthorizedException, ValidationException
|
||||||
|
{
|
||||||
|
getLesson().setCurrentAction(s, getActionName());
|
||||||
|
|
||||||
|
if (isAuthenticated(s))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new UnauthenticatedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract String getNextPage(WebSession s);
|
||||||
|
|
||||||
|
public AbstractLesson getLesson()
|
||||||
|
{
|
||||||
|
return lesson;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLessonName()
|
||||||
|
{
|
||||||
|
return lessonName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getActionName()
|
||||||
|
{
|
||||||
|
return actionName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSessionAttribute(WebSession s, String name, Object value)
|
||||||
|
{
|
||||||
|
s.getRequest().getSession().setAttribute(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRequestAttribute(WebSession s, String name, Object value)
|
||||||
|
{
|
||||||
|
s.getRequest().setAttribute(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeSessionAttribute(WebSession s, String name)
|
||||||
|
{
|
||||||
|
s.getRequest().getSession().removeAttribute(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getSessionAttribute(WebSession s, String name) throws ParameterNotFoundException
|
||||||
|
{
|
||||||
|
String value = (String) s.getRequest().getSession().getAttribute(name);
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
throw new ParameterNotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean getBooleanSessionAttribute(WebSession s, String name) throws ParameterNotFoundException
|
||||||
|
{
|
||||||
|
boolean value = false;
|
||||||
|
|
||||||
|
Object attribute = s.getRequest().getSession().getAttribute(name);
|
||||||
|
if (attribute == null)
|
||||||
|
{
|
||||||
|
throw new ParameterNotFoundException();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//System.out.println("Attribute " + name + " is of type " + s.getRequest().getSession().getAttribute(name).getClass().getName());
|
||||||
|
//System.out.println("Attribute value: " + s.getRequest().getSession().getAttribute(name));
|
||||||
|
value = ((Boolean) attribute).booleanValue();
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int getIntSessionAttribute(WebSession s, String name) throws ParameterNotFoundException
|
||||||
|
{
|
||||||
|
int value = -1;
|
||||||
|
String ss = (String) s.getRequest().getSession().getAttribute(name);
|
||||||
|
if (ss == null)
|
||||||
|
{
|
||||||
|
throw new ParameterNotFoundException();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
value = Integer.parseInt(ss);
|
||||||
|
}
|
||||||
|
catch (NumberFormatException nfe)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getRequestAttribute(WebSession s, String name) throws ParameterNotFoundException
|
||||||
|
{
|
||||||
|
String value = (String) s.getRequest().getAttribute(name);
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
throw new ParameterNotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int getIntRequestAttribute(WebSession s, String name) throws ParameterNotFoundException
|
||||||
|
{
|
||||||
|
int value = -1;
|
||||||
|
String ss = (String) s.getRequest().getAttribute(name);
|
||||||
|
if (ss == null)
|
||||||
|
{
|
||||||
|
throw new ParameterNotFoundException();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
value = Integer.parseInt(ss);
|
||||||
|
}
|
||||||
|
catch (NumberFormatException nfe)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getUserId(WebSession s) throws ParameterNotFoundException
|
||||||
|
{
|
||||||
|
return getIntSessionAttribute(s, getLessonName() + "." + RoleBasedAccessControl.USER_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUserName(WebSession s) throws ParameterNotFoundException
|
||||||
|
{
|
||||||
|
String name = null;
|
||||||
|
|
||||||
|
int employeeId = getUserId(s);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String query = "SELECT first_name FROM employee WHERE userid = " + employeeId;
|
||||||
|
|
||||||
|
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())
|
||||||
|
name = answer_results.getString("first_name");
|
||||||
|
}
|
||||||
|
catch ( SQLException sqle )
|
||||||
|
{
|
||||||
|
s.setMessage( "Error getting user name" );
|
||||||
|
sqle.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
s.setMessage( "Error getting user name" );
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean requiresAuthentication()
|
||||||
|
{
|
||||||
|
// Default to true
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAuthenticated(WebSession s)
|
||||||
|
{
|
||||||
|
boolean authenticated = false;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
authenticated = getBooleanSessionAttribute(s, getLessonName() + ".isAuthenticated");
|
||||||
|
}
|
||||||
|
catch (ParameterNotFoundException e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
return authenticated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAuthorized(WebSession s, int employeeId, String functionId)
|
||||||
|
{
|
||||||
|
String employer_id = (String)s.getRequest().getSession().getAttribute(getLessonName() + "." + RoleBasedAccessControl.USER_ID);
|
||||||
|
//System.out.println("Authorizing " + employeeId + " for use of function: " + functionId + " having USER_ID = " + employer_id );
|
||||||
|
boolean authorized = false;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String query = "SELECT * FROM auth WHERE auth.role in (SELECT roles.role FROM roles WHERE userid = " + employeeId + ") and functionid = '" + functionId + "'";
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Statement answer_statement = WebSession.getConnection(s).createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY );
|
||||||
|
ResultSet answer_results = answer_statement.executeQuery( query );
|
||||||
|
authorized = answer_results.first();
|
||||||
|
|
||||||
|
/* User is validated for function, but can the user perform that function on the specified user? */
|
||||||
|
if(authorized)
|
||||||
|
{
|
||||||
|
query = "SELECT * FROM ownership WHERE employer_id = " + Integer.parseInt(employer_id) +
|
||||||
|
" AND employee_id = " + employeeId;
|
||||||
|
answer_statement = WebSession.getConnection(s).createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY );
|
||||||
|
answer_results = answer_statement.executeQuery( query );
|
||||||
|
authorized = answer_results.first();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( SQLException sqle )
|
||||||
|
{
|
||||||
|
s.setMessage( "Error authorizing" );
|
||||||
|
sqle.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
s.setMessage( "Error authorizing" );
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update lesson status if necessary.
|
||||||
|
if (getStage(s) == 2)
|
||||||
|
{
|
||||||
|
//System.out.println("Checking for stage 2 completion handling action " + functionId);
|
||||||
|
if (lessonName.equals("RoleBasedAccessControl") && !calledFromJsp("isAuthorized") && !authorized &&
|
||||||
|
functionId.equals(RoleBasedAccessControl.DELETEPROFILE_ACTION))
|
||||||
|
{
|
||||||
|
s.setMessage( "Welcome to stage 3 -- exploiting the data layer" );
|
||||||
|
setStage(s, 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//System.out.println("isAuthorized() exit stage: " + getStage(s));
|
||||||
|
|
||||||
|
//System.out.println("Authorized? " + authorized);
|
||||||
|
return authorized;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAuthorizedForEmployee(WebSession s, int userId, int employeeId)
|
||||||
|
{
|
||||||
|
//System.out.println("Authorizing " + userId + " for access to employee: " + employeeId);
|
||||||
|
boolean authorized = false;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String query = "SELECT * FROM ownership WHERE employer_id = ? AND employee_id = ?";
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
PreparedStatement answer_statement = WebSession.getConnection(s).prepareStatement( query,
|
||||||
|
ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY );
|
||||||
|
answer_statement.setInt(1, userId);
|
||||||
|
answer_statement.setInt(2, employeeId);
|
||||||
|
ResultSet answer_results = answer_statement.executeQuery();
|
||||||
|
authorized = answer_results.first();
|
||||||
|
}
|
||||||
|
catch ( SQLException sqle )
|
||||||
|
{
|
||||||
|
s.setMessage( "Error authorizing" );
|
||||||
|
sqle.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
s.setMessage( "Error authorizing" );
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update lesson status if necessary.
|
||||||
|
if (getStage(s) == 4)
|
||||||
|
{
|
||||||
|
//System.out.println("Checking for stage 4 completion");
|
||||||
|
if (lessonName.equals("RoleBasedAccessControl") && !calledFromJsp("isAuthorized") && !authorized)
|
||||||
|
{
|
||||||
|
s.setMessage("Congratulations. You have successfully completed this lesson.");
|
||||||
|
getLesson().getLessonTracker( s ).setCompleted( true );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return authorized;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Determine if the calling method was in turn called from a compiled JSP class.
|
||||||
|
* This skips calling methods that start with the given string (e.g. isAuthorized).
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private boolean calledFromJsp(String caller)
|
||||||
|
{
|
||||||
|
boolean fromJsp = false;
|
||||||
|
|
||||||
|
Throwable throwable = new Throwable();
|
||||||
|
StackTraceElement[] trace = throwable.getStackTrace();
|
||||||
|
int callerIndex = 0;
|
||||||
|
boolean done = false;
|
||||||
|
for (int i = 1; i < trace.length && !done; i++)
|
||||||
|
{
|
||||||
|
String callerMethodName = trace[i].getMethodName();
|
||||||
|
//System.out.println("calledFromJsp() callee (" + i + ") is " + callerMethodName);
|
||||||
|
if (!callerMethodName.startsWith(caller)) // Yikes what a hack!
|
||||||
|
{
|
||||||
|
callerIndex = i;
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String callerClassName = trace[callerIndex].getClassName();
|
||||||
|
//System.out.println("calledFromJsp() callee class (" + (callerIndex) + ") is " + callerClassName);
|
||||||
|
|
||||||
|
if (callerClassName.endsWith("_jsp"))
|
||||||
|
fromJsp = true;
|
||||||
|
|
||||||
|
//System.out.println("calledFromJsp() result: " + fromJsp);
|
||||||
|
return fromJsp;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setStage(WebSession s, int stage)
|
||||||
|
{
|
||||||
|
getLesson().setStage(s, stage);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int getStage(WebSession s)
|
||||||
|
{
|
||||||
|
return getLesson().getStage(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return getActionName();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
1185
webgoat/main/project/org/owasp/webgoat/lessons/Encoding.java
Normal file
1185
webgoat/main/project/org/owasp/webgoat/lessons/Encoding.java
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,157 @@
|
|||||||
|
package org.owasp.webgoat.lessons;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
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 org.owasp.webgoat.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
|
||||||
|
*/
|
||||||
|
public class FailOpenAuthentication extends WeakAuthenticationCookie
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param s Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
protected Element createContent( WebSession s )
|
||||||
|
{
|
||||||
|
boolean logout = s.getParser().getBooleanParameter( LOGOUT, false );
|
||||||
|
|
||||||
|
if ( logout )
|
||||||
|
{
|
||||||
|
s.setMessage( "Goodbye!" );
|
||||||
|
s.eatCookies();
|
||||||
|
|
||||||
|
return ( makeLogin( s ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
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." );
|
||||||
|
|
||||||
|
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 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the category attribute of the FailOpenAuthentication object
|
||||||
|
*
|
||||||
|
* @return The category value
|
||||||
|
*/
|
||||||
|
public Category getDefaultCategory()
|
||||||
|
{
|
||||||
|
return AbstractLesson.A7;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the hints attribute of the AuthenticateScreen object
|
||||||
|
*
|
||||||
|
* @return The hints value
|
||||||
|
*/
|
||||||
|
protected List getHints()
|
||||||
|
{
|
||||||
|
List hints = new ArrayList();
|
||||||
|
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 instructions attribute of the FailOpenAuthentication object
|
||||||
|
*
|
||||||
|
* @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 ( "How to Bypass a Fail Open Authentication Scheme" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,86 @@
|
|||||||
|
package org.owasp.webgoat.lessons;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
import org.apache.ecs.StringElement;
|
||||||
|
|
||||||
|
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 org.owasp.webgoat.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
|
||||||
|
*/
|
||||||
|
public class ForcedBrowsing extends LessonAdapter
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param s Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
protected Element createContent( WebSession 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 AbstractLesson.A10;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the hints attribute of the HelloScreen object
|
||||||
|
*
|
||||||
|
* @return The hints value
|
||||||
|
*/
|
||||||
|
public List getHints()
|
||||||
|
{
|
||||||
|
List hints = new ArrayList();
|
||||||
|
hints.add( "Lesson Hint 1" );
|
||||||
|
hints.add( "Lesson Hint 2" );
|
||||||
|
|
||||||
|
return hints;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private final static Integer DEFAULT_RANKING = new Integer(15);
|
||||||
|
|
||||||
|
protected Integer getDefaultRanking()
|
||||||
|
{
|
||||||
|
return DEFAULT_RANKING;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Gets the title attribute of the HelloScreen object
|
||||||
|
*
|
||||||
|
* @return The title value
|
||||||
|
*/
|
||||||
|
public String getTitle()
|
||||||
|
{
|
||||||
|
return ( "Forced Browsing" );
|
||||||
|
}
|
||||||
|
|
||||||
|
public Element getCredits()
|
||||||
|
{
|
||||||
|
return new StringElement("This screen created by: Your name could go here");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,306 @@
|
|||||||
|
package org.owasp.webgoat.lessons;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
import org.apache.ecs.ElementContainer;
|
||||||
|
import org.apache.ecs.StringElement;
|
||||||
|
import org.apache.ecs.html.B;
|
||||||
|
import org.apache.ecs.html.BR;
|
||||||
|
import org.apache.ecs.html.H1;
|
||||||
|
import org.apache.ecs.html.IMG;
|
||||||
|
import org.apache.ecs.html.Input;
|
||||||
|
import org.apache.ecs.html.TD;
|
||||||
|
import org.apache.ecs.html.TH;
|
||||||
|
import org.apache.ecs.html.TR;
|
||||||
|
import org.apache.ecs.html.Table;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.session.ECSFactory;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2002 Free Software Foundation developed under the custody of the Open Web
|
||||||
|
* Application Security Project (http://www.owasp.org) This software package org.owasp.webgoat.is published by OWASP
|
||||||
|
* under the GPL. You should read and accept the LICENSE before you use, modify and/or redistribute
|
||||||
|
* this software.
|
||||||
|
*
|
||||||
|
* @author Eric Sheridan <a href="http://www.aspectsecurity.com">Aspect Security</a>
|
||||||
|
* @created December 18, 2005
|
||||||
|
*/
|
||||||
|
public class ForgotPassword extends LessonAdapter
|
||||||
|
{
|
||||||
|
final static IMG ASPECT_LOGO = new IMG( "images/logos/aspect.jpg" ).setAlt( "Aspect Security" ).setBorder( 0 ).setHspace( 0 ).setVspace( 0 );
|
||||||
|
private final static String USERNAME = "Username";
|
||||||
|
private static String USERNAME_RESPONSE = "";
|
||||||
|
private final static String COLOR = "Color";
|
||||||
|
private static String COLOR_RESPONSE = "";
|
||||||
|
private static int STAGE = 1;
|
||||||
|
private final static HashMap<String, String> USERS = new HashMap<String, String>();
|
||||||
|
private final static HashMap<String, String> COLORS = new HashMap<String, String>();
|
||||||
|
|
||||||
|
private void populateTables()
|
||||||
|
{
|
||||||
|
USERS.put("admin", "2275$starBo0rn3");
|
||||||
|
USERS.put("jeff", "(_I_)illia(V)s");
|
||||||
|
USERS.put("dave", "\\V/ich3r$");
|
||||||
|
USERS.put("intern", "H3yn0w");
|
||||||
|
USERS.put("webgoat", "webgoat");
|
||||||
|
|
||||||
|
COLORS.put("admin", "green");
|
||||||
|
COLORS.put("jeff", "orange");
|
||||||
|
COLORS.put("dave", "purple");
|
||||||
|
COLORS.put("intern", "yellow");
|
||||||
|
COLORS.put("webgoat", "red");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Element doStage1(WebSession s)
|
||||||
|
{
|
||||||
|
ElementContainer ec = new ElementContainer();
|
||||||
|
|
||||||
|
ec.addElement( new BR().addElement( new H1().addElement( "Webgoat Password Recovery " )));
|
||||||
|
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("Please input your username. 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();
|
||||||
|
tr.addElement( new TD().addElement(" ").setColSpan(2));
|
||||||
|
t.addElement( tr );
|
||||||
|
|
||||||
|
TR row1 = new TR();
|
||||||
|
row1.addElement( new TD( new B( new StringElement( "*User Name: " ) ) ));
|
||||||
|
|
||||||
|
Input input1 = new Input( Input.TEXT, USERNAME, "" );
|
||||||
|
row1.addElement( new TD( input1 ) );
|
||||||
|
t.addElement( row1 );
|
||||||
|
|
||||||
|
Element b = ECSFactory.makeButton( "Submit" );
|
||||||
|
t.addElement( new TR( new TD( b ) ) );
|
||||||
|
ec.addElement( t );
|
||||||
|
|
||||||
|
return ( ec );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
protected Element doStage2(WebSession s)
|
||||||
|
{
|
||||||
|
ElementContainer ec = new ElementContainer();
|
||||||
|
|
||||||
|
ec.addElement( new H1().addElement( "Webgoat Password Recovery " ));
|
||||||
|
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("Secret Question: What is your favorite color?")
|
||||||
|
.setColSpan(2).setAlign("left"));
|
||||||
|
t.addElement( tr );
|
||||||
|
|
||||||
|
tr = new TR();
|
||||||
|
tr.addElement( new TD().addElement("*Required Fields").setWidth("20%"));
|
||||||
|
t.addElement( tr );
|
||||||
|
|
||||||
|
tr = new TR();
|
||||||
|
tr.addElement( new TD().addElement(" ").setColSpan(2));
|
||||||
|
t.addElement( tr );
|
||||||
|
|
||||||
|
TR row1 = new TR();
|
||||||
|
row1.addElement( new TD( new B( new StringElement( "*Answer: " ) ) ));
|
||||||
|
|
||||||
|
Input input1 = new Input( Input.TEXT, COLOR, "" );
|
||||||
|
row1.addElement( new TD( input1 ) );
|
||||||
|
t.addElement( row1 );
|
||||||
|
|
||||||
|
Element b = ECSFactory.makeButton( "Submit" );
|
||||||
|
t.addElement( new TR( new TD( b ) ) );
|
||||||
|
ec.addElement( t );
|
||||||
|
|
||||||
|
return ( ec );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Element doStage3(WebSession s)
|
||||||
|
{
|
||||||
|
ElementContainer ec = new ElementContainer();
|
||||||
|
|
||||||
|
ec.addElement( new H1().addElement( "Webgoat Password Recovery " ));
|
||||||
|
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("For security reasons, please change your password immediately.")
|
||||||
|
.setColSpan(2).setAlign("left"));
|
||||||
|
t.addElement( tr );
|
||||||
|
|
||||||
|
tr = new TR();
|
||||||
|
tr.addElement( new TD().addElement( new BR().addElement( new B().addElement( new StringElement("Results:")))).setAlign("left"));
|
||||||
|
t.addElement ( tr );
|
||||||
|
|
||||||
|
tr = new TR();
|
||||||
|
tr.addElement( new TD().addElement( new StringElement("Username: " + USERNAME_RESPONSE)));
|
||||||
|
t.addElement ( tr );
|
||||||
|
|
||||||
|
tr = new TR();
|
||||||
|
tr.addElement(new TD().addElement( new StringElement("Color: " + COLOR_RESPONSE)));
|
||||||
|
t.addElement ( tr );
|
||||||
|
|
||||||
|
tr = new TR();
|
||||||
|
tr.addElement(new TD().addElement( new StringElement("Password: " + USERS.get(USERNAME_RESPONSE).toString())));
|
||||||
|
t.addElement(tr);
|
||||||
|
|
||||||
|
ec.addElement(t);
|
||||||
|
|
||||||
|
if(USERNAME_RESPONSE.equals("admin") && COLOR_RESPONSE.equals("green"))
|
||||||
|
{
|
||||||
|
makeSuccess(s);
|
||||||
|
}
|
||||||
|
else if(!USERNAME_RESPONSE.equals("webgoat") && USERS.containsKey(USERNAME_RESPONSE))
|
||||||
|
{
|
||||||
|
s.setMessage("Close. Now try to get the password of a privileged account.");
|
||||||
|
}
|
||||||
|
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();
|
||||||
|
String username = "";
|
||||||
|
String color = "";
|
||||||
|
|
||||||
|
color = s.getParser().getStringParameter(COLOR, "");
|
||||||
|
|
||||||
|
if(color.length() > 0)
|
||||||
|
STAGE = 2;
|
||||||
|
else
|
||||||
|
STAGE = 1;
|
||||||
|
|
||||||
|
|
||||||
|
if(USERS.size() == 0)
|
||||||
|
{
|
||||||
|
populateTables();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(STAGE == 2)
|
||||||
|
{
|
||||||
|
color = s.getParser().getStringParameter(COLOR, "");
|
||||||
|
|
||||||
|
if(COLORS.get(USERNAME_RESPONSE).equals(color))
|
||||||
|
{
|
||||||
|
STAGE = 1;
|
||||||
|
COLOR_RESPONSE = color;
|
||||||
|
ec.addElement(doStage3(s));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s.setMessage("Incorrect response for " + USERNAME_RESPONSE + ". Please try again!");
|
||||||
|
ec.addElement(doStage2(s));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(STAGE == 1)
|
||||||
|
{
|
||||||
|
username = s.getParser().getStringParameter(USERNAME, "");
|
||||||
|
|
||||||
|
if(USERS.containsKey(username))
|
||||||
|
{
|
||||||
|
STAGE = 2;
|
||||||
|
USERNAME_RESPONSE = username;
|
||||||
|
ec.addElement(doStage2(s));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(username.length() > 0)
|
||||||
|
s.setMessage("Not a valid username. Please try again");
|
||||||
|
ec.addElement(doStage1(s));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ec.addElement(doStage1(s));
|
||||||
|
STAGE = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ec;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the category attribute of the ForgotPassword object
|
||||||
|
*
|
||||||
|
* @return The category value
|
||||||
|
*/
|
||||||
|
protected Category getDefaultCategory()
|
||||||
|
{
|
||||||
|
|
||||||
|
return AbstractLesson.A3;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the hints attribute of the HelloScreen object
|
||||||
|
*
|
||||||
|
* @return The hints value
|
||||||
|
*/
|
||||||
|
public List getHints()
|
||||||
|
{
|
||||||
|
List<String> hints = new ArrayList<String>();
|
||||||
|
hints.add( "There is no lock out policy in place, brute force your way!" );
|
||||||
|
hints.add( "Try using usernames you might encounter throughout WebGoat." );
|
||||||
|
hints.add( "There are only so many possible colors, can you guess one?" );
|
||||||
|
hints.add( "The administrative account is \"admin\"" );
|
||||||
|
|
||||||
|
return hints;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private final static Integer DEFAULT_RANKING = new Integer(15);
|
||||||
|
|
||||||
|
protected Integer getDefaultRanking()
|
||||||
|
{
|
||||||
|
return DEFAULT_RANKING;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the title attribute of the HelloScreen object
|
||||||
|
*
|
||||||
|
* @return The title value
|
||||||
|
*/
|
||||||
|
public String getTitle()
|
||||||
|
{
|
||||||
|
return ( "Forgot Password" );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Element getCredits()
|
||||||
|
{
|
||||||
|
return super.getCustomCredits("The Intern", ASPECT_LOGO);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,192 @@
|
|||||||
|
package org.owasp.webgoat.lessons;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
import org.apache.ecs.ElementContainer;
|
||||||
|
import org.apache.ecs.html.B;
|
||||||
|
import org.apache.ecs.html.BR;
|
||||||
|
import org.apache.ecs.html.Center;
|
||||||
|
import org.apache.ecs.html.H1;
|
||||||
|
import org.apache.ecs.html.Input;
|
||||||
|
import org.apache.ecs.html.P;
|
||||||
|
import org.apache.ecs.html.TD;
|
||||||
|
import org.apache.ecs.html.TH;
|
||||||
|
import org.apache.ecs.html.TR;
|
||||||
|
import org.apache.ecs.html.Table;
|
||||||
|
import org.owasp.webgoat.session.ECSFactory;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2002 Free Software Foundation developed under the custody of the Open Web
|
||||||
|
* Application Security Project (http://www.owasp.org) This software package org.owasp.webgoat.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
|
||||||
|
*/
|
||||||
|
public class HiddenFieldTampering extends LessonAdapter
|
||||||
|
{
|
||||||
|
private final static String PRICE = "Price";
|
||||||
|
|
||||||
|
private final static String PRICE_TV = "2999.99";
|
||||||
|
|
||||||
|
private final static String PRICE_TV_HACKED = "9.99";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for the HiddenFieldScreen object
|
||||||
|
*/
|
||||||
|
public HiddenFieldTampering() { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
{
|
||||||
|
String price = s.getParser().getRawParameter( PRICE, PRICE_TV );
|
||||||
|
float quantity = s.getParser().getFloatParameter("QTY", 1.0f);
|
||||||
|
float total = quantity * Float.parseFloat(price);
|
||||||
|
|
||||||
|
if ( price.equals(PRICE_TV) )
|
||||||
|
{
|
||||||
|
ec.addElement( new Center().addElement( new H1().addElement( "Shopping Cart " )));
|
||||||
|
ec.addElement( new BR() );
|
||||||
|
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("56 inch HDTV (model KTV-551)"));
|
||||||
|
tr.addElement( new TD().addElement(PRICE_TV).setAlign("right"));
|
||||||
|
tr.addElement( new TD().addElement(new Input( Input.TEXT, "QTY", 1 )).setAlign( "right" ));
|
||||||
|
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( "$" + total ));
|
||||||
|
tr.addElement( new TD().addElement( ECSFactory.makeButton( "Update Cart" )));
|
||||||
|
tr.addElement( new TD().addElement( ECSFactory.makeButton( "Purchase" )));
|
||||||
|
t.addElement( tr );
|
||||||
|
|
||||||
|
ec.addElement(t);
|
||||||
|
|
||||||
|
Input input = new Input( Input.HIDDEN, PRICE, PRICE_TV );
|
||||||
|
ec.addElement( input );
|
||||||
|
ec.addElement( new BR() );
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( !price.toString().equals( PRICE_TV ) )
|
||||||
|
{
|
||||||
|
makeSuccess( s );
|
||||||
|
}
|
||||||
|
|
||||||
|
ec.addElement( new P().addElement( "Your total price is:" ) );
|
||||||
|
ec.addElement( new B( "$" + total ) );
|
||||||
|
ec.addElement( new BR() );
|
||||||
|
ec.addElement( new P().addElement( "This amount will be charged to your credit card immediately." ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
s.setMessage( "Error generating " + this.getClass().getName() );
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( ec );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DOCUMENT ME!
|
||||||
|
*
|
||||||
|
* @return DOCUMENT ME!
|
||||||
|
*/
|
||||||
|
protected Category getDefaultCategory()
|
||||||
|
{
|
||||||
|
return AbstractLesson.A1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the hints attribute of the HiddenFieldScreen object
|
||||||
|
*
|
||||||
|
* @return The hints value
|
||||||
|
*/
|
||||||
|
protected List getHints()
|
||||||
|
{
|
||||||
|
List hints = new ArrayList();
|
||||||
|
hints.add( "This application is using hidden fields to transmit price information to the server." );
|
||||||
|
hints.add( "Use a program to intercept and change the value in the hidden field." );
|
||||||
|
hints.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 + "." );
|
||||||
|
|
||||||
|
return hints;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the instructions attribute of the HiddenFieldTampering object
|
||||||
|
*
|
||||||
|
* @return The instructions value
|
||||||
|
*/
|
||||||
|
public String getInstructions(WebSession s)
|
||||||
|
{
|
||||||
|
String instructions = "Try to purchase the HDTV for less than the purchase price, if you have not done so already.";
|
||||||
|
|
||||||
|
return ( instructions );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private final static Integer DEFAULT_RANKING = new Integer(50);
|
||||||
|
|
||||||
|
protected Integer getDefaultRanking()
|
||||||
|
{
|
||||||
|
return DEFAULT_RANKING;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the title attribute of the HiddenFieldScreen object
|
||||||
|
*
|
||||||
|
* @return The title value
|
||||||
|
*/
|
||||||
|
public String getTitle()
|
||||||
|
{
|
||||||
|
return ( "How to Exploit Hidden Fields" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
217
webgoat/main/project/org/owasp/webgoat/lessons/HtmlClues.java
Normal file
217
webgoat/main/project/org/owasp/webgoat/lessons/HtmlClues.java
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
package org.owasp.webgoat.lessons;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
import org.apache.ecs.ElementContainer;
|
||||||
|
import org.apache.ecs.StringElement;
|
||||||
|
import org.apache.ecs.html.B;
|
||||||
|
import org.apache.ecs.html.Comment;
|
||||||
|
import org.apache.ecs.html.H1;
|
||||||
|
import org.apache.ecs.html.Input;
|
||||||
|
import org.apache.ecs.html.P;
|
||||||
|
import org.apache.ecs.html.TD;
|
||||||
|
import org.apache.ecs.html.TH;
|
||||||
|
import org.apache.ecs.html.TR;
|
||||||
|
import org.apache.ecs.html.Table;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.session.ECSFactory;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2002 Free Software Foundation developed under the custody of the Open Web
|
||||||
|
* Application Security Project (http://www.owasp.org) This software package org.owasp.webgoat.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
|
||||||
|
*/
|
||||||
|
public class HtmlClues extends LessonAdapter
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 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("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();
|
||||||
|
tr.addElement( new TD().addElement(" ").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, "" );
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the hints attribute of the CluesScreen object
|
||||||
|
*
|
||||||
|
* @return The hints value
|
||||||
|
*/
|
||||||
|
protected List getHints()
|
||||||
|
{
|
||||||
|
List hints = new ArrayList();
|
||||||
|
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 AbstractLesson.CODE_QUALITY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the title attribute of the CluesScreen object
|
||||||
|
*
|
||||||
|
* @return The title value
|
||||||
|
*/
|
||||||
|
public String getTitle()
|
||||||
|
{
|
||||||
|
return ( "How to Discover Clues in the HTML" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
108
webgoat/main/project/org/owasp/webgoat/lessons/HttpBasics.java
Normal file
108
webgoat/main/project/org/owasp/webgoat/lessons/HttpBasics.java
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
package org.owasp.webgoat.lessons;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
import org.apache.ecs.ElementContainer;
|
||||||
|
import org.apache.ecs.StringElement;
|
||||||
|
import org.apache.ecs.html.Input;
|
||||||
|
import org.owasp.webgoat.session.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2002 Free Software Foundation developed under the custody of the Open Web
|
||||||
|
* Application Security Project (http://www.owasp.org) This software package org.owasp.webgoat.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
|
||||||
|
*/
|
||||||
|
public class HttpBasics extends LessonAdapter
|
||||||
|
{
|
||||||
|
private final static String PERSON = "person";
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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();
|
||||||
|
|
||||||
|
StringBuffer person = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ec.addElement( new StringElement( "Enter your name: " ) );
|
||||||
|
|
||||||
|
person = new StringBuffer( s.getParser().getStringParameter( PERSON, "" ) );
|
||||||
|
person.reverse();
|
||||||
|
|
||||||
|
Input input = new Input( Input.TEXT, PERSON, person.toString() );
|
||||||
|
ec.addElement( input );
|
||||||
|
|
||||||
|
Element b = ECSFactory.makeButton( "Go!" );
|
||||||
|
ec.addElement( b );
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
s.setMessage( "Error generating " + this.getClass().getName() );
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !person.toString().equals( "" ) && getLessonTracker( s ).getNumVisits() > 3 )
|
||||||
|
{
|
||||||
|
makeSuccess( s );
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( ec );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the hints attribute of the HelloScreen object
|
||||||
|
*
|
||||||
|
* @return The hints value
|
||||||
|
*/
|
||||||
|
public List getHints()
|
||||||
|
{
|
||||||
|
List hints = new ArrayList();
|
||||||
|
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" );
|
||||||
|
|
||||||
|
return hints;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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()
|
||||||
|
{
|
||||||
|
return AbstractLesson.GENERAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the title attribute of the HelloScreen object
|
||||||
|
*
|
||||||
|
* @return The title value
|
||||||
|
*/
|
||||||
|
public String getTitle()
|
||||||
|
{
|
||||||
|
return ( "Http Basics" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
391
webgoat/main/project/org/owasp/webgoat/lessons/HttpOnly.java
Normal file
391
webgoat/main/project/org/owasp/webgoat/lessons/HttpOnly.java
Normal file
@ -0,0 +1,391 @@
|
|||||||
|
package org.owasp.webgoat.lessons;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
import org.apache.ecs.ElementContainer;
|
||||||
|
import org.apache.ecs.StringElement;
|
||||||
|
import org.apache.ecs.html.Form;
|
||||||
|
import org.apache.ecs.html.Input;
|
||||||
|
import org.apache.ecs.html.TD;
|
||||||
|
import org.apache.ecs.html.TR;
|
||||||
|
import org.apache.ecs.html.Table;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
|
||||||
|
import sun.misc.BASE64Encoder;
|
||||||
|
|
||||||
|
public class HttpOnly extends LessonAdapter {
|
||||||
|
|
||||||
|
private final static Integer DEFAULT_RANKING = new Integer(125);
|
||||||
|
|
||||||
|
private final static String UNIQUE2U = "unique2u";
|
||||||
|
|
||||||
|
private final static String HTTPONLY = "httponly";
|
||||||
|
|
||||||
|
private final static String ACTION = "action";
|
||||||
|
|
||||||
|
private final static String READ = "Read Cookie";
|
||||||
|
|
||||||
|
private final static String WRITE = "Write Cookie";
|
||||||
|
|
||||||
|
private final static String READ_RESULT = "read_result";
|
||||||
|
|
||||||
|
private boolean httpOnly = false;
|
||||||
|
|
||||||
|
private boolean readSuccess = false;
|
||||||
|
|
||||||
|
private boolean writeSuccess = false;
|
||||||
|
|
||||||
|
private String original = "undefined";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the title attribute of the EmailScreen object
|
||||||
|
*
|
||||||
|
* @return The title value
|
||||||
|
*/
|
||||||
|
public String getTitle()
|
||||||
|
{
|
||||||
|
return ( "HTTPOnly Test" );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Integer getDefaultRanking()
|
||||||
|
{
|
||||||
|
return DEFAULT_RANKING;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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();
|
||||||
|
String action = null;
|
||||||
|
String http = null;
|
||||||
|
|
||||||
|
http = s.getRequest().getParameter(HTTPONLY);
|
||||||
|
action = s.getRequest().getParameter(ACTION);
|
||||||
|
|
||||||
|
if(http != null) {
|
||||||
|
httpOnly = Boolean.parseBoolean(http);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(httpOnly) {
|
||||||
|
// System.out.println("HttpOnly: Setting HttpOnly for cookie");
|
||||||
|
setHttpOnly(s);
|
||||||
|
} else {
|
||||||
|
// System.out.println("HttpOnly: Removing HttpOnly for cookie");
|
||||||
|
removeHttpOnly(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(action != null) {
|
||||||
|
if(action.equals(READ)) {
|
||||||
|
handleReadAction(s);
|
||||||
|
} else if(action.equals(WRITE)) {
|
||||||
|
handleWriteAction(s);
|
||||||
|
} else {
|
||||||
|
//s.setMessage("Invalid Request. Please try again.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ec.addElement(makeContent(s));
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
s.setMessage( "Error generating " + this.getClass().getName() );
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( ec );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DOCUMENT ME!
|
||||||
|
*
|
||||||
|
* @return DOCUMENT ME!
|
||||||
|
*/
|
||||||
|
protected Category getDefaultCategory()
|
||||||
|
{
|
||||||
|
return AbstractLesson.A4;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the hints attribute of the EmailScreen object
|
||||||
|
*
|
||||||
|
* @return The hints value
|
||||||
|
*/
|
||||||
|
protected List getHints()
|
||||||
|
{
|
||||||
|
List hints = new ArrayList();
|
||||||
|
|
||||||
|
|
||||||
|
return hints;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String createCustomCookieValue() {
|
||||||
|
String value = null;
|
||||||
|
byte[] buffer = null;
|
||||||
|
MessageDigest md = null;
|
||||||
|
BASE64Encoder encoder = new BASE64Encoder();
|
||||||
|
|
||||||
|
try {
|
||||||
|
md = MessageDigest.getInstance("SHA");
|
||||||
|
buffer = new Date().toString().getBytes();
|
||||||
|
|
||||||
|
md.update(buffer);
|
||||||
|
value = encoder.encode(md.digest());
|
||||||
|
original = value;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setHttpOnly(WebSession s) {
|
||||||
|
String value = createCustomCookieValue();
|
||||||
|
HttpServletResponse response = s.getResponse();
|
||||||
|
String cookie = s.getCookie(UNIQUE2U);
|
||||||
|
|
||||||
|
if(cookie == null || cookie.equals("HACKED")) {
|
||||||
|
response.setHeader("Set-Cookie", UNIQUE2U + "=" + value + "; HttpOnly");
|
||||||
|
original = value;
|
||||||
|
} else {
|
||||||
|
response.setHeader("Set-Cookie", UNIQUE2U + "=" + cookie + "; HttpOnly");
|
||||||
|
original = cookie;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeHttpOnly(WebSession s) {
|
||||||
|
String value = createCustomCookieValue();
|
||||||
|
HttpServletResponse response = s.getResponse();
|
||||||
|
String cookie = s.getCookie(UNIQUE2U);
|
||||||
|
|
||||||
|
if(cookie == null || cookie.equals("HACKED")) {
|
||||||
|
response.setHeader("Set-Cookie", UNIQUE2U + "=" + value + ";");
|
||||||
|
original = value;
|
||||||
|
} else {
|
||||||
|
response.setHeader("Set-Cookie", UNIQUE2U + "=" + cookie + ";");
|
||||||
|
original = cookie;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ElementContainer makeContent(WebSession s) {
|
||||||
|
ElementContainer ec = new ElementContainer();
|
||||||
|
Element r = null;
|
||||||
|
Table t = null;
|
||||||
|
TR tr = null;
|
||||||
|
Form f = null;
|
||||||
|
|
||||||
|
ec.addElement(new StringElement(getJavaScript()));
|
||||||
|
|
||||||
|
f = new Form();
|
||||||
|
|
||||||
|
t = new Table();
|
||||||
|
t.setWidth(500);
|
||||||
|
|
||||||
|
tr = new TR();
|
||||||
|
|
||||||
|
tr.addElement(new TD(new StringElement("Your browser appears to be: " + getBrowserType(s))));
|
||||||
|
t.addElement(tr);
|
||||||
|
|
||||||
|
tr = new TR();
|
||||||
|
t.addElement(tr);
|
||||||
|
|
||||||
|
tr = new TR();
|
||||||
|
|
||||||
|
tr.addElement( new TD(new StringElement ("Do you wish to turn HTTPOnly on?")));
|
||||||
|
|
||||||
|
tr.addElement( new TD(new StringElement ("Yes")));
|
||||||
|
|
||||||
|
if(httpOnly == true) {
|
||||||
|
r = new Input(Input.RADIO, HTTPONLY, "True" ).addAttribute("Checked", "true");
|
||||||
|
} else {
|
||||||
|
r = new Input(Input.RADIO, HTTPONLY, "True" ).addAttribute("onClick", "document.form.submit()");
|
||||||
|
}
|
||||||
|
|
||||||
|
tr.addElement(new TD(r));
|
||||||
|
|
||||||
|
tr.addElement( new TD(new StringElement ("No")));
|
||||||
|
|
||||||
|
if(httpOnly == false) {
|
||||||
|
r = new Input(Input.RADIO, HTTPONLY, "False").addAttribute("Checked", "True");
|
||||||
|
} else {
|
||||||
|
r = new Input(Input.RADIO, HTTPONLY, "False").addAttribute("onClick", "document.form.submit()");
|
||||||
|
}
|
||||||
|
|
||||||
|
tr.addElement(new TD(r));
|
||||||
|
|
||||||
|
r = new Input(Input.HIDDEN, READ_RESULT, "");
|
||||||
|
tr.addElement(r);
|
||||||
|
|
||||||
|
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 id=\"status\">On</div>")));
|
||||||
|
} else {
|
||||||
|
tr.addElement(new TD(new StringElement ("<div id=\"status\">Off</div>")));
|
||||||
|
}
|
||||||
|
|
||||||
|
t.addElement(tr);
|
||||||
|
t.addElement(new TR(new TD(new StringElement("<br/>"))));
|
||||||
|
*/ f.addElement(t);
|
||||||
|
|
||||||
|
t = new Table();
|
||||||
|
tr = new TR();
|
||||||
|
|
||||||
|
r = new Input(Input.SUBMIT, ACTION, READ).addAttribute("onclick", "myAlert();");
|
||||||
|
tr.addElement(new TD(r));
|
||||||
|
|
||||||
|
r = new Input(Input.SUBMIT, ACTION, WRITE).addAttribute("onclick", "modifyAlert();");
|
||||||
|
tr.addElement(new TD(r));
|
||||||
|
t.addElement(tr);
|
||||||
|
|
||||||
|
f.addElement(t);
|
||||||
|
ec.addElement(f);
|
||||||
|
|
||||||
|
return ec;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleReadAction(WebSession s) {
|
||||||
|
|
||||||
|
String displayed = s.getRequest().getParameter(READ_RESULT);
|
||||||
|
|
||||||
|
if(httpOnly == true) {
|
||||||
|
if(displayed.indexOf(UNIQUE2U) != -1) {
|
||||||
|
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.");
|
||||||
|
} else {
|
||||||
|
s.setMessage("SUCCESS: Your browser enforced the HTTPOnly flag properly for the '" + UNIQUE2U
|
||||||
|
+ "' cookie by preventing direct client side read access to this cookie.");
|
||||||
|
if (writeSuccess) {
|
||||||
|
if (!this.isCompleted(s)) {
|
||||||
|
makeSuccess(s);
|
||||||
|
readSuccess = false;
|
||||||
|
writeSuccess = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!this.isCompleted(s)) {
|
||||||
|
s.setMessage("Now try to see if your browser protects write access to this cookie.");
|
||||||
|
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 {
|
||||||
|
s.setMessage("Since HTTPOnly was not enabled, the '" + UNIQUE2U
|
||||||
|
+ "' cookie should have been displayed in the alert dialog, but was not for some reason. "
|
||||||
|
+ "(This shouldn't happen)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleWriteAction(WebSession s) {
|
||||||
|
String hacked = s.getCookie(UNIQUE2U);
|
||||||
|
|
||||||
|
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.");
|
||||||
|
s.setMessage("The " + UNIQUE2U + " cookie was successfully modified to " + hacked + " 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);
|
||||||
|
readSuccess = false;
|
||||||
|
writeSuccess = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!this.isCompleted(s)) {
|
||||||
|
s.setMessage("Now try to see if your browser protects read access to this cookie.");
|
||||||
|
writeSuccess = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if(!original.equals(hacked)) {
|
||||||
|
s.setMessage("Since HTTPOnly was not enabled, the browser allowed the '" + UNIQUE2U
|
||||||
|
+ "' cookie to be modified on the client side.");
|
||||||
|
} else {
|
||||||
|
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. "
|
||||||
|
+ "(This shouldn't happen)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getJavaScript() {
|
||||||
|
StringBuffer buffer = new StringBuffer();
|
||||||
|
|
||||||
|
buffer.append("<script language=\"javascript\">\n");
|
||||||
|
buffer.append("function myAlert() {\n");
|
||||||
|
buffer.append("alert(document.cookie);\n");
|
||||||
|
buffer.append("document.form.read_result.value=document.cookie;\n");
|
||||||
|
buffer.append("return true;\n");
|
||||||
|
buffer.append("}\n");
|
||||||
|
buffer.append("function modifyAlert() {\n");
|
||||||
|
buffer.append("document.cookie='" + UNIQUE2U + "=HACKED;\';\n");
|
||||||
|
buffer.append("alert(document.cookie);\n");
|
||||||
|
buffer.append("return true;\n");
|
||||||
|
buffer.append("}\n");
|
||||||
|
buffer.append("</script>\n");
|
||||||
|
|
||||||
|
return buffer.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getBrowserType(WebSession s) {
|
||||||
|
int offset = -1;
|
||||||
|
String result = "unknown";
|
||||||
|
String browser = s.getHeader("user-agent").toLowerCase();
|
||||||
|
|
||||||
|
if(browser != null) {
|
||||||
|
if(browser.indexOf("firefox") != -1) {
|
||||||
|
browser = browser.substring(browser.indexOf("firefox"));
|
||||||
|
|
||||||
|
offset = getOffset(browser);
|
||||||
|
|
||||||
|
result = browser.substring(0, offset);
|
||||||
|
} else if(browser.indexOf("msie 6") != -1) {
|
||||||
|
result = "Internet Explorer 6";
|
||||||
|
} else if(browser.indexOf("msie 7") != -1) {
|
||||||
|
result = "Internet Explorer 7";
|
||||||
|
} else if(browser.indexOf("msie") != -1) {
|
||||||
|
result = "Internet Explorer";
|
||||||
|
} else if(browser.indexOf("opera") != -1) {
|
||||||
|
result = "Opera";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getOffset(String s) {
|
||||||
|
int result = s.length();
|
||||||
|
|
||||||
|
for(int i=0; i<s.length(); i++) {
|
||||||
|
if(s.charAt(i) < 33 || s.charAt(i) > 126) {
|
||||||
|
result = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,264 @@
|
|||||||
|
package org.owasp.webgoat.lessons;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
import org.apache.ecs.ElementContainer;
|
||||||
|
import org.apache.ecs.StringElement;
|
||||||
|
import org.apache.ecs.html.Div;
|
||||||
|
import org.apache.ecs.html.Input;
|
||||||
|
import org.apache.ecs.html.P;
|
||||||
|
import org.apache.ecs.html.TextArea;
|
||||||
|
|
||||||
|
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 org.owasp.webgoat.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
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class JavaScriptValidation extends LessonAdapter
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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();
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
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
|
||||||
|
// these should never match unless the client side pattern script doesn't work
|
||||||
|
|
||||||
|
int err = 0;
|
||||||
|
String msg = "";
|
||||||
|
|
||||||
|
if ( !pattern1.matcher( param1 ).matches() )
|
||||||
|
{
|
||||||
|
err++;
|
||||||
|
msg += "<BR>Server side validation violation: You succeeded for Field1.";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !pattern2.matcher( param2 ).matches() )
|
||||||
|
{
|
||||||
|
err++;
|
||||||
|
msg += "<BR>Server side validation violation: You succeeded for Field2.";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !pattern3.matcher( param3 ).matches() )
|
||||||
|
{
|
||||||
|
err++;
|
||||||
|
msg += "<BR>Server side validation violation: You succeeded for Field3.";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !pattern4.matcher( param4 ).matches() )
|
||||||
|
{
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DOCUMENT ME!
|
||||||
|
*
|
||||||
|
* @return DOCUMENT ME!
|
||||||
|
*/
|
||||||
|
protected Category getDefaultCategory()
|
||||||
|
{
|
||||||
|
return AbstractLesson.A1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the hints attribute of the AccessControlScreen object
|
||||||
|
*
|
||||||
|
* @return The hints value
|
||||||
|
*/
|
||||||
|
protected List getHints()
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
|
||||||
|
protected Integer getDefaultRanking()
|
||||||
|
{
|
||||||
|
return DEFAULT_RANKING;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the title attribute of the AccessControlScreen object
|
||||||
|
*
|
||||||
|
* @return The title value
|
||||||
|
*/
|
||||||
|
public String getTitle()
|
||||||
|
{
|
||||||
|
return ( "How to Bypass Client Side JavaScript Validation" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
package org.owasp.webgoat.lessons;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.session.ParameterNotFoundException;
|
||||||
|
import org.owasp.webgoat.session.UnauthenticatedException;
|
||||||
|
import org.owasp.webgoat.session.UnauthorizedException;
|
||||||
|
import org.owasp.webgoat.session.ValidationException;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
|
||||||
|
public interface LessonAction
|
||||||
|
{
|
||||||
|
public void handleRequest(WebSession s)
|
||||||
|
throws ParameterNotFoundException, UnauthenticatedException, UnauthorizedException, ValidationException;
|
||||||
|
|
||||||
|
public String getNextPage(WebSession s);
|
||||||
|
|
||||||
|
public String getActionName();
|
||||||
|
|
||||||
|
public boolean requiresAuthentication();
|
||||||
|
|
||||||
|
public boolean isAuthenticated(WebSession s);
|
||||||
|
|
||||||
|
public boolean isAuthorized(WebSession s, int employeeId, String functionId);
|
||||||
|
|
||||||
|
public int getUserId(WebSession s) throws ParameterNotFoundException;
|
||||||
|
|
||||||
|
public String getUserName(WebSession s) throws ParameterNotFoundException;
|
||||||
|
}
|
||||||
@ -0,0 +1,330 @@
|
|||||||
|
package org.owasp.webgoat.lessons;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
import org.apache.ecs.ElementContainer;
|
||||||
|
import org.apache.ecs.HtmlColor;
|
||||||
|
import org.apache.ecs.StringElement;
|
||||||
|
import org.apache.ecs.html.Center;
|
||||||
|
import org.apache.ecs.html.H3;
|
||||||
|
import org.apache.ecs.html.IMG;
|
||||||
|
import org.apache.ecs.html.P;
|
||||||
|
import org.apache.ecs.html.PRE;
|
||||||
|
import org.apache.ecs.html.TD;
|
||||||
|
import org.apache.ecs.html.TR;
|
||||||
|
import org.apache.ecs.html.Table;
|
||||||
|
|
||||||
|
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 org.owasp.webgoat.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
|
||||||
|
*/
|
||||||
|
public abstract class LessonAdapter extends AbstractLesson
|
||||||
|
{
|
||||||
|
final static IMG ASPECT_LOGO = new IMG( "images/logos/aspect.jpg" ).setAlt( "Aspect Security" ).setBorder( 0 ).setHspace( 0 ).setVspace( 0 );
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param s Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
protected Element createContent( WebSession s )
|
||||||
|
{
|
||||||
|
// Mark this lesson as completed.
|
||||||
|
makeSuccess( s );
|
||||||
|
|
||||||
|
ElementContainer ec = new ElementContainer();
|
||||||
|
|
||||||
|
ec.addElement( new Center().addElement( new H3().addElement( new StringElement( "This lesson needs a creator." ) ) ) );
|
||||||
|
ec.addElement( new P() );
|
||||||
|
ec.addElement( new StringElement( "Lesson are simple to create and very little coding is required. " +
|
||||||
|
"In fact, most lessons can be created by following the easy to use instructions in the " +
|
||||||
|
"<A HREF=http://prdownloads.sourceforge.net/owasp/WebGoatVersion2UserGuide.pdf?download>WebGoat User Guide.</A> " +
|
||||||
|
"If you would prefer, send your lesson ideas to " + s.getFeedbackAddress() ) );
|
||||||
|
|
||||||
|
String fileName = s.getContext().getRealPath( "doc/New Lesson Instructions.txt");
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
ec.addElement( pre );
|
||||||
|
}
|
||||||
|
catch ( Exception e ){}
|
||||||
|
}
|
||||||
|
return ( ec );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected Element createStagedContent( WebSession s )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int stage = getLessonTracker(s).getStage();
|
||||||
|
//int stage = Integer.parseInt( getLessonTracker(s).getLessonProperties().getProperty(WebSession.STAGE,"1"));
|
||||||
|
|
||||||
|
switch ( stage )
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
return ( doStage1( s ) );
|
||||||
|
case 2:
|
||||||
|
return ( doStage2( s ) );
|
||||||
|
case 3:
|
||||||
|
return ( doStage3( s ) );
|
||||||
|
case 4:
|
||||||
|
return ( doStage4( s ) );
|
||||||
|
case 5:
|
||||||
|
return ( doStage5( s ) );
|
||||||
|
case 6:
|
||||||
|
return ( doStage6( s ) );
|
||||||
|
default:
|
||||||
|
throw new Exception( "Invalid stage" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
s.setMessage( "Error generating " + this.getClass().getName() );
|
||||||
|
System.out.println( e );
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
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 doStage3( WebSession s ) throws Exception
|
||||||
|
{
|
||||||
|
ElementContainer ec = new ElementContainer();
|
||||||
|
ec.addElement("Stage 3 Stub");
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the category attribute of the LessonAdapter object. The default category is "General" Only
|
||||||
|
* override this method if you wish to create a new category or if you wish this lesson to reside
|
||||||
|
* within a category other the "General"
|
||||||
|
*
|
||||||
|
* @return The category value
|
||||||
|
*/
|
||||||
|
protected Category getDefaultCategory()
|
||||||
|
{
|
||||||
|
return 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()
|
||||||
|
{
|
||||||
|
return getHints().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 getHints()
|
||||||
|
{
|
||||||
|
List hints = new ArrayList();
|
||||||
|
hints.add( "There are no hints defined." );
|
||||||
|
|
||||||
|
return hints;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHint(int hintNumber)
|
||||||
|
{
|
||||||
|
return (String) getHints().get(hintNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the credits attribute of the AbstractLesson object
|
||||||
|
*
|
||||||
|
* @return The credits value
|
||||||
|
*/
|
||||||
|
public Element getCredits()
|
||||||
|
{
|
||||||
|
return getCustomCredits("Sponsored by ", ASPECT_LOGO);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 ){}
|
||||||
|
|
||||||
|
return buff.toString();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fill in a descriptive title for this lesson. The title of the lesson. This will appear above
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
s.getLessonSession(this).setCurrentLessonScreen(lessonScreen);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getSessionAttribute(WebSession s, String key) {
|
||||||
|
return s.getRequest().getSession().getAttribute(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
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.");
|
||||||
|
|
||||||
|
return ( null );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the credits attribute of the AbstractLesson object
|
||||||
|
*
|
||||||
|
* @return The credits value
|
||||||
|
*/
|
||||||
|
protected Element getCustomCredits(String text, IMG logo)
|
||||||
|
{
|
||||||
|
ElementContainer ec = new ElementContainer();
|
||||||
|
|
||||||
|
Table t = new Table().setCellSpacing( 0 ).setCellPadding( 0 ).setBorder( 0 ).setWidth("90%").setAlign("RIGHT");
|
||||||
|
TR tr = new TR();
|
||||||
|
tr.addElement( new TD(text).setVAlign("MIDDLE").setAlign("RIGHT").setWidth("100%"));
|
||||||
|
tr.addElement( new TD(logo).setVAlign("MIDDLE").setAlign("RIGHT"));
|
||||||
|
t.addElement(tr);
|
||||||
|
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,65 @@
|
|||||||
|
package org.owasp.webgoat.lessons;
|
||||||
|
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
import org.apache.ecs.StringElement;
|
||||||
|
|
||||||
|
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 org.owasp.webgoat.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
|
||||||
|
*/
|
||||||
|
public class ParameterInjection extends LessonAdapter
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param s Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
protected Element createContent( WebSession s )
|
||||||
|
{
|
||||||
|
// just to get the generic how to text.
|
||||||
|
return super.createContent(s);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Gets the category attribute of the CommandInjection object
|
||||||
|
*
|
||||||
|
* @return The category value
|
||||||
|
*/
|
||||||
|
protected Category getDefaultCategory()
|
||||||
|
{
|
||||||
|
return AbstractLesson.A6;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private final static Integer DEFAULT_RANKING = new Integer(40);
|
||||||
|
|
||||||
|
protected Integer getDefaultRanking()
|
||||||
|
{
|
||||||
|
return DEFAULT_RANKING;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the title attribute of the DirectoryScreen object
|
||||||
|
*
|
||||||
|
* @return The title value
|
||||||
|
*/
|
||||||
|
public String getTitle()
|
||||||
|
{
|
||||||
|
return ( "How to Perform Parameter Injection" );
|
||||||
|
}
|
||||||
|
|
||||||
|
public Element getCredits()
|
||||||
|
{
|
||||||
|
return new StringElement("This screen created by: Your name could go here");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,262 @@
|
|||||||
|
package org.owasp.webgoat.lessons;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
import org.apache.ecs.ElementContainer;
|
||||||
|
import org.apache.ecs.StringElement;
|
||||||
|
import org.apache.ecs.html.BR;
|
||||||
|
import org.apache.ecs.html.HR;
|
||||||
|
import org.apache.ecs.html.TD;
|
||||||
|
import org.apache.ecs.html.TR;
|
||||||
|
import org.apache.ecs.html.Table;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.session.ECSFactory;
|
||||||
|
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 org.owasp.webgoat.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
|
||||||
|
*/
|
||||||
|
public class PathBasedAccessControl extends LessonAdapter
|
||||||
|
{
|
||||||
|
private final static String FILE = "File";
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
{
|
||||||
|
String dir = s.getContext().getRealPath( "/lesson_plans" );
|
||||||
|
File d = new File( dir );
|
||||||
|
|
||||||
|
Table t = new Table().setCellSpacing( 0 ).setCellPadding( 2 ).setWidth("90%").setAlign("center");
|
||||||
|
|
||||||
|
if ( s.isColor() )
|
||||||
|
{
|
||||||
|
t.setBorder( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] list = d.list();
|
||||||
|
String listing = " <p><B>Current Directory is:</B> " + Encoding.urlDecode( dir ) + "<br><br> Choose the file to view:</p>";
|
||||||
|
|
||||||
|
TR tr = new TR();
|
||||||
|
tr.addElement(new TD().setColSpan(2).addElement( new StringElement(listing) ));
|
||||||
|
t.addElement(tr);
|
||||||
|
|
||||||
|
tr = new TR();
|
||||||
|
tr.addElement( new TD().setWidth("35%").addElement( ECSFactory.makePulldown( FILE, list, "", 15 )));
|
||||||
|
tr.addElement( new TD().addElement( ECSFactory.makeButton( "View File" )));
|
||||||
|
t.addElement(tr);
|
||||||
|
|
||||||
|
ec.addElement( t );
|
||||||
|
|
||||||
|
|
||||||
|
// FIXME: would be cool to allow encodings here -- hex, percent, url, etc...
|
||||||
|
String file = s.getParser().getRawParameter( FILE, "" );
|
||||||
|
|
||||||
|
// defuse file searching
|
||||||
|
boolean illegalCommand = s.isDefuseOSCommands();
|
||||||
|
if ( s.isDefuseOSCommands() )
|
||||||
|
{
|
||||||
|
// allow them to look at any file in the webgoat hierachy. Don't allow them
|
||||||
|
// to look about the webgoat root, except to see the LICENSE file
|
||||||
|
if( upDirCount( file ) == 3 && !file.endsWith("LICENSE"))
|
||||||
|
{
|
||||||
|
s.setMessage( "Access denied" );
|
||||||
|
s.setMessage( "It appears that you are on the right track. " +
|
||||||
|
"Commands that may compromise the operating system have been disabled. " +
|
||||||
|
"You are only allowed to see one file in this directory. ");;
|
||||||
|
}
|
||||||
|
else if ( upDirCount( file ) > 3 )
|
||||||
|
{
|
||||||
|
s.setMessage( "Access denied" );
|
||||||
|
s.setMessage( "It appears that you are on the right track. " +
|
||||||
|
"Commands that may compromise the operating system have been disabled. " +
|
||||||
|
"You are only allowed to see files in the webgoat directory. ");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
illegalCommand = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Using the URI supports encoding of the data.
|
||||||
|
// We could force the user to use encoded '/'s == %2f to make the lesson more difficult.
|
||||||
|
// We url Encode our dir name to avoid problems with special characters in our own path.
|
||||||
|
//File f = new File( new URI("file:///" + Encoding.urlEncode(dir).replaceAll("\\\\","/") + "/" + file.replaceAll("\\\\","/")) );
|
||||||
|
File f = new File( (dir + "\\" + file).replaceAll("\\\\","/"));
|
||||||
|
|
||||||
|
if( s.isDebug() )
|
||||||
|
{
|
||||||
|
|
||||||
|
s.setMessage("File: " + file );
|
||||||
|
s.setMessage("Dir: " + dir );
|
||||||
|
//s.setMessage("File URI: " + "file:///" + (Encoding.urlEncode(dir) + "\\" + Encoding.urlEncode(file)).replaceAll("\\\\","/"));
|
||||||
|
s.setMessage(" - isFile(): " + f.isFile() );
|
||||||
|
s.setMessage(" - exists(): " + f.exists() );
|
||||||
|
}
|
||||||
|
if ( !illegalCommand )
|
||||||
|
{
|
||||||
|
if ( f.isFile() && f.exists() )
|
||||||
|
{
|
||||||
|
// Don't set completion if they are listing files in the
|
||||||
|
// directory listing we gave them.
|
||||||
|
if ( upDirCount( file ) >= 1 )
|
||||||
|
{
|
||||||
|
s.setMessage( "Congratulations! Access to file allowed" );
|
||||||
|
s.setMessage( " ==> " + Encoding.urlDecode( f.getCanonicalPath() ));
|
||||||
|
makeSuccess( s );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s.setMessage( "File is already in allowed directory - try again!" );
|
||||||
|
s.setMessage( " ==> " + Encoding.urlDecode( f.getCanonicalPath() ));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( file != null && file.length() != 0 )
|
||||||
|
{
|
||||||
|
s.setMessage( "Access to file/directory \"" + Encoding.urlDecode( f.getCanonicalPath() ) + "\" denied" );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// do nothing, probably entry screen
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Show them the file
|
||||||
|
// Strip out some of the extra html from the "help" file
|
||||||
|
ec.addElement( new BR() );
|
||||||
|
ec.addElement( new BR() );
|
||||||
|
ec.addElement( new HR().setWidth("100%") );
|
||||||
|
ec.addElement( "Viewing file: " + f.getCanonicalPath() );
|
||||||
|
ec.addElement( new HR().setWidth("100%") );
|
||||||
|
if ( f.length() > 80000 )
|
||||||
|
{
|
||||||
|
throw new Exception("File is too large");
|
||||||
|
}
|
||||||
|
String fileData= getFileText( new BufferedReader( new FileReader( f ) ), false );
|
||||||
|
if ( fileData.indexOf(0x00) != -1)
|
||||||
|
{
|
||||||
|
throw new Exception("File is binary");
|
||||||
|
}
|
||||||
|
ec.addElement( new StringElement( fileData.replaceAll(System.getProperty("line.separator"),"<br>")
|
||||||
|
.replaceAll("(?s)<!DOCTYPE.*/head>","")
|
||||||
|
.replaceAll("<br><br>","<br>")
|
||||||
|
.replaceAll("<br>\\s<br>","<br>")
|
||||||
|
.replaceAll("<\\?", "<")
|
||||||
|
.replaceAll("<(r|u|t)", "<$1")));
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
ec.addElement( new BR() );
|
||||||
|
ec.addElement("The following error occurred while accessing the file: <");
|
||||||
|
ec.addElement( e.getMessage() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
s.setMessage( "Error generating " + this.getClass().getName() );
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( ec );
|
||||||
|
}
|
||||||
|
|
||||||
|
private int upDirCount( String fileName )
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
int startIndex = fileName.indexOf("..");
|
||||||
|
while ( startIndex != -1 )
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
startIndex = fileName.indexOf("..", startIndex+1);
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DOCUMENT ME!
|
||||||
|
*
|
||||||
|
* @return DOCUMENT ME!
|
||||||
|
*/
|
||||||
|
protected Category getDefaultCategory()
|
||||||
|
{
|
||||||
|
return AbstractLesson.A2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the hints attribute of the AccessControlScreen object
|
||||||
|
*
|
||||||
|
* @return The hints value
|
||||||
|
*/
|
||||||
|
protected List getHints()
|
||||||
|
{
|
||||||
|
List<String> hints = new ArrayList<String>();
|
||||||
|
hints.add( "Most operating systems allow special characters in the path." );
|
||||||
|
hints.add( "Use a file explorer to find the tomcat\\webapps\\WebGoat\\lesson_plans directory" );
|
||||||
|
hints.add( "Try .. in the path" );
|
||||||
|
hints.add( "Try ..\\..\\..\\LICENSE" );
|
||||||
|
|
||||||
|
return hints;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the instructions attribute of the WeakAccessControl object
|
||||||
|
*
|
||||||
|
* @return The instructions value
|
||||||
|
*/
|
||||||
|
public String getInstructions(WebSession s)
|
||||||
|
{
|
||||||
|
String instructions = "The '" + s.getUserName() + "' user has access to all the files in the " +
|
||||||
|
"lesson_plans directory. Try to break the access control mechanism and access a " +
|
||||||
|
"resource that is not in the listed directory. After selecting a file to view, WebGoat " +
|
||||||
|
"will report if access to the file was granted. An interesting file to try and obtain might " +
|
||||||
|
"be a file like tomcat/conf/tomcat-users.xml";
|
||||||
|
|
||||||
|
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 ( "How to Bypass a Path Based Access Control Scheme" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
235
webgoat/main/project/org/owasp/webgoat/lessons/ReflectedXSS.java
Normal file
235
webgoat/main/project/org/owasp/webgoat/lessons/ReflectedXSS.java
Normal file
@ -0,0 +1,235 @@
|
|||||||
|
package org.owasp.webgoat.lessons;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
import org.apache.ecs.ElementContainer;
|
||||||
|
import org.apache.ecs.html.BR;
|
||||||
|
import org.apache.ecs.html.Center;
|
||||||
|
import org.apache.ecs.html.H1;
|
||||||
|
import org.apache.ecs.html.HR;
|
||||||
|
import org.apache.ecs.html.Input;
|
||||||
|
import org.apache.ecs.html.TD;
|
||||||
|
import org.apache.ecs.html.TH;
|
||||||
|
import org.apache.ecs.html.TR;
|
||||||
|
import org.apache.ecs.html.Table;
|
||||||
|
import org.owasp.webgoat.session.ECSFactory;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
import org.owasp.webgoat.util.HtmlEncoder;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2002 Free Software Foundation developed under the custody of the Open Web
|
||||||
|
* Application Security Project (http://www.owasp.org) This software package org.owasp.webgoat.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
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ReflectedXSS extends LessonAdapter
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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();
|
||||||
|
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
|
||||||
|
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", 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<65> Centrino<6E>"));
|
||||||
|
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( " " ).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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DOCUMENT ME!
|
||||||
|
*
|
||||||
|
* @return DOCUMENT ME!
|
||||||
|
*/
|
||||||
|
protected Category getDefaultCategory()
|
||||||
|
{
|
||||||
|
return AbstractLesson.A4;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the hints attribute of the AccessControlScreen object
|
||||||
|
*
|
||||||
|
* @return The hints value
|
||||||
|
*/
|
||||||
|
protected List getHints()
|
||||||
|
{
|
||||||
|
List hints = new ArrayList();
|
||||||
|
hints.add( "A simple script is <SCRIPT>alert('bang!');</SCRIPT>." );
|
||||||
|
hints.add( "Can you get the script to disclose the JSESSIONID cookie?" );
|
||||||
|
hints.add( "You can use <SCRIPT>alert(document.cookie);</SCRIPT> 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>" +
|
||||||
|
"<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; while (str1.indexOf(\"\\n\") > -1) str1 = str1.replace(\"\\n\",\"<br>\"); " +
|
||||||
|
"document.write(str1);}</script>");
|
||||||
|
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 instructions attribute of the WeakAccessControl object
|
||||||
|
*
|
||||||
|
* @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()
|
||||||
|
{
|
||||||
|
return DEFAULT_RANKING;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the title attribute of the AccessControlScreen object
|
||||||
|
*
|
||||||
|
* @return The title value
|
||||||
|
*/
|
||||||
|
public String getTitle()
|
||||||
|
{
|
||||||
|
return "How to Perform Reflected Cross Site Scripting (XSS) Attacks";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,95 @@
|
|||||||
|
package org.owasp.webgoat.lessons;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
import org.apache.ecs.ElementContainer;
|
||||||
|
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 org.owasp.webgoat.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
|
||||||
|
*/
|
||||||
|
public class RemoteAdminFlaw extends LessonAdapter
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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();
|
||||||
|
|
||||||
|
if ( s.completedHackableAdmin() )
|
||||||
|
{
|
||||||
|
makeSuccess( s );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ec.addElement( "WebGoat has an admin interface. To 'complete' this lesson you must figure "
|
||||||
|
+ "out how to access the administrative interface for WebGoat.");
|
||||||
|
}
|
||||||
|
return ec;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the category attribute of the ForgotPassword object
|
||||||
|
*
|
||||||
|
* @return The category value
|
||||||
|
*/
|
||||||
|
protected Category getDefaultCategory()
|
||||||
|
{
|
||||||
|
|
||||||
|
return AbstractLesson.A2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the hints attribute of the HelloScreen object
|
||||||
|
*
|
||||||
|
* @return The hints value
|
||||||
|
*/
|
||||||
|
public List getHints()
|
||||||
|
{
|
||||||
|
List hints = new ArrayList();
|
||||||
|
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(15);
|
||||||
|
|
||||||
|
protected Integer getDefaultRanking()
|
||||||
|
{
|
||||||
|
return DEFAULT_RANKING;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the title attribute of the HelloScreen object
|
||||||
|
*
|
||||||
|
* @return The title value
|
||||||
|
*/
|
||||||
|
public String getTitle()
|
||||||
|
{
|
||||||
|
return ( "Remote Admin Access" );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,137 @@
|
|||||||
|
package org.owasp.webgoat.lessons.RoleBasedAccessControl;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||||
|
import org.owasp.webgoat.lessons.DefaultLessonAction;
|
||||||
|
import org.owasp.webgoat.lessons.LessonAction;
|
||||||
|
import org.owasp.webgoat.session.ParameterNotFoundException;
|
||||||
|
import org.owasp.webgoat.session.UnauthenticatedException;
|
||||||
|
import org.owasp.webgoat.session.UnauthorizedException;
|
||||||
|
import org.owasp.webgoat.session.ValidationException;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
|
||||||
|
public class DeleteProfile extends DefaultLessonAction
|
||||||
|
{
|
||||||
|
private LessonAction chainedAction;
|
||||||
|
|
||||||
|
public DeleteProfile(AbstractLesson 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);
|
||||||
|
|
||||||
|
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 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
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteEmployeeProfile_BACKUP(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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void updateLessonStatus(WebSession s)
|
||||||
|
{
|
||||||
|
// If the logged in user is not authorized to be here, stage is complete.
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int userId = getIntSessionAttribute(s, getLessonName() + "." + RoleBasedAccessControl.USER_ID);
|
||||||
|
|
||||||
|
if (!isAuthorized(s, userId, RoleBasedAccessControl.DELETEPROFILE_ACTION))
|
||||||
|
{
|
||||||
|
s.setMessage( "Welcome to stage 2 -- protecting the business layer" );
|
||||||
|
setStage(s, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ParameterNotFoundException e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,160 @@
|
|||||||
|
package org.owasp.webgoat.lessons.RoleBasedAccessControl;
|
||||||
|
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||||
|
import org.owasp.webgoat.lessons.DefaultLessonAction;
|
||||||
|
import org.owasp.webgoat.session.Employee;
|
||||||
|
import org.owasp.webgoat.session.ParameterNotFoundException;
|
||||||
|
import org.owasp.webgoat.session.UnauthenticatedException;
|
||||||
|
import org.owasp.webgoat.session.UnauthorizedException;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
|
||||||
|
public class EditProfile extends DefaultLessonAction
|
||||||
|
{
|
||||||
|
public EditProfile(AbstractLesson 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 = getUserId(s);
|
||||||
|
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 String getNextPage(WebSession s)
|
||||||
|
{
|
||||||
|
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 = ?";
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,151 @@
|
|||||||
|
package org.owasp.webgoat.lessons.RoleBasedAccessControl;
|
||||||
|
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||||
|
import org.owasp.webgoat.lessons.DefaultLessonAction;
|
||||||
|
import org.owasp.webgoat.lessons.LessonAction;
|
||||||
|
import org.owasp.webgoat.session.Employee;
|
||||||
|
import org.owasp.webgoat.session.ParameterNotFoundException;
|
||||||
|
import org.owasp.webgoat.session.UnauthenticatedException;
|
||||||
|
import org.owasp.webgoat.session.UnauthorizedException;
|
||||||
|
import org.owasp.webgoat.session.ValidationException;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
|
||||||
|
public class FindProfile extends DefaultLessonAction
|
||||||
|
{
|
||||||
|
private LessonAction chainedAction;
|
||||||
|
|
||||||
|
public FindProfile(AbstractLesson 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() + "." + RoleBasedAccessControl.USER_ID);
|
||||||
|
|
||||||
|
String pattern = s.getParser().getRawParameter(RoleBasedAccessControl.SEARCHNAME);
|
||||||
|
|
||||||
|
findEmployeeProfile(s, userId, pattern);
|
||||||
|
|
||||||
|
// 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 = RoleBasedAccessControl.SEARCHSTAFF_ACTION;
|
||||||
|
|
||||||
|
if (foundEmployee(s))
|
||||||
|
page = RoleBasedAccessControl.VIEWPROFILE_ACTION;
|
||||||
|
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean foundEmployee(WebSession s)
|
||||||
|
{
|
||||||
|
boolean found = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int id = getIntRequestAttribute(s, getLessonName() + "." + RoleBasedAccessControl.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() + "." + RoleBasedAccessControl.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 = ?";
|
||||||
|
|
||||||
|
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() + "." + RoleBasedAccessControl.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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,134 @@
|
|||||||
|
package org.owasp.webgoat.lessons.RoleBasedAccessControl;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||||
|
import org.owasp.webgoat.lessons.DefaultLessonAction;
|
||||||
|
import org.owasp.webgoat.session.EmployeeStub;
|
||||||
|
import org.owasp.webgoat.session.ParameterNotFoundException;
|
||||||
|
import org.owasp.webgoat.session.UnauthenticatedException;
|
||||||
|
import org.owasp.webgoat.session.UnauthorizedException;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
|
||||||
|
public class ListStaff extends DefaultLessonAction
|
||||||
|
{
|
||||||
|
public ListStaff(AbstractLesson 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() + "." + RoleBasedAccessControl.USER_ID);
|
||||||
|
|
||||||
|
List employees = getAllEmployees(s, userId);
|
||||||
|
setSessionAttribute(s, getLessonName() + "." + RoleBasedAccessControl.STAFF_ATTRIBUTE_KEY, employees);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new UnauthenticatedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNextPage(WebSession s)
|
||||||
|
{
|
||||||
|
return RoleBasedAccessControl.LISTSTAFF_ACTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public List getAllEmployees(WebSession s, int userId)
|
||||||
|
throws UnauthorizedException
|
||||||
|
{
|
||||||
|
// Query the database for all employees "owned" by the given employee
|
||||||
|
|
||||||
|
List employees = new Vector();
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List getAllEmployees_BACKUP(WebSession s, int userId)
|
||||||
|
throws UnauthorizedException
|
||||||
|
{
|
||||||
|
// Query the database for all employees "owned" by the given employee
|
||||||
|
|
||||||
|
List employees = new Vector();
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,172 @@
|
|||||||
|
package org.owasp.webgoat.lessons.RoleBasedAccessControl;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||||
|
import org.owasp.webgoat.lessons.DefaultLessonAction;
|
||||||
|
import org.owasp.webgoat.lessons.LessonAction;
|
||||||
|
import org.owasp.webgoat.session.EmployeeStub;
|
||||||
|
import org.owasp.webgoat.session.ParameterNotFoundException;
|
||||||
|
import org.owasp.webgoat.session.UnauthenticatedException;
|
||||||
|
import org.owasp.webgoat.session.UnauthorizedException;
|
||||||
|
import org.owasp.webgoat.session.ValidationException;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
|
||||||
|
public class Login extends DefaultLessonAction
|
||||||
|
{
|
||||||
|
private LessonAction chainedAction;
|
||||||
|
|
||||||
|
public Login(AbstractLesson 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() + "." + RoleBasedAccessControl.STAFF_ATTRIBUTE_KEY, employees);
|
||||||
|
|
||||||
|
int employeeId = -1;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
employeeId = s.getParser().getIntParameter(RoleBasedAccessControl.EMPLOYEE_ID);
|
||||||
|
String password = s.getParser().getStringParameter(RoleBasedAccessControl.PASSWORD);
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
{
|
||||||
|
// No credentials offered, so we log them out
|
||||||
|
setSessionAttribute(s, getLessonName() + ".isAuthenticated", Boolean.FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 = RoleBasedAccessControl.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, getLessonName() + ".isAuthenticated", Boolean.TRUE);
|
||||||
|
setSessionAttribute(s, getLessonName() + "." + RoleBasedAccessControl.USER_ID, Integer.toString(userId));
|
||||||
|
authenticated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch ( SQLException sqle )
|
||||||
|
{
|
||||||
|
s.setMessage( "Error logging in" );
|
||||||
|
sqle.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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 employees = new Vector();
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,51 @@
|
|||||||
|
package org.owasp.webgoat.lessons.RoleBasedAccessControl;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||||
|
import org.owasp.webgoat.lessons.DefaultLessonAction;
|
||||||
|
import org.owasp.webgoat.lessons.LessonAction;
|
||||||
|
import org.owasp.webgoat.session.ParameterNotFoundException;
|
||||||
|
import org.owasp.webgoat.session.UnauthenticatedException;
|
||||||
|
import org.owasp.webgoat.session.UnauthorizedException;
|
||||||
|
import org.owasp.webgoat.session.ValidationException;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
|
||||||
|
public class Logout extends DefaultLessonAction
|
||||||
|
{
|
||||||
|
private LessonAction chainedAction;
|
||||||
|
|
||||||
|
public Logout(AbstractLesson 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);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,440 @@
|
|||||||
|
package org.owasp.webgoat.lessons.RoleBasedAccessControl;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Hashtable;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.ecs.ElementContainer;
|
||||||
|
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||||
|
import org.owasp.webgoat.lessons.Category;
|
||||||
|
import org.owasp.webgoat.lessons.LessonAction;
|
||||||
|
import org.owasp.webgoat.lessons.LessonAdapter;
|
||||||
|
import org.owasp.webgoat.session.DatabaseUtilities;
|
||||||
|
import org.owasp.webgoat.session.ParameterNotFoundException;
|
||||||
|
import org.owasp.webgoat.session.UnauthenticatedException;
|
||||||
|
import org.owasp.webgoat.session.UnauthorizedException;
|
||||||
|
import org.owasp.webgoat.session.ValidationException;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2006 Free Software Foundation developed under the custody of the Open Web
|
||||||
|
* Application Security Project (http://www.owasp.org) This software package org.owasp.webgoat.is published by OWASP
|
||||||
|
* under the GPL. You should read and accept the LICENSE before you use, modify and/or redistribute
|
||||||
|
* this software.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class RoleBasedAccessControl extends LessonAdapter
|
||||||
|
{
|
||||||
|
public final static String DESCRIPTION = "description";
|
||||||
|
public final static String DISCIPLINARY_DATE = "disciplinaryDate";
|
||||||
|
public final static String DISCIPLINARY_NOTES = "disciplinaryNotes";
|
||||||
|
public final static String CCN_LIMIT = "ccnLimit";
|
||||||
|
public final static String CCN = "ccn";
|
||||||
|
public final static String SALARY = "salary";
|
||||||
|
public final static String START_DATE = "startDate";
|
||||||
|
public final static String MANAGER = "manager";
|
||||||
|
public final static String ADDRESS1 = "address1";
|
||||||
|
public final static String ADDRESS2 = "address2";
|
||||||
|
public final static String PHONE_NUMBER = "phoneNumber";
|
||||||
|
public final static String TITLE = "title";
|
||||||
|
public final static String SSN = "ssn";
|
||||||
|
public final static String LAST_NAME = "lastName";
|
||||||
|
public final static String FIRST_NAME = "firstName";
|
||||||
|
public final static String PASSWORD = "password";
|
||||||
|
|
||||||
|
public final static String EMPLOYEE_ID = "employee_id";
|
||||||
|
public final static String USER_ID = "user_id";
|
||||||
|
public final static String SEARCHNAME = "search_name";
|
||||||
|
public final static String SEARCHRESULT_ATTRIBUTE_KEY = "SearchResult";
|
||||||
|
public final static String EMPLOYEE_ATTRIBUTE_KEY = "Employee";
|
||||||
|
public final static String STAFF_ATTRIBUTE_KEY = "Staff";
|
||||||
|
|
||||||
|
public final static String LOGIN_ACTION = "Login";
|
||||||
|
public final static String LOGOUT_ACTION = "Logout";
|
||||||
|
public final static String LISTSTAFF_ACTION = "ListStaff";
|
||||||
|
public final static String SEARCHSTAFF_ACTION = "SearchStaff";
|
||||||
|
public final static String FINDPROFILE_ACTION = "FindProfile";
|
||||||
|
public final static String VIEWPROFILE_ACTION = "ViewProfile";
|
||||||
|
public final static String EDITPROFILE_ACTION = "EditProfile";
|
||||||
|
public final static String UPDATEPROFILE_ACTION = "UpdateProfile";
|
||||||
|
public final static String CREATEPROFILE_ACTION = "CreateProfile";
|
||||||
|
public final static String DELETEPROFILE_ACTION = "DeleteProfile";
|
||||||
|
public final static String ERROR_ACTION = "error";
|
||||||
|
|
||||||
|
private final static String LESSON_NAME = "RoleBasedAccessControl";
|
||||||
|
private final static String JSP_PATH = "/lessons/" + LESSON_NAME + "/";
|
||||||
|
|
||||||
|
private final static Integer DEFAULT_RANKING = new Integer(120);
|
||||||
|
|
||||||
|
private static Connection connection = null;
|
||||||
|
|
||||||
|
private Map lessonFunctions = new Hashtable();
|
||||||
|
|
||||||
|
public static synchronized Connection getConnection(WebSession s)
|
||||||
|
throws SQLException, ClassNotFoundException
|
||||||
|
{
|
||||||
|
if ( connection == null )
|
||||||
|
{
|
||||||
|
connection = DatabaseUtilities.makeConnection( s );
|
||||||
|
}
|
||||||
|
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RoleBasedAccessControl()
|
||||||
|
{
|
||||||
|
String myClassName = parseClassName(this.getClass().getName());
|
||||||
|
registerAction(new ListStaff(this, myClassName, LISTSTAFF_ACTION));
|
||||||
|
registerAction(new SearchStaff(this, myClassName, SEARCHSTAFF_ACTION));
|
||||||
|
registerAction(new ViewProfile(this, myClassName, VIEWPROFILE_ACTION));
|
||||||
|
registerAction(new EditProfile(this, myClassName, EDITPROFILE_ACTION));
|
||||||
|
registerAction(new EditProfile(this, myClassName, CREATEPROFILE_ACTION));
|
||||||
|
|
||||||
|
// These actions are special in that they chain to other actions.
|
||||||
|
registerAction(new Login(this, myClassName, LOGIN_ACTION, getAction(LISTSTAFF_ACTION)));
|
||||||
|
registerAction(new Logout(this, myClassName, LOGOUT_ACTION, getAction(LOGIN_ACTION)));
|
||||||
|
registerAction(new FindProfile(this, myClassName, FINDPROFILE_ACTION, getAction(VIEWPROFILE_ACTION)));
|
||||||
|
registerAction(new UpdateProfile(this, myClassName, UPDATEPROFILE_ACTION, getAction(VIEWPROFILE_ACTION)));
|
||||||
|
registerAction(new DeleteProfile(this, myClassName, DELETEPROFILE_ACTION, getAction(LISTSTAFF_ACTION)));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the category attribute of the CommandInjection object
|
||||||
|
*
|
||||||
|
* @return The category value
|
||||||
|
*/
|
||||||
|
public Category getDefaultCategory()
|
||||||
|
{
|
||||||
|
return AbstractLesson.A2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the hints attribute of the DirectoryScreen object
|
||||||
|
*
|
||||||
|
* @return The hints value
|
||||||
|
*/
|
||||||
|
protected List getHints()
|
||||||
|
{
|
||||||
|
List hints = new ArrayList();
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the instructions attribute of the ParameterInjection object
|
||||||
|
*
|
||||||
|
* @return The instructions value
|
||||||
|
*/
|
||||||
|
public String getInstructions(WebSession s)
|
||||||
|
{
|
||||||
|
String instructions = "";
|
||||||
|
|
||||||
|
if (!getLessonTracker(s).getCompleted())
|
||||||
|
{
|
||||||
|
switch (getStage(s))
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
instructions = "Stage " + getStage(s) + ": Breaking functional access control.<br>" +
|
||||||
|
"You should be able to login as a regular employee and delete another user's employee " +
|
||||||
|
"profile, even though that is supposed to be an HR-only function.";
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
instructions = "Stage " + getStage(s) + ": Implementing access control in the Business Layer<br>"
|
||||||
|
+ "Access control has already been implemented in the Presentation Layer, but as we have just " +
|
||||||
|
"seen, this is not enough. Implement access control in the Businesss Layer to verify " +
|
||||||
|
"authorization to use the Delete function before actually executing it.";
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
instructions = "Stage " + getStage(s) + ": Breaking data access control.<br>" +
|
||||||
|
"Data Layer access control is being already done on the staff list, but it has not been " +
|
||||||
|
"globally implemented. Take advantage of this to login as a regular employee and view the " +
|
||||||
|
"CEO's employee profile.";
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
instructions = "Stage " + getStage(s) + ": Implementing access control in the Data Layer.<br>" +
|
||||||
|
"Implement Data Layer access control to prevent unauthorized (and potentially career threatening) " +
|
||||||
|
"access to employee personal data.";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Illegal stage value
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return instructions;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected LessonAction getAction(String actionName)
|
||||||
|
{
|
||||||
|
return (LessonAction) lessonFunctions.get(actionName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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");
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
catch (ParameterNotFoundException pnfe)
|
||||||
|
{
|
||||||
|
// Let them eat login page.
|
||||||
|
requestedActionName = LOGIN_ACTION;
|
||||||
|
}
|
||||||
|
//System.out.println("Requested lesson action: " + requestedActionName);
|
||||||
|
|
||||||
|
if (requestedActionName != null)
|
||||||
|
{
|
||||||
|
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))
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAuthorized(WebSession s, int userId, String functionId)
|
||||||
|
{
|
||||||
|
//System.out.println("Checking authorization from " + getCurrentAction(s));
|
||||||
|
LessonAction action = (LessonAction) lessonFunctions.get(getCurrentAction(s));
|
||||||
|
return action.isAuthorized(s, userId, functionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getUserId(WebSession s) throws ParameterNotFoundException
|
||||||
|
{
|
||||||
|
LessonAction action = (LessonAction) lessonFunctions.get(getCurrentAction(s));
|
||||||
|
return action.getUserId(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUserName(WebSession s) throws ParameterNotFoundException
|
||||||
|
{
|
||||||
|
LessonAction action = (LessonAction) lessonFunctions.get(getCurrentAction(s));
|
||||||
|
return action.getUserName(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTemplatePage(WebSession s)
|
||||||
|
{
|
||||||
|
return JSP_PATH + LESSON_NAME + ".jsp";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPage(WebSession s)
|
||||||
|
{
|
||||||
|
String page = JSP_PATH + getCurrentAction(s) + ".jsp";
|
||||||
|
//System.out.println("Retrieved sub-view page for " + this.getClass().getName() + " of " + page);
|
||||||
|
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
|
||||||
|
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";
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
package org.owasp.webgoat.lessons.RoleBasedAccessControl;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||||
|
import org.owasp.webgoat.lessons.DefaultLessonAction;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
|
||||||
|
public class SearchStaff extends DefaultLessonAction
|
||||||
|
{
|
||||||
|
public SearchStaff(AbstractLesson lesson, String lessonName, String actionName)
|
||||||
|
{
|
||||||
|
super(lesson, lessonName, actionName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNextPage(WebSession s)
|
||||||
|
{
|
||||||
|
return RoleBasedAccessControl.SEARCHSTAFF_ACTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,254 @@
|
|||||||
|
package org.owasp.webgoat.lessons.RoleBasedAccessControl;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||||
|
import org.owasp.webgoat.lessons.DefaultLessonAction;
|
||||||
|
import org.owasp.webgoat.lessons.LessonAction;
|
||||||
|
import org.owasp.webgoat.session.Employee;
|
||||||
|
import org.owasp.webgoat.session.ParameterNotFoundException;
|
||||||
|
import org.owasp.webgoat.session.UnauthenticatedException;
|
||||||
|
import org.owasp.webgoat.session.UnauthorizedException;
|
||||||
|
import org.owasp.webgoat.session.ValidationException;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
|
||||||
|
public class UpdateProfile extends DefaultLessonAction
|
||||||
|
{
|
||||||
|
private LessonAction chainedAction;
|
||||||
|
|
||||||
|
public UpdateProfile(AbstractLesson 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() + "." + 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 = '" + employee.getFirstName() +
|
||||||
|
"', last_name = '" + employee.getLastName() +
|
||||||
|
"', ssn = '" + employee.getSsn() +
|
||||||
|
"', title = '" + employee.getTitle() +
|
||||||
|
"', phone = '" + employee.getPhoneNumber() +
|
||||||
|
"', address1 = '" + employee.getAddress1() +
|
||||||
|
"', address2 = '" + employee.getAddress2() +
|
||||||
|
"', manager = " + employee.getManager() +
|
||||||
|
", start_date = '" + employee.getStartDate() +
|
||||||
|
"', ccn = '" + employee.getCcn() +
|
||||||
|
"', ccn_limit = " + employee.getCcnLimit() +
|
||||||
|
// "', disciplined_date = '" + employee.getDisciplinaryActionDate() +
|
||||||
|
// "', disciplined_notes = '" + employee.getDisciplinaryActionNotes() +
|
||||||
|
", personal_description = '" + employee.getPersonalDescription() +
|
||||||
|
"' WHERE userid = " + subjectId;
|
||||||
|
//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 );
|
||||||
|
}
|
||||||
|
catch ( SQLException sqle )
|
||||||
|
{
|
||||||
|
s.setMessage( "Error updating employee profile" );
|
||||||
|
sqle.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
s.setMessage( "Error updating employee profile" );
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void changeEmployeeProfile_BACKUP(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 = '" + employee.getFirstName() +
|
||||||
|
"', last_name = '" + employee.getLastName() +
|
||||||
|
"', ssn = '" + employee.getSsn() +
|
||||||
|
"', title = '" + employee.getTitle() +
|
||||||
|
"', phone = '" + employee.getPhoneNumber() +
|
||||||
|
"', address1 = '" + employee.getAddress1() +
|
||||||
|
"', address2 = '" + employee.getAddress2() +
|
||||||
|
"', manager = " + employee.getManager() +
|
||||||
|
", start_date = '" + employee.getStartDate() +
|
||||||
|
"', ccn = '" + employee.getCcn() +
|
||||||
|
"', ccn_limit = " + employee.getCcnLimit() +
|
||||||
|
// "', disciplined_date = '" + employee.getDisciplinaryActionDate() +
|
||||||
|
// "', disciplined_notes = '" + employee.getDisciplinaryActionNotes() +
|
||||||
|
", personal_description = '" + employee.getPersonalDescription() +
|
||||||
|
"' WHERE userid = " + subjectId;
|
||||||
|
//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 );
|
||||||
|
}
|
||||||
|
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 newUID = getNextUID(s);
|
||||||
|
// FIXME: This max() thing doesn't work on InstantDB.
|
||||||
|
String query = "INSERT INTO employee VALUES (" + newUID + ", '"
|
||||||
|
+ employee.getFirstName() + "','"
|
||||||
|
+ employee.getLastName() + "','"
|
||||||
|
+ employee.getSsn() + "','goober57x','"
|
||||||
|
+ employee.getTitle() + "','"
|
||||||
|
+ employee.getPhoneNumber() + "','"
|
||||||
|
+ employee.getAddress1() + "','"
|
||||||
|
+ employee.getAddress2() + "',"
|
||||||
|
+ employee.getManager() + ",'"
|
||||||
|
+ employee.getStartDate() + "',"
|
||||||
|
+ employee.getSalary() + ",'"
|
||||||
|
+ employee.getCcn() + "',"
|
||||||
|
+ employee.getCcnLimit() + ",'"
|
||||||
|
+ employee.getDisciplinaryActionDate() + "','"
|
||||||
|
+ employee.getDisciplinaryActionNotes() + "','"
|
||||||
|
+ employee.getPersonalDescription()
|
||||||
|
+ "')";
|
||||||
|
|
||||||
|
//System.out.println("Query: " + query);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Statement statement = WebSession.getConnection(s).createStatement();
|
||||||
|
statement.executeUpdate(query);
|
||||||
|
}
|
||||||
|
catch ( SQLException sqle )
|
||||||
|
{
|
||||||
|
sqle.printStackTrace();
|
||||||
|
s.setMessage( "Error updating employee profile" );
|
||||||
|
}
|
||||||
|
|
||||||
|
query = "INSERT INTO roles VALUES (" + newUID + ", 'hr')";
|
||||||
|
|
||||||
|
//System.out.println("Query: " + query);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Statement statement = WebSession.getConnection(s).createStatement();
|
||||||
|
statement.executeUpdate(query);
|
||||||
|
}
|
||||||
|
catch ( SQLException sqle )
|
||||||
|
{
|
||||||
|
sqle.printStackTrace();
|
||||||
|
s.setMessage( "Error updating employee profile" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
s.setMessage( "Error updating employee profile" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,185 @@
|
|||||||
|
package org.owasp.webgoat.lessons.RoleBasedAccessControl;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||||
|
import org.owasp.webgoat.lessons.DefaultLessonAction;
|
||||||
|
import org.owasp.webgoat.session.Employee;
|
||||||
|
import org.owasp.webgoat.session.ParameterNotFoundException;
|
||||||
|
import org.owasp.webgoat.session.UnauthenticatedException;
|
||||||
|
import org.owasp.webgoat.session.UnauthorizedException;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
|
||||||
|
public class ViewProfile extends DefaultLessonAction
|
||||||
|
{
|
||||||
|
public ViewProfile(AbstractLesson 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() + "." + 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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() + "." + RoleBasedAccessControl.USER_ID);
|
||||||
|
int employeeId = s.getParser().getIntParameter(RoleBasedAccessControl.EMPLOYEE_ID);
|
||||||
|
|
||||||
|
if (getStage(s) == 3 && !isAuthorizedForEmployee(s, userId, employeeId))
|
||||||
|
{
|
||||||
|
s.setMessage( "Welcome to stage 4 -- protecting the data layer" );
|
||||||
|
setStage(s, 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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.
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,134 @@
|
|||||||
|
package org.owasp.webgoat.lessons.SQLInjection;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||||
|
import org.owasp.webgoat.lessons.DefaultLessonAction;
|
||||||
|
import org.owasp.webgoat.session.EmployeeStub;
|
||||||
|
import org.owasp.webgoat.session.ParameterNotFoundException;
|
||||||
|
import org.owasp.webgoat.session.UnauthenticatedException;
|
||||||
|
import org.owasp.webgoat.session.UnauthorizedException;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
|
||||||
|
public class ListStaff extends DefaultLessonAction
|
||||||
|
{
|
||||||
|
public ListStaff(AbstractLesson 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() + "." + SQLInjection.USER_ID);
|
||||||
|
|
||||||
|
List employees = getAllEmployees(s, userId);
|
||||||
|
setSessionAttribute(s, getLessonName() + "." + SQLInjection.STAFF_ATTRIBUTE_KEY, employees);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new UnauthenticatedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNextPage(WebSession s)
|
||||||
|
{
|
||||||
|
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 employees = new Vector();
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List getAllEmployees_BACKUP(WebSession s, int userId)
|
||||||
|
throws UnauthorizedException
|
||||||
|
{
|
||||||
|
// Query the database for all employees "owned" by the given employee
|
||||||
|
|
||||||
|
List employees = new Vector();
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,245 @@
|
|||||||
|
package org.owasp.webgoat.lessons.SQLInjection;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||||
|
import org.owasp.webgoat.lessons.DefaultLessonAction;
|
||||||
|
import org.owasp.webgoat.lessons.LessonAction;
|
||||||
|
import org.owasp.webgoat.session.EmployeeStub;
|
||||||
|
import org.owasp.webgoat.session.ParameterNotFoundException;
|
||||||
|
import org.owasp.webgoat.session.UnauthenticatedException;
|
||||||
|
import org.owasp.webgoat.session.UnauthorizedException;
|
||||||
|
import org.owasp.webgoat.session.ValidationException;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
|
||||||
|
public class Login extends DefaultLessonAction
|
||||||
|
{
|
||||||
|
private LessonAction chainedAction;
|
||||||
|
|
||||||
|
public Login(AbstractLesson 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(SQLInjection.EMPLOYEE_ID);
|
||||||
|
String password = s.getParser().getRawParameter(SQLInjection.PASSWORD);
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
{
|
||||||
|
// No credentials offered, so we log them out
|
||||||
|
setSessionAttribute(s, getLessonName() + ".isAuthenticated", Boolean.FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
{
|
||||||
|
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, getLessonName() + ".isAuthenticated", Boolean.TRUE);
|
||||||
|
setSessionAttribute(s, getLessonName() + "." + SQLInjection.USER_ID, userId);
|
||||||
|
authenticated = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( SQLException sqle )
|
||||||
|
{
|
||||||
|
s.setMessage( "Error logging in" );
|
||||||
|
sqle.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
s.setMessage( "Error logging in" );
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
//System.out.println("Lesson login result: " + authenticated);
|
||||||
|
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 + " 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, getLessonName() + ".isAuthenticated", Boolean.TRUE);
|
||||||
|
setSessionAttribute(s, getLessonName() + "." + SQLInjection.USER_ID, userId);
|
||||||
|
authenticated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch ( SQLException sqle )
|
||||||
|
{
|
||||||
|
s.setMessage( "Error logging in" );
|
||||||
|
sqle.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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 employees = new Vector();
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void updateLessonStatus(WebSession s)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String employeeId = s.getParser().getStringParameter(SQLInjection.EMPLOYEE_ID);
|
||||||
|
String password = s.getParser().getRawParameter(SQLInjection.PASSWORD);
|
||||||
|
switch (getStage(s))
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
if (Integer.parseInt(employeeId) == SQLInjection.PRIZE_EMPLOYEE_ID && isAuthenticated(s))
|
||||||
|
{
|
||||||
|
s.setMessage( "Welcome to stage 2" );
|
||||||
|
setStage(s, 2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
// This assumes the student hasn't modified login_BACKUP().
|
||||||
|
if (Integer.parseInt(employeeId) == SQLInjection.PRIZE_EMPLOYEE_ID &&
|
||||||
|
!isAuthenticated(s) && login_BACKUP(s, employeeId, password))
|
||||||
|
{
|
||||||
|
s.setMessage( "Welcome to stage 3" );
|
||||||
|
setStage(s, 3);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ParameterNotFoundException pnfe)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,346 @@
|
|||||||
|
package org.owasp.webgoat.lessons.SQLInjection;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Hashtable;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.ecs.ElementContainer;
|
||||||
|
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||||
|
import org.owasp.webgoat.lessons.Category;
|
||||||
|
import org.owasp.webgoat.lessons.LessonAction;
|
||||||
|
import org.owasp.webgoat.lessons.LessonAdapter;
|
||||||
|
import org.owasp.webgoat.lessons.RoleBasedAccessControl.DeleteProfile;
|
||||||
|
import org.owasp.webgoat.lessons.RoleBasedAccessControl.EditProfile;
|
||||||
|
import org.owasp.webgoat.lessons.RoleBasedAccessControl.FindProfile;
|
||||||
|
import org.owasp.webgoat.lessons.RoleBasedAccessControl.Logout;
|
||||||
|
import org.owasp.webgoat.lessons.RoleBasedAccessControl.SearchStaff;
|
||||||
|
import org.owasp.webgoat.lessons.RoleBasedAccessControl.UpdateProfile;
|
||||||
|
import org.owasp.webgoat.session.DatabaseUtilities;
|
||||||
|
import org.owasp.webgoat.session.ParameterNotFoundException;
|
||||||
|
import org.owasp.webgoat.session.UnauthenticatedException;
|
||||||
|
import org.owasp.webgoat.session.UnauthorizedException;
|
||||||
|
import org.owasp.webgoat.session.ValidationException;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2006 Free Software Foundation developed under the custody of the Open Web
|
||||||
|
* Application Security Project (http://www.owasp.org) This software package org.owasp.webgoat.is published by OWASP
|
||||||
|
* under the GPL. You should read and accept the LICENSE before you use, modify and/or redistribute
|
||||||
|
* this software.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class SQLInjection extends LessonAdapter
|
||||||
|
{
|
||||||
|
public final static String DESCRIPTION = "description";
|
||||||
|
public final static String DISCIPLINARY_DATE = "disciplinaryDate";
|
||||||
|
public final static String DISCIPLINARY_NOTES = "disciplinaryNotes";
|
||||||
|
public final static String CCN_LIMIT = "ccnLimit";
|
||||||
|
public final static String CCN = "ccn";
|
||||||
|
public final static String SALARY = "salary";
|
||||||
|
public final static String START_DATE = "startDate";
|
||||||
|
public final static String MANAGER = "manager";
|
||||||
|
public final static String ADDRESS1 = "address1";
|
||||||
|
public final static String ADDRESS2 = "address2";
|
||||||
|
public final static String PHONE_NUMBER = "phoneNumber";
|
||||||
|
public final static String TITLE = "title";
|
||||||
|
public final static String SSN = "ssn";
|
||||||
|
public final static String LAST_NAME = "lastName";
|
||||||
|
public final static String FIRST_NAME = "firstName";
|
||||||
|
public final static String PASSWORD = "password";
|
||||||
|
|
||||||
|
public final static String EMPLOYEE_ID = "employee_id";
|
||||||
|
public final static String USER_ID = "user_id";
|
||||||
|
public final static String SEARCHNAME = "search_name";
|
||||||
|
public final static String SEARCHRESULT_ATTRIBUTE_KEY = "SearchResult";
|
||||||
|
public final static String EMPLOYEE_ATTRIBUTE_KEY = "Employee";
|
||||||
|
public final static String STAFF_ATTRIBUTE_KEY = "Staff";
|
||||||
|
|
||||||
|
public final static String LOGIN_ACTION = "Login";
|
||||||
|
public final static String LOGOUT_ACTION = "Logout";
|
||||||
|
public final static String LISTSTAFF_ACTION = "ListStaff";
|
||||||
|
public final static String SEARCHSTAFF_ACTION = "SearchStaff";
|
||||||
|
public final static String FINDPROFILE_ACTION = "FindProfile";
|
||||||
|
public final static String VIEWPROFILE_ACTION = "ViewProfile";
|
||||||
|
public final static String EDITPROFILE_ACTION = "EditProfile";
|
||||||
|
public final static String UPDATEPROFILE_ACTION = "UpdateProfile";
|
||||||
|
public final static String CREATEPROFILE_ACTION = "CreateProfile";
|
||||||
|
public final static String DELETEPROFILE_ACTION = "DeleteProfile";
|
||||||
|
public final static String ERROR_ACTION = "error";
|
||||||
|
|
||||||
|
private final static String LESSON_NAME = "SQLInjection";
|
||||||
|
private final static String JSP_PATH = "/lessons/" + LESSON_NAME + "/";
|
||||||
|
|
||||||
|
private final static Integer DEFAULT_RANKING = new Integer(75);
|
||||||
|
|
||||||
|
public final static int PRIZE_EMPLOYEE_ID = 112;
|
||||||
|
public final static String PRIZE_EMPLOYEE_NAME = "Neville Bartholomew";
|
||||||
|
|
||||||
|
private static Connection connection = null;
|
||||||
|
|
||||||
|
private Map lessonFunctions = new Hashtable();
|
||||||
|
|
||||||
|
public static synchronized Connection getConnection(WebSession s)
|
||||||
|
throws SQLException, ClassNotFoundException
|
||||||
|
{
|
||||||
|
if ( connection == null )
|
||||||
|
{
|
||||||
|
connection = DatabaseUtilities.makeConnection( s );
|
||||||
|
}
|
||||||
|
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SQLInjection()
|
||||||
|
{
|
||||||
|
String myClassName = parseClassName(this.getClass().getName());
|
||||||
|
registerAction(new ListStaff(this, myClassName, LISTSTAFF_ACTION));
|
||||||
|
registerAction(new SearchStaff(this, myClassName, SEARCHSTAFF_ACTION));
|
||||||
|
registerAction(new ViewProfile(this, myClassName, VIEWPROFILE_ACTION));
|
||||||
|
registerAction(new EditProfile(this, myClassName, EDITPROFILE_ACTION));
|
||||||
|
registerAction(new EditProfile(this, myClassName, CREATEPROFILE_ACTION));
|
||||||
|
|
||||||
|
// These actions are special in that they chain to other actions.
|
||||||
|
registerAction(new Login(this, myClassName, LOGIN_ACTION, getAction(LISTSTAFF_ACTION)));
|
||||||
|
registerAction(new Logout(this, myClassName, LOGOUT_ACTION, getAction(LOGIN_ACTION)));
|
||||||
|
registerAction(new FindProfile(this, myClassName, FINDPROFILE_ACTION, getAction(VIEWPROFILE_ACTION)));
|
||||||
|
registerAction(new UpdateProfile(this, myClassName, UPDATEPROFILE_ACTION, getAction(VIEWPROFILE_ACTION)));
|
||||||
|
registerAction(new DeleteProfile(this, myClassName, DELETEPROFILE_ACTION, getAction(LISTSTAFF_ACTION)));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the category attribute of the CrossSiteScripting object
|
||||||
|
*
|
||||||
|
* @return The category value
|
||||||
|
*/
|
||||||
|
public Category getDefaultCategory()
|
||||||
|
{
|
||||||
|
return AbstractLesson.A6;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the hints attribute of the DirectoryScreen object
|
||||||
|
*
|
||||||
|
* @return The hints value
|
||||||
|
*/
|
||||||
|
protected List getHints()
|
||||||
|
{
|
||||||
|
List hints = new ArrayList();
|
||||||
|
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 a password of [ 101 OR 1=1 ORDER BY 'salary' ]." );
|
||||||
|
|
||||||
|
// Stage 4
|
||||||
|
|
||||||
|
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())
|
||||||
|
{
|
||||||
|
switch (getStage(s))
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
instructions = "Stage " + getStage(s) + ": 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.";
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
instructions = "Stage " + getStage(s) + ": Use a parameterized query.<br>" +
|
||||||
|
"A dynamic SQL query is not necessary for the login function to work. Change login " +
|
||||||
|
"to use a parameterized query to protect against malicious SQL in the query parameters.";
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
instructions = "Stage " + getStage(s) + ": Use Integer SQL Injection to bypass access control.<br>" +
|
||||||
|
"The goal here is to view the CEO's employee profile, again, even with data access " +
|
||||||
|
"control checks in place from a previous lesson. " +
|
||||||
|
"As before, you do not have the password, but the form is SQL injectable.";
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
instructions = "Stage " + getStage(s) + ": Use a parameterized query again.<br>" +
|
||||||
|
"Change the ViewProfile function to use a parameterized query to protect against " +
|
||||||
|
"malicious SQL in the numeric query parameter.";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Illegal stage value
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return instructions;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected LessonAction getAction(String actionName)
|
||||||
|
{
|
||||||
|
return (LessonAction) 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAuthorized(WebSession s, int userId, String functionId)
|
||||||
|
{
|
||||||
|
//System.out.println("Checking authorization from " + getCurrentAction(s));
|
||||||
|
LessonAction action = (LessonAction) lessonFunctions.get(getCurrentAction(s));
|
||||||
|
return action.isAuthorized(s, userId, functionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getUserId(WebSession s) throws ParameterNotFoundException
|
||||||
|
{
|
||||||
|
LessonAction action = (LessonAction) lessonFunctions.get(getCurrentAction(s));
|
||||||
|
return action.getUserId(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUserName(WebSession s) throws ParameterNotFoundException
|
||||||
|
{
|
||||||
|
LessonAction action = (LessonAction) lessonFunctions.get(getCurrentAction(s));
|
||||||
|
return action.getUserName(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTemplatePage(WebSession s)
|
||||||
|
{
|
||||||
|
return JSP_PATH + LESSON_NAME + ".jsp";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPage(WebSession s)
|
||||||
|
{
|
||||||
|
String page = JSP_PATH + getCurrentAction(s) + ".jsp";
|
||||||
|
//System.out.println("Retrieved sub-view page for " + this.getClass().getName() + " of " + page);
|
||||||
|
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Integer getDefaultRanking()
|
||||||
|
{
|
||||||
|
return DEFAULT_RANKING;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the title attribute of the CrossSiteScripting object
|
||||||
|
*
|
||||||
|
* @return The title value
|
||||||
|
*/
|
||||||
|
public String getTitle()
|
||||||
|
{
|
||||||
|
return "LAB: SQL Injection";
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,224 @@
|
|||||||
|
package org.owasp.webgoat.lessons.SQLInjection;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||||
|
import org.owasp.webgoat.lessons.DefaultLessonAction;
|
||||||
|
import org.owasp.webgoat.session.Employee;
|
||||||
|
import org.owasp.webgoat.session.ParameterNotFoundException;
|
||||||
|
import org.owasp.webgoat.session.UnauthenticatedException;
|
||||||
|
import org.owasp.webgoat.session.UnauthorizedException;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
|
||||||
|
public class ViewProfile extends DefaultLessonAction
|
||||||
|
{
|
||||||
|
public ViewProfile(AbstractLesson lesson, String lessonName, 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() + "." + 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 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 * 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, 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);
|
||||||
|
switch (getStage(s))
|
||||||
|
{
|
||||||
|
case 3:
|
||||||
|
// 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()))
|
||||||
|
{
|
||||||
|
s.setMessage( "Welcome to stage 4" );
|
||||||
|
setStage(s, 4);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
// 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)
|
||||||
|
{
|
||||||
|
s.setMessage("Congratulations. You have successfully completed this lesson");
|
||||||
|
getLesson().getLessonTracker( s ).setCompleted( true );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ParameterNotFoundException pnfe)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
418
webgoat/main/project/org/owasp/webgoat/lessons/SoapRequest.java
Normal file
418
webgoat/main/project/org/owasp/webgoat/lessons/SoapRequest.java
Normal file
@ -0,0 +1,418 @@
|
|||||||
|
/*
|
||||||
|
* Created on May 26, 2005
|
||||||
|
*
|
||||||
|
* TODO To change the template for this generated file go to
|
||||||
|
* Window - Preferences - Java - Code Style - Code Templates
|
||||||
|
*/
|
||||||
|
package org.owasp.webgoat.lessons;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
import org.apache.ecs.ElementContainer;
|
||||||
|
import org.apache.ecs.html.A;
|
||||||
|
import org.apache.ecs.html.BR;
|
||||||
|
import org.apache.ecs.html.Input;
|
||||||
|
import org.apache.ecs.html.P;
|
||||||
|
import org.apache.ecs.html.TD;
|
||||||
|
import org.apache.ecs.html.TR;
|
||||||
|
import org.apache.ecs.html.Table;
|
||||||
|
import org.owasp.webgoat.session.DatabaseUtilities;
|
||||||
|
import org.owasp.webgoat.session.ECSFactory;
|
||||||
|
import org.owasp.webgoat.session.ParameterNotFoundException;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author asmolen
|
||||||
|
*
|
||||||
|
* TODO To change the template for this generated type comment go to
|
||||||
|
* Window - Preferences - Java - Code Style - Code Templates
|
||||||
|
*/
|
||||||
|
public class SoapRequest extends LessonAdapter {
|
||||||
|
/* TEST CODE
|
||||||
|
private final static String ACCT_NUM = "account_number";
|
||||||
|
private static Connection connection = null;
|
||||||
|
private String accountNumber;
|
||||||
|
*/
|
||||||
|
|
||||||
|
//static boolean completed;
|
||||||
|
public static Connection connection = null;
|
||||||
|
public final static String firstName = "getFirstName";
|
||||||
|
public final static String lastName = "getLastName";
|
||||||
|
public final static String loginCount = "getLoginCount";
|
||||||
|
public final static String ccNumber = "getCreditCard";
|
||||||
|
|
||||||
|
//int instead of boolean to keep track of method invocation count
|
||||||
|
static int accessFirstName;
|
||||||
|
static int accessLastName;
|
||||||
|
static int accessCreditCard;
|
||||||
|
static int accessLoginCount;
|
||||||
|
|
||||||
|
protected Category getDefaultCategory()
|
||||||
|
{
|
||||||
|
return AbstractLesson.WEB_SERVICES;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List getHints()
|
||||||
|
{
|
||||||
|
List<String> hints = new ArrayList<String>();
|
||||||
|
hints.add("Accessible operations are delimited by the <operation> tag contained within the <portType> section of the WSDL. <BR> Below is an example of a typical operation (getFirstName): <br><br>" +
|
||||||
|
"<wsdl:portType name=\"SoapRequest\"> <br>" +
|
||||||
|
"<wsdl:<strong>operation name=\"getFirstName\"</strong>><br>" +
|
||||||
|
"<wsdl:input message=\"impl:getFirstNameRequest\" name=\"getFirstNameRequest\" /><br>" +
|
||||||
|
"<wsdl:output message=\"impl:getFirstNameResponse\" name=\"getFirstNameResponse\" /><br>" +
|
||||||
|
"<wsdlsoap:operation soapAction=\"\" />" +
|
||||||
|
"</wsdl:portType><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 <definitions> 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 \"<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>" +
|
||||||
|
"<wsdl:message name=\"getFirstNameRequest\"<br><br>" +
|
||||||
|
"<wsdl:<strong>part name=\"id\" type=\"xsd:int\"</strong> /><br>" +
|
||||||
|
"</wsdl:message><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 "" <br><br>" +
|
||||||
|
"The SOAP message body has the following format:<br>" +
|
||||||
|
"<?xml version=\"1.0\" encoding=\"UTF-8\"?> <br>" +
|
||||||
|
"<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\"> <br>" +
|
||||||
|
" <SOAP-ENV:Body> <br>" +
|
||||||
|
" <ns1:getFirstName SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:ns1=\"http://lessons\"> <br>" +
|
||||||
|
" <id xsi:type=\"xsd:int\">101</id> <br>"+
|
||||||
|
" </ns1:getFirstName> <br>" +
|
||||||
|
" </SOAP-ENV:Body> <br>" +
|
||||||
|
"</SOAP-ENV:Envelope> <br><br>" +
|
||||||
|
"Intercept the HTTP request and try to create a SOAP request.";
|
||||||
|
soapEnv.replaceAll("(?s) "," ");
|
||||||
|
hints.add(soapEnv);
|
||||||
|
|
||||||
|
return hints;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final static Integer DEFAULT_RANKING = new Integer(100);
|
||||||
|
|
||||||
|
protected Integer getDefaultRanking()
|
||||||
|
{
|
||||||
|
return DEFAULT_RANKING;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitle()
|
||||||
|
{
|
||||||
|
return "How to 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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
TR tr = new TR();
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
TR tr = new TR();
|
||||||
|
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);
|
||||||
|
|
||||||
|
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;
|
||||||
|
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
|
||||||
|
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");
|
||||||
|
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");
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
//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>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//getLessonTracker( s ).setCompleted( SoapRequest.completed );
|
||||||
|
return (ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getResults(int id, String field) {
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Connection connection = DatabaseUtilities.makeConnection();
|
||||||
|
if (connection == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,348 @@
|
|||||||
|
package org.owasp.webgoat.lessons;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.ResultSetMetaData;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
import org.apache.ecs.ElementContainer;
|
||||||
|
import org.apache.ecs.html.BR;
|
||||||
|
import org.apache.ecs.html.Option;
|
||||||
|
import org.apache.ecs.html.P;
|
||||||
|
import org.apache.ecs.html.PRE;
|
||||||
|
import org.apache.ecs.html.Select;
|
||||||
|
import org.owasp.webgoat.session.DatabaseUtilities;
|
||||||
|
import org.owasp.webgoat.session.ECSFactory;
|
||||||
|
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 org.owasp.webgoat.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
|
||||||
|
*/
|
||||||
|
public class SqlNumericInjection extends LessonAdapter
|
||||||
|
{
|
||||||
|
|
||||||
|
private final static String STATION_ID = "station";
|
||||||
|
|
||||||
|
private static Connection connection = null;
|
||||||
|
private String station;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
{
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
if ( connection == null )
|
||||||
|
{
|
||||||
|
connection = DatabaseUtilities.makeConnection( 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
|
||||||
|
{
|
||||||
|
if ( connection == null )
|
||||||
|
{
|
||||||
|
connection = DatabaseUtilities.makeConnection( 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 );
|
||||||
|
|
||||||
|
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
|
||||||
|
{
|
||||||
|
|
||||||
|
if ( connection == null )
|
||||||
|
{
|
||||||
|
connection = DatabaseUtilities.makeConnection( 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 AbstractLesson.A6;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the hints attribute of the DatabaseFieldScreen object
|
||||||
|
*
|
||||||
|
* @return The hints value
|
||||||
|
*/
|
||||||
|
protected List getHints()
|
||||||
|
{
|
||||||
|
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 ( "How to Perform Numeric SQL Injection" );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for the DatabaseFieldScreen object
|
||||||
|
*
|
||||||
|
* @param s Description of the Parameter
|
||||||
|
*/
|
||||||
|
public void handleRequest( WebSession s )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
super.handleRequest( s );
|
||||||
|
|
||||||
|
if ( connection == null )
|
||||||
|
{
|
||||||
|
connection = DatabaseUtilities.makeConnection( s );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
System.out.println( "Exception caught: " + e );
|
||||||
|
e.printStackTrace( System.out );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,275 @@
|
|||||||
|
package org.owasp.webgoat.lessons;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.ResultSetMetaData;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
import org.apache.ecs.ElementContainer;
|
||||||
|
import org.apache.ecs.html.BR;
|
||||||
|
import org.apache.ecs.html.Input;
|
||||||
|
import org.apache.ecs.html.P;
|
||||||
|
import org.apache.ecs.html.PRE;
|
||||||
|
import org.owasp.webgoat.session.DatabaseUtilities;
|
||||||
|
import org.owasp.webgoat.session.ECSFactory;
|
||||||
|
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 org.owasp.webgoat.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
|
||||||
|
*/
|
||||||
|
public class SqlStringInjection extends LessonAdapter
|
||||||
|
{
|
||||||
|
private final static String ACCT_NAME = "account_name";
|
||||||
|
private static Connection connection = null;
|
||||||
|
private static String STAGE = "stage";
|
||||||
|
private String accountName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
{
|
||||||
|
if ( connection == null )
|
||||||
|
{
|
||||||
|
connection = DatabaseUtilities.makeConnection( s );
|
||||||
|
}
|
||||||
|
|
||||||
|
ec.addElement( makeAccountLine( s ) );
|
||||||
|
|
||||||
|
String query = "SELECT * FROM user_data WHERE last_name = '" + accountName +"'";
|
||||||
|
ec.addElement( new PRE( query ) );
|
||||||
|
|
||||||
|
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 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 switch 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() ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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. Type 'restart' in the input field if you wish to " +
|
||||||
|
" to return to the injectable query");
|
||||||
|
if ( s.getParser().getRawParameter( ACCT_NAME, "YOUR_NAME" ).equals("restart"))
|
||||||
|
{
|
||||||
|
getLessonTracker(s).getLessonProperties().setProperty(STAGE,"1");
|
||||||
|
return( injectableQuery(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
ec.addElement( new BR() );
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if ( connection == null )
|
||||||
|
{
|
||||||
|
connection = DatabaseUtilities.makeConnection( 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( ec );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Element makeAccountLine( WebSession s )
|
||||||
|
{
|
||||||
|
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 AbstractLesson.A6;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the hints attribute of the DatabaseFieldScreen object
|
||||||
|
*
|
||||||
|
* @return The hints value
|
||||||
|
*/
|
||||||
|
protected List getHints()
|
||||||
|
{
|
||||||
|
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 ( "How to Perform String SQL Injection" );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for the DatabaseFieldScreen object
|
||||||
|
*
|
||||||
|
* @param s Description of the Parameter
|
||||||
|
*/
|
||||||
|
public void handleRequest( WebSession s )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
super.handleRequest( s );
|
||||||
|
|
||||||
|
if ( connection == null )
|
||||||
|
{
|
||||||
|
connection = DatabaseUtilities.makeConnection( s );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
System.out.println( "Exception caught: " + e );
|
||||||
|
e.printStackTrace( System.out );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
333
webgoat/main/project/org/owasp/webgoat/lessons/StoredXss.java
Normal file
333
webgoat/main/project/org/owasp/webgoat/lessons/StoredXss.java
Normal file
@ -0,0 +1,333 @@
|
|||||||
|
package org.owasp.webgoat.lessons;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
import org.apache.ecs.ElementContainer;
|
||||||
|
import org.apache.ecs.StringElement;
|
||||||
|
import org.apache.ecs.html.A;
|
||||||
|
import org.apache.ecs.html.B;
|
||||||
|
import org.apache.ecs.html.H1;
|
||||||
|
import org.apache.ecs.html.HR;
|
||||||
|
import org.apache.ecs.html.Input;
|
||||||
|
import org.apache.ecs.html.P;
|
||||||
|
import org.apache.ecs.html.TD;
|
||||||
|
import org.apache.ecs.html.TR;
|
||||||
|
import org.apache.ecs.html.Table;
|
||||||
|
import org.apache.ecs.html.TextArea;
|
||||||
|
import org.owasp.webgoat.session.*;
|
||||||
|
import org.owasp.webgoat.util.HtmlEncoder;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2002 Free Software Foundation developed under the custody of the Open Web
|
||||||
|
* Application Security Project (http://www.owasp.org) This software package org.owasp.webgoat.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
|
||||||
|
*/
|
||||||
|
public class StoredXss extends LessonAdapter
|
||||||
|
{
|
||||||
|
private final static String MESSAGE = "message";
|
||||||
|
private final static int MESSAGE_COL = 3;
|
||||||
|
private final static String NUMBER = "Num";
|
||||||
|
private final static int NUM_COL = 1;
|
||||||
|
private final static String STANDARD_QUERY = "SELECT * FROM messages";
|
||||||
|
private final static String TITLE = "title";
|
||||||
|
private final static int TITLE_COL = 2;
|
||||||
|
private static Connection connection = null;
|
||||||
|
private static int count = 1;
|
||||||
|
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
|
||||||
|
*
|
||||||
|
* @param s The feature to be added to the Message attribute
|
||||||
|
*/
|
||||||
|
protected void addMessage( WebSession s )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String title = HtmlEncoder.encode( s.getParser().getRawParameter( TITLE, "" ) );
|
||||||
|
String message = s.getParser().getRawParameter( MESSAGE, "" );
|
||||||
|
|
||||||
|
if ( connection == null )
|
||||||
|
{
|
||||||
|
connection = DatabaseUtilities.makeConnection( s );
|
||||||
|
}
|
||||||
|
|
||||||
|
String query = "INSERT INTO messages VALUES (?, ?, ?, ? )";
|
||||||
|
|
||||||
|
PreparedStatement statement = connection.prepareStatement( query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY );
|
||||||
|
statement.setInt(1, count++);
|
||||||
|
statement.setString(2, title);
|
||||||
|
statement.setString(3, message);
|
||||||
|
statement.setString(4, s.getUserName());
|
||||||
|
ResultSet results = statement.executeQuery();
|
||||||
|
}
|
||||||
|
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" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param s Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
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 AbstractLesson.A4;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the hints attribute of the MessageBoardScreen object
|
||||||
|
*
|
||||||
|
* @return The hints value
|
||||||
|
*/
|
||||||
|
protected List getHints()
|
||||||
|
{
|
||||||
|
List hints = new ArrayList();
|
||||||
|
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: <script language=\"javascript\" type=\"text/javascript\">alert(\"Ha Ha Ha\");</script> in the message field." );
|
||||||
|
hints.add( "Enter this: <script>alert(\"document.cookie\");</script> 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 ( "How to Perform Stored Cross Site Scripting (XSS)" );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 );
|
||||||
|
|
||||||
|
if ( connection == null )
|
||||||
|
{
|
||||||
|
connection = DatabaseUtilities.makeConnection( 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( 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
|
||||||
|
{
|
||||||
|
if ( connection == null )
|
||||||
|
{
|
||||||
|
connection = DatabaseUtilities.makeConnection( 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,181 @@
|
|||||||
|
package org.owasp.webgoat.lessons;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.ResultSetMetaData;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
import org.apache.ecs.ElementContainer;
|
||||||
|
import org.apache.ecs.StringElement;
|
||||||
|
import org.apache.ecs.html.Input;
|
||||||
|
import org.apache.ecs.html.P;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.session.*;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2002 Free Software Foundation developed under the custody of the Open Web
|
||||||
|
* Application Security Project (http://www.owasp.org) This software package org.owasp.webgoat.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
|
||||||
|
*/
|
||||||
|
public class ThreadSafetyProblem extends LessonAdapter
|
||||||
|
{
|
||||||
|
private final static String USER_NAME = "username";
|
||||||
|
private Connection connection = null;
|
||||||
|
private static String currentUser;
|
||||||
|
private String originalUser;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
{
|
||||||
|
if ( connection == null )
|
||||||
|
{
|
||||||
|
connection = DatabaseUtilities.makeConnection( s );
|
||||||
|
}
|
||||||
|
|
||||||
|
ec.addElement( new StringElement( "Enter user name: " ) );
|
||||||
|
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: " + 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( "Error generating " + this.getClass().getName() );
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( ec );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the hints attribute of the ConcurrencyScreen object
|
||||||
|
*
|
||||||
|
* @return The hints value
|
||||||
|
*/
|
||||||
|
protected List getHints()
|
||||||
|
{
|
||||||
|
List hints = new ArrayList();
|
||||||
|
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 AbstractLesson.GENERAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the title attribute of the ConcurrencyScreen object
|
||||||
|
*
|
||||||
|
* @return The title value
|
||||||
|
*/
|
||||||
|
public String getTitle()
|
||||||
|
{
|
||||||
|
return ( "How to Exploit Thread Safety Problems" );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for the ConcurrencyScreen object
|
||||||
|
*
|
||||||
|
* @param s Description of the Parameter
|
||||||
|
*/
|
||||||
|
public void handleRequest( WebSession s )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
super.handleRequest( s );
|
||||||
|
|
||||||
|
if ( connection == null )
|
||||||
|
{
|
||||||
|
connection = DatabaseUtilities.makeConnection( s );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
System.out.println( "Exception caught: " + e );
|
||||||
|
e.printStackTrace( System.out );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
225
webgoat/main/project/org/owasp/webgoat/lessons/TraceXSS.java
Normal file
225
webgoat/main/project/org/owasp/webgoat/lessons/TraceXSS.java
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
package org.owasp.webgoat.lessons;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
import org.apache.ecs.ElementContainer;
|
||||||
|
import org.apache.ecs.html.BR;
|
||||||
|
import org.apache.ecs.html.Center;
|
||||||
|
import org.apache.ecs.html.H1;
|
||||||
|
import org.apache.ecs.html.HR;
|
||||||
|
import org.apache.ecs.html.Input;
|
||||||
|
import org.apache.ecs.html.TD;
|
||||||
|
import org.apache.ecs.html.TH;
|
||||||
|
import org.apache.ecs.html.TR;
|
||||||
|
import org.apache.ecs.html.Table;
|
||||||
|
import org.owasp.webgoat.session.ECSFactory;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
import org.owasp.webgoat.util.HtmlEncoder;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2002 Free Software Foundation developed under the custody of the Open Web
|
||||||
|
* Application Security Project (http://www.owasp.org) This software package org.owasp.webgoat.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
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class TraceXSS extends LessonAdapter
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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();
|
||||||
|
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
|
||||||
|
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<65> Centrino<6E>"));
|
||||||
|
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( " " ).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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DOCUMENT ME!
|
||||||
|
*
|
||||||
|
* @return DOCUMENT ME!
|
||||||
|
*/
|
||||||
|
protected Category getDefaultCategory()
|
||||||
|
{
|
||||||
|
return AbstractLesson.A4;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the hints attribute of the AccessControlScreen object
|
||||||
|
*
|
||||||
|
* @return The hints value
|
||||||
|
*/
|
||||||
|
protected List getHints()
|
||||||
|
{
|
||||||
|
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>" +
|
||||||
|
"<script type=\"text/javascript\">if ( navigator.appName.indexOf(\"Microsoft\") !=-1)" +
|
||||||
|
" {var xmlHttp = new ActiveXObject(\"Microsoft.XMLHTTP\");xmlHttp.open(\"GET\", \"./\", false);" +
|
||||||
|
" xmlHttp.send();str1=xmlHttp.responseText; " +
|
||||||
|
"document.write(str1);</script>");
|
||||||
|
hints.add( "Try changing the HTTP GET to a HTTP TRACE" );
|
||||||
|
hints.add( "Try a cross site trace (XST) Command:<br>" +
|
||||||
|
"<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; while (str1.indexOf(\"\\n\") > -1) str1 = str1.replace(\"\\n\",\"<br>\"); " +
|
||||||
|
"document.write(str1);}</script>");
|
||||||
|
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>
|
||||||
|
|
||||||
|
private final static Integer DEFAULT_RANKING = new Integer(130);
|
||||||
|
|
||||||
|
protected Integer getDefaultRanking()
|
||||||
|
{
|
||||||
|
return DEFAULT_RANKING;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the title attribute of the AccessControlScreen object
|
||||||
|
*
|
||||||
|
* @return The title value
|
||||||
|
*/
|
||||||
|
public String getTitle()
|
||||||
|
{
|
||||||
|
return ( "How to Perform Cross Site Trace Attacks" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,226 @@
|
|||||||
|
package org.owasp.webgoat.lessons;
|
||||||
|
|
||||||
|
import java.text.Format;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
import org.apache.ecs.ElementContainer;
|
||||||
|
import org.apache.ecs.StringElement;
|
||||||
|
import org.apache.ecs.html.B;
|
||||||
|
import org.apache.ecs.html.BR;
|
||||||
|
import org.apache.ecs.html.Center;
|
||||||
|
import org.apache.ecs.html.H1;
|
||||||
|
import org.apache.ecs.html.H3;
|
||||||
|
import org.apache.ecs.html.HR;
|
||||||
|
import org.apache.ecs.html.Input;
|
||||||
|
import org.apache.ecs.html.TD;
|
||||||
|
import org.apache.ecs.html.TH;
|
||||||
|
import org.apache.ecs.html.TR;
|
||||||
|
import org.apache.ecs.html.Table;
|
||||||
|
import org.apache.ecs.html.TextArea;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.session.ECSFactory;
|
||||||
|
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 org.owasp.webgoat.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
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class UncheckedEmail extends LessonAdapter
|
||||||
|
{
|
||||||
|
|
||||||
|
private final static String MESSAGE = "msg";
|
||||||
|
private final static String TO = "to";
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
{
|
||||||
|
String to = s.getParser().getRawParameter( TO, "" );
|
||||||
|
|
||||||
|
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("Send OWASP your Comments<BR>").setAlign("left").setColSpan(3));
|
||||||
|
t.addElement( tr );
|
||||||
|
|
||||||
|
tr = new TR();
|
||||||
|
tr.addElement( new TD().addElement( " ").setColSpan(3));
|
||||||
|
t.addElement( tr );
|
||||||
|
|
||||||
|
tr = new TR();
|
||||||
|
tr.addElement( new TH().addElement(new H1("Contact Us")).setAlign("left").setWidth("55%").setVAlign("BOTTOM"));
|
||||||
|
tr.addElement( new TH().addElement( " "));
|
||||||
|
tr.addElement( new TH().addElement(new H3("Contact Information:")).setAlign("left").setVAlign("BOTTOM"));
|
||||||
|
t.addElement( tr );
|
||||||
|
|
||||||
|
|
||||||
|
tr = new TR();
|
||||||
|
tr.addElement( new TD().addElement("We value your comments. To send OWASP your questions or comments regarding the " +
|
||||||
|
"WebGoat tool, please enter your comments below. The information you provide will be handled according " +
|
||||||
|
"to our <U>Privacy Policy</U>."));
|
||||||
|
tr.addElement( new TD().addElement( " "));
|
||||||
|
tr.addElement( new TD().addElement("<b>OWASP</B><BR>" +
|
||||||
|
"9175 Guilford Rd <BR> Suite 300 <BR>" +
|
||||||
|
"Columbia, MD. 21046").setVAlign("top"));
|
||||||
|
t.addElement( tr );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
tr = new TR();
|
||||||
|
tr.addElement( new TD().addElement( " ").setColSpan(3));
|
||||||
|
t.addElement( tr );
|
||||||
|
|
||||||
|
Input input = new Input( Input.HIDDEN, TO, "webgoat.admin@owasp.org" );
|
||||||
|
tr = new TR();
|
||||||
|
tr.addElement( new TD().addElement( "Questions or Comments:"));
|
||||||
|
tr.addElement( new TD().addElement( " "));
|
||||||
|
tr.addElement( new TD().setAlign( "LEFT" ).addElement( input ));
|
||||||
|
t.addElement( tr );
|
||||||
|
|
||||||
|
|
||||||
|
tr = new TR();
|
||||||
|
String message = s.getParser().getRawParameter( MESSAGE, "" );
|
||||||
|
TextArea ta = new TextArea( MESSAGE, 5, 40 );
|
||||||
|
ta.addElement( new StringElement( convertMetachars(message) ));
|
||||||
|
tr.addElement( new TD().setAlign( "LEFT" ).addElement( ta ));
|
||||||
|
tr.addElement( new TD().setAlign( "LEFT" ).setVAlign( "MIDDLE" ).addElement( ECSFactory.makeButton( "Send!" ) ) );
|
||||||
|
tr.addElement( new TD().addElement( " "));
|
||||||
|
t.addElement( tr );
|
||||||
|
ec.addElement( t );
|
||||||
|
|
||||||
|
// Eventually we could send the actually mail, but the point should already be made
|
||||||
|
//ec.addElement(exec( use java mail here + to));
|
||||||
|
|
||||||
|
if ( to.length() > 0 )
|
||||||
|
{
|
||||||
|
Format formatter;
|
||||||
|
// Get today's date
|
||||||
|
Date date = new Date();
|
||||||
|
formatter = new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss Z");
|
||||||
|
String today = formatter.format(date);
|
||||||
|
// Tue, 09 Jan 2002 22:14:02 -0500
|
||||||
|
|
||||||
|
ec.addElement( new HR() );
|
||||||
|
ec.addElement( new Center().addElement( new B().addElement( "You sent the following message to: " + to ) ) );
|
||||||
|
ec.addElement( new BR() );
|
||||||
|
ec.addElement( new StringElement("<b>Return-Path:</b> <webgoat@owasp.org>"));
|
||||||
|
ec.addElement( new BR() );
|
||||||
|
ec.addElement( new StringElement("<b>Delivered-To:</b> " + to));
|
||||||
|
ec.addElement( new BR() );
|
||||||
|
ec.addElement( new StringElement("<b>Received:</b> (qmail 614458 invoked by uid 239); " + today));
|
||||||
|
ec.addElement( new BR() );
|
||||||
|
ec.addElement( new StringElement("for <" + to+">; " + today ));
|
||||||
|
ec.addElement( new BR() );
|
||||||
|
ec.addElement( new StringElement("<b>To:</b> " + to));
|
||||||
|
ec.addElement( new BR() );
|
||||||
|
ec.addElement( new StringElement("<b>From:</b> Blame it on the Goat <webgoat@owasp.org>"));
|
||||||
|
ec.addElement( new BR() );
|
||||||
|
ec.addElement( new StringElement("<b>Subject:</b> OWASP security issues"));
|
||||||
|
ec.addElement( new BR() );
|
||||||
|
ec.addElement( new BR() );
|
||||||
|
ec.addElement( new StringElement( message ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// only complete the lesson if they changed the "to" hidden field
|
||||||
|
if ( to.length() > 0 && ! "webgoat.admin@owasp.org".equals( to ) )
|
||||||
|
{
|
||||||
|
makeSuccess( s );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
s.setMessage( "Error generating " + this.getClass().getName() );
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return ( ec );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DOCUMENT ME!
|
||||||
|
*
|
||||||
|
* @return DOCUMENT ME!
|
||||||
|
*/
|
||||||
|
protected Category getDefaultCategory()
|
||||||
|
{
|
||||||
|
return AbstractLesson.A1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the hints attribute of the EmailScreen object
|
||||||
|
*
|
||||||
|
* @return The hints value
|
||||||
|
*/
|
||||||
|
protected List getHints()
|
||||||
|
{
|
||||||
|
List hints = new ArrayList();
|
||||||
|
hints.add( "Try sending an anonymous message to yourself." );
|
||||||
|
hints.add( "Try inserting some html or javascript code in the message field" );
|
||||||
|
hints.add( "Look at the hidden fields in the HTML.");
|
||||||
|
hints.add( "Insert <A href=\"http://www.aspectsecurity.com/webgoat.html\">Click here for Aspect</A> in the message field" );
|
||||||
|
hints.add( "Insert <script>alert(\"Bad Stuff\");</script> in the message field" );
|
||||||
|
return hints;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the instructions attribute of the UncheckedEmail object
|
||||||
|
*
|
||||||
|
* @return The instructions value
|
||||||
|
*/
|
||||||
|
public String getInstructions(WebSession s)
|
||||||
|
{
|
||||||
|
String instructions = "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>"
|
||||||
|
+ "2) Send a malicious script to a 'friend' from OWASP.<br>";
|
||||||
|
return ( instructions );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private final static Integer DEFAULT_RANKING = new Integer(55);
|
||||||
|
|
||||||
|
protected Integer getDefaultRanking()
|
||||||
|
{
|
||||||
|
return DEFAULT_RANKING;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the title attribute of the EmailScreen object
|
||||||
|
*
|
||||||
|
* @return The title value
|
||||||
|
*/
|
||||||
|
public String getTitle()
|
||||||
|
{
|
||||||
|
return ( "How to Exploit Unchecked Email" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
262
webgoat/main/project/org/owasp/webgoat/lessons/WSDLScanning.java
Normal file
262
webgoat/main/project/org/owasp/webgoat/lessons/WSDLScanning.java
Normal file
@ -0,0 +1,262 @@
|
|||||||
|
/*
|
||||||
|
* Created on May 26, 2005
|
||||||
|
*
|
||||||
|
* TODO To change the template for this generated file go to
|
||||||
|
* Window - Preferences - Java - Code Style - Code Templates
|
||||||
|
*/
|
||||||
|
package org.owasp.webgoat.lessons;
|
||||||
|
|
||||||
|
import java.rmi.RemoteException;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.xml.namespace.QName;
|
||||||
|
import javax.xml.rpc.ParameterMode;
|
||||||
|
import javax.xml.rpc.ServiceException;
|
||||||
|
|
||||||
|
import org.apache.axis.client.Call;
|
||||||
|
import org.apache.axis.client.Service;
|
||||||
|
import org.apache.axis.encoding.XMLType;
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
import org.apache.ecs.ElementContainer;
|
||||||
|
import org.apache.ecs.html.A;
|
||||||
|
import org.apache.ecs.html.BR;
|
||||||
|
import org.apache.ecs.html.IMG;
|
||||||
|
import org.apache.ecs.html.Input;
|
||||||
|
import org.apache.ecs.html.Option;
|
||||||
|
import org.apache.ecs.html.P;
|
||||||
|
import org.apache.ecs.html.Select;
|
||||||
|
import org.apache.ecs.html.TD;
|
||||||
|
import org.apache.ecs.html.TR;
|
||||||
|
import org.apache.ecs.html.Table;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.session.DatabaseUtilities;
|
||||||
|
import org.owasp.webgoat.session.ECSFactory;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author asmolen
|
||||||
|
*
|
||||||
|
* TODO To change the template for this generated type comment go to
|
||||||
|
* Window - Preferences - Java - Code Style - Code Templates
|
||||||
|
*/
|
||||||
|
public class WSDLScanning extends LessonAdapter {
|
||||||
|
static boolean completed = false;
|
||||||
|
static boolean beenRestartedYet = false;
|
||||||
|
public static Connection connection = null;
|
||||||
|
public final static String firstName = "getFirstName";
|
||||||
|
public final static String lastName = "getLastName";
|
||||||
|
public final static String loginCount = "getLoginCount";
|
||||||
|
public final static String ccNumber = "getCreditCard";
|
||||||
|
final static IMG CREDITS_LOGO = new IMG( "images/logos/parasoft.jpg" ).setAlt( "Parasoft" ).setBorder( 0 ).setHspace( 0 ).setVspace( 0 );
|
||||||
|
|
||||||
|
protected Category getDefaultCategory()
|
||||||
|
{
|
||||||
|
return AbstractLesson.WEB_SERVICES;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List getHints()
|
||||||
|
{
|
||||||
|
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, String proc, String parameterName, Object parameterValue) {
|
||||||
|
String targetNamespace = "WebGoat";
|
||||||
|
try {
|
||||||
|
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/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;
|
||||||
|
}
|
||||||
|
protected Element createContent(WebSession s)
|
||||||
|
{
|
||||||
|
ElementContainer ec = new ElementContainer();
|
||||||
|
|
||||||
|
|
||||||
|
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" );
|
||||||
|
if ( connection == null )
|
||||||
|
{
|
||||||
|
connection = DatabaseUtilities.makeConnection( s );
|
||||||
|
}
|
||||||
|
|
||||||
|
Table t = new Table().setCellSpacing( 0 ).setCellPadding( 2 ).setBorder( 1 );
|
||||||
|
|
||||||
|
if ( s.isColor() )
|
||||||
|
{
|
||||||
|
t.setBorder( 1 );
|
||||||
|
}
|
||||||
|
TR header = new TR();
|
||||||
|
TR results = new TR();
|
||||||
|
for (int i=0; i<fields.length;i++) {
|
||||||
|
header.addElement(new TD().addElement(fields[i]));
|
||||||
|
results.addElement(new TD().addElement((String) accessWGService("WSDLScanning", 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");
|
||||||
|
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.makeConnection();
|
||||||
|
if (connection == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
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");
|
||||||
|
if (result != null)
|
||||||
|
{
|
||||||
|
completed = true;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
public String getFirstName(int id) {
|
||||||
|
String result = getResults(id, "first_name");
|
||||||
|
if (result != null)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
public String getLastName(int id) {
|
||||||
|
String result = getResults(id, "last_name");
|
||||||
|
if (result != null)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
public String getLoginCount(int id) {
|
||||||
|
String result = getResults(id, "login_count");
|
||||||
|
if (result != null)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Element getCredits()
|
||||||
|
{
|
||||||
|
return super.getCustomCredits("By Alex Smolen", CREDITS_LOGO);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,348 @@
|
|||||||
|
package org.owasp.webgoat.lessons;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.servlet.http.Cookie;
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
import org.apache.ecs.ElementContainer;
|
||||||
|
import org.apache.ecs.StringElement;
|
||||||
|
import org.apache.ecs.html.B;
|
||||||
|
import org.apache.ecs.html.H1;
|
||||||
|
import org.apache.ecs.html.Input;
|
||||||
|
import org.apache.ecs.html.P;
|
||||||
|
import org.apache.ecs.html.TD;
|
||||||
|
import org.apache.ecs.html.TH;
|
||||||
|
import org.apache.ecs.html.TR;
|
||||||
|
import org.apache.ecs.html.Table;
|
||||||
|
import org.owasp.webgoat.session.*;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2002 Free Software Foundation developed under the custody of the Open Web
|
||||||
|
* Application Security Project (http://www.owasp.org) This software package org.owasp.webgoat.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
|
||||||
|
*/
|
||||||
|
public class WeakAuthenticationCookie extends LessonAdapter
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Description of the Field
|
||||||
|
*/
|
||||||
|
protected final static String AUTHCOOKIE = "AuthCookie";
|
||||||
|
/**
|
||||||
|
* Description of the Field
|
||||||
|
*/
|
||||||
|
protected final static String LOGOUT = "WACLogout";
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
* @exception Exception Description of the Exception
|
||||||
|
*/
|
||||||
|
protected String checkCookie( WebSession s ) throws Exception
|
||||||
|
{
|
||||||
|
String cookie = getCookie( s );
|
||||||
|
|
||||||
|
if ( cookie != null )
|
||||||
|
{
|
||||||
|
if ( cookie.equals( encode( "webgoat12345" ) ) )
|
||||||
|
{
|
||||||
|
return ( "webgoat" );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( cookie.equals( encode( "aspect12345" ) ) )
|
||||||
|
{
|
||||||
|
return ( "aspect" );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( cookie.equals( encode( "alice12345" ) ) )
|
||||||
|
{
|
||||||
|
makeSuccess( s );
|
||||||
|
return ( "alice" );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s.setMessage( "Invalid cookie" );
|
||||||
|
s.eatCookies();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( null );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param s Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
* @exception Exception Description of the Exception
|
||||||
|
*/
|
||||||
|
protected String checkParams( WebSession s ) throws Exception
|
||||||
|
{
|
||||||
|
String username = s.getParser().getStringParameter( USERNAME, "" );
|
||||||
|
String password = s.getParser().getStringParameter( PASSWORD, "" );
|
||||||
|
|
||||||
|
if ( ( username.length() > 0 ) && ( password.length() > 0 ) )
|
||||||
|
{
|
||||||
|
String loginID = "";
|
||||||
|
|
||||||
|
if ( username.equals( "webgoat" ) && password.equals( "webgoat" ) )
|
||||||
|
{
|
||||||
|
loginID = encode( "webgoat12345" );
|
||||||
|
}
|
||||||
|
else if ( username.equals( "aspect" ) && password.equals( "aspect" ) )
|
||||||
|
{
|
||||||
|
loginID = encode( "aspect12345" );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( loginID != "" )
|
||||||
|
{
|
||||||
|
Cookie newCookie = new Cookie( AUTHCOOKIE, loginID );
|
||||||
|
s.setMessage( "Your identity has been remembered" );
|
||||||
|
s.getResponse().addCookie( newCookie );
|
||||||
|
|
||||||
|
return ( username );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s.setMessage( "Invalid username and password entered." );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( null );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param s Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
protected Element createContent( WebSession s )
|
||||||
|
{
|
||||||
|
boolean logout = s.getParser().getBooleanParameter( LOGOUT, false );
|
||||||
|
|
||||||
|
if ( logout )
|
||||||
|
{
|
||||||
|
s.setMessage( "Goodbye! Your password has been forgotten" );
|
||||||
|
s.eatCookies();
|
||||||
|
|
||||||
|
return ( makeLogin( s ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String user = checkCookie( s );
|
||||||
|
|
||||||
|
if ( ( user != null ) && ( user.length() > 0 ) )
|
||||||
|
{
|
||||||
|
return ( makeUser( s, user, "COOKIE" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
user = checkParams( s );
|
||||||
|
|
||||||
|
if ( ( user != null ) && ( user.length() > 0 ) )
|
||||||
|
{
|
||||||
|
return ( makeUser( s, user, "PARAMETERS" ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
s.setMessage( "Error generating " + this.getClass().getName() );
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( makeLogin( s ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param value Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
private String encode( String value )
|
||||||
|
{
|
||||||
|
//<START_OMIT_SOURCE>
|
||||||
|
StringBuffer encoded = new StringBuffer();
|
||||||
|
|
||||||
|
for ( int i = 0; i < value.length(); i++ )
|
||||||
|
{
|
||||||
|
encoded.append( String.valueOf( (char) ( value.charAt( i ) + 1 ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return encoded.reverse().toString();
|
||||||
|
//<END_OMIT_SOURCE>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the category attribute of the WeakAuthenticationCookie object
|
||||||
|
*
|
||||||
|
* @return The category value
|
||||||
|
*/
|
||||||
|
protected Category getDefaultCategory()
|
||||||
|
{
|
||||||
|
return AbstractLesson.A3;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the cookie attribute of the CookieScreen object
|
||||||
|
*
|
||||||
|
* @param s Description of the Parameter
|
||||||
|
* @return The cookie value
|
||||||
|
*/
|
||||||
|
protected String getCookie( WebSession s )
|
||||||
|
{
|
||||||
|
Cookie[] cookies = s.getRequest().getCookies();
|
||||||
|
|
||||||
|
for ( int i = 0; i < cookies.length; i++ )
|
||||||
|
{
|
||||||
|
if ( cookies[i].getName().equalsIgnoreCase( AUTHCOOKIE ) )
|
||||||
|
{
|
||||||
|
return ( cookies[i].getValue() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( null );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the hints attribute of the CookieScreen object
|
||||||
|
*
|
||||||
|
* @return The hints value
|
||||||
|
*/
|
||||||
|
protected List getHints()
|
||||||
|
{
|
||||||
|
List hints = new ArrayList();
|
||||||
|
hints.add( "The server skips authentication if you send the right cookie." );
|
||||||
|
hints.add( "Is the AuthCookie value guessable knowing the username and password?" );
|
||||||
|
hints.add( "Add 'AuthCookie=********;' to the Cookie: header using <A href=\"http://www.owasp.org/development/webscarab\">WebScarab</A>." );
|
||||||
|
|
||||||
|
return hints;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the instructions attribute of the WeakAuthenticationCookie object
|
||||||
|
*
|
||||||
|
* @return The instructions value
|
||||||
|
*/
|
||||||
|
public String getInstructions(WebSession s)
|
||||||
|
{
|
||||||
|
String instructions = "Login using the webgoat/webgoat account to see what happens. You may also try aspect/aspect. When you understand the authentication cookie, try changing your identity to alice.";
|
||||||
|
|
||||||
|
return ( instructions );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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 ( "How to Spoof an Authentication Cookie" );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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();
|
||||||
|
|
||||||
|
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("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();
|
||||||
|
tr.addElement( new TD().addElement(" ").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, "" );
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 ) );
|
||||||
|
ec.addElement( new P().addElement( ECSFactory.makeLink( "Logout", LOGOUT, true ) ) );
|
||||||
|
ec.addElement( new P().addElement( ECSFactory.makeLink( "Refresh", "", "" ) ) );
|
||||||
|
|
||||||
|
return ( ec );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,218 @@
|
|||||||
|
package org.owasp.webgoat.lessons;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.servlet.http.Cookie;
|
||||||
|
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
import org.apache.ecs.ElementContainer;
|
||||||
|
import org.apache.ecs.StringElement;
|
||||||
|
import org.apache.ecs.html.B;
|
||||||
|
import org.apache.ecs.html.H1;
|
||||||
|
import org.apache.ecs.html.Input;
|
||||||
|
import org.apache.ecs.html.TD;
|
||||||
|
import org.apache.ecs.html.TH;
|
||||||
|
import org.apache.ecs.html.TR;
|
||||||
|
import org.apache.ecs.html.Table;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.session.ECSFactory;
|
||||||
|
import org.owasp.webgoat.session.ParameterNotFoundException;
|
||||||
|
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 org.owasp.webgoat.is published by OWASP
|
||||||
|
* under the GPL. You should read and accept the LICENSE before you use, modify and/or redistribute
|
||||||
|
* this software.
|
||||||
|
*
|
||||||
|
* @author Rogan Dawes <a href="http://dawes.za.net/rogan">Rogan Dawes</a>
|
||||||
|
* @created March 30, 2005
|
||||||
|
*/
|
||||||
|
public class WeakSessionID extends LessonAdapter {
|
||||||
|
/**
|
||||||
|
* Description of the Field
|
||||||
|
*/
|
||||||
|
protected final static String SESSIONID = "WEAKID";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Field
|
||||||
|
*/
|
||||||
|
protected final static String PASSWORD = "Password";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Field
|
||||||
|
*/
|
||||||
|
protected final static String USERNAME = "Username";
|
||||||
|
|
||||||
|
protected static List<String> sessionList = new ArrayList<String>();
|
||||||
|
protected static long seq = Math.round(Math.random() * 10240) + 10000;
|
||||||
|
protected static long lastTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the credits attribute of the AbstractLesson object
|
||||||
|
*
|
||||||
|
* @return The credits value
|
||||||
|
*/
|
||||||
|
public Element getCredits() {
|
||||||
|
return new StringElement("By Rogan Dawes");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String newCookie() {
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
seq ++;
|
||||||
|
if (seq % 29 == 0) {
|
||||||
|
String target = encode(seq++, lastTime + (now - lastTime)/2);
|
||||||
|
sessionList.add(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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the category attribute of the WeakAuthenticationCookie object
|
||||||
|
*
|
||||||
|
* @return The category value
|
||||||
|
*/
|
||||||
|
protected Category getDefaultCategory() {
|
||||||
|
return AbstractLesson.A3;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the hints attribute of the CookieScreen object
|
||||||
|
*
|
||||||
|
* @return The hints value
|
||||||
|
*/
|
||||||
|
protected List getHints() {
|
||||||
|
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!" );
|
||||||
|
|
||||||
|
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 ( "How to 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();
|
||||||
|
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(" ").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 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,128 @@
|
|||||||
|
package org.owasp.webgoat.lessons;
|
||||||
|
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
import org.apache.ecs.ElementContainer;
|
||||||
|
import org.apache.ecs.HtmlColor;
|
||||||
|
import org.apache.ecs.StringElement;
|
||||||
|
import org.apache.ecs.html.Center;
|
||||||
|
import org.apache.ecs.html.Form;
|
||||||
|
import org.apache.ecs.html.TD;
|
||||||
|
import org.apache.ecs.html.TR;
|
||||||
|
import org.apache.ecs.html.Table;
|
||||||
|
import org.owasp.webgoat.session.*;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2002 Free Software Foundation developed under the custody of the Open Web
|
||||||
|
* Application Security Project (http://www.owasp.org) This software package org.owasp.webgoat.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
|
||||||
|
*/
|
||||||
|
public class WelcomeScreen extends Screen
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Constructor for the WelcomeScreen object
|
||||||
|
*
|
||||||
|
* @param s Description of the Parameter
|
||||||
|
*/
|
||||||
|
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" );
|
||||||
|
}
|
||||||
|
|
||||||
|
Table container = new Table().setWidth( "100%" ).setCellSpacing( 10 ).setCellPadding( 0 ).setBorder( 0 );
|
||||||
|
|
||||||
|
// CreateContent can generate error messages so you MUST call it before makeMessages()
|
||||||
|
Element content = createContent( s );
|
||||||
|
container.addElement( new TR().addElement( new TD().setColSpan( 2 ).setVAlign( "TOP" ).addElement(
|
||||||
|
makeMessages( s ) ) ) );
|
||||||
|
container.addElement( new TR().addElement( new TD().setColSpan( 2 ).addElement( content ) ) );
|
||||||
|
container.addElement( new TR() );
|
||||||
|
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
public Element getCredits()
|
||||||
|
{
|
||||||
|
return new ElementContainer();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the instructions attribute of the WelcomeScreen object
|
||||||
|
*
|
||||||
|
* @return The instructions value
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,180 @@
|
|||||||
|
/*
|
||||||
|
* Created on Jun 1, 2005
|
||||||
|
*
|
||||||
|
* TODO To change the template for this generated file go to
|
||||||
|
* Window - Preferences - Java - Code Style - Code Templates
|
||||||
|
*/
|
||||||
|
package org.owasp.webgoat.lessons;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.StringReader;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
import org.apache.ecs.ElementContainer;
|
||||||
|
import org.apache.ecs.StringElement;
|
||||||
|
import org.apache.ecs.html.B;
|
||||||
|
import org.apache.ecs.html.Input;
|
||||||
|
import org.apache.ecs.html.P;
|
||||||
|
import org.apache.ecs.html.PRE;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.session.ECSFactory;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
import org.owasp.webgoat.util.HtmlEncoder;
|
||||||
|
import org.xml.sax.Attributes;
|
||||||
|
import org.xml.sax.InputSource;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
import org.xml.sax.XMLReader;
|
||||||
|
import org.xml.sax.helpers.DefaultHandler;
|
||||||
|
import org.xml.sax.helpers.XMLReaderFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author rdawes
|
||||||
|
*
|
||||||
|
* TODO To change the template for this generated type comment go to Window -
|
||||||
|
* Preferences - Java - Code Style - Code Templates
|
||||||
|
*/
|
||||||
|
public class WsSAXInjection extends LessonAdapter {
|
||||||
|
private final static String PASSWORD = "password";
|
||||||
|
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
private static String template1 = "<?xml version='1.0' encoding='UTF-8'?>\n"
|
||||||
|
+ "<wsns0:Envelope\n"
|
||||||
|
+ " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'\n"
|
||||||
|
+ " xmlns:xsd='http://www.w3.org/2001/XMLSchema'\n"
|
||||||
|
+ " xmlns:wsns0='http://schemas.xmlsoap.org/soap/envelope/'\n"
|
||||||
|
+ " xmlns:wsns1='http://lessons.webgoat.owasp.org'>\n"
|
||||||
|
+ " <wsns0:Body>\n"
|
||||||
|
+ " <wsns1:changePassword>\n"
|
||||||
|
+ " <id xsi:type='xsd:int'>101</id>\n"
|
||||||
|
+ " <password xsi:type='xsd:string'>";
|
||||||
|
|
||||||
|
private static String template2 = "</password>\n"
|
||||||
|
+ " </wsns1:changePassword>\n" + " </wsns0:Body>\n"
|
||||||
|
+ "</wsns0:Envelope>";
|
||||||
|
|
||||||
|
static boolean completed;
|
||||||
|
|
||||||
|
protected Category getDefaultCategory() {
|
||||||
|
return AbstractLesson.WEB_SERVICES;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List getHints() {
|
||||||
|
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));
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,217 @@
|
|||||||
|
/*
|
||||||
|
* Created on Jun 1, 2005
|
||||||
|
*
|
||||||
|
* TODO To change the template for this generated file go to
|
||||||
|
* Window - Preferences - Java - Code Style - Code Templates
|
||||||
|
*/
|
||||||
|
package org.owasp.webgoat.lessons;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.ResultSetMetaData;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
import org.apache.ecs.ElementContainer;
|
||||||
|
import org.apache.ecs.html.A;
|
||||||
|
import org.apache.ecs.html.BR;
|
||||||
|
import org.apache.ecs.html.IMG;
|
||||||
|
import org.apache.ecs.html.Input;
|
||||||
|
import org.apache.ecs.html.P;
|
||||||
|
import org.apache.ecs.html.PRE;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.session.DatabaseUtilities;
|
||||||
|
import org.owasp.webgoat.session.ECSFactory;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author asmolen
|
||||||
|
*
|
||||||
|
* TODO To change the template for this generated type comment go to
|
||||||
|
* Window - Preferences - Java - Code Style - Code Templates
|
||||||
|
*/
|
||||||
|
public class WsSqlInjection extends LessonAdapter {
|
||||||
|
public final static String ccNumber = "cc_number";
|
||||||
|
private final static String ACCT_NUM = "account_number";
|
||||||
|
private String accountNumber;
|
||||||
|
final static IMG CREDITS_LOGO = new IMG( "images/logos/parasoft.jpg" ).setAlt( "Parasoft" ).setBorder( 0 ).setHspace( 0 ).setVspace( 0 );
|
||||||
|
private static Connection connection = null;
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see lessons.AbstractLesson#getMenuItem()
|
||||||
|
*/
|
||||||
|
static boolean completed;
|
||||||
|
|
||||||
|
protected Category getDefaultCategory()
|
||||||
|
{
|
||||||
|
return AbstractLesson.WEB_SERVICES;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List getHints()
|
||||||
|
{
|
||||||
|
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 ""<br><br>" +
|
||||||
|
"The soap message body has the following format:<br>" +
|
||||||
|
"<?xml version='1.0' encoding='UTF-8'?> <br>" +
|
||||||
|
" <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'> <br>" +
|
||||||
|
" <SOAP-ENV:Body> <br>" +
|
||||||
|
" <ns1:getCreditCard SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' xmlns:ns1='http://lessons'> <br>" +
|
||||||
|
" <id xsi:type='xsd:string'>101</id> <br>" +
|
||||||
|
" </ns1:getCreditCard> <br>" +
|
||||||
|
" </SOAP-ENV:Body> <br>" +
|
||||||
|
" </SOAP-ENV:Envelope> <br>" +
|
||||||
|
"");
|
||||||
|
/* "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <br>" +
|
||||||
|
" <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\"> <br>" +
|
||||||
|
" <SOAP-ENV:Body> <br>" +
|
||||||
|
" <ns1:getCreditCard SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:ns1=\"http://lessons\"> <br>" +
|
||||||
|
" <id xsi:type=\"xsd:string\">101</id> <br>"+
|
||||||
|
" </ns1:getCreditCard> <br>" +
|
||||||
|
" </SOAP-ENV:Body> <br>" +
|
||||||
|
" </SOAP-ENV:Envelope> <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
|
||||||
|
{
|
||||||
|
if ( connection == null )
|
||||||
|
{
|
||||||
|
connection = DatabaseUtilities.makeConnection( s );
|
||||||
|
}
|
||||||
|
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");
|
||||||
|
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.makeConnection();
|
||||||
|
if (connection == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,76 @@
|
|||||||
|
package org.owasp.webgoat.lessons.admin;
|
||||||
|
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||||
|
import org.owasp.webgoat.session.Screen;
|
||||||
|
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 org.owasp.webgoat.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
|
||||||
|
*/
|
||||||
|
public abstract class AdminScreen extends Screen
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Description of the Field
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
public AdminScreen( WebSession s ) { }
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for the AdminScreen object
|
||||||
|
*/
|
||||||
|
public AdminScreen() { }
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the title attribute of the AdminScreen object
|
||||||
|
*
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,105 @@
|
|||||||
|
package org.owasp.webgoat.lessons.admin;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.ResultSetMetaData;
|
||||||
|
import java.sql.Statement;
|
||||||
|
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
import org.apache.ecs.ElementContainer;
|
||||||
|
import org.owasp.webgoat.lessons.Category;
|
||||||
|
import org.owasp.webgoat.lessons.LessonAdapter;
|
||||||
|
import org.owasp.webgoat.session.DatabaseUtilities;
|
||||||
|
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 org.owasp.webgoat.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
|
||||||
|
*/
|
||||||
|
public class ProductsAdminScreen extends LessonAdapter
|
||||||
|
{
|
||||||
|
private final static String QUERY = "SELECT * FROM product_system_data";
|
||||||
|
private static Connection connection = null;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
{
|
||||||
|
if ( connection == null )
|
||||||
|
{
|
||||||
|
connection = DatabaseUtilities.makeConnection( s );
|
||||||
|
}
|
||||||
|
|
||||||
|
Statement statement = connection.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY );
|
||||||
|
ResultSet results = statement.executeQuery( QUERY );
|
||||||
|
|
||||||
|
if ( results != null )
|
||||||
|
{
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the category attribute of the ProductsAdminScreen object
|
||||||
|
*
|
||||||
|
* @return The category value
|
||||||
|
*/
|
||||||
|
protected Category getDefaultCategory()
|
||||||
|
{
|
||||||
|
return ADMIN_FUNCTIONS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the role attribute of the ProductsAdminScreen object
|
||||||
|
*
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,143 @@
|
|||||||
|
package org.owasp.webgoat.lessons.admin;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import org.owasp.webgoat.lessons.*;
|
||||||
|
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
import org.apache.ecs.ElementContainer;
|
||||||
|
import org.apache.ecs.StringElement;
|
||||||
|
import org.apache.ecs.html.A;
|
||||||
|
import org.apache.ecs.html.TD;
|
||||||
|
import org.apache.ecs.html.TR;
|
||||||
|
import org.apache.ecs.html.Table;
|
||||||
|
import org.owasp.webgoat.session.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2002 Free Software Foundation developed under the custody of the Open Web
|
||||||
|
* Application Security Project (http://www.owasp.org) This software package org.owasp.webgoat.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
|
||||||
|
*/
|
||||||
|
public class RefreshDBScreen extends LessonAdapter
|
||||||
|
{
|
||||||
|
private final static String REFRESH = "Refresh";
|
||||||
|
private static Connection connection = null;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
{
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( ec );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the category attribute of the RefreshDBScreen object
|
||||||
|
*
|
||||||
|
* @return The category value
|
||||||
|
*/
|
||||||
|
protected Category getDefaultCategory()
|
||||||
|
{
|
||||||
|
return 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
|
||||||
|
{
|
||||||
|
if ( connection == null )
|
||||||
|
{
|
||||||
|
connection = DatabaseUtilities.makeConnection( 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,278 @@
|
|||||||
|
package org.owasp.webgoat.lessons.admin;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
import org.apache.ecs.ElementContainer;
|
||||||
|
import org.apache.ecs.HtmlColor;
|
||||||
|
import org.apache.ecs.StringElement;
|
||||||
|
import org.apache.ecs.html.Center;
|
||||||
|
import org.apache.ecs.html.H2;
|
||||||
|
import org.apache.ecs.html.TD;
|
||||||
|
import org.apache.ecs.html.TH;
|
||||||
|
import org.apache.ecs.html.TR;
|
||||||
|
import org.apache.ecs.html.Table;
|
||||||
|
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||||
|
import org.owasp.webgoat.lessons.Category;
|
||||||
|
import org.owasp.webgoat.lessons.LessonAdapter;
|
||||||
|
import org.owasp.webgoat.session.LessonTracker;
|
||||||
|
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 org.owasp.webgoat.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
|
||||||
|
*/
|
||||||
|
public class ReportCardScreen extends LessonAdapter
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
protected Element createContent( WebSession s )
|
||||||
|
{
|
||||||
|
ElementContainer ec = new ElementContainer();
|
||||||
|
|
||||||
|
String user = null;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Element makeFeedback( WebSession s )
|
||||||
|
{
|
||||||
|
ElementContainer ec = new ElementContainer();
|
||||||
|
ec.addElement( new Center( new StringElement( "Comments and suggestions are welcome. " + s.getFeedbackAddress() )) );
|
||||||
|
|
||||||
|
return ec;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Gets the category attribute of the UserAdminScreen object
|
||||||
|
*
|
||||||
|
* @return The category value
|
||||||
|
*/
|
||||||
|
protected Category getDefaultCategory()
|
||||||
|
{
|
||||||
|
return 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 );
|
||||||
|
}
|
||||||
|
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
|
||||||
|
*
|
||||||
|
* @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();
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,292 @@
|
|||||||
|
package org.owasp.webgoat.lessons.admin;
|
||||||
|
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
import org.apache.ecs.ElementContainer;
|
||||||
|
import org.apache.ecs.HtmlColor;
|
||||||
|
import org.apache.ecs.html.Center;
|
||||||
|
import org.apache.ecs.html.Input;
|
||||||
|
import org.apache.ecs.html.P;
|
||||||
|
import org.apache.ecs.html.TD;
|
||||||
|
import org.apache.ecs.html.TH;
|
||||||
|
import org.apache.ecs.html.TR;
|
||||||
|
import org.apache.ecs.html.Table;
|
||||||
|
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||||
|
import org.owasp.webgoat.lessons.Category;
|
||||||
|
import org.owasp.webgoat.lessons.LessonAdapter;
|
||||||
|
import org.owasp.webgoat.session.LessonTracker;
|
||||||
|
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 org.owasp.webgoat.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
|
||||||
|
*/
|
||||||
|
public class SummaryReportCardScreen extends LessonAdapter
|
||||||
|
{
|
||||||
|
|
||||||
|
private int totalUsersNormalComplete = 0;
|
||||||
|
private int totalUsersAdminComplete = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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();
|
||||||
|
|
||||||
|
String selectedUser = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if ( s.getRequest().isUserInRole( WebSession.WEBGOAT_ADMIN ) )
|
||||||
|
{
|
||||||
|
Enumeration e = s.getParser().getParameterNames();
|
||||||
|
|
||||||
|
while ( e.hasMoreElements() )
|
||||||
|
{
|
||||||
|
String key = (String) e.nextElement();
|
||||||
|
if ( key.startsWith( "View_" ) )
|
||||||
|
{
|
||||||
|
selectedUser = key.substring( "View_".length() );
|
||||||
|
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 userIter = UserTracker.instance().getAllUsers(WebSession.WEBGOAT_USER).iterator(); userIter.hasNext(); )
|
||||||
|
{
|
||||||
|
|
||||||
|
String user = (String) userIter.next();
|
||||||
|
t.addElement( makeUserSummaryRow( s, user ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
ec.addElement( new Center().addElement( t ) );
|
||||||
|
|
||||||
|
return ec;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected Element makeSummary( WebSession s)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 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++;
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEnterprise()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,106 @@
|
|||||||
|
package org.owasp.webgoat.lessons.admin;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.ResultSetMetaData;
|
||||||
|
import java.sql.Statement;
|
||||||
|
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
import org.apache.ecs.ElementContainer;
|
||||||
|
import org.owasp.webgoat.lessons.Category;
|
||||||
|
import org.owasp.webgoat.lessons.LessonAdapter;
|
||||||
|
import org.owasp.webgoat.session.DatabaseUtilities;
|
||||||
|
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 org.owasp.webgoat.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
|
||||||
|
*/
|
||||||
|
public class UserAdminScreen extends LessonAdapter
|
||||||
|
{
|
||||||
|
private final static String QUERY = "SELECT * FROM user_system_data";
|
||||||
|
private static Connection connection = null;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
{
|
||||||
|
if ( connection == null )
|
||||||
|
{
|
||||||
|
connection = DatabaseUtilities.makeConnection( s );
|
||||||
|
}
|
||||||
|
|
||||||
|
Statement statement = connection.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY );
|
||||||
|
ResultSet results = statement.executeQuery( QUERY );
|
||||||
|
|
||||||
|
if ( results != null )
|
||||||
|
{
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the category attribute of the UserAdminScreen object
|
||||||
|
*
|
||||||
|
* @return The category value
|
||||||
|
*/
|
||||||
|
protected Category getDefaultCategory()
|
||||||
|
{
|
||||||
|
return 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 HACKED_ADMIN_ROLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the title attribute of the UserAdminScreen object
|
||||||
|
*
|
||||||
|
* @return The title value
|
||||||
|
*/
|
||||||
|
public String getTitle()
|
||||||
|
{
|
||||||
|
return ( "User Information" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,147 @@
|
|||||||
|
package org.owasp.webgoat.lessons.admin;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.ResultSetMetaData;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import org.owasp.webgoat.lessons.*;
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
import org.apache.ecs.ElementContainer;
|
||||||
|
import org.apache.ecs.StringElement;
|
||||||
|
import org.apache.ecs.html.Input;
|
||||||
|
import org.owasp.webgoat.session.*;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2002 Free Software Foundation developed under the custody of the Open Web
|
||||||
|
* Application Security Project (http://www.owasp.org) This software package org.owasp.webgoat.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
|
||||||
|
*/
|
||||||
|
public class ViewDatabase extends LessonAdapter
|
||||||
|
{
|
||||||
|
private final static String SQL = "sql";
|
||||||
|
private static Connection connection = null;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
{
|
||||||
|
ec.addElement( new StringElement( "Enter a SQL statement: " ) );
|
||||||
|
|
||||||
|
StringBuffer sqlStatement = new StringBuffer( s.getParser().getRawParameter( SQL, "" ) );
|
||||||
|
Input input = new Input( Input.TEXT, SQL, sqlStatement.toString() );
|
||||||
|
ec.addElement( input );
|
||||||
|
|
||||||
|
Element b = ECSFactory.makeButton( "Go!" );
|
||||||
|
ec.addElement( b );
|
||||||
|
|
||||||
|
if ( connection == null )
|
||||||
|
{
|
||||||
|
connection = DatabaseUtilities.makeConnection( 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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the category attribute of the DatabaseScreen object
|
||||||
|
*
|
||||||
|
* @return The category value
|
||||||
|
*/
|
||||||
|
protected Category getDefaultCategory()
|
||||||
|
{
|
||||||
|
return ADMIN_FUNCTIONS;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final static Integer DEFAULT_RANKING = new Integer(1000);
|
||||||
|
|
||||||
|
protected Integer getDefaultRanking()
|
||||||
|
{
|
||||||
|
return DEFAULT_RANKING;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the hints attribute of the DatabaseScreen object
|
||||||
|
*
|
||||||
|
* @return The hints value
|
||||||
|
*/
|
||||||
|
protected List getHints()
|
||||||
|
{
|
||||||
|
List hints = new ArrayList();
|
||||||
|
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 ( "Database Dump" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,67 @@
|
|||||||
|
package org.owasp.webgoat.lessons.admin;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.lessons.WelcomeScreen;
|
||||||
|
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
import org.apache.ecs.ElementContainer;
|
||||||
|
import org.apache.ecs.html.Center;
|
||||||
|
import org.apache.ecs.html.H1;
|
||||||
|
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 org.owasp.webgoat.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
|
||||||
|
*/
|
||||||
|
public class WelcomeAdminScreen extends WelcomeScreen
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Constructor for the WelcomeAdminScreen object
|
||||||
|
*
|
||||||
|
* @param s Description of the Parameter
|
||||||
|
*/
|
||||||
|
public WelcomeAdminScreen( WebSession s )
|
||||||
|
{
|
||||||
|
super( s );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for the WelcomeAdminScreen object
|
||||||
|
*/
|
||||||
|
public WelcomeAdminScreen() { }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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" ) ) );
|
||||||
|
ec.addElement( super.createContent( s ) );
|
||||||
|
|
||||||
|
return ( ec );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the title attribute of the WelcomeAdminScreen object
|
||||||
|
*
|
||||||
|
* @return The title value
|
||||||
|
*/
|
||||||
|
public String getTitle()
|
||||||
|
{
|
||||||
|
return ( "Admin Welcome" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,57 @@
|
|||||||
|
package org.owasp.webgoat.lessons.instructor.CrossSiteScripting;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||||
|
import org.owasp.webgoat.lessons.LessonAction;
|
||||||
|
import org.owasp.webgoat.lessons.CrossSiteScripting.FindProfile;
|
||||||
|
import org.owasp.webgoat.session.ParameterNotFoundException;
|
||||||
|
import org.owasp.webgoat.session.ValidationException;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
|
||||||
|
/* STAGE 5 FIXES
|
||||||
|
Solution Summary: Edit FindProfile.java and change getRequestParameter().
|
||||||
|
Modify getRequestParameter() with lines denoted by // STAGE 5 - FIX.
|
||||||
|
Solution Steps:
|
||||||
|
1. Talk about the different parser methods. We could have used the parser method that takes a regular expression.
|
||||||
|
2. Call validate on the request parameter.
|
||||||
|
return validate(s.getParser().getRawParameter(name), (Pattern) patterns.get(name));
|
||||||
|
|
||||||
|
Note: patterns.get(name) is used to fetch the XSS validation pattern that is defined
|
||||||
|
in FindProfile.Java
|
||||||
|
|
||||||
|
protected static Map patterns = new HashMap();
|
||||||
|
static
|
||||||
|
{
|
||||||
|
patterns.put(CrossSiteScripting.SEARCHNAME, Pattern.compile("[a-zA-Z ]{0,20}"));
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class FindProfile_i extends FindProfile
|
||||||
|
{
|
||||||
|
public FindProfile_i(AbstractLesson lesson, String lessonName, String actionName, LessonAction chainedAction)
|
||||||
|
{
|
||||||
|
super(lesson, lessonName, actionName, chainedAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getRequestParameter(WebSession s, String name)
|
||||||
|
throws ParameterNotFoundException, ValidationException
|
||||||
|
{
|
||||||
|
// NOTE:
|
||||||
|
//
|
||||||
|
// In order for this to work generically, the name of the parameter and the name
|
||||||
|
// of the regular expression validation patter must be the same.
|
||||||
|
//
|
||||||
|
// Another way this could be done is to use the reguler expression method in the
|
||||||
|
// ParameterParser class
|
||||||
|
|
||||||
|
// STAGE 5 - FIX
|
||||||
|
return validate(s.getParser().getRawParameter(name), (Pattern) patterns.get(name));
|
||||||
|
|
||||||
|
// Note the design goal here...
|
||||||
|
//return s.getParser().getStringParameter(name), (Pattern) patterns.get(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,109 @@
|
|||||||
|
package org.owasp.webgoat.lessons.instructor.CrossSiteScripting;
|
||||||
|
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||||
|
import org.owasp.webgoat.lessons.LessonAction;
|
||||||
|
import org.owasp.webgoat.lessons.CrossSiteScripting.CrossSiteScripting;
|
||||||
|
import org.owasp.webgoat.lessons.CrossSiteScripting.UpdateProfile;
|
||||||
|
import org.owasp.webgoat.session.Employee;
|
||||||
|
import org.owasp.webgoat.session.ParameterNotFoundException;
|
||||||
|
import org.owasp.webgoat.session.ParameterParser;
|
||||||
|
import org.owasp.webgoat.session.ValidationException;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
|
||||||
|
/* STAGE 2 FIXES
|
||||||
|
Solution Summary: Edit UpdateProfile.java and change parseEmployeeProfile().
|
||||||
|
Modify parseEmployeeProfile() with lines denoted by // STAGE 2 - FIX.
|
||||||
|
Solution Steps:
|
||||||
|
1. Talk about the different parser methods.
|
||||||
|
a. parseEmployeeProfile(subjectId, s.getRequest())
|
||||||
|
- uses the request object directly.
|
||||||
|
- calling validate() on the appropriate parameter
|
||||||
|
b. parseEmployeeProfile(subjectId, s.getParser())
|
||||||
|
- uses the parser object to pull request data (centralized mechanism)
|
||||||
|
|
||||||
|
2. Fix the request object version of the call // STAGE 2 - FIX
|
||||||
|
Replace the call to:
|
||||||
|
String address1 = request.getParameter(CrossSiteScripting.ADDRESS1);
|
||||||
|
|
||||||
|
With:
|
||||||
|
final Pattern PATTERN_ADDRESS1 = Pattern.compile("[a-zA-Z0-9,\\.\\- ]{0,80}"); // STAGE 2 - FIX
|
||||||
|
String address1 = validate(request.getParameter(CrossSiteScripting.ADDRESS1), PATTERN_ADDRESS1); // STAGE 2 - FIX
|
||||||
|
|
||||||
|
|
||||||
|
3. Fix the parser version of the call. // STAGE 2 - ALTERNATE FIX
|
||||||
|
Change all calls in parseEmployeeProfile(subjectId, s.getParser()) to use
|
||||||
|
the appropriate parser.method() call
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class UpdateProfile_i extends UpdateProfile
|
||||||
|
{
|
||||||
|
public UpdateProfile_i(AbstractLesson lesson, String lessonName, String actionName, LessonAction chainedAction)
|
||||||
|
{
|
||||||
|
super(lesson, lessonName, actionName, chainedAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected Employee parseEmployeeProfile(int subjectId, WebSession s) throws ParameterNotFoundException, ValidationException
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
|
||||||
|
// Validate this parameter against a regular expression pattern designed for street addresses.
|
||||||
|
final Pattern PATTERN_ADDRESS1 = Pattern.compile("[a-zA-Z0-9,\\.\\- ]{0,80}"); // STAGE 2 - FIX
|
||||||
|
String address1 = validate(request.getParameter(CrossSiteScripting.ADDRESS1), PATTERN_ADDRESS1); // STAGE 2 - FIX
|
||||||
|
|
||||||
|
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(int subjectId, ParameterParser parser)
|
||||||
|
throws ParameterNotFoundException, ValidationException
|
||||||
|
{
|
||||||
|
// STAGE 2 - ALTERNATE FIX
|
||||||
|
String firstName = parser.getStrictAlphaParameter(CrossSiteScripting.FIRST_NAME, 20);
|
||||||
|
String lastName = parser.getStrictAlphaParameter(CrossSiteScripting.LAST_NAME, 20);
|
||||||
|
String ssn = parser.getSsnParameter(CrossSiteScripting.SSN);
|
||||||
|
String title = parser.getStrictAlphaParameter(CrossSiteScripting.TITLE, 20);
|
||||||
|
String phone = parser.getPhoneParameter(CrossSiteScripting.PHONE_NUMBER);
|
||||||
|
String address1 = parser.getStringParameter(CrossSiteScripting.ADDRESS1);
|
||||||
|
String address2 = parser.getStringParameter(CrossSiteScripting.ADDRESS2);
|
||||||
|
int manager = parser.getIntParameter(CrossSiteScripting.MANAGER);
|
||||||
|
String startDate = parser.getDateParameter(CrossSiteScripting.START_DATE);
|
||||||
|
int salary = parser.getIntParameter(CrossSiteScripting.SALARY);
|
||||||
|
String ccn = parser.getCcnParameter(CrossSiteScripting.CCN);
|
||||||
|
int ccnLimit = parser.getIntParameter(CrossSiteScripting.CCN_LIMIT);
|
||||||
|
String disciplinaryActionDate = parser.getDateParameter(CrossSiteScripting.DISCIPLINARY_DATE);
|
||||||
|
String disciplinaryActionNotes = parser.getStrictAlphaParameter(CrossSiteScripting.DISCIPLINARY_NOTES, 60);
|
||||||
|
String personalDescription = parser.getStrictAlphaParameter(CrossSiteScripting.DESCRIPTION, 60);
|
||||||
|
|
||||||
|
Employee employee = new Employee(subjectId, firstName, lastName, ssn, title, phone,
|
||||||
|
address1, address2, manager, startDate, salary,
|
||||||
|
ccn, ccnLimit, disciplinaryActionDate, disciplinaryActionNotes,
|
||||||
|
personalDescription);
|
||||||
|
|
||||||
|
return employee;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
package org.owasp.webgoat.lessons.instructor.CrossSiteScripting;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||||
|
import org.owasp.webgoat.lessons.CrossSiteScripting.ViewProfile;
|
||||||
|
|
||||||
|
/* STAGE 4 FIXES
|
||||||
|
Solution Summary: Look in the WebContent/lesson/CrossSiteScripting/ViewProfile.jsp
|
||||||
|
|
||||||
|
Look for the <-- STAGE 4 - FIX in the ViewProfile.jsp
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ViewProfile_i extends ViewProfile
|
||||||
|
{
|
||||||
|
public ViewProfile_i(AbstractLesson lesson, String lessonName, String actionName)
|
||||||
|
{
|
||||||
|
super(lesson, lessonName, actionName);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,55 @@
|
|||||||
|
package org.owasp.webgoat.lessons.instructor.RoleBasedAccessControl;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||||
|
import org.owasp.webgoat.lessons.LessonAction;
|
||||||
|
import org.owasp.webgoat.lessons.RoleBasedAccessControl.DeleteProfile;
|
||||||
|
import org.owasp.webgoat.lessons.RoleBasedAccessControl.RoleBasedAccessControl;
|
||||||
|
import org.owasp.webgoat.session.UnauthorizedException;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
|
||||||
|
public class DeleteProfile_i extends DeleteProfile
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
public DeleteProfile_i(AbstractLesson lesson, String lessonName, String actionName, LessonAction chainedAction)
|
||||||
|
{
|
||||||
|
super(lesson, lessonName, actionName, chainedAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void doDeleteEmployeeProfile(WebSession s, int userId, int employeeId)
|
||||||
|
throws UnauthorizedException
|
||||||
|
{
|
||||||
|
if (s.isAuthorizedInLesson(userId, RoleBasedAccessControl.DELETEPROFILE_ACTION)) // FIX
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String query = "DELETE FROM employee WHERE userid = " + employeeId;
|
||||||
|
//System.out.println("Query: " + query);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Statement statement = RoleBasedAccessControl.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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new UnauthorizedException(); // FIX
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,102 @@
|
|||||||
|
package org.owasp.webgoat.lessons.instructor.RoleBasedAccessControl;
|
||||||
|
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||||
|
import org.owasp.webgoat.lessons.RoleBasedAccessControl.EditProfile;
|
||||||
|
import org.owasp.webgoat.lessons.RoleBasedAccessControl.RoleBasedAccessControl;
|
||||||
|
import org.owasp.webgoat.lessons.SQLInjection.SQLInjection;
|
||||||
|
import org.owasp.webgoat.session.Employee;
|
||||||
|
import org.owasp.webgoat.session.UnauthorizedException;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2006 Free Software Foundation developed under the custody of the Open Web
|
||||||
|
* Application Security Project (http://www.owasp.org) This software package org.owasp.webgoat.is published by OWASP
|
||||||
|
* under the GPL. You should read and accept the LICENSE before you use, modify and/or redistribute
|
||||||
|
* this software.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*************************************************/
|
||||||
|
/* */
|
||||||
|
/* This file is not currently used in the course */
|
||||||
|
/* */
|
||||||
|
/*************************************************/
|
||||||
|
|
||||||
|
public class EditProfile_i extends EditProfile
|
||||||
|
{
|
||||||
|
public EditProfile_i(AbstractLesson lesson, String lessonName, String actionName)
|
||||||
|
{
|
||||||
|
super(lesson, lessonName, actionName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Employee getEmployeeProfile(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;
|
||||||
|
|
||||||
|
if (s.isAuthorizedInLesson(userId, RoleBasedAccessControl.EDITPROFILE_ACTION)) // FIX
|
||||||
|
{
|
||||||
|
// Query the database for the profile data of the given employee
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String query = "SELECT * FROM employee WHERE userid = ?";
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
PreparedStatement answer_statement = SQLInjection.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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new UnauthorizedException(); // FIX
|
||||||
|
}
|
||||||
|
|
||||||
|
return profile;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
package org.owasp.webgoat.lessons.instructor.RoleBasedAccessControl;
|
||||||
@ -0,0 +1,138 @@
|
|||||||
|
package org.owasp.webgoat.lessons.instructor.RoleBasedAccessControl;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||||
|
import org.owasp.webgoat.lessons.LessonAction;
|
||||||
|
import org.owasp.webgoat.lessons.RoleBasedAccessControl.RoleBasedAccessControl;
|
||||||
|
import org.owasp.webgoat.lessons.RoleBasedAccessControl.UpdateProfile;
|
||||||
|
import org.owasp.webgoat.session.Employee;
|
||||||
|
import org.owasp.webgoat.session.UnauthorizedException;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2006 Free Software Foundation developed under the custody of the Open Web
|
||||||
|
* Application Security Project (http://www.owasp.org) This software package org.owasp.webgoat.is published by OWASP
|
||||||
|
* under the GPL. You should read and accept the LICENSE before you use, modify and/or redistribute
|
||||||
|
* this software.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*************************************************/
|
||||||
|
/* */
|
||||||
|
/* This file is not currently used in the course */
|
||||||
|
/* */
|
||||||
|
/*************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
public class UpdateProfile_i extends UpdateProfile
|
||||||
|
{
|
||||||
|
public UpdateProfile_i(AbstractLesson lesson, String lessonName, String actionName, LessonAction chainedAction)
|
||||||
|
{
|
||||||
|
super(lesson, lessonName, actionName, chainedAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void changeEmployeeProfile(WebSession s, int userId, int subjectId, Employee employee)
|
||||||
|
throws UnauthorizedException
|
||||||
|
{
|
||||||
|
if (s.isAuthorizedInLesson(userId, RoleBasedAccessControl.UPDATEPROFILE_ACTION)) // FIX
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Note: The password field is ONLY set by ChangePassword
|
||||||
|
String query = "UPDATE employee SET first_name = '" + employee.getFirstName() +
|
||||||
|
"', last_name = '" + employee.getLastName() +
|
||||||
|
"', ssn = '" + employee.getSsn() +
|
||||||
|
"', title = '" + employee.getTitle() +
|
||||||
|
"', phone = '" + employee.getPhoneNumber() +
|
||||||
|
"', address1 = '" + employee.getAddress1() +
|
||||||
|
"', address2 = '" + employee.getAddress2() +
|
||||||
|
"', manager = " + employee.getManager() +
|
||||||
|
", start_date = '" + employee.getStartDate() +
|
||||||
|
"', ccn = '" + employee.getCcn() +
|
||||||
|
"', ccn_limit = " + employee.getCcnLimit() +
|
||||||
|
// "', disciplined_date = '" + employee.getDisciplinaryActionDate() +
|
||||||
|
// "', disciplined_notes = '" + employee.getDisciplinaryActionNotes() +
|
||||||
|
", personal_description = '" + employee.getPersonalDescription() +
|
||||||
|
"' WHERE userid = " + subjectId;
|
||||||
|
//System.out.println("Query: " + query);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Statement answer_statement = RoleBasedAccessControl.getConnection(s).createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY );
|
||||||
|
ResultSet answer_results = answer_statement.executeQuery( query );
|
||||||
|
}
|
||||||
|
catch ( SQLException sqle )
|
||||||
|
{
|
||||||
|
s.setMessage( "Error updating employee profile" );
|
||||||
|
sqle.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
s.setMessage( "Error updating employee profile" );
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new UnauthorizedException(); // FIX
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void createEmployeeProfile(WebSession s, int userId, Employee employee)
|
||||||
|
throws UnauthorizedException
|
||||||
|
{
|
||||||
|
if (s.isAuthorizedInLesson(userId, RoleBasedAccessControl.UPDATEPROFILE_ACTION)) // FIX
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// FIXME: Cannot choose the id because we cannot guarantee uniqueness
|
||||||
|
String query = "INSERT INTO employee VALUES ( max(userid)+1, '"
|
||||||
|
+ employee.getFirstName() + "','"
|
||||||
|
+ employee.getLastName() + "','"
|
||||||
|
+ employee.getSsn() + "','"
|
||||||
|
+ employee.getFirstName().toLowerCase() + "','"
|
||||||
|
+ employee.getTitle() + "','"
|
||||||
|
+ employee.getPhoneNumber() + "','"
|
||||||
|
+ employee.getAddress1() + "','"
|
||||||
|
+ employee.getAddress2() + "',"
|
||||||
|
+ employee.getManager() + ",'"
|
||||||
|
+ employee.getStartDate() + "',"
|
||||||
|
+ employee.getSalary() + ",'"
|
||||||
|
+ employee.getCcn() + "',"
|
||||||
|
+ employee.getCcnLimit() + ",'"
|
||||||
|
+ employee.getDisciplinaryActionDate() + "','"
|
||||||
|
+ employee.getDisciplinaryActionNotes() + "','"
|
||||||
|
+ employee.getPersonalDescription()
|
||||||
|
+ "')";
|
||||||
|
|
||||||
|
//System.out.println("Query: " + query);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Statement statement = RoleBasedAccessControl.getConnection(s).createStatement();
|
||||||
|
statement.executeUpdate(query);
|
||||||
|
}
|
||||||
|
catch ( SQLException sqle )
|
||||||
|
{
|
||||||
|
s.setMessage( "Error updating employee profile" );
|
||||||
|
sqle.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
s.setMessage( "Error updating employee profile" );
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new UnauthorizedException(); // FIX
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,132 @@
|
|||||||
|
package org.owasp.webgoat.lessons.instructor.RoleBasedAccessControl;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||||
|
import org.owasp.webgoat.lessons.RoleBasedAccessControl.RoleBasedAccessControl;
|
||||||
|
import org.owasp.webgoat.lessons.RoleBasedAccessControl.ViewProfile;
|
||||||
|
import org.owasp.webgoat.session.Employee;
|
||||||
|
import org.owasp.webgoat.session.UnauthorizedException;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
|
||||||
|
/* STAGE 4 FIXES
|
||||||
|
1. Find the code location where this flaw of directly retrieving the profile without data-level access control checking exists:
|
||||||
|
public void handleRequest( WebSession s )
|
||||||
|
{ <09>
|
||||||
|
Employee employee = getEmployeeProfile(s, userId, employeeId);
|
||||||
|
<09> }
|
||||||
|
public Employee getEmployeeProfile(WebSession s, int employeeId, int subjectUserId) throws UnauthorizedException { <09>
|
||||||
|
return getEmployeeProfile(s, employeeId, subjectUserId);
|
||||||
|
<09> }
|
||||||
|
2. The solution requires a data-level access control check to ensure the user has the rights to access the data they are requesting.
|
||||||
|
a. There is a common method you can take advantage of:
|
||||||
|
isAuthorizedForEmployee(s, userId, subjectUserId)
|
||||||
|
Either tell the student this exists or have them look in DefaultLessonAction.
|
||||||
|
Note that this is not required to implement data access control but is for detection of violations.
|
||||||
|
b. Uncomment the modified query retrieving the user data to have data access control
|
||||||
|
String query = "SELECT * FROM employee,ownership WHERE employee.userid = ownership.employee_id and " +
|
||||||
|
"ownership.employer_id = " + userId + " and ownership.employee_id = " + subjectUserId;
|
||||||
|
3. Bundle the entire logic with this call and throw an unauthorized exception
|
||||||
|
if (isAuthorizedForEmployee(s, userId, subjectUserId))
|
||||||
|
{ ...
|
||||||
|
//String query = "SELECT * FROM employee WHERE userid = " + subjectUserId;
|
||||||
|
String query = "SELECT * FROM employee,ownership WHERE employee.userid = ownership.employee_id and " +
|
||||||
|
"ownership.employer_id = " + userId + " and ownership.employee_id = " + subjectUserId; // STAGE 4 - FIX
|
||||||
|
...
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new UnauthorizedException();
|
||||||
|
}
|
||||||
|
4. Repeat stage 3 and note that the function fails with a "Not authorized" message.
|
||||||
|
Adding the access check in the query is providing data-level access control.
|
||||||
|
The access check from isAuthorizedForEmployee is used to detect a violation.
|
||||||
|
The same logic could've been applied after the query but isAuthorizedForEmployee provides a nice centralized abstraction of that logic.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ViewProfile_i extends ViewProfile
|
||||||
|
{
|
||||||
|
public ViewProfile_i(AbstractLesson lesson, String lessonName, String actionName)
|
||||||
|
{
|
||||||
|
super(lesson, lessonName, actionName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Employee getEmployeeProfile(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;
|
||||||
|
|
||||||
|
// isAuthorizedForEmployee() allows us to determine authorization violations
|
||||||
|
|
||||||
|
if (isAuthorizedForEmployee(s, userId, subjectUserId)) // STAGE 4 - (ALTERNATE) FIX
|
||||||
|
{
|
||||||
|
// Query the database for the profile data of the given employee
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//String query = "SELECT * FROM employee WHERE userid = " + subjectUserId; // STAGE 4 - FIX
|
||||||
|
|
||||||
|
// Switch to this query to add Data Access Control
|
||||||
|
//
|
||||||
|
// Join employee and ownership to get all valid record combinations
|
||||||
|
// - qualify on ownership.employer_id to see only the current userId records
|
||||||
|
// - qualify on ownership.employee_id to see the current selected employee profile
|
||||||
|
|
||||||
|
String query = "SELECT * FROM employee,ownership WHERE employee.userid = ownership.employee_id and " +
|
||||||
|
"ownership.employer_id = " + userId + " and ownership.employee_id = " + subjectUserId; // STAGE 4 - FIX
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Statement answer_statement = RoleBasedAccessControl.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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new UnauthorizedException(); // STAGE 4 - ALTERNATE FIX
|
||||||
|
}
|
||||||
|
|
||||||
|
return profile;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,80 @@
|
|||||||
|
package org.owasp.webgoat.lessons.instructor.SQLInjection;
|
||||||
|
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||||
|
import org.owasp.webgoat.lessons.LessonAction;
|
||||||
|
import org.owasp.webgoat.lessons.SQLInjection.Login;
|
||||||
|
import org.owasp.webgoat.lessons.SQLInjection.SQLInjection;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Solution Summary: Edit Login.java and change login().
|
||||||
|
Modify login() with lines denoted by // STAGE 2 - FIX.
|
||||||
|
Solution Steps:
|
||||||
|
1. Change dynamic query to parameterized query.
|
||||||
|
a. Replace the dynamic varaibles with the "?"
|
||||||
|
String query = "SELECT * FROM employee WHERE userid = ? and password = ?"
|
||||||
|
|
||||||
|
b. Create a preparedStatement using the new query
|
||||||
|
PreparedStatement answer_statement = SQLInjection.getConnection(s).prepareStatement(
|
||||||
|
query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY );
|
||||||
|
|
||||||
|
c. Set the values of the parameterized query
|
||||||
|
answer_statement.setString(1, userId); // STAGE 2 - FIX
|
||||||
|
answer_statement.setString(2, password); // STAGE 2 - FIX
|
||||||
|
|
||||||
|
d. Execute the preparedStatement
|
||||||
|
ResultSet answer_results = answer_statement.executeQuery();
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class Login_i extends Login
|
||||||
|
{
|
||||||
|
public Login_i(AbstractLesson lesson, String lessonName, String actionName, LessonAction chainedAction)
|
||||||
|
{
|
||||||
|
super(lesson, lessonName, actionName, chainedAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = ? and password = ?"; // STAGE 2 - FIX
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
PreparedStatement answer_statement = SQLInjection.getConnection(s).prepareStatement( query,
|
||||||
|
ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY ); // STAGE 2 - FIX
|
||||||
|
answer_statement.setString(1, userId); // STAGE 2 - FIX
|
||||||
|
answer_statement.setString(2, password); // STAGE 2 - FIX
|
||||||
|
ResultSet answer_results = answer_statement.executeQuery(); // STAGE 2 - FIX
|
||||||
|
if (answer_results.first())
|
||||||
|
{
|
||||||
|
setSessionAttribute(s, getLessonName() + ".isAuthenticated", Boolean.TRUE);
|
||||||
|
setSessionAttribute(s, getLessonName() + "." + SQLInjection.USER_ID, userId);
|
||||||
|
authenticated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch ( SQLException sqle )
|
||||||
|
{
|
||||||
|
s.setMessage( "Error logging in" );
|
||||||
|
sqle.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
s.setMessage( "Error logging in" );
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
//System.out.println("Lesson login result: " + authenticated);
|
||||||
|
return authenticated;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,99 @@
|
|||||||
|
package org.owasp.webgoat.lessons.instructor.SQLInjection;
|
||||||
|
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||||
|
import org.owasp.webgoat.lessons.SQLInjection.SQLInjection;
|
||||||
|
import org.owasp.webgoat.lessons.SQLInjection.ViewProfile;
|
||||||
|
import org.owasp.webgoat.session.Employee;
|
||||||
|
import org.owasp.webgoat.session.UnauthorizedException;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Solution Summary: Edit ViewProfile.java and change getEmployeeProfile().
|
||||||
|
Modify getEmployeeProfile() with lines denoted by // STAGE 4 - FIX.
|
||||||
|
|
||||||
|
Solution Steps:
|
||||||
|
1. Change dynamic query to parameterized query.
|
||||||
|
a. Replace the dynamic varaibles with the "?"
|
||||||
|
String query = "SELECT * FROM employee WHERE userid = ?";
|
||||||
|
|
||||||
|
b. Create a preparedStatement using the new query
|
||||||
|
PreparedStatement answer_statement = SQLInjection.getConnection(s).prepareStatement(
|
||||||
|
query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY );
|
||||||
|
|
||||||
|
c. Set the values of the parameterized query
|
||||||
|
answer_statement.setInt(1, Integer.parseInt(subjectUserId));
|
||||||
|
|
||||||
|
d. Execute the preparedStatement
|
||||||
|
ResultSet answer_results = answer_statement.executeQuery();
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ViewProfile_i extends ViewProfile
|
||||||
|
{
|
||||||
|
public ViewProfile_i(AbstractLesson lesson, String lessonName, String actionName)
|
||||||
|
{
|
||||||
|
super(lesson, lessonName, actionName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Employee getEmployeeProfile(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;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String query = "SELECT * FROM employee WHERE userid = ?"; // STAGE 4 - FIX
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
PreparedStatement answer_statement = SQLInjection.getConnection(s).prepareStatement( query,
|
||||||
|
ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY ); // STAGE 4 - FIX
|
||||||
|
answer_statement.setInt(1, Integer.parseInt(subjectUserId)); // STAGE 4 - FIX
|
||||||
|
ResultSet answer_results = answer_statement.executeQuery(); // STAGE 4 - FIX
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
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;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class Controller extends HttpServlet
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
package org.owasp.webgoat.session;
|
||||||
|
|
||||||
|
import java.util.Hashtable;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class Authorization
|
||||||
|
{
|
||||||
|
Map permissions = new Hashtable();
|
||||||
|
|
||||||
|
public Authorization()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPermission(int userId, int functionId)
|
||||||
|
{
|
||||||
|
permissions.put(new Integer(userId), new Integer(functionId));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAllowed(int userId, int functionId)
|
||||||
|
{
|
||||||
|
return (permissions.get(new Integer(userId)) != null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
448
webgoat/main/project/org/owasp/webgoat/session/Course.java
Normal file
448
webgoat/main/project/org/owasp/webgoat/session/Course.java
Normal file
@ -0,0 +1,448 @@
|
|||||||
|
package org.owasp.webgoat.session;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.HammerHead;
|
||||||
|
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||||
|
import org.owasp.webgoat.lessons.Category;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2002 Free Software Foundation developed under the custody of the Open Web
|
||||||
|
* Application Security Project (http://www.owasp.org) This software package org.owasp.webgoat.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
|
||||||
|
*/
|
||||||
|
public class Course
|
||||||
|
{
|
||||||
|
private List lessons = new ArrayList();
|
||||||
|
private final static String PROPERTIES_FILENAME = HammerHead.propertiesPath;
|
||||||
|
private WebgoatProperties properties = null;
|
||||||
|
|
||||||
|
public Course()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
properties = new WebgoatProperties(PROPERTIES_FILENAME);
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
System.out.println("Error loading WebGoat properties");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param fileName Description of the Parameter
|
||||||
|
* @param path Description of the Parameter
|
||||||
|
* @param ext Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
private String clean( String fileName, String path, String ext )
|
||||||
|
{
|
||||||
|
fileName = fileName.trim();
|
||||||
|
|
||||||
|
// check if file is a directory
|
||||||
|
if ( fileName.endsWith( "/" ) )
|
||||||
|
{
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if file is a class or java file
|
||||||
|
if ( !fileName.endsWith( ext ) )
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the file is in /WEB-INF/classes strip the dir info off
|
||||||
|
int index = fileName.indexOf( "/WEB-INF/classes/" );
|
||||||
|
if ( index != -1 )
|
||||||
|
{
|
||||||
|
fileName = fileName.substring( index + "/WEB-INF/classes/".length(), fileName.length() - ext.length() );
|
||||||
|
fileName = fileName.replace( '/', '.' );
|
||||||
|
fileName = fileName.replace( '\\', '.' );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Strip off the leading path info
|
||||||
|
fileName = fileName.substring( path.length(), fileName.length() - ext.length() );
|
||||||
|
}
|
||||||
|
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
* @param lesson Description of the Parameter
|
||||||
|
* @param context Description of the Parameter
|
||||||
|
* @param path Description of the Parameter
|
||||||
|
* @param courseName Description of the Parameter
|
||||||
|
* @param extension TODO
|
||||||
|
*/
|
||||||
|
private void findSourceResource( AbstractLesson lesson, ServletContext context, String path, String className, String extension )
|
||||||
|
{
|
||||||
|
//System.out.println("findSourceResource() looking for source files in: " + path);
|
||||||
|
//System.out.println("findSourceResource() looking for source files for class: " + className);
|
||||||
|
Set files = context.getResourcePaths( path );
|
||||||
|
Iterator fileIter = files.iterator();
|
||||||
|
String resource = null;
|
||||||
|
|
||||||
|
while ( fileIter.hasNext() )
|
||||||
|
{
|
||||||
|
resource = (String) fileIter.next();
|
||||||
|
//System.out.println("findSourceResource() inspecting resource: " + resource);
|
||||||
|
String lessonName = clean( resource, path, extension );
|
||||||
|
//System.out.println("findSourceResource() cleaned resource name: " + lessonName);
|
||||||
|
//if ( className != null )
|
||||||
|
//{
|
||||||
|
// System.out.println("Resource to check: " + resource);
|
||||||
|
// System.out.println("Lesson name: " + lessonName);
|
||||||
|
//}
|
||||||
|
|
||||||
|
// Not a match
|
||||||
|
if ( lessonName == null )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// A subdirectory
|
||||||
|
else if ( ( lessonName.length() != 1 ) && lessonName.endsWith( "/" ) )
|
||||||
|
{
|
||||||
|
findSourceResource( lesson, context, lessonName, className, extension );
|
||||||
|
}
|
||||||
|
// A source file
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Course name will be the fully qualified name:
|
||||||
|
// like lesson.admin.lessonName
|
||||||
|
if ( className.endsWith( lessonName ) )
|
||||||
|
{
|
||||||
|
int length = 0;
|
||||||
|
int index = className.indexOf("admin.");
|
||||||
|
if ( index == -1 )
|
||||||
|
{
|
||||||
|
index = className.indexOf("lessons.");
|
||||||
|
length = "lessons.".length();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
length = "admin.".length();
|
||||||
|
}
|
||||||
|
className = className.substring(index + length);
|
||||||
|
//System.out.println("Resource to check: " + resource);
|
||||||
|
//System.out.println("Lesson name: " + lessonName);
|
||||||
|
|
||||||
|
//store the web path of the source file in the lesson
|
||||||
|
lesson.setSourceFileName(resource);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
* @param lesson Description of the Parameter
|
||||||
|
* @param context Description of the Parameter
|
||||||
|
* @param path Description of the Parameter
|
||||||
|
* @param courseName Description of the Parameter
|
||||||
|
* @param extension TODO
|
||||||
|
*/
|
||||||
|
private void findLessonPlanResource( AbstractLesson lesson, ServletContext context, String path, String courseName, String extension )
|
||||||
|
{
|
||||||
|
Set files = context.getResourcePaths( path );
|
||||||
|
Iterator fileIter = files.iterator();
|
||||||
|
String resource = null;
|
||||||
|
|
||||||
|
while ( fileIter.hasNext() )
|
||||||
|
{
|
||||||
|
resource = (String) fileIter.next();
|
||||||
|
String className = clean( resource, path, extension );
|
||||||
|
//if ( className != null )
|
||||||
|
//{
|
||||||
|
// System.out.println("ClassName: " + className);
|
||||||
|
// System.out.println("ResourceToCheck: " + resourceToCheck);
|
||||||
|
//}
|
||||||
|
|
||||||
|
if ( className == null )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if ( ( className.length() != 1 ) && className.endsWith( "/" ) )
|
||||||
|
{
|
||||||
|
findLessonPlanResource( lesson, context, className, courseName, extension );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Course name will be the fully qualified name:
|
||||||
|
// like lesson.admin.lessonName
|
||||||
|
if ( courseName.endsWith( className ) )
|
||||||
|
{
|
||||||
|
int length = 0;
|
||||||
|
int index = courseName.indexOf("admin.");
|
||||||
|
if ( index == -1 )
|
||||||
|
{
|
||||||
|
index = courseName.indexOf("lessons.");
|
||||||
|
length = "lessons.".length();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
length = "admin.".length();
|
||||||
|
}
|
||||||
|
courseName = courseName.substring(index + length);
|
||||||
|
//System.out.println("ClassName: " + className);
|
||||||
|
//System.out.println("ResourceToCheck: " + resource);
|
||||||
|
|
||||||
|
//store the web path of the source file in the lesson
|
||||||
|
lesson.setLessonPlanFileName(resource);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the categories attribute of the Course object
|
||||||
|
*
|
||||||
|
* @return The categories value
|
||||||
|
*/
|
||||||
|
public List getCategories()
|
||||||
|
{
|
||||||
|
List categories = new ArrayList();
|
||||||
|
Iterator iter = lessons.iterator();
|
||||||
|
|
||||||
|
while ( iter.hasNext() )
|
||||||
|
{
|
||||||
|
AbstractLesson lesson = (AbstractLesson) iter.next();
|
||||||
|
|
||||||
|
if ( !categories.contains( lesson.getCategory() ) )
|
||||||
|
{
|
||||||
|
categories.add( lesson.getCategory() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Collections.sort( categories );
|
||||||
|
|
||||||
|
return categories;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the firstLesson attribute of the Course object
|
||||||
|
*
|
||||||
|
* @return The firstLesson value
|
||||||
|
*/
|
||||||
|
public AbstractLesson getFirstLesson()
|
||||||
|
{
|
||||||
|
List roles = new ArrayList();
|
||||||
|
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 roles )
|
||||||
|
{
|
||||||
|
if (s.isHackedAdmin())
|
||||||
|
{
|
||||||
|
roles.add(AbstractLesson.HACKED_ADMIN_ROLE);
|
||||||
|
}
|
||||||
|
//System.out.println("getLesson() with roles: " + roles);
|
||||||
|
Iterator iter = lessons.iterator();
|
||||||
|
|
||||||
|
while ( iter.hasNext() )
|
||||||
|
{
|
||||||
|
AbstractLesson lesson = (AbstractLesson) iter.next();
|
||||||
|
|
||||||
|
//System.out.println("getLesson() at role: " + lesson.getRole());
|
||||||
|
if ( lesson.getScreenId() == lessonId && roles.contains(lesson.getRole()) )
|
||||||
|
{
|
||||||
|
return lesson;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AbstractLesson getLesson( WebSession s, int lessonId, String role )
|
||||||
|
{
|
||||||
|
List roles = new Vector();
|
||||||
|
roles.add(role);
|
||||||
|
return getLesson(s, lessonId, roles);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List getLessons( WebSession s, String role )
|
||||||
|
{
|
||||||
|
List roles = new Vector();
|
||||||
|
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 getLessons( WebSession s, List roles )
|
||||||
|
{
|
||||||
|
if (s.isHackedAdmin())
|
||||||
|
{
|
||||||
|
roles.add(AbstractLesson.HACKED_ADMIN_ROLE);
|
||||||
|
}
|
||||||
|
List lessonList = new ArrayList();
|
||||||
|
Iterator categoryIter = getCategories().iterator();
|
||||||
|
|
||||||
|
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 getLessons( Category category, List roles )
|
||||||
|
{
|
||||||
|
List lessonList = new ArrayList();
|
||||||
|
|
||||||
|
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));
|
||||||
|
return lessonList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List getLessons( WebSession s, Category category, String role )
|
||||||
|
{
|
||||||
|
List roles = new Vector();
|
||||||
|
roles.add(role);
|
||||||
|
return getLessons(s, category, roles);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List getLessons(WebSession s, Category category, List roles)
|
||||||
|
{
|
||||||
|
if (s.isHackedAdmin())
|
||||||
|
{
|
||||||
|
roles.add(AbstractLesson.HACKED_ADMIN_ROLE);
|
||||||
|
}
|
||||||
|
return getLessons(category, roles);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param path Description of the Parameter
|
||||||
|
* @param context Description of the Parameter
|
||||||
|
*/
|
||||||
|
public void loadCourses( boolean enterprise, ServletContext context, String path )
|
||||||
|
{
|
||||||
|
Set files = context.getResourcePaths( path );
|
||||||
|
Iterator fileIter = files.iterator();
|
||||||
|
|
||||||
|
while ( fileIter.hasNext() )
|
||||||
|
{
|
||||||
|
String file = (String) fileIter.next();
|
||||||
|
String className = clean( file, path, ".class" );
|
||||||
|
|
||||||
|
//if ( className != null )
|
||||||
|
//{
|
||||||
|
// System.out.println( "Checking file: " + file );
|
||||||
|
// System.out.println( " class: " + className );
|
||||||
|
//}
|
||||||
|
if ( className == null )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if ( ( className.length() != 1 ) && className.endsWith( "/" ) )
|
||||||
|
{
|
||||||
|
loadCourses( enterprise, context, className );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Class lessonClass = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
lessonClass = Class.forName( className );
|
||||||
|
Object possibleLesson = lessonClass.newInstance();
|
||||||
|
|
||||||
|
if ( possibleLesson instanceof AbstractLesson )
|
||||||
|
{
|
||||||
|
AbstractLesson lesson = (AbstractLesson) possibleLesson;
|
||||||
|
|
||||||
|
// Determine if the screen is to be loaded. Look
|
||||||
|
// to see if the session parameter has been initialized.
|
||||||
|
// Look to see if the screen is an enterprise edition screen.
|
||||||
|
if ( !enterprise )
|
||||||
|
{
|
||||||
|
if ( lesson.isEnterprise() )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do not load instructor screens. Currently, they must be manually deployed.
|
||||||
|
if (lesson.getClass().getName().indexOf("instructor") > -1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// There are two methods instead of one because the developer was not
|
||||||
|
// smart enough to figure out the recursive return value
|
||||||
|
findSourceResource( lesson, context, "/", className, ".java" );
|
||||||
|
findLessonPlanResource( lesson, context, "/", className, ".html" );
|
||||||
|
|
||||||
|
// Override lesson attributes based on properties.
|
||||||
|
lesson.update(properties);
|
||||||
|
|
||||||
|
if(lesson.getHidden() == false)
|
||||||
|
lessons.add( lesson );
|
||||||
|
//System.out.println( "Found lesson: " + lesson );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
//System.out.println("Could not load lesson: " + className);
|
||||||
|
//e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
852
webgoat/main/project/org/owasp/webgoat/session/CreateDB.java
Normal file
852
webgoat/main/project/org/owasp/webgoat/session/CreateDB.java
Normal file
@ -0,0 +1,852 @@
|
|||||||
|
package org.owasp.webgoat.session;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2002 Free Software Foundation developed under the custody of
|
||||||
|
* the Open Web Application Security Project (http://www.owasp.org) This
|
||||||
|
* software package org.owasp.webgoat.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>
|
||||||
|
*/
|
||||||
|
public class CreateDB
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The main program for the AccessSqlInjection class
|
||||||
|
*
|
||||||
|
* @param args The command line arguments
|
||||||
|
*/
|
||||||
|
public static void main(String[] args)
|
||||||
|
{
|
||||||
|
|
||||||
|
CreateDB db = new CreateDB();
|
||||||
|
Connection connection = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver").newInstance();
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
System.out.println("Failed to load DB driver");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
connection = DriverManager.getConnection("jdbc:odbc:;DRIVER=Microsoft Access Driver (*.mdb);DBQ=c:/webgoat.mdb;PWD=webgoat", "webgoat", "webgoat");
|
||||||
|
db.makeDB(connection);
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
System.out.println("Driver Manager failed!");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getAllEmployees
|
||||||
|
*/
|
||||||
|
String query = "SELECT userid,first_name,last_name FROM employee WHERE userid in (SELECT employee_id FROM ownership WHERE employer_id = 101)";
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Statement answer_statement = connection.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY );
|
||||||
|
ResultSet answer_results = answer_statement.executeQuery( query );
|
||||||
|
answer_results.first();
|
||||||
|
int employeeId = answer_results.getInt("userid");
|
||||||
|
String firstName = answer_results.getString("first_name");
|
||||||
|
String lastName = answer_results.getString("last_name");
|
||||||
|
System.out.println("Query 1 Results: " + firstName + " " + lastName + " " + employeeId);
|
||||||
|
}
|
||||||
|
catch ( SQLException sqle )
|
||||||
|
{
|
||||||
|
sqle.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* isAllowed
|
||||||
|
*/
|
||||||
|
|
||||||
|
query = "SELECT * FROM auth WHERE role in (SELECT role FROM roles WHERE userid = 101) and functionid = 113";
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Statement answer_statement = connection.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY );
|
||||||
|
ResultSet answer_results = answer_statement.executeQuery( query );
|
||||||
|
boolean allowed = answer_results.first();
|
||||||
|
//boolean allowed = answer_results.next();
|
||||||
|
|
||||||
|
if(allowed)
|
||||||
|
System.out.println("User is allowed");
|
||||||
|
else
|
||||||
|
System.out.println("User is NOT allowed");
|
||||||
|
}
|
||||||
|
catch ( SQLException sqle )
|
||||||
|
{
|
||||||
|
sqle.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param connection Description of the Parameter
|
||||||
|
*
|
||||||
|
* @exception SQLException Description of the Exception
|
||||||
|
*/
|
||||||
|
private void createMessageTable(Connection connection) throws SQLException
|
||||||
|
{
|
||||||
|
Statement statement = connection.createStatement();
|
||||||
|
|
||||||
|
// Drop admin user table
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String dropTable = "DROP TABLE messages";
|
||||||
|
statement.executeUpdate(dropTable);
|
||||||
|
}
|
||||||
|
catch (SQLException e)
|
||||||
|
{
|
||||||
|
System.out.println("Error dropping message database");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the new table
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String createTableStatement = "CREATE TABLE messages ("
|
||||||
|
+ "num int not null,"
|
||||||
|
+ "title varchar(50),"
|
||||||
|
+ "message varchar(200),"
|
||||||
|
+ "user_name varchar(50) not null "
|
||||||
|
+ ")";
|
||||||
|
statement.executeUpdate(createTableStatement);
|
||||||
|
}
|
||||||
|
catch (SQLException e)
|
||||||
|
{
|
||||||
|
System.out.println("Error creating message database");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param connection Description of the Parameter
|
||||||
|
*
|
||||||
|
* @exception SQLException Description of the Exception
|
||||||
|
*/
|
||||||
|
private void createProductTable(Connection connection) throws SQLException
|
||||||
|
{
|
||||||
|
Statement statement = connection.createStatement();
|
||||||
|
|
||||||
|
// Drop admin user table
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String dropTable = "DROP TABLE product_system_data";
|
||||||
|
statement.executeUpdate(dropTable);
|
||||||
|
}
|
||||||
|
catch (SQLException e)
|
||||||
|
{
|
||||||
|
System.out.println("Error dropping product database");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the new table
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String createTableStatement = "CREATE TABLE product_system_data ("
|
||||||
|
+ "productid varchar(6) not null primary key,"
|
||||||
|
+ "product_name varchar(20),"
|
||||||
|
+ "price varchar(10)" + ")";
|
||||||
|
statement.executeUpdate(createTableStatement);
|
||||||
|
}
|
||||||
|
catch (SQLException e)
|
||||||
|
{
|
||||||
|
System.out.println("Error creating product database");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Populate
|
||||||
|
String insertData1 = "INSERT INTO product_system_data VALUES ('32226','Dog Bone','$1.99')";
|
||||||
|
String insertData2 = "INSERT INTO product_system_data VALUES ('35632','DVD Player','$214.99')";
|
||||||
|
String insertData3 = "INSERT INTO product_system_data VALUES ('24569','60 GB Hard Drive','$149.99')";
|
||||||
|
String insertData4 = "INSERT INTO product_system_data VALUES ('56970','80 GB Hard Drive','$179.99')";
|
||||||
|
String insertData5 = "INSERT INTO product_system_data VALUES ('14365','56 inch HDTV','$6999.99')";
|
||||||
|
statement.executeUpdate(insertData1);
|
||||||
|
statement.executeUpdate(insertData2);
|
||||||
|
statement.executeUpdate(insertData3);
|
||||||
|
statement.executeUpdate(insertData4);
|
||||||
|
statement.executeUpdate(insertData5);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param connection Description of the Parameter
|
||||||
|
*
|
||||||
|
* @exception SQLException Description of the Exception
|
||||||
|
*/
|
||||||
|
private void createUserAdminTable(Connection connection) throws SQLException
|
||||||
|
{
|
||||||
|
Statement statement = connection.createStatement();
|
||||||
|
|
||||||
|
// Drop admin user table
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String dropTable = "DROP TABLE user_system_data";
|
||||||
|
statement.executeUpdate(dropTable);
|
||||||
|
}
|
||||||
|
catch (SQLException e)
|
||||||
|
{
|
||||||
|
System.out.println("Error dropping user admin database");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the new table
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String createTableStatement = "CREATE TABLE user_system_data ("
|
||||||
|
+ "userid varchar(5) not null primary key,"
|
||||||
|
+ "user_name varchar(12),"
|
||||||
|
+ "password varchar(10),"
|
||||||
|
+ "cookie varchar(30)"
|
||||||
|
+ ")";
|
||||||
|
statement.executeUpdate(createTableStatement);
|
||||||
|
}
|
||||||
|
catch (SQLException e)
|
||||||
|
{
|
||||||
|
System.out.println("Error creating user admin database");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Populate
|
||||||
|
String insertData1 = "INSERT INTO user_system_data VALUES ('101','jsnow','passwd1', '')";
|
||||||
|
String insertData2 = "INSERT INTO user_system_data VALUES ('102','jdoe','passwd2', '')";
|
||||||
|
String insertData3 = "INSERT INTO user_system_data VALUES ('103','jplane','passwd3', '')";
|
||||||
|
String insertData4 = "INSERT INTO user_system_data VALUES ('104','jeff','jeff', '')";
|
||||||
|
String insertData5 = "INSERT INTO user_system_data VALUES ('105','dave','dave', '')";
|
||||||
|
statement.executeUpdate(insertData1);
|
||||||
|
statement.executeUpdate(insertData2);
|
||||||
|
statement.executeUpdate(insertData3);
|
||||||
|
statement.executeUpdate(insertData4);
|
||||||
|
statement.executeUpdate(insertData5);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param connection Description of the Parameter
|
||||||
|
*
|
||||||
|
* @exception SQLException Description of the Exception
|
||||||
|
*/
|
||||||
|
private void createUserDataTable(Connection connection) throws SQLException
|
||||||
|
{
|
||||||
|
Statement statement = connection.createStatement();
|
||||||
|
|
||||||
|
// Delete table if there is one
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String dropTable = "DROP TABLE user_data";
|
||||||
|
statement.executeUpdate(dropTable);
|
||||||
|
}
|
||||||
|
catch (SQLException e)
|
||||||
|
{
|
||||||
|
System.out.println("Error dropping user database");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the new table
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String createTableStatement = "CREATE TABLE user_data ("
|
||||||
|
+ "userid int not null,"
|
||||||
|
+ "first_name varchar(20),"
|
||||||
|
+ "last_name varchar(20),"
|
||||||
|
+ "cc_number varchar(30),"
|
||||||
|
+ "cc_type varchar(10),"
|
||||||
|
+ "cookie varchar(20),"
|
||||||
|
+ "login_count int"
|
||||||
|
+ ")";
|
||||||
|
statement.executeUpdate(createTableStatement);
|
||||||
|
}
|
||||||
|
catch (SQLException e)
|
||||||
|
{
|
||||||
|
System.out.println("Error creating user database");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Populate it
|
||||||
|
String insertData1 = "INSERT INTO user_data VALUES (101,'Joe','Snow','987654321','VISA',' ',0)";
|
||||||
|
String insertData2 = "INSERT INTO user_data VALUES (101,'Joe','Snow','2234200065411','MC',' ',0)";
|
||||||
|
String insertData3 = "INSERT INTO user_data VALUES (102,'John','Smith','2435600002222','MC',' ',0)";
|
||||||
|
String insertData4 = "INSERT INTO user_data VALUES (102,'John','Smith','4352209902222','AMEX',' ',0)";
|
||||||
|
String insertData5 = "INSERT INTO user_data VALUES (103,'Jane','Plane','123456789','MC',' ',0)";
|
||||||
|
String insertData6 = "INSERT INTO user_data VALUES (103,'Jane','Plane','333498703333','AMEX',' ',0)";
|
||||||
|
String insertData7 = "INSERT INTO user_data VALUES (10312,'Jolly','Hershey','176896789','MC',' ',0)";
|
||||||
|
String insertData8 = "INSERT INTO user_data VALUES (10312,'Jolly','Hershey','333300003333','AMEX',' ',0)";
|
||||||
|
String insertData9 = "INSERT INTO user_data VALUES (10323,'Grumpy','White','673834489','MC',' ',0)";
|
||||||
|
String insertData10 = "INSERT INTO user_data VALUES (10323,'Grumpy','White','33413003333','AMEX',' ',0)";
|
||||||
|
String insertData11 = "INSERT INTO user_data VALUES (15603,'Peter','Sand','123609789','MC',' ',0)";
|
||||||
|
String insertData12 = "INSERT INTO user_data VALUES (15603,'Peter','Sand','338893453333','AMEX',' ',0)";
|
||||||
|
String insertData13 = "INSERT INTO user_data VALUES (15613,'Joesph','Something','33843453533','AMEX',' ',0)";
|
||||||
|
statement.executeUpdate(insertData1);
|
||||||
|
statement.executeUpdate(insertData2);
|
||||||
|
statement.executeUpdate(insertData3);
|
||||||
|
statement.executeUpdate(insertData4);
|
||||||
|
statement.executeUpdate(insertData5);
|
||||||
|
statement.executeUpdate(insertData6);
|
||||||
|
statement.executeUpdate(insertData7);
|
||||||
|
statement.executeUpdate(insertData8);
|
||||||
|
statement.executeUpdate(insertData9);
|
||||||
|
statement.executeUpdate(insertData10);
|
||||||
|
statement.executeUpdate(insertData11);
|
||||||
|
statement.executeUpdate(insertData12);
|
||||||
|
statement.executeUpdate(insertData13);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createLoginTable(Connection connection) throws SQLException
|
||||||
|
{
|
||||||
|
Statement statement = connection.createStatement();
|
||||||
|
|
||||||
|
// Delete table if there is one
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String dropTable = "DROP TABLE user_login";
|
||||||
|
statement.executeUpdate(dropTable);
|
||||||
|
}
|
||||||
|
catch (SQLException e)
|
||||||
|
{
|
||||||
|
System.out.println("Error dropping user_login table");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the new table
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String createTableStatement = "CREATE TABLE user_login ("
|
||||||
|
+ "userid varchar(5),"
|
||||||
|
+ "webgoat_user varchar(20)"
|
||||||
|
+ ")";
|
||||||
|
statement.executeUpdate(createTableStatement);
|
||||||
|
}
|
||||||
|
catch (SQLException e)
|
||||||
|
{
|
||||||
|
System.out.println("Error creating user database");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param connection Description of the Parameter
|
||||||
|
*
|
||||||
|
* @exception SQLException Description of the Exception
|
||||||
|
*/
|
||||||
|
private void createWeatherDataTable(Connection connection) throws SQLException
|
||||||
|
{
|
||||||
|
Statement statement = connection.createStatement();
|
||||||
|
|
||||||
|
// Delete table if there is one
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String dropTable = "DROP TABLE weather_data";
|
||||||
|
statement.executeUpdate(dropTable);
|
||||||
|
}
|
||||||
|
catch (SQLException e)
|
||||||
|
{
|
||||||
|
System.out.println("Error dropping weather database");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the new table
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String createTableStatement = "CREATE TABLE weather_data ("
|
||||||
|
+ "station int not null,"
|
||||||
|
+ "name varchar(20) not null,"
|
||||||
|
+ "state char(2) not null,"
|
||||||
|
+ "min_temp int not null,"
|
||||||
|
+ "max_temp int not null"
|
||||||
|
+ ")";
|
||||||
|
statement.executeUpdate(createTableStatement);
|
||||||
|
}
|
||||||
|
catch (SQLException e)
|
||||||
|
{
|
||||||
|
System.out.println("Error creating weather database");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Populate it
|
||||||
|
String insertData1 = "INSERT INTO weather_data VALUES (101,'Columbia','MD',-10,102)";
|
||||||
|
String insertData2 = "INSERT INTO weather_data VALUES (102,'Seattle','WA',-15,90)";
|
||||||
|
String insertData3 = "INSERT INTO weather_data VALUES (103,'New York','NY',-10,110)";
|
||||||
|
String insertData4 = "INSERT INTO weather_data VALUES (104,'Houston','TX',20,120)";
|
||||||
|
String insertData5 = "INSERT INTO weather_data VALUES (10001,'Camp David','MD',-10,100)";
|
||||||
|
String insertData6 = "INSERT INTO weather_data VALUES (11001,'Ice Station Zebra','NA',-60,30)";
|
||||||
|
statement.executeUpdate(insertData1);
|
||||||
|
statement.executeUpdate(insertData2);
|
||||||
|
statement.executeUpdate(insertData3);
|
||||||
|
statement.executeUpdate(insertData4);
|
||||||
|
statement.executeUpdate(insertData5);
|
||||||
|
statement.executeUpdate(insertData6);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// The tables below are for WebGoat Financials
|
||||||
|
//
|
||||||
|
// DO NOT MODIFY THESE TABLES - unless you change the org chart
|
||||||
|
// and access control matrix documents
|
||||||
|
//
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
private void createEmployeeTable(Connection connection) throws SQLException
|
||||||
|
{
|
||||||
|
Statement statement = connection.createStatement();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String dropTable = "DROP TABLE employee";
|
||||||
|
statement.executeUpdate(dropTable);
|
||||||
|
}
|
||||||
|
catch ( SQLException e )
|
||||||
|
{
|
||||||
|
System.out.println("Error: unable to drop employee table");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create Table
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String createTable = "CREATE TABLE employee ("
|
||||||
|
//+ "userid INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,"
|
||||||
|
+ "userid INT NOT NULL PRIMARY KEY,"
|
||||||
|
+ "first_name VARCHAR(20),"
|
||||||
|
+ "last_name VARCHAR(20),"
|
||||||
|
+ "ssn VARCHAR(12),"
|
||||||
|
+ "password VARCHAR(10),"
|
||||||
|
+ "title VARCHAR(20),"
|
||||||
|
+ "phone VARCHAR(13),"
|
||||||
|
+ "address1 VARCHAR(80),"
|
||||||
|
+ "address2 VARCHAR(80),"
|
||||||
|
+ "manager INT,"
|
||||||
|
+ "start_date CHAR(8),"
|
||||||
|
+ "salary INT,"
|
||||||
|
+ "ccn VARCHAR(30),"
|
||||||
|
+ "ccn_limit INT,"
|
||||||
|
+ "disciplined_date CHAR(8)," // date of write up, NA otherwise
|
||||||
|
+ "disciplined_notes VARCHAR(60)," // reason for the recent write-up
|
||||||
|
+ "personal_description VARCHAR(60)" // We can be rude here
|
||||||
|
//+ ",CONSTRAINT fl UNIQUE NONCLUSTERED (first_name, last_name)"
|
||||||
|
+ ")";
|
||||||
|
|
||||||
|
statement.executeUpdate(createTable);
|
||||||
|
}
|
||||||
|
catch ( SQLException e )
|
||||||
|
{
|
||||||
|
System.out.println("Error: unable to create employee table");
|
||||||
|
}
|
||||||
|
|
||||||
|
String insertData1 = "INSERT INTO employee VALUES (101, 'Larry', 'Stooge', '386-09-5451', 'larry'," +
|
||||||
|
"'Technician','443-689-0192','9175 Guilford Rd','New York, NY', 102, 01012000,55000,'2578546969853547'," +
|
||||||
|
"5000,010106,'Constantly harrassing coworkers','Does not work well with others')";
|
||||||
|
|
||||||
|
String insertData2 = "INSERT INTO employee VALUES (102, 'Moe', 'Stooge', '936-18-4524','moe'," +
|
||||||
|
"'CSO','443-938-5301', '3013 AMD Ave', 'New York, NY', 112, 03082003, 140000, 'NA', 0, 0101013, " +
|
||||||
|
"'Hit Curly over head', 'Very dominating over Larry and Curly')";
|
||||||
|
|
||||||
|
String insertData3 = "INSERT INTO employee VALUES (103, 'Curly', 'Stooge', '961-08-0047','curly'," +
|
||||||
|
"'Technician','410-667-6654', '1112 Crusoe Lane', 'New York, NY', 102, 02122001, 50000, 'NA', 0, 0101014, " +
|
||||||
|
"'Hit Moe back', 'Owes three-thousand to company for fradulent purchases')";
|
||||||
|
|
||||||
|
String insertData4 = "INSERT INTO employee VALUES (104, 'Eric', 'Walker', '445-66-5565','eric'," +
|
||||||
|
"'Engineer','410-887-1193', '1160 Prescott Rd', 'New York, NY', 107, 12152005, 13000, 'NA', 0, 0101013, " +
|
||||||
|
"'Bothering Larry about webgoat problems', 'Late. Always needs help. Too intern-ish.')";
|
||||||
|
|
||||||
|
String insertData5 = "INSERT INTO employee VALUES (105, 'Tom', 'Cat', '792-14-6364','tom'," +
|
||||||
|
"'Engineer','443-599-0762', '2211 HyperThread Rd.', 'New York, NY', 106, 01011999, 80000, '5481360857968521', 30000, 0, " +
|
||||||
|
"'NA', 'Co-Owner.')";
|
||||||
|
|
||||||
|
String insertData6 = "INSERT INTO employee VALUES (106, 'Jerry', 'Mouse', '858-55-4452','jerry'," +
|
||||||
|
"'Human Resources','443-699-3366', '3011 Unix Drive', 'New York, NY', 102, 01011999, 70000, '6981754825013564', 20000, 0, " +
|
||||||
|
"'NA', 'Co-Owner.')";
|
||||||
|
|
||||||
|
String insertData7 = "INSERT INTO employee VALUES (107, 'David', 'Giambi', '439-20-9405','david'," +
|
||||||
|
"'Human Resources','610-521-8413', '5132 DIMM Avenue', 'New York, NY', 102, 05011999, 100000, '6981754825018101', 10000, 061402, " +
|
||||||
|
"'Hacked into accounting server. Modified personal pay.', 'Strong work habbit. Questionable ethics.')";
|
||||||
|
|
||||||
|
String insertData8 = "INSERT INTO employee VALUES (108, 'Bruce', 'McGuirre', '707-95-9482','bruce'," +
|
||||||
|
"'Engineer','610-282-1103', '8899 FreeBSD Drive<script>alert(document.cookie)</script> ', 'New York, NY', 107, 03012000, 110000, '6981754825854136', 30000, 061502, " +
|
||||||
|
"'Tortuous Boot Camp workout at 5am. Employees felt sick.', 'Enjoys watching others struggle in exercises.')";
|
||||||
|
|
||||||
|
String insertData9 = "INSERT INTO employee VALUES (109, 'Sean', 'Livingston', '136-55-1046','sean'," +
|
||||||
|
"'Engineer','610-878-9549', '6422 dFlyBSD Road', 'New York, NY', 107, 06012003, 130000, '6981754825014510', 5000, 072804, " +
|
||||||
|
"'Late to work 30 days in row due to excessive Halo 2', 'Has some fascination with Steelers. Go Ravens.')";
|
||||||
|
|
||||||
|
String insertData10 = "INSERT INTO employee VALUES (110, 'Joanne', 'McDougal', '789-54-2413','joanne'," +
|
||||||
|
"'Human Resources','610-213-6341', '5567 Broadband Lane', 'New York, NY', 106, 01012001, 90000, '6981754825081054', 300, 112005, " +
|
||||||
|
"'Used company cc to purchase new car. Limit adjusted.', 'Finds it necessary to leave early every day.')";
|
||||||
|
|
||||||
|
String insertData11 = "INSERT INTO employee VALUES (111, 'John', 'Wayne', '129-69-4572', 'john'," +
|
||||||
|
"'CTO','610-213-1134', '129 Third St', 'New York, NY', 112, 01012001, 200000, '4437334565679921', 300, 112005, " +
|
||||||
|
"'', '')";
|
||||||
|
String insertData12 = "INSERT INTO employee VALUES (112, 'Neville', 'Bartholomew', '111-111-1111', 'socks'," +
|
||||||
|
"'CEO','408-587-0024', '1 Corporate Headquarters', 'San Jose, CA', 112, 03012000, 450000, '4803389267684109', 300, 112005, " +
|
||||||
|
"'', '')";
|
||||||
|
|
||||||
|
statement.executeUpdate(insertData1);
|
||||||
|
statement.executeUpdate(insertData2);
|
||||||
|
statement.executeUpdate(insertData3);
|
||||||
|
statement.executeUpdate(insertData4);
|
||||||
|
statement.executeUpdate(insertData5);
|
||||||
|
statement.executeUpdate(insertData6);
|
||||||
|
statement.executeUpdate(insertData7);
|
||||||
|
statement.executeUpdate(insertData8);
|
||||||
|
statement.executeUpdate(insertData9);
|
||||||
|
statement.executeUpdate(insertData10);
|
||||||
|
statement.executeUpdate(insertData11);
|
||||||
|
statement.executeUpdate(insertData12);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createRolesTable(Connection connection) throws SQLException
|
||||||
|
{
|
||||||
|
Statement statement = connection.createStatement();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String dropTable = "DROP TABLE roles";
|
||||||
|
statement.executeUpdate(dropTable);
|
||||||
|
}
|
||||||
|
catch ( SQLException e )
|
||||||
|
{
|
||||||
|
System.out.println("Error: unable to drop roles");
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String createTable = "CREATE TABLE roles ("
|
||||||
|
+ "userid INT NOT NULL,"
|
||||||
|
+ "role VARCHAR(10) NOT NULL,"
|
||||||
|
+ "PRIMARY KEY (userid, role)"
|
||||||
|
+ ")";
|
||||||
|
|
||||||
|
statement.executeUpdate(createTable);
|
||||||
|
}
|
||||||
|
catch ( SQLException e )
|
||||||
|
{
|
||||||
|
System.out.println ("Error: Unable to create role table");
|
||||||
|
}
|
||||||
|
|
||||||
|
String insertData1 = "INSERT INTO roles VALUES (101, 'employee')";
|
||||||
|
String insertData2 = "INSERT INTO roles VALUES (102, 'manager')";
|
||||||
|
String insertData3 = "INSERT INTO roles VALUES (103, 'employee')";
|
||||||
|
String insertData4 = "INSERT INTO roles VALUES (104, 'employee')";
|
||||||
|
String insertData5 = "INSERT INTO roles VALUES (105, 'employee')";
|
||||||
|
String insertData6 = "INSERT INTO roles VALUES (106, 'hr')";
|
||||||
|
String insertData7 = "INSERT INTO roles VALUES (107, 'manager')";
|
||||||
|
String insertData8 = "INSERT INTO roles VALUES (108, 'employee')";
|
||||||
|
String insertData9 = "INSERT INTO roles VALUES (109, 'employee')";
|
||||||
|
String insertData10 = "INSERT INTO roles VALUES (110, 'hr')";
|
||||||
|
String insertData11 = "INSERT INTO roles VALUES (111, 'admin')";
|
||||||
|
String insertData12 = "INSERT INTO roles VALUES (112, 'admin')";
|
||||||
|
|
||||||
|
statement.executeUpdate(insertData1);
|
||||||
|
statement.executeUpdate(insertData2);
|
||||||
|
statement.executeUpdate(insertData3);
|
||||||
|
statement.executeUpdate(insertData4);
|
||||||
|
statement.executeUpdate(insertData5);
|
||||||
|
statement.executeUpdate(insertData6);
|
||||||
|
statement.executeUpdate(insertData7);
|
||||||
|
statement.executeUpdate(insertData8);
|
||||||
|
statement.executeUpdate(insertData9);
|
||||||
|
statement.executeUpdate(insertData10);
|
||||||
|
statement.executeUpdate(insertData11);
|
||||||
|
statement.executeUpdate(insertData12);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createAuthTable(Connection connection) throws SQLException
|
||||||
|
{
|
||||||
|
Statement statement = connection.createStatement();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String dropTable = "DROP TABLE auth";
|
||||||
|
statement.executeUpdate(dropTable);
|
||||||
|
}
|
||||||
|
catch ( SQLException e )
|
||||||
|
{
|
||||||
|
System.out.println("Error: unable to drop auth");
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String createTable = "CREATE TABLE auth ("
|
||||||
|
+ "role VARCHAR(10) NOT NULL,"
|
||||||
|
+ "functionid VARCHAR(20) NOT NULL,"
|
||||||
|
+ "PRIMARY KEY (role, functionid)"
|
||||||
|
+ ")";
|
||||||
|
|
||||||
|
statement.executeUpdate(createTable);
|
||||||
|
}
|
||||||
|
catch ( SQLException e )
|
||||||
|
{
|
||||||
|
System.out.println("Error: unable to create auth table");
|
||||||
|
}
|
||||||
|
|
||||||
|
String insertData1 = "INSERT INTO auth VALUES('employee', 'Logout')";
|
||||||
|
String insertData2 = "INSERT INTO auth VALUES('employee', 'ListStaff')";
|
||||||
|
String insertData3 = "INSERT INTO auth VALUES('employee', 'ViewProfile')";
|
||||||
|
String insertData4 = "INSERT INTO auth VALUES('employee', 'EditProfile')";
|
||||||
|
String insertData4_1 = "INSERT INTO auth VALUES('employee', 'SearchStaff')";
|
||||||
|
String insertData4_2 = "INSERT INTO auth VALUES('employee', 'FindProfile')";
|
||||||
|
String insertData5 = "INSERT INTO auth VALUES('manager', 'Logout')";
|
||||||
|
String insertData6 = "INSERT INTO auth VALUES('manager', 'ListStaff')";
|
||||||
|
String insertData7 = "INSERT INTO auth VALUES('manager', 'ViewProfile')";
|
||||||
|
String insertData7_1 = "INSERT INTO auth VALUES('manager', 'SearchStaff')";
|
||||||
|
String insertData7_2 = "INSERT INTO auth VALUES('manager', 'FindProfile')";
|
||||||
|
// String insertData8 = "INSERT INTO auth VALUES('manager', 'EditProfile')";
|
||||||
|
// String insertData9 = "INSERT INTO auth VALUES('manager', 'CreateProfile')";
|
||||||
|
// String insertData10 = "INSERT INTO auth VALUES('manager', 'DeleteProfile')";
|
||||||
|
// String insertData11 = "INSERT INTO auth VALUES('manager', 'UpdateProfile')";
|
||||||
|
String insertData12 = "INSERT INTO auth VALUES('hr', 'Logout')";
|
||||||
|
String insertData13 = "INSERT INTO auth VALUES('hr', 'ListStaff')";
|
||||||
|
String insertData14 = "INSERT INTO auth VALUES('hr', 'ViewProfile')";
|
||||||
|
String insertData15 = "INSERT INTO auth VALUES('hr', 'EditProfile')";
|
||||||
|
String insertData16 = "INSERT INTO auth VALUES('hr', 'CreateProfile')";
|
||||||
|
String insertData17 = "INSERT INTO auth VALUES('hr', 'DeleteProfile')";
|
||||||
|
String insertData18 = "INSERT INTO auth VALUES('hr', 'UpdateProfile')";
|
||||||
|
String insertData18_1 = "INSERT INTO auth VALUES('hr', 'SearchStaff')";
|
||||||
|
String insertData18_2 = "INSERT INTO auth VALUES('hr', 'FindProfile')";
|
||||||
|
String insertData19 = "INSERT INTO auth VALUES('admin', 'Logout')";
|
||||||
|
String insertData20 = "INSERT INTO auth VALUES('admin', 'ListStaff')";
|
||||||
|
String insertData21 = "INSERT INTO auth VALUES('admin', 'ViewProfile')";
|
||||||
|
String insertData22 = "INSERT INTO auth VALUES('admin', 'EditProfile')";
|
||||||
|
String insertData23 = "INSERT INTO auth VALUES('admin', 'CreateProfile')";
|
||||||
|
String insertData24 = "INSERT INTO auth VALUES('admin', 'DeleteProfile')";
|
||||||
|
String insertData25 = "INSERT INTO auth VALUES('admin', 'UpdateProfile')";
|
||||||
|
String insertData25_1 = "INSERT INTO auth VALUES('admin', 'SearchStaff')";
|
||||||
|
String insertData25_2 = "INSERT INTO auth VALUES('admin', 'FindProfile')";
|
||||||
|
|
||||||
|
// Add a permission for the webgoat role to see the source.
|
||||||
|
// The challenge(s) will change the default role to "challenge"
|
||||||
|
String insertData26 = "INSERT INTO auth VALUES('" + AbstractLesson.USER_ROLE + "','" + WebSession.SHOWSOURCE +"')";
|
||||||
|
String insertData27 = "INSERT INTO auth VALUES('" + AbstractLesson.USER_ROLE + "','" + WebSession.SHOWHINTS + "')";
|
||||||
|
|
||||||
|
statement.executeUpdate(insertData1);
|
||||||
|
statement.executeUpdate(insertData2);
|
||||||
|
statement.executeUpdate(insertData3);
|
||||||
|
statement.executeUpdate(insertData4);
|
||||||
|
statement.executeUpdate(insertData4_1);
|
||||||
|
statement.executeUpdate(insertData4_2);
|
||||||
|
statement.executeUpdate(insertData5);
|
||||||
|
statement.executeUpdate(insertData6);
|
||||||
|
statement.executeUpdate(insertData7);
|
||||||
|
statement.executeUpdate(insertData7_1);
|
||||||
|
statement.executeUpdate(insertData7_2);
|
||||||
|
// statement.executeUpdate(insertData8);
|
||||||
|
// statement.executeUpdate(insertData9);
|
||||||
|
// statement.executeUpdate(insertData10);
|
||||||
|
// statement.executeUpdate(insertData11);
|
||||||
|
statement.executeUpdate(insertData12);
|
||||||
|
statement.executeUpdate(insertData13);
|
||||||
|
statement.executeUpdate(insertData14);
|
||||||
|
statement.executeUpdate(insertData15);
|
||||||
|
statement.executeUpdate(insertData16);
|
||||||
|
statement.executeUpdate(insertData17);
|
||||||
|
statement.executeUpdate(insertData18);
|
||||||
|
statement.executeUpdate(insertData18_1);
|
||||||
|
statement.executeUpdate(insertData18_2);
|
||||||
|
statement.executeUpdate(insertData19);
|
||||||
|
statement.executeUpdate(insertData20);
|
||||||
|
statement.executeUpdate(insertData21);
|
||||||
|
statement.executeUpdate(insertData22);
|
||||||
|
statement.executeUpdate(insertData23);
|
||||||
|
statement.executeUpdate(insertData24);
|
||||||
|
statement.executeUpdate(insertData25);
|
||||||
|
statement.executeUpdate(insertData25_1);
|
||||||
|
statement.executeUpdate(insertData25_2);
|
||||||
|
statement.executeUpdate(insertData26);
|
||||||
|
statement.executeUpdate(insertData27);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createOwnershipTable(Connection connection) throws SQLException
|
||||||
|
{
|
||||||
|
Statement statement = connection.createStatement();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String dropTable = "DROP TABLE ownership";
|
||||||
|
statement.executeUpdate(dropTable);
|
||||||
|
}
|
||||||
|
catch ( SQLException e )
|
||||||
|
{
|
||||||
|
System.out.println("Error: unable to drop ownership");
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String createTable = "CREATE TABLE ownership ("
|
||||||
|
+ "employer_id INT NOT NULL,"
|
||||||
|
+ "employee_id INT NOT NULL,"
|
||||||
|
+ "PRIMARY KEY (employee_id, employer_id)"
|
||||||
|
+ ")";
|
||||||
|
|
||||||
|
statement.executeUpdate(createTable);
|
||||||
|
}
|
||||||
|
catch ( SQLException e )
|
||||||
|
{
|
||||||
|
System.out.println("Error: unable to create ownership table");
|
||||||
|
}
|
||||||
|
|
||||||
|
String inputData = "INSERT INTO ownership VALUES (112, 101)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
inputData = "INSERT INTO ownership VALUES (112, 102)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
inputData = "INSERT INTO ownership VALUES (112, 103)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
inputData = "INSERT INTO ownership VALUES (112, 104)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
inputData = "INSERT INTO ownership VALUES (112, 105)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
inputData = "INSERT INTO ownership VALUES (112, 106)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
inputData = "INSERT INTO ownership VALUES (112, 107)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
inputData = "INSERT INTO ownership VALUES (112, 108)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
inputData = "INSERT INTO ownership VALUES (112, 109)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
inputData = "INSERT INTO ownership VALUES (112, 110)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
inputData = "INSERT INTO ownership VALUES (112, 111)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
inputData = "INSERT INTO ownership VALUES (112, 112)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
|
||||||
|
inputData = "INSERT INTO ownership VALUES (102, 101)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
inputData = "INSERT INTO ownership VALUES (102, 102)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
inputData = "INSERT INTO ownership VALUES (102, 103)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
inputData = "INSERT INTO ownership VALUES (102, 104)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
inputData = "INSERT INTO ownership VALUES (102, 105)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
inputData = "INSERT INTO ownership VALUES (102, 106)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
inputData = "INSERT INTO ownership VALUES (102, 107)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
inputData = "INSERT INTO ownership VALUES (102, 108)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
inputData = "INSERT INTO ownership VALUES (102, 109)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
inputData = "INSERT INTO ownership VALUES (102, 110)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
inputData = "INSERT INTO ownership VALUES (102, 111)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
|
||||||
|
inputData = "INSERT INTO ownership VALUES (111, 101)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
inputData = "INSERT INTO ownership VALUES (111, 102)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
inputData = "INSERT INTO ownership VALUES (111, 103)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
inputData = "INSERT INTO ownership VALUES (111, 104)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
inputData = "INSERT INTO ownership VALUES (111, 105)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
inputData = "INSERT INTO ownership VALUES (111, 106)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
inputData = "INSERT INTO ownership VALUES (111, 107)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
inputData = "INSERT INTO ownership VALUES (111, 108)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
inputData = "INSERT INTO ownership VALUES (111, 109)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
inputData = "INSERT INTO ownership VALUES (111, 110)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
inputData = "INSERT INTO ownership VALUES (111, 111)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
|
||||||
|
inputData = "INSERT INTO ownership VALUES (106, 105)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
inputData = "INSERT INTO ownership VALUES (106, 106)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
inputData = "INSERT INTO ownership VALUES (106, 110)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
|
||||||
|
inputData = "INSERT INTO ownership VALUES (101, 101)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
|
||||||
|
inputData = "INSERT INTO ownership VALUES (103, 103)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
|
||||||
|
inputData = "INSERT INTO ownership VALUES (107, 104)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
inputData = "INSERT INTO ownership VALUES (107, 108)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
inputData = "INSERT INTO ownership VALUES (107, 109)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
inputData = "INSERT INTO ownership VALUES (107, 107)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
|
||||||
|
inputData = "INSERT INTO ownership VALUES (105, 105)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
|
||||||
|
inputData = "INSERT INTO ownership VALUES (110, 110)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
|
||||||
|
inputData = "INSERT INTO ownership VALUES (104, 104)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
|
||||||
|
inputData = "INSERT INTO ownership VALUES (108, 108)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
|
||||||
|
inputData = "INSERT INTO ownership VALUES (109, 109)";
|
||||||
|
statement.executeUpdate(inputData);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// End of WebGoat Financials
|
||||||
|
//
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param connection Description of the Parameter
|
||||||
|
*
|
||||||
|
* @exception SQLException Description of the Exception
|
||||||
|
*/
|
||||||
|
public void makeDB(Connection connection) throws SQLException
|
||||||
|
{
|
||||||
|
System.out.println("Successful connection to database");
|
||||||
|
createUserDataTable(connection);
|
||||||
|
createLoginTable(connection);
|
||||||
|
createUserAdminTable(connection);
|
||||||
|
createProductTable(connection);
|
||||||
|
createMessageTable(connection);
|
||||||
|
createEmployeeTable(connection);
|
||||||
|
createRolesTable(connection);
|
||||||
|
createAuthTable(connection);
|
||||||
|
createOwnershipTable(connection);
|
||||||
|
createWeatherDataTable(connection);
|
||||||
|
System.out.println("Success: creating tables.");
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,135 @@
|
|||||||
|
package org.owasp.webgoat.session;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.ResultSetMetaData;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import org.apache.ecs.MultiPartElement;
|
||||||
|
import org.apache.ecs.html.B;
|
||||||
|
import org.apache.ecs.html.TD;
|
||||||
|
import org.apache.ecs.html.TR;
|
||||||
|
import org.apache.ecs.html.Table;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2002 Free Software Foundation developed under the custody of
|
||||||
|
* the Open Web Application Security Project (http://www.owasp.org) This
|
||||||
|
* software package org.owasp.webgoat.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>
|
||||||
|
*/
|
||||||
|
public class DatabaseUtilities
|
||||||
|
{
|
||||||
|
public static String servletContextRealPath = null;
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param s Description of the Parameter
|
||||||
|
*
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*
|
||||||
|
* @exception ClassNotFoundException Description of the Exception
|
||||||
|
* @exception SQLException Description of the Exception
|
||||||
|
*/
|
||||||
|
public static Connection makeConnection(WebSession s) throws ClassNotFoundException, SQLException
|
||||||
|
{
|
||||||
|
Class.forName(s.getDatabaseDriver());
|
||||||
|
|
||||||
|
return (DriverManager.getConnection(s.getDatabaseConnectionString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Connection makeConnection(String driverName, String connectionString)
|
||||||
|
throws ClassNotFoundException, SQLException
|
||||||
|
{
|
||||||
|
Class.forName(driverName);
|
||||||
|
|
||||||
|
return (DriverManager.getConnection(connectionString));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Connection makeConnection() {
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// FIXME: Work around for not having a session object with the web service lessons
|
||||||
|
// This is the same "logic" in the web.xml file
|
||||||
|
// Get the path to webgoat database
|
||||||
|
|
||||||
|
String dbName = (servletContextRealPath + "database" + File.separator);
|
||||||
|
String os = System.getProperty("os.name","Windows");
|
||||||
|
if ( os.toLowerCase().indexOf("window") != -1 )
|
||||||
|
{
|
||||||
|
dbName = dbName.concat("webgoat.mdb");
|
||||||
|
System.out.println("DBName: " + dbName);
|
||||||
|
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
|
||||||
|
return DriverManager.getConnection("jdbc:odbc:;DRIVER=Microsoft Access Driver (*.mdb);DBQ=" + dbName + ";PWD=webgoat");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dbName = dbName.concat("database.prp");
|
||||||
|
Class.forName("org.enhydra.instantdb.jdbc.idbDriver");
|
||||||
|
return DriverManager.getConnection("jdbc:idb:" + dbName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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())
|
||||||
|
{
|
||||||
|
Table t = new Table(1); // 1 = with border
|
||||||
|
t.setCellPadding(1);
|
||||||
|
|
||||||
|
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++)
|
||||||
|
{
|
||||||
|
row.addElement(new TD(results.getString(i).replaceAll(" ", " ")));
|
||||||
|
}
|
||||||
|
|
||||||
|
t.addElement(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (t);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return (new B("Query Successful; however no data was returned from this query."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
688
webgoat/main/project/org/owasp/webgoat/session/ECSFactory.java
Normal file
688
webgoat/main/project/org/owasp/webgoat/session/ECSFactory.java
Normal file
@ -0,0 +1,688 @@
|
|||||||
|
package org.owasp.webgoat.session;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
import org.apache.ecs.ElementContainer;
|
||||||
|
import org.apache.ecs.StringElement;
|
||||||
|
import org.apache.ecs.html.A;
|
||||||
|
import org.apache.ecs.html.BR;
|
||||||
|
import org.apache.ecs.html.H3;
|
||||||
|
import org.apache.ecs.html.Input;
|
||||||
|
import org.apache.ecs.html.Label;
|
||||||
|
import org.apache.ecs.html.Option;
|
||||||
|
import org.apache.ecs.html.P;
|
||||||
|
import org.apache.ecs.html.Select;
|
||||||
|
import org.apache.ecs.html.TD;
|
||||||
|
import org.apache.ecs.html.TH;
|
||||||
|
import org.apache.ecs.html.TR;
|
||||||
|
import org.apache.ecs.html.U;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2002 Free Software Foundation developed under the custody of the Open Web
|
||||||
|
* Application Security Project (http://www.owasp.org) This software package org.owasp.webgoat.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 (jeff.williams@aspectsecurity.com)
|
||||||
|
* @created October 29, 2003
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ECSFactory
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Field
|
||||||
|
*/
|
||||||
|
|
||||||
|
public final static String ON = "On";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Field
|
||||||
|
*/
|
||||||
|
|
||||||
|
public final static String PASSWORD = "Password";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Don't let anyone instantiate this class
|
||||||
|
*/
|
||||||
|
|
||||||
|
private ECSFactory() { }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param name Description of the Parameter
|
||||||
|
* @param value Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static Element makeBox( String name, String value )
|
||||||
|
{
|
||||||
|
|
||||||
|
Input i = new Input( Input.CHECKBOX, name, ON );
|
||||||
|
|
||||||
|
i.setChecked( value.equals( ON ) );
|
||||||
|
|
||||||
|
return ( i );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param text Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static Element makeButton( String text )
|
||||||
|
{
|
||||||
|
|
||||||
|
Input b = new Input();
|
||||||
|
|
||||||
|
b.setType( Input.SUBMIT );
|
||||||
|
b.setValue( text );
|
||||||
|
b.setName(Input.SUBMIT);
|
||||||
|
|
||||||
|
return ( b );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param labeltext Description of the Parameter
|
||||||
|
* @param value Description of the Parameter
|
||||||
|
* @param e Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static TR makeField( String labeltext, String value, Element e )
|
||||||
|
{
|
||||||
|
|
||||||
|
TD left = new TD().setAlign( "right" );
|
||||||
|
|
||||||
|
Label label = new Label().addElement( labeltext );
|
||||||
|
|
||||||
|
left.addElement( label );
|
||||||
|
|
||||||
|
TD right = new TD().setAlign( "left" );
|
||||||
|
|
||||||
|
right.addElement( e );
|
||||||
|
|
||||||
|
TR row = new TR();
|
||||||
|
|
||||||
|
row.addElement( left );
|
||||||
|
|
||||||
|
row.addElement( right );
|
||||||
|
|
||||||
|
return ( row );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param labeltext Description of the Parameter
|
||||||
|
* @param name Description of the Parameter
|
||||||
|
* @param value Description of the Parameter
|
||||||
|
* @param size Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static TR makeField( String labeltext, String name, String value, int size )
|
||||||
|
{
|
||||||
|
|
||||||
|
Input field = new Input().setName( name ).setValue( value ).setSize( size ).setMaxlength( size );
|
||||||
|
|
||||||
|
// double check in case someone means to make a * starred out password field
|
||||||
|
|
||||||
|
if ( name.equals( PASSWORD ) )
|
||||||
|
{
|
||||||
|
|
||||||
|
field.setType( Input.PASSWORD );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( makeField( labeltext, value, field ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param label Description of the Parameter
|
||||||
|
* @param type Description of the Parameter
|
||||||
|
* @param name Description of the Parameter
|
||||||
|
* @param value Description of the Parameter
|
||||||
|
* @param alignment Description of the Parameter
|
||||||
|
* @param selected Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static Element makeInput( String label, String type, String name, boolean value, boolean selected, String alignment )
|
||||||
|
{
|
||||||
|
|
||||||
|
return makeInput( label, type, name, new Boolean( value ).toString(), selected, alignment );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param label Description of the Parameter
|
||||||
|
* @param type Description of the Parameter
|
||||||
|
* @param name Description of the Parameter
|
||||||
|
* @param value Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static Element makeInput( String label, String type, String name, String value )
|
||||||
|
{
|
||||||
|
|
||||||
|
return makeInput( label, type, name, value, new Boolean( value ).booleanValue(), "RIGHT" );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param label Description of the Parameter
|
||||||
|
* @param type Description of the Parameter
|
||||||
|
* @param name Description of the Parameter
|
||||||
|
* @param value Description of the Parameter
|
||||||
|
* @param alignment Description of the Parameter
|
||||||
|
* @param selected Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static Element makeInput( String label, String type, String name, String value, boolean selected, String alignment )
|
||||||
|
{
|
||||||
|
|
||||||
|
ElementContainer ec = new ElementContainer();
|
||||||
|
|
||||||
|
if ( !alignment.equalsIgnoreCase( "LEFT" ) )
|
||||||
|
{
|
||||||
|
|
||||||
|
ec.addElement( new StringElement( label ) );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Input input = new Input( type, name, value );
|
||||||
|
|
||||||
|
ec.addElement( input );
|
||||||
|
|
||||||
|
if ( alignment.equalsIgnoreCase( "LEFT" ) )
|
||||||
|
{
|
||||||
|
|
||||||
|
ec.addElement( new StringElement( label ) );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( type.equalsIgnoreCase( "CHECKBOX" ) )
|
||||||
|
{
|
||||||
|
|
||||||
|
input.setChecked( selected );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( ec );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param text Description of the Parameter
|
||||||
|
* @param name Description of the Parameter
|
||||||
|
* @param value Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static A makeLink( String text, String name, String value )
|
||||||
|
{
|
||||||
|
|
||||||
|
String href = "attack?" + name;
|
||||||
|
|
||||||
|
if ( value.length() > 0 )
|
||||||
|
{
|
||||||
|
|
||||||
|
href = href + "=" + value;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
A a = new A( href );
|
||||||
|
|
||||||
|
a.addElement( new U().addElement( text ) );
|
||||||
|
|
||||||
|
a.addAttribute( "style", "cursor:hand" );
|
||||||
|
|
||||||
|
return ( a );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param text Description of the Parameter
|
||||||
|
* @param name Description of the Parameter
|
||||||
|
* @param value Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static A makeLink( String text, String name, int value )
|
||||||
|
{
|
||||||
|
|
||||||
|
return ( makeLink( text, name, Integer.toString( value ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param text Description of the Parameter
|
||||||
|
* @param name Description of the Parameter
|
||||||
|
* @param value Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static A makeLink( String text, String name, boolean value )
|
||||||
|
{
|
||||||
|
|
||||||
|
return ( makeLink( text, name, new Boolean( value ).toString() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param text Description of the Parameter
|
||||||
|
* @param clickAction Description of the Parameter
|
||||||
|
* @param type Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static Input makeOnClickInput( String text, String clickAction, String type )
|
||||||
|
{
|
||||||
|
|
||||||
|
Input b = new Input();
|
||||||
|
|
||||||
|
b.setType( type );
|
||||||
|
|
||||||
|
b.setValue( text );
|
||||||
|
|
||||||
|
b.setOnClick( clickAction );
|
||||||
|
|
||||||
|
return ( b );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param labeltext Description of the Parameter
|
||||||
|
* @param value Description of the Parameter
|
||||||
|
* @param e Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static TR makeOption( String labeltext, String value, Element e )
|
||||||
|
{
|
||||||
|
|
||||||
|
TD left = new TD().setAlign( "left" ).setWidth( "10%" );
|
||||||
|
|
||||||
|
left.addElement( e );
|
||||||
|
|
||||||
|
TD right = new TD().setAlign( "right" );
|
||||||
|
|
||||||
|
Label label = new Label().addElement( labeltext );
|
||||||
|
|
||||||
|
right.addElement( label );
|
||||||
|
|
||||||
|
TR row = new TR();
|
||||||
|
|
||||||
|
row.addElement( right );
|
||||||
|
|
||||||
|
row.addElement( left );
|
||||||
|
|
||||||
|
return ( row );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param label Description of the Parameter
|
||||||
|
* @param value Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static Option makeOption( String label, boolean value )
|
||||||
|
{
|
||||||
|
|
||||||
|
Option option = new Option( label, new Boolean( value ).toString() );
|
||||||
|
|
||||||
|
option.setSelected( value );
|
||||||
|
|
||||||
|
return option;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param line Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
|
||||||
|
private static org.apache.ecs.html.Option makeOption( String line )
|
||||||
|
{
|
||||||
|
|
||||||
|
StringTokenizer st = new StringTokenizer( line, "|" );
|
||||||
|
|
||||||
|
org.apache.ecs.html.Option o = new org.apache.ecs.html.Option();
|
||||||
|
|
||||||
|
String token = "";
|
||||||
|
|
||||||
|
if ( st.hasMoreTokens() )
|
||||||
|
{
|
||||||
|
|
||||||
|
token = st.nextToken();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
o.addElement( token );
|
||||||
|
|
||||||
|
return ( o );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param name Description of the Parameter
|
||||||
|
* @param options Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static Element makePulldown( String name, List options )
|
||||||
|
{
|
||||||
|
|
||||||
|
Select s = new Select( name );
|
||||||
|
|
||||||
|
s.addElement( (String[]) options.toArray( new String[options.size()] ) );
|
||||||
|
|
||||||
|
return ( s );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param results Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static Element makePulldown( String name, String results )
|
||||||
|
{
|
||||||
|
|
||||||
|
Select select = new Select(name);
|
||||||
|
|
||||||
|
StringTokenizer st = new StringTokenizer( results, "\n" );
|
||||||
|
|
||||||
|
if ( !st.hasMoreTokens() )
|
||||||
|
{
|
||||||
|
|
||||||
|
return ( new StringElement( "" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
while ( st.hasMoreTokens() )
|
||||||
|
{
|
||||||
|
|
||||||
|
String line = st.nextToken();
|
||||||
|
|
||||||
|
select.addElement( makeOption( line ) );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
select.addElement( "-------------------------" );
|
||||||
|
|
||||||
|
return ( select );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param name Description of the Parameter
|
||||||
|
* @param list Description of the Parameter
|
||||||
|
* @param selected Description of the Parameter
|
||||||
|
* @param rowsShowing Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static Select makePulldown( String name, Object[] list, String selected, int rowsShowing )
|
||||||
|
{
|
||||||
|
|
||||||
|
Select select = new Select( name );
|
||||||
|
|
||||||
|
for ( int loop = 0; loop < list.length; loop++ )
|
||||||
|
{
|
||||||
|
|
||||||
|
String value = list[loop].toString();
|
||||||
|
|
||||||
|
org.apache.ecs.html.Option o = new org.apache.ecs.html.Option( value, value, value );
|
||||||
|
|
||||||
|
if ( value.equals( selected ) )
|
||||||
|
{
|
||||||
|
|
||||||
|
o.setSelected( true );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
select.addElement( o );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
select.setSize( rowsShowing );
|
||||||
|
|
||||||
|
return select;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default size of 1 for rows showing in select box.
|
||||||
|
*
|
||||||
|
* @param diffNames Description of the Parameter
|
||||||
|
* @param select Description of the Parameter
|
||||||
|
* @param name Description of the Parameter
|
||||||
|
* @param options Description of the Parameter
|
||||||
|
* @param list Description of the Parameter
|
||||||
|
* @param selected Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static Element makeSelect( boolean diffNames, Select select, String name, Vector options, String[] list, String selected )
|
||||||
|
{
|
||||||
|
|
||||||
|
return makeSelect( diffNames, select, name, options, list, selected, 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param diffNames Description of the Parameter
|
||||||
|
* @param select Description of the Parameter
|
||||||
|
* @param name Description of the Parameter
|
||||||
|
* @param options Description of the Parameter
|
||||||
|
* @param list Description of the Parameter
|
||||||
|
* @param selected Description of the Parameter
|
||||||
|
* @param rowsShowing Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static Select makeSelect( boolean diffNames, Select select, String name, Vector options, String[] list, String selected, int rowsShowing )
|
||||||
|
{
|
||||||
|
|
||||||
|
if ( select == null )
|
||||||
|
{
|
||||||
|
|
||||||
|
select = new Select( name );
|
||||||
|
|
||||||
|
if ( diffNames )
|
||||||
|
{
|
||||||
|
|
||||||
|
for ( int loop = 0; loop < list.length; loop += 2 )
|
||||||
|
{
|
||||||
|
|
||||||
|
String value = list[loop];
|
||||||
|
|
||||||
|
String label = list[loop + 1];
|
||||||
|
|
||||||
|
org.apache.ecs.html.Option o = new org.apache.ecs.html.Option( value );
|
||||||
|
|
||||||
|
if ( loop == 0 )
|
||||||
|
{
|
||||||
|
|
||||||
|
o.setSelected( true );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
options.addElement( o );// add to Vector containing all options
|
||||||
|
|
||||||
|
select.addElement( o );
|
||||||
|
|
||||||
|
select.addElement( label );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
for ( int loop = 0; loop < list.length; loop++ )
|
||||||
|
{
|
||||||
|
|
||||||
|
String value = list[loop];
|
||||||
|
|
||||||
|
org.apache.ecs.html.Option o = new org.apache.ecs.html.Option( value );
|
||||||
|
|
||||||
|
if ( loop == 0 )
|
||||||
|
{
|
||||||
|
|
||||||
|
o.setSelected( true );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
options.addElement( o );// add to Vector containing all options
|
||||||
|
|
||||||
|
select.addElement( o );
|
||||||
|
|
||||||
|
select.addElement( value );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// find selected option and set selected
|
||||||
|
|
||||||
|
Iterator i = options.iterator();
|
||||||
|
|
||||||
|
while ( i.hasNext() )
|
||||||
|
{
|
||||||
|
|
||||||
|
org.apache.ecs.html.Option o = (org.apache.ecs.html.Option) i.next();
|
||||||
|
|
||||||
|
if ( selected.equalsIgnoreCase( o.getAttribute( "value" ) ) )
|
||||||
|
{
|
||||||
|
|
||||||
|
o.setSelected( true );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
select.setSize( rowsShowing );
|
||||||
|
|
||||||
|
return ( select );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param title Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
public static Element makeTallHeader( String title )
|
||||||
|
{
|
||||||
|
StringBuffer buff = new StringBuffer();
|
||||||
|
for ( int i = 0; i < title.length(); i++ )
|
||||||
|
{
|
||||||
|
buff.append( title.charAt( i ) );
|
||||||
|
buff.append( "<BR>" );
|
||||||
|
}
|
||||||
|
return new TH( buff.toString() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param title Description of the Parameter
|
||||||
|
* @param text Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static Element makeTextArea( String title, String text )
|
||||||
|
{
|
||||||
|
|
||||||
|
ElementContainer ec = new ElementContainer();
|
||||||
|
|
||||||
|
ec.addElement( new BR() );
|
||||||
|
|
||||||
|
ec.addElement( new H3().addElement( title ) );
|
||||||
|
|
||||||
|
ec.addElement( new P() );
|
||||||
|
|
||||||
|
ec.addElement( "<CENTER><TEXTAREA ROWS=10 COLS=90 READONLY>" + text + "</TEXTAREA></CENTER>" );
|
||||||
|
|
||||||
|
ec.addElement( new BR() );
|
||||||
|
|
||||||
|
ec.addElement( new BR() );
|
||||||
|
|
||||||
|
return ( ec );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
218
webgoat/main/project/org/owasp/webgoat/session/Employee.java
Normal file
218
webgoat/main/project/org/owasp/webgoat/session/Employee.java
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
package org.owasp.webgoat.session;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public class Employee implements Serializable
|
||||||
|
{
|
||||||
|
public final static String EMPLOYEE_ROLE = "employee";
|
||||||
|
public final static String MANAGER_ROLE = "manager";
|
||||||
|
public final static String HR_ROLE = "hr";
|
||||||
|
|
||||||
|
private int id;
|
||||||
|
|
||||||
|
private String firstName;
|
||||||
|
|
||||||
|
private String lastName;
|
||||||
|
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
private String ssn;
|
||||||
|
|
||||||
|
private String phone;
|
||||||
|
|
||||||
|
private String address1;
|
||||||
|
|
||||||
|
private String address2;
|
||||||
|
|
||||||
|
private int manager;
|
||||||
|
|
||||||
|
private String startDate;
|
||||||
|
|
||||||
|
private int salary;
|
||||||
|
|
||||||
|
private String ccn;
|
||||||
|
|
||||||
|
private int ccnLimit;
|
||||||
|
|
||||||
|
private String disciplinaryActionDate;
|
||||||
|
|
||||||
|
private String disciplinaryActionNotes;
|
||||||
|
|
||||||
|
private String personalDescription;
|
||||||
|
|
||||||
|
// FIXME: To be deleted
|
||||||
|
public Employee()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public Employee(
|
||||||
|
int id,
|
||||||
|
String firstName,
|
||||||
|
String lastName,
|
||||||
|
String ssn,
|
||||||
|
String title,
|
||||||
|
String phone,
|
||||||
|
String address1,
|
||||||
|
String address2,
|
||||||
|
int manager,
|
||||||
|
String startDate,
|
||||||
|
int salary,
|
||||||
|
String ccn,
|
||||||
|
int ccnLimit,
|
||||||
|
String disciplinaryActionDate,
|
||||||
|
String disciplinaryActionNotes,
|
||||||
|
String personalDescription)
|
||||||
|
{
|
||||||
|
this.id = id;
|
||||||
|
this.firstName = firstName;
|
||||||
|
this.lastName = lastName;
|
||||||
|
this.ssn = ssn;
|
||||||
|
this.title = title;
|
||||||
|
this.phone = phone;
|
||||||
|
this.address1 = address1;
|
||||||
|
this.address2 = address2;
|
||||||
|
this.manager = manager;
|
||||||
|
this.startDate = startDate;
|
||||||
|
this.salary = salary;
|
||||||
|
this.ccn = ccn;
|
||||||
|
this.ccnLimit = ccnLimit;
|
||||||
|
this.disciplinaryActionDate = disciplinaryActionDate;
|
||||||
|
this.disciplinaryActionNotes = disciplinaryActionNotes;
|
||||||
|
this.personalDescription = personalDescription;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAddress1()
|
||||||
|
{
|
||||||
|
return address1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAddress1(String address1)
|
||||||
|
{
|
||||||
|
this.address1 = address1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAddress2()
|
||||||
|
{
|
||||||
|
return address2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAddress2(String address2)
|
||||||
|
{
|
||||||
|
this.address2 = address2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCcn()
|
||||||
|
{
|
||||||
|
return ccn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCcn(String ccn)
|
||||||
|
{
|
||||||
|
this.ccn = ccn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCcnLimit()
|
||||||
|
{
|
||||||
|
return ccnLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCcnLimit(int ccnLimit)
|
||||||
|
{
|
||||||
|
this.ccnLimit = ccnLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFirstName()
|
||||||
|
{
|
||||||
|
return firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFirstName(String firstName)
|
||||||
|
{
|
||||||
|
this.firstName = firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLastName()
|
||||||
|
{
|
||||||
|
return lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastName(String lastName)
|
||||||
|
{
|
||||||
|
this.lastName = lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPhoneNumber()
|
||||||
|
{
|
||||||
|
return phone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPhoneNumber(String phone)
|
||||||
|
{
|
||||||
|
this.phone = phone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSalary()
|
||||||
|
{
|
||||||
|
return salary;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSalary(int salary)
|
||||||
|
{
|
||||||
|
this.salary = salary;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSsn()
|
||||||
|
{
|
||||||
|
return ssn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSsn(String ssn)
|
||||||
|
{
|
||||||
|
this.ssn = ssn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStartDate()
|
||||||
|
{
|
||||||
|
return startDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStartDate(String startDate)
|
||||||
|
{
|
||||||
|
this.startDate = startDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId()
|
||||||
|
{
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(int id)
|
||||||
|
{
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitle()
|
||||||
|
{
|
||||||
|
return this.title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getManager()
|
||||||
|
{
|
||||||
|
return this.manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDisciplinaryActionDate()
|
||||||
|
{
|
||||||
|
return this.disciplinaryActionDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDisciplinaryActionNotes()
|
||||||
|
{
|
||||||
|
return this.disciplinaryActionNotes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPersonalDescription()
|
||||||
|
{
|
||||||
|
return this.personalDescription;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
package org.owasp.webgoat.session;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public class EmployeeStub implements Serializable
|
||||||
|
{
|
||||||
|
private int id;
|
||||||
|
private String firstName;
|
||||||
|
private String lastName;
|
||||||
|
private String role;
|
||||||
|
|
||||||
|
public EmployeeStub(int id, String firstName, String lastName)
|
||||||
|
{
|
||||||
|
this(id, firstName, lastName, Employee.EMPLOYEE_ROLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EmployeeStub(int id, String firstName, String lastName, String role)
|
||||||
|
{
|
||||||
|
this.id = id;
|
||||||
|
this.firstName = firstName;
|
||||||
|
this.lastName = lastName;
|
||||||
|
this.role = role;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFirstName()
|
||||||
|
{
|
||||||
|
return firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId()
|
||||||
|
{
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLastName()
|
||||||
|
{
|
||||||
|
return lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRole()
|
||||||
|
{
|
||||||
|
return role;
|
||||||
|
}
|
||||||
|
}
|
||||||
255
webgoat/main/project/org/owasp/webgoat/session/ErrorScreen.java
Normal file
255
webgoat/main/project/org/owasp/webgoat/session/ErrorScreen.java
Normal file
@ -0,0 +1,255 @@
|
|||||||
|
package org.owasp.webgoat.session;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
|
||||||
|
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||||
|
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
import org.apache.ecs.ElementContainer;
|
||||||
|
import org.apache.ecs.HtmlColor;
|
||||||
|
import org.apache.ecs.StringElement;
|
||||||
|
import org.apache.ecs.html.Div;
|
||||||
|
import org.apache.ecs.html.Form;
|
||||||
|
import org.apache.ecs.html.H2;
|
||||||
|
import org.apache.ecs.html.Small;
|
||||||
|
import org.apache.ecs.html.TD;
|
||||||
|
import org.apache.ecs.html.TR;
|
||||||
|
import org.apache.ecs.html.Table;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2002 Free Software Foundation developed under the custody of the Open Web
|
||||||
|
* Application Security Project (http://www.owasp.org) This software package org.owasp.webgoat.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 November 4, 2003
|
||||||
|
*/
|
||||||
|
public class ErrorScreen extends Screen
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Description of the Field
|
||||||
|
*/
|
||||||
|
protected Throwable error;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Field
|
||||||
|
*/
|
||||||
|
protected String message;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for the ErrorScreen object
|
||||||
|
*
|
||||||
|
* @param s Description of the Parameter
|
||||||
|
* @param t Description of the Parameter
|
||||||
|
*/
|
||||||
|
public ErrorScreen( WebSession s, Throwable t )
|
||||||
|
{
|
||||||
|
this.error = t;
|
||||||
|
fixCurrentScreen( s );
|
||||||
|
setup( s );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for the ErrorScreen object
|
||||||
|
*
|
||||||
|
* @param s Description of the Parameter
|
||||||
|
* @param msg Description of the Parameter
|
||||||
|
*/
|
||||||
|
public ErrorScreen( WebSession s, String msg )
|
||||||
|
{
|
||||||
|
this.message = msg;
|
||||||
|
fixCurrentScreen( s );
|
||||||
|
setup( s );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void fixCurrentScreen( WebSession s )
|
||||||
|
{
|
||||||
|
// So the user can't get stuck on the error screen, reset the
|
||||||
|
// current screen to something known
|
||||||
|
if ( s!= null )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
s.setCurrentScreen( s.getCourse().getFirstLesson().getScreenId() );
|
||||||
|
}
|
||||||
|
catch ( Throwable t )
|
||||||
|
{
|
||||||
|
s.setCurrentScreen( WebSession.WELCOME );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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" );
|
||||||
|
}
|
||||||
|
|
||||||
|
Table container = new Table().setWidth( "100%" ).setCellSpacing( 10 ).setCellPadding( 0 ).setBorder( 0 );
|
||||||
|
|
||||||
|
// CreateContent can generate error messages so you MUST call it before makeMessages()
|
||||||
|
Element content = createContent( s );
|
||||||
|
container.addElement( new TR().addElement( new TD().setColSpan( 2 ).setVAlign( "TOP" ).addElement(
|
||||||
|
makeMessages( s ) ) ) );
|
||||||
|
container.addElement( new TR().addElement( new TD().setColSpan( 2 ).addElement( content ) ) );
|
||||||
|
container.addElement( new TR() );
|
||||||
|
|
||||||
|
return ( container );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param s Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
protected Element createContent( WebSession s )
|
||||||
|
{
|
||||||
|
System.out.println( "errorscreen createContent Error:" + this.error + " message:" + this.message );
|
||||||
|
|
||||||
|
Element content;
|
||||||
|
|
||||||
|
if ( this.error != null )
|
||||||
|
{
|
||||||
|
content = createContent( this.error );
|
||||||
|
}
|
||||||
|
else if ( this.message != null )
|
||||||
|
{
|
||||||
|
content = createContent( this.message );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
content = new StringElement( "An unknown error occurred." );
|
||||||
|
}
|
||||||
|
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param s Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
protected Element createContent( String s )
|
||||||
|
{
|
||||||
|
StringElement list = new StringElement( s );
|
||||||
|
|
||||||
|
return ( list );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param t Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
protected Element createContent( Throwable t )
|
||||||
|
{
|
||||||
|
StringElement list = new StringElement();
|
||||||
|
list.addElement( new H2().addElement( new StringElement( "Error Message: " + t.getMessage() ) ) );
|
||||||
|
list.addElement( formatStackTrace( t ) );
|
||||||
|
|
||||||
|
if ( t instanceof ServletException )
|
||||||
|
{
|
||||||
|
Throwable root = ( (ServletException) t ).getRootCause();
|
||||||
|
|
||||||
|
if ( root != null )
|
||||||
|
{
|
||||||
|
list.addElement( new H2().addElement( new StringElement( "Root Message: " + root.getMessage() ) ) );
|
||||||
|
list.addElement( formatStackTrace( root ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( new Small().addElement( list ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
public Element getCredits()
|
||||||
|
{
|
||||||
|
return new ElementContainer();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param t Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
public static Element formatStackTrace( Throwable t )
|
||||||
|
{
|
||||||
|
String trace = getStackTrace( t );
|
||||||
|
StringElement list = new StringElement();
|
||||||
|
StringTokenizer st = new StringTokenizer( trace, "\r\n\t" );
|
||||||
|
|
||||||
|
while ( st.hasMoreTokens() )
|
||||||
|
{
|
||||||
|
String line = st.nextToken();
|
||||||
|
list.addElement( new Div( line ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( list );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the stackTrace attribute of the ErrorScreen class
|
||||||
|
*
|
||||||
|
* @param t Description of the Parameter
|
||||||
|
* @return The stackTrace value
|
||||||
|
*/
|
||||||
|
public static String getStackTrace( Throwable t )
|
||||||
|
{
|
||||||
|
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
|
||||||
|
PrintWriter writer = new PrintWriter( bytes, true );
|
||||||
|
t.printStackTrace( writer );
|
||||||
|
|
||||||
|
return ( bytes.toString() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the title attribute of the ErrorScreen object
|
||||||
|
*
|
||||||
|
* @return The title value
|
||||||
|
*/
|
||||||
|
public String getTitle()
|
||||||
|
{
|
||||||
|
return ( "Error" );
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRole() {
|
||||||
|
return AbstractLesson.USER_ROLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
package org.owasp.webgoat.session;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a virtual session for a lesson. Lesson-specific session data may
|
||||||
|
* be stored here.
|
||||||
|
*
|
||||||
|
* @author David Anderson <a href="http://www.aspectsecurity.com">Aspect Security</a>
|
||||||
|
* @created January 19, 2006
|
||||||
|
*/
|
||||||
|
public class LessonSession
|
||||||
|
{
|
||||||
|
private boolean isAuthenticated = false;
|
||||||
|
|
||||||
|
private String currentLessonScreen;
|
||||||
|
|
||||||
|
public void setAuthenticated(boolean isAuthenticated)
|
||||||
|
{
|
||||||
|
this.isAuthenticated = isAuthenticated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAuthenticated()
|
||||||
|
{
|
||||||
|
return this.isAuthenticated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCurrentLessonScreen(String currentLessonScreen)
|
||||||
|
{
|
||||||
|
this.currentLessonScreen = currentLessonScreen;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCurrentLessonScreen()
|
||||||
|
{
|
||||||
|
return this.currentLessonScreen;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,384 @@
|
|||||||
|
package org.owasp.webgoat.session;
|
||||||
|
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Class
|
||||||
|
*
|
||||||
|
* @author Bruce Mayhew
|
||||||
|
* @created October 29, 2003
|
||||||
|
*/
|
||||||
|
public class LessonTracker
|
||||||
|
{
|
||||||
|
private boolean completed = false;
|
||||||
|
private int currentStage = 1;
|
||||||
|
private int maxHintLevel = 0;
|
||||||
|
|
||||||
|
private int numVisits = 0;
|
||||||
|
private boolean viewedCookies = false;
|
||||||
|
private boolean viewedHtml = false;
|
||||||
|
private boolean viewedLessonPlan = false;
|
||||||
|
private boolean viewedParameters = false;
|
||||||
|
private boolean viewedSource = false;
|
||||||
|
|
||||||
|
Properties lessonProperties = new Properties();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the completed attribute of the LessonTracker object
|
||||||
|
*
|
||||||
|
* @return The completed value
|
||||||
|
*/
|
||||||
|
public boolean getCompleted()
|
||||||
|
{
|
||||||
|
return completed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int getStage()
|
||||||
|
{
|
||||||
|
return currentStage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStage(int stage)
|
||||||
|
{
|
||||||
|
currentStage = stage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the maxHintLevel attribute of the LessonTracker object
|
||||||
|
*
|
||||||
|
* @return The maxHintLevel value
|
||||||
|
*/
|
||||||
|
public int getMaxHintLevel()
|
||||||
|
{
|
||||||
|
return maxHintLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the numVisits attribute of the LessonTracker object
|
||||||
|
*
|
||||||
|
* @return The numVisits value
|
||||||
|
*/
|
||||||
|
public int getNumVisits()
|
||||||
|
{
|
||||||
|
return numVisits;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the viewedCookies attribute of the LessonTracker object
|
||||||
|
*
|
||||||
|
* @return The viewedCookies value
|
||||||
|
*/
|
||||||
|
public boolean getViewedCookies()
|
||||||
|
{
|
||||||
|
return viewedCookies;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the viewedHtml attribute of the LessonTracker object
|
||||||
|
*
|
||||||
|
* @return The viewedHtml value
|
||||||
|
*/
|
||||||
|
public boolean getViewedHtml()
|
||||||
|
{
|
||||||
|
return viewedHtml;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the viewedLessonPlan attribute of the LessonTracker object
|
||||||
|
*
|
||||||
|
* @return The viewedLessonPlan value
|
||||||
|
*/
|
||||||
|
public boolean getViewedLessonPlan()
|
||||||
|
{
|
||||||
|
return viewedLessonPlan;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the viewedParameters attribute of the LessonTracker object
|
||||||
|
*
|
||||||
|
* @return The viewedParameters value
|
||||||
|
*/
|
||||||
|
public boolean getViewedParameters()
|
||||||
|
{
|
||||||
|
return viewedParameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the viewedSource attribute of the LessonTracker object
|
||||||
|
*
|
||||||
|
* @return The viewedSource value
|
||||||
|
*/
|
||||||
|
public boolean getViewedSource()
|
||||||
|
{
|
||||||
|
return viewedSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*/
|
||||||
|
public void incrementNumVisits()
|
||||||
|
{
|
||||||
|
numVisits++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the properties attribute of the LessonTracker object
|
||||||
|
*
|
||||||
|
* @param props The new properties value
|
||||||
|
*/
|
||||||
|
private void setProperties( Properties props, Screen screen )
|
||||||
|
{
|
||||||
|
completed = Boolean.valueOf( props.getProperty( screen.getTitle() + ".completed" ) ).booleanValue();
|
||||||
|
maxHintLevel = Integer.parseInt( props.getProperty( screen.getTitle() + ".maxHintLevel" ) );
|
||||||
|
currentStage = Integer.parseInt( props.getProperty( screen.getTitle() + ".currentStage" ) );
|
||||||
|
numVisits = Integer.parseInt( props.getProperty( screen.getTitle() + ".numVisits" ) );
|
||||||
|
viewedCookies = Boolean.valueOf( props.getProperty( screen.getTitle() + ".viewedCookies" ) ).booleanValue();
|
||||||
|
viewedHtml = Boolean.valueOf( props.getProperty( screen.getTitle() + ".viewedHtml" ) ).booleanValue();
|
||||||
|
viewedLessonPlan = Boolean.valueOf( props.getProperty( screen.getTitle() + ".viewedLessonPlan" ) ).booleanValue();
|
||||||
|
viewedParameters = Boolean.valueOf( props.getProperty( screen.getTitle() + ".viewedParameters" ) ).booleanValue();
|
||||||
|
viewedSource = Boolean.valueOf( props.getProperty( screen.getTitle() + ".viewedSource" ) ).booleanValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String getUserDir( WebSession s )
|
||||||
|
{
|
||||||
|
return s.getContext().getRealPath( "users" ) +"/";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getTrackerFile( WebSession s, String user, Screen screen )
|
||||||
|
{
|
||||||
|
return getUserDir( s ) + user + "." + screen.getClass().getName() + ".props";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param screen Description of the Parameter
|
||||||
|
* @param s Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
public static LessonTracker load( WebSession s, String user, Screen screen )
|
||||||
|
{
|
||||||
|
FileInputStream in = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String fileName = getTrackerFile(s, user, screen);
|
||||||
|
if ( fileName != null )
|
||||||
|
{
|
||||||
|
Properties tempProps = new Properties();
|
||||||
|
//System.out.println("Loading lesson state from: " + fileName);
|
||||||
|
in = new FileInputStream( fileName );
|
||||||
|
tempProps.load( in );
|
||||||
|
// allow the screen to use any custom properties it may have set
|
||||||
|
LessonTracker tempLessonTracker = screen.createLessonTracker( tempProps );
|
||||||
|
tempLessonTracker.setProperties( tempProps, screen );
|
||||||
|
return tempLessonTracker;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( FileNotFoundException e )
|
||||||
|
{
|
||||||
|
// Normal if the lesson has not been accessed yet.
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
System.out.println("Failed to load lesson state for " + screen);
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
|
catch (Exception e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
return screen.createLessonTracker();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the completed attribute of the LessonTracker object
|
||||||
|
*
|
||||||
|
* @param completed The new completed value
|
||||||
|
*/
|
||||||
|
public void setCompleted( boolean completed )
|
||||||
|
{
|
||||||
|
this.completed = completed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the maxHintLevel attribute of the LessonTracker object
|
||||||
|
*
|
||||||
|
* @param maxHintLevel The new maxHintLevel value
|
||||||
|
*/
|
||||||
|
public void setMaxHintLevel( int maxHintLevel )
|
||||||
|
{
|
||||||
|
this.maxHintLevel = Math.max( this.maxHintLevel, maxHintLevel );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the viewedCookies attribute of the LessonTracker object
|
||||||
|
*
|
||||||
|
* @param viewedCookies The new viewedCookies value
|
||||||
|
*/
|
||||||
|
public void setViewedCookies( boolean viewedCookies )
|
||||||
|
{
|
||||||
|
this.viewedCookies = viewedCookies;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the viewedHtml attribute of the LessonTracker object
|
||||||
|
*
|
||||||
|
* @param viewedHtml The new viewedHtml value
|
||||||
|
*/
|
||||||
|
public void setViewedHtml( boolean viewedHtml )
|
||||||
|
{
|
||||||
|
this.viewedHtml = viewedHtml;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the viewedLessonPlan attribute of the LessonTracker object
|
||||||
|
*
|
||||||
|
* @param viewedLessonPlan The new viewedLessonPlan value
|
||||||
|
*/
|
||||||
|
public void setViewedLessonPlan( boolean viewedLessonPlan )
|
||||||
|
{
|
||||||
|
this.viewedLessonPlan = viewedLessonPlan;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the viewedParameters attribute of the LessonTracker object
|
||||||
|
*
|
||||||
|
* @param viewedParameters The new viewedParameters value
|
||||||
|
*/
|
||||||
|
public void setViewedParameters( boolean viewedParameters )
|
||||||
|
{
|
||||||
|
this.viewedParameters = viewedParameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the viewedSource attribute of the LessonTracker object
|
||||||
|
*
|
||||||
|
* @param viewedSource The new viewedSource value
|
||||||
|
*/
|
||||||
|
public void setViewedSource( boolean viewedSource )
|
||||||
|
{
|
||||||
|
this.viewedSource = viewedSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows the storing of properties for the logged in and a screen.
|
||||||
|
*
|
||||||
|
* @param s Description of the Parameter
|
||||||
|
*/
|
||||||
|
public void store( WebSession s, Screen screen )
|
||||||
|
{
|
||||||
|
store( s, screen, s.getUserName() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows the storing of properties for a user and a screen.
|
||||||
|
*
|
||||||
|
* @param s Description of the Parameter
|
||||||
|
*/
|
||||||
|
public void store( WebSession s, Screen screen, String user )
|
||||||
|
{
|
||||||
|
FileOutputStream out = null;
|
||||||
|
String fileName = getTrackerFile(s, user, screen);
|
||||||
|
//System.out.println( "Storing data to" + fileName );
|
||||||
|
lessonProperties.setProperty( screen.getTitle() + ".completed", Boolean.toString( completed ) );
|
||||||
|
lessonProperties.setProperty( screen.getTitle() + ".currentStage", Integer.toString( currentStage ) );
|
||||||
|
lessonProperties.setProperty( screen.getTitle() + ".maxHintLevel", Integer.toString( maxHintLevel ) );
|
||||||
|
lessonProperties.setProperty( screen.getTitle() + ".numVisits", Integer.toString( numVisits ) );
|
||||||
|
lessonProperties.setProperty( screen.getTitle() + ".viewedCookies", Boolean.toString( viewedCookies ) );
|
||||||
|
lessonProperties.setProperty( screen.getTitle() + ".viewedHtml", Boolean.toString( viewedHtml ) );
|
||||||
|
lessonProperties.setProperty( screen.getTitle() + ".viewedLessonPlan", Boolean.toString( viewedLessonPlan ) );
|
||||||
|
lessonProperties.setProperty( screen.getTitle() + ".viewedParameters", Boolean.toString( viewedParameters ) );
|
||||||
|
lessonProperties.setProperty( screen.getTitle() + ".viewedSource", Boolean.toString( viewedSource ) );
|
||||||
|
try
|
||||||
|
{
|
||||||
|
out = new FileOutputStream( fileName );
|
||||||
|
lessonProperties.store( out, s.getUserName() );
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
// what do we want to do, I think nothing.
|
||||||
|
System.out.println( "Warning User data for " + s.getUserName() + " will not persist" );
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
catch (Exception e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
StringBuffer buff = new StringBuffer();
|
||||||
|
buff.append( "LessonTracker:" + "\n" );
|
||||||
|
buff.append( " - completed:.......... " + completed + "\n" );
|
||||||
|
buff.append( " - currentStage:....... " + currentStage + "\n" );
|
||||||
|
buff.append( " - maxHintLevel:....... " + maxHintLevel + "\n" );
|
||||||
|
buff.append( " - numVisits:.......... " + numVisits + "\n" );
|
||||||
|
buff.append( " - viewedCookies:...... " + viewedCookies + "\n" );
|
||||||
|
buff.append( " - viewedHtml:......... " + viewedHtml + "\n" );
|
||||||
|
buff.append( " - viewedLessonPlan:... " + viewedLessonPlan + "\n" );
|
||||||
|
buff.append( " - viewedParameters:... " + viewedParameters + "\n" );
|
||||||
|
buff.append( " - viewedSource:....... " + viewedSource + "\n" + "\n" );
|
||||||
|
return buff.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Returns the lessonProperties.
|
||||||
|
*/
|
||||||
|
public Properties getLessonProperties()
|
||||||
|
{
|
||||||
|
return lessonProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param lessonProperties The lessonProperties to set.
|
||||||
|
*/
|
||||||
|
public void setLessonProperties(Properties lessonProperties)
|
||||||
|
{
|
||||||
|
this.lessonProperties = lessonProperties;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,46 @@
|
|||||||
|
package org.owasp.webgoat.session;
|
||||||
|
|
||||||
|
public class Parameter implements Comparable {
|
||||||
|
|
||||||
|
String name;
|
||||||
|
String value;
|
||||||
|
|
||||||
|
public Parameter(String name, String value) {
|
||||||
|
this.name=name;
|
||||||
|
this.value=value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName()
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getValue()
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
//@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if ( obj instanceof Parameter )
|
||||||
|
{
|
||||||
|
Parameter other = (Parameter)obj;
|
||||||
|
return ( name.equals( other.getName() ) && value.equals( other.getValue() ) );
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return toString().hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
//@Override
|
||||||
|
public String toString() {
|
||||||
|
return( name + "=" + value );
|
||||||
|
}
|
||||||
|
|
||||||
|
public int compareTo(Object o) {
|
||||||
|
return toString().compareTo( o.toString() );
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
package org.owasp.webgoat.session;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2002 Free Software Foundation developed under the custody of
|
||||||
|
* the Open Web Application Security Project (http://www.owasp.org) This
|
||||||
|
* software package org.owasp.webgoat.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>
|
||||||
|
*/
|
||||||
|
public class ParameterNotFoundException extends Exception
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Constructs a new ParameterNotFoundException with no detail message.
|
||||||
|
*/
|
||||||
|
public ParameterNotFoundException()
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new ParameterNotFoundException with the specified detail
|
||||||
|
* message.
|
||||||
|
*
|
||||||
|
*@param s the detail message
|
||||||
|
*/
|
||||||
|
public ParameterNotFoundException(String s)
|
||||||
|
{
|
||||||
|
super(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
1032
webgoat/main/project/org/owasp/webgoat/session/ParameterParser.java
Normal file
1032
webgoat/main/project/org/owasp/webgoat/session/ParameterParser.java
Normal file
File diff suppressed because it is too large
Load Diff
328
webgoat/main/project/org/owasp/webgoat/session/Screen.java
Normal file
328
webgoat/main/project/org/owasp/webgoat/session/Screen.java
Normal file
@ -0,0 +1,328 @@
|
|||||||
|
package org.owasp.webgoat.session;
|
||||||
|
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.apache.ecs.Element;
|
||||||
|
import org.apache.ecs.HtmlColor;
|
||||||
|
import org.apache.ecs.StringElement;
|
||||||
|
import org.apache.ecs.html.A;
|
||||||
|
import org.apache.ecs.html.B;
|
||||||
|
import org.apache.ecs.html.Font;
|
||||||
|
import org.apache.ecs.html.IMG;
|
||||||
|
import org.apache.ecs.html.TD;
|
||||||
|
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2002 Free Software Foundation developed under the custody of the Open Web
|
||||||
|
* Application Security Project (http://www.owasp.org) This software package org.owasp.webgoat.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
|
||||||
|
*/
|
||||||
|
public abstract class Screen
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Description of the Field
|
||||||
|
*/
|
||||||
|
public static int MAIN_SIZE = 375;
|
||||||
|
|
||||||
|
|
||||||
|
//private Head head;
|
||||||
|
private Element content;
|
||||||
|
private LessonTracker lessonTracker;
|
||||||
|
final static IMG logo = new IMG( "images/aspectlogo-horizontal-small.jpg" ).setAlt( "Aspect Security" ).setBorder( 0 ).setHspace( 0 ).setVspace( 0 );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for the Screen object
|
||||||
|
*/
|
||||||
|
|
||||||
|
public Screen() { }
|
||||||
|
|
||||||
|
|
||||||
|
// FIXME: Each lesson should have a role assigned to it. Each user/student
|
||||||
|
// should also have a role(s) assigned. The user would only be allowed
|
||||||
|
// to see lessons that correspond to their role. Eventually these roles
|
||||||
|
// will be stored in the internal database. The user will be able to hack
|
||||||
|
// into the database and change their role. This will allow the user to
|
||||||
|
// see the admin screens, once they figure out how to turn the admin switch on.
|
||||||
|
public abstract String getRole();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param s Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
|
||||||
|
protected abstract Element createContent( WebSession s );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the credits attribute of the Screen object
|
||||||
|
*
|
||||||
|
* @return The credits value
|
||||||
|
*/
|
||||||
|
public abstract Element getCredits();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new lessonTracker object.
|
||||||
|
*
|
||||||
|
* @param props The properties file that was used to persist the user data.
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
|
||||||
|
public LessonTracker createLessonTracker( Properties props )
|
||||||
|
{
|
||||||
|
|
||||||
|
// If the lesson had any specialized properties in the user persisted properties,
|
||||||
|
// now would be the time to pull them out.
|
||||||
|
|
||||||
|
lessonTracker = createLessonTracker();
|
||||||
|
return lessonTracker;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This allows the screens to provide a custom LessonTracker object if needed.
|
||||||
|
*
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
public LessonTracker createLessonTracker()
|
||||||
|
{
|
||||||
|
lessonTracker = new LessonTracker();
|
||||||
|
return lessonTracker;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the lessonTracker attribute of the AbstractLesson object
|
||||||
|
*
|
||||||
|
* @param userName Description of the Parameter
|
||||||
|
* @return The lessonTracker value
|
||||||
|
*/
|
||||||
|
|
||||||
|
public LessonTracker getLessonTracker( WebSession s )
|
||||||
|
{
|
||||||
|
UserTracker userTracker = UserTracker.instance();
|
||||||
|
return userTracker.getLessonTracker( s, this );
|
||||||
|
}
|
||||||
|
|
||||||
|
public LessonTracker getLessonTracker( WebSession s, String userNameOverride )
|
||||||
|
{
|
||||||
|
UserTracker userTracker = UserTracker.instance();
|
||||||
|
return userTracker.getLessonTracker( s, userNameOverride, this );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public LessonTracker getLessonTracker( WebSession s, AbstractLesson lesson )
|
||||||
|
{
|
||||||
|
UserTracker userTracker = UserTracker.instance();
|
||||||
|
return userTracker.getLessonTracker( s, lesson );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fill in a descriptive title for this lesson
|
||||||
|
*
|
||||||
|
* @return The title value
|
||||||
|
*/
|
||||||
|
public abstract String getTitle();
|
||||||
|
|
||||||
|
|
||||||
|
protected void setContent(Element content)
|
||||||
|
{
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
|
||||||
|
protected Element makeLogo()
|
||||||
|
{
|
||||||
|
|
||||||
|
return new A("http://www.aspectsecurity.com/webgoat.html", logo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSponsor()
|
||||||
|
{
|
||||||
|
return "Aspect Security";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSponsorLogoResource()
|
||||||
|
{
|
||||||
|
return "images/aspectlogo-horizontal-small.jpg";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param text Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
|
||||||
|
protected TD makeMenuCategory_DELETE_ME( String text )
|
||||||
|
{
|
||||||
|
return ( new TD().setWidth( "100%" ).addElement( new Font().setColor( HtmlColor.WHITE ).addElement( new B().addElement( text ) ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param s Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
|
||||||
|
protected Element makeMessages( WebSession s )
|
||||||
|
{
|
||||||
|
|
||||||
|
if ( s == null )
|
||||||
|
{
|
||||||
|
|
||||||
|
return ( new StringElement( "" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
Font f = new Font().setColor( HtmlColor.RED );
|
||||||
|
|
||||||
|
String message = s.getMessage();
|
||||||
|
|
||||||
|
f.addElement( message );
|
||||||
|
|
||||||
|
return ( f );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the content length of the the html.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public int getContentLength()
|
||||||
|
{
|
||||||
|
return content.toString().length();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param out Description of the Parameter
|
||||||
|
*/
|
||||||
|
|
||||||
|
public void output( PrintWriter out )
|
||||||
|
{
|
||||||
|
|
||||||
|
// format output -- then send to printwriter
|
||||||
|
|
||||||
|
// otherwise we're doing way too much SSL encryption work
|
||||||
|
|
||||||
|
out.print( content.toString() );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getContent()
|
||||||
|
{
|
||||||
|
return (content == null) ? "" : content.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param x Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
|
||||||
|
protected static String pad( int x )
|
||||||
|
{
|
||||||
|
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
|
||||||
|
if ( x < 10 )
|
||||||
|
{
|
||||||
|
|
||||||
|
sb.append( " " );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( x < 100 )
|
||||||
|
{
|
||||||
|
|
||||||
|
sb.append( " " );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.append( x );
|
||||||
|
|
||||||
|
return ( sb.toString() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param token Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
protected static String convertMetachars( String token )
|
||||||
|
{
|
||||||
|
|
||||||
|
int mci = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* meta char array
|
||||||
|
*
|
||||||
|
* FIXME: Removed the conversion of whitespace " " to " " in order for the
|
||||||
|
* html to be automatically wrapped in client browser. It is better to add line
|
||||||
|
* length checking and only do " " conversion in lines that won't exceed
|
||||||
|
* screen size, say less than 80 characters.
|
||||||
|
*/
|
||||||
|
String[] metaChar = {"&", "<", ">", "\"", "\t", System.getProperty("line.separator")};
|
||||||
|
|
||||||
|
String[] htmlCode = {"&", "<", ">", """, " ", "<br>"};
|
||||||
|
|
||||||
|
String replacedString = token;
|
||||||
|
for ( ; mci < metaChar.length; mci += 1 )
|
||||||
|
{
|
||||||
|
replacedString = replacedString.replaceAll( metaChar[mci], htmlCode[mci] );
|
||||||
|
}
|
||||||
|
return ( replacedString );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param token Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
protected static String convertMetacharsJavaCode( String token )
|
||||||
|
{
|
||||||
|
return( convertMetachars(token).replaceAll(" ", " ") );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param s Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
|
||||||
|
//protected abstract Element wrapForm( WebSession s );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
package org.owasp.webgoat.session;
|
||||||
|
|
||||||
|
public class UnauthenticatedException extends Exception
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
package org.owasp.webgoat.session;
|
||||||
|
|
||||||
|
public class UnauthorizedException extends Exception
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
243
webgoat/main/project/org/owasp/webgoat/session/UserTracker.java
Normal file
243
webgoat/main/project/org/owasp/webgoat/session/UserTracker.java
Normal file
@ -0,0 +1,243 @@
|
|||||||
|
package org.owasp.webgoat.session;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.catalina.Role;
|
||||||
|
import org.apache.catalina.User;
|
||||||
|
import org.apache.catalina.users.MemoryUserDatabase;
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2002 Free Software Foundation developed under the custody of the Open Web
|
||||||
|
* Application Security Project (http://www.owasp.org) This software package org.owasp.webgoat.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 29, 2003
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class UserTracker
|
||||||
|
{
|
||||||
|
|
||||||
|
private static UserTracker instance;
|
||||||
|
|
||||||
|
// FIXME: persist this somehow!
|
||||||
|
|
||||||
|
private static HashMap storage = new HashMap();
|
||||||
|
|
||||||
|
private static MemoryUserDatabase usersDB = new MemoryUserDatabase();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for the UserTracker object
|
||||||
|
*/
|
||||||
|
private UserTracker() { }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the completed attribute of the UserTracker object
|
||||||
|
*
|
||||||
|
* @param userName Description of the Parameter
|
||||||
|
* @return The completed value
|
||||||
|
*/
|
||||||
|
public int getCompleted( String userName )
|
||||||
|
{
|
||||||
|
|
||||||
|
HashMap usermap = getUserMap( userName );
|
||||||
|
|
||||||
|
Iterator i = usermap.entrySet().iterator();
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
while ( i.hasNext() )
|
||||||
|
{
|
||||||
|
|
||||||
|
Map.Entry entry = (Map.Entry) i.next();
|
||||||
|
|
||||||
|
int value = ( (Integer) entry.getValue() ).intValue();
|
||||||
|
|
||||||
|
if ( value > 5 )
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the users attribute of the UserTracker object
|
||||||
|
*
|
||||||
|
* @return The users value
|
||||||
|
*/
|
||||||
|
public Collection getUsers()
|
||||||
|
{
|
||||||
|
return storage.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection getAllUsers(String roleName)
|
||||||
|
{
|
||||||
|
synchronized ( usersDB ) {
|
||||||
|
Collection allUsers = new ArrayList();
|
||||||
|
try {
|
||||||
|
usersDB.open();
|
||||||
|
Iterator users = usersDB.getUsers();
|
||||||
|
while (users.hasNext())
|
||||||
|
{
|
||||||
|
User user = (User) users.next();
|
||||||
|
Iterator roles = user.getRoles();
|
||||||
|
while( roles.hasNext() )
|
||||||
|
{
|
||||||
|
Role role = (Role)roles.next();
|
||||||
|
if ( role.getRolename().trim().equals(roleName))
|
||||||
|
{
|
||||||
|
allUsers.add( user.getUsername() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
usersDB.close();
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{}
|
||||||
|
return allUsers;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteUser( String user )
|
||||||
|
{
|
||||||
|
synchronized ( usersDB ) {
|
||||||
|
try
|
||||||
|
{
|
||||||
|
usersDB.open();
|
||||||
|
Iterator users = usersDB.getUsers();
|
||||||
|
while (users.hasNext())
|
||||||
|
{
|
||||||
|
User tomcatUser = (User) users.next();
|
||||||
|
if ( tomcatUser.getUsername().equals( user ) )
|
||||||
|
{
|
||||||
|
usersDB.removeUser(tomcatUser);
|
||||||
|
// FIXME: delete all the lesson tracking property files
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
usersDB.close();
|
||||||
|
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the lessonTracker attribute of the UserTracker object
|
||||||
|
*
|
||||||
|
* @param screen Description of the Parameter
|
||||||
|
* @param userName Description of the Parameter
|
||||||
|
* @return The lessonTracker value
|
||||||
|
*/
|
||||||
|
public LessonTracker getLessonTracker( WebSession s, Screen screen )
|
||||||
|
{
|
||||||
|
return getLessonTracker(s, s.getUserName(), screen );
|
||||||
|
}
|
||||||
|
|
||||||
|
public LessonTracker getLessonTracker( WebSession s, String user, Screen screen )
|
||||||
|
{
|
||||||
|
HashMap usermap = getUserMap( user );
|
||||||
|
LessonTracker tracker = (LessonTracker) usermap.get( screen.getTitle() );
|
||||||
|
if ( tracker == null )
|
||||||
|
{
|
||||||
|
// Creates a new lesson tracker, if one does not exist on disk.
|
||||||
|
tracker = LessonTracker.load( s, user, screen );
|
||||||
|
usermap.put( screen.getTitle(), tracker );
|
||||||
|
}
|
||||||
|
//System.out.println( "User: [" + userName + "] UserTracker:getLessonTracker() LTH " + tracker.hashCode() + " for " + screen );
|
||||||
|
return tracker;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the status attribute of the UserTracker object
|
||||||
|
*
|
||||||
|
* @param screen Description of the Parameter
|
||||||
|
* @param userName Description of the Parameter
|
||||||
|
* @return The status value
|
||||||
|
*/
|
||||||
|
public String getStatus( WebSession s, Screen screen )
|
||||||
|
{
|
||||||
|
return ( "User [" + s.getUserName() + "] has accessed " + screen + " UserTracker:getStatus()LTH = " + getLessonTracker( s, screen ).hashCode() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the userMap attribute of the UserTracker object
|
||||||
|
*
|
||||||
|
* @param userName Description of the Parameter
|
||||||
|
* @return The userMap value
|
||||||
|
*/
|
||||||
|
private HashMap getUserMap( String userName )
|
||||||
|
{
|
||||||
|
|
||||||
|
HashMap usermap = (HashMap) storage.get( userName );
|
||||||
|
|
||||||
|
if ( usermap == null )
|
||||||
|
{
|
||||||
|
|
||||||
|
usermap = new HashMap();
|
||||||
|
|
||||||
|
storage.put( userName, usermap );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( usermap );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
public static synchronized UserTracker instance()
|
||||||
|
{
|
||||||
|
|
||||||
|
if ( instance == null )
|
||||||
|
{
|
||||||
|
|
||||||
|
instance = new UserTracker();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param screen Description of the Parameter
|
||||||
|
* @param s Description of the Parameter
|
||||||
|
*/
|
||||||
|
public void update( WebSession s, Screen screen )
|
||||||
|
{
|
||||||
|
|
||||||
|
LessonTracker tracker = getLessonTracker( s, screen );
|
||||||
|
|
||||||
|
//System.out.println( "User [" + s.getUserName() + "] TRACKER: updating " + screen + " LTH " + tracker.hashCode() );
|
||||||
|
tracker.store( s, screen );
|
||||||
|
|
||||||
|
HashMap usermap = getUserMap( s.getUserName() );
|
||||||
|
usermap.put( screen.getTitle(), tracker );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
package org.owasp.webgoat.session;
|
||||||
|
|
||||||
|
public class ValidationException extends Exception
|
||||||
|
{
|
||||||
|
public ValidationException()
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValidationException(String message)
|
||||||
|
{
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
1185
webgoat/main/project/org/owasp/webgoat/session/WebSession.java
Normal file
1185
webgoat/main/project/org/owasp/webgoat/session/WebSession.java
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,91 @@
|
|||||||
|
package org.owasp.webgoat.session;
|
||||||
|
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
public class WebgoatProperties extends Properties
|
||||||
|
{
|
||||||
|
public WebgoatProperties(String propertiesFileName) throws IOException
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
FileInputStream in = new FileInputStream(propertiesFileName);
|
||||||
|
load(in);
|
||||||
|
}
|
||||||
|
catch ( IOException e )
|
||||||
|
{
|
||||||
|
System.out.println("Warning: Unable to open webgoat.properties file");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getIntProperty(String key, int defaultValue)
|
||||||
|
{
|
||||||
|
int value = defaultValue;
|
||||||
|
|
||||||
|
String s = getProperty(key);
|
||||||
|
if (s != null)
|
||||||
|
{
|
||||||
|
value = Integer.parseInt(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getBooleanProperty(String key, boolean defaultValue)
|
||||||
|
{
|
||||||
|
boolean value = defaultValue;
|
||||||
|
key = this.trimLesson(key);
|
||||||
|
|
||||||
|
String s = getProperty(key);
|
||||||
|
if (s != null)
|
||||||
|
{
|
||||||
|
if (s.equalsIgnoreCase("true"))
|
||||||
|
value = true;
|
||||||
|
else if (s.equalsIgnoreCase("yes"))
|
||||||
|
value = true;
|
||||||
|
else if (s.equalsIgnoreCase("on"))
|
||||||
|
value = true;
|
||||||
|
else if (s.equalsIgnoreCase("false"))
|
||||||
|
value = false;
|
||||||
|
else if (s.equalsIgnoreCase("no"))
|
||||||
|
value = false;
|
||||||
|
else if (s.equalsIgnoreCase("off"))
|
||||||
|
value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String trimLesson(String lesson)
|
||||||
|
{
|
||||||
|
String result = "";
|
||||||
|
|
||||||
|
if(lesson.startsWith("org.owasp.webgoat.lessons."))
|
||||||
|
{
|
||||||
|
result = lesson.substring("org.owasp.webgoat.lessons.".length(), lesson.length());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = lesson;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args)
|
||||||
|
{
|
||||||
|
WebgoatProperties properties = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
properties = new WebgoatProperties("C:\\webgoat.properties");
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
System.out.println("Error loading properties");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
System.out.println(properties.getProperty("CommandInjection.category"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
508
webgoat/main/project/org/owasp/webgoat/util/Exec.java
Normal file
508
webgoat/main/project/org/owasp/webgoat/util/Exec.java
Normal file
@ -0,0 +1,508 @@
|
|||||||
|
package org.owasp.webgoat.util;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.BitSet;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2002 Free Software Foundation developed under the custody of the Open Web
|
||||||
|
* Application Security Project (http://www.owasp.org) This software package org.owasp.webgoat.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
|
||||||
|
*/
|
||||||
|
public class Exec
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param command Description of the Parameter
|
||||||
|
* @param input Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
public static ExecResults execInput( String command, String input )
|
||||||
|
{
|
||||||
|
return ( execOptions( command, input, 0, 0, false ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param command Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
public static ExecResults execLazy( String command )
|
||||||
|
{
|
||||||
|
return ( execOptions( command, "", 0, 0, true ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Execute an OS command and capture the output in an ExecResults.
|
||||||
|
* All exceptions are caught and stored in the ExecResults.
|
||||||
|
* @param String command is the OS command to execute
|
||||||
|
* @param String input is piped into the OS command
|
||||||
|
* @param int successCode is the expected return code if the command completes successfully
|
||||||
|
* @param int timeout is the number of milliseconds to wait before interrupting the command
|
||||||
|
* @param boolean quit tells the method to exit when there is no more output waiting
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param command Description of the Parameter
|
||||||
|
* @param input Description of the Parameter
|
||||||
|
* @param successCode Description of the Parameter
|
||||||
|
* @param timeout Description of the Parameter
|
||||||
|
* @param lazy Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
public static ExecResults execOptions( String[] command, String input, int successCode, int timeout, boolean lazy )
|
||||||
|
{
|
||||||
|
Process child = null;
|
||||||
|
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||||
|
ByteArrayOutputStream errors = new ByteArrayOutputStream();
|
||||||
|
ExecResults results = new ExecResults( command[0], input, successCode, timeout );
|
||||||
|
BitSet interrupted = new BitSet( 1 );
|
||||||
|
boolean lazyQuit = false;
|
||||||
|
ThreadWatcher watcher;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// start the command
|
||||||
|
child = Runtime.getRuntime().exec( command );
|
||||||
|
|
||||||
|
// get the streams in and out of the command
|
||||||
|
InputStream processIn = child.getInputStream();
|
||||||
|
InputStream processError = child.getErrorStream();
|
||||||
|
OutputStream processOut = child.getOutputStream();
|
||||||
|
|
||||||
|
// start the clock running
|
||||||
|
if ( timeout > 0 )
|
||||||
|
{
|
||||||
|
watcher = new ThreadWatcher( child, interrupted, timeout );
|
||||||
|
new Thread( watcher ).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write to the child process' input stream
|
||||||
|
if ( ( input != null ) && !input.equals( "" ) )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
processOut.write( input.getBytes() );
|
||||||
|
processOut.flush();
|
||||||
|
processOut.close();
|
||||||
|
}
|
||||||
|
catch ( IOException e1 )
|
||||||
|
{
|
||||||
|
results.setThrowable( e1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read from the child process' output stream
|
||||||
|
// The process may get killed by the watcher at any time
|
||||||
|
int c = 0;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
while ( true )
|
||||||
|
{
|
||||||
|
if ( interrupted.get( 0 ) || lazyQuit )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// interrupted
|
||||||
|
c = processIn.read();
|
||||||
|
|
||||||
|
if ( c == -1 )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// end of stream
|
||||||
|
output.write( c );
|
||||||
|
|
||||||
|
if ( lazy && ( processIn.available() < 1 ) )
|
||||||
|
{
|
||||||
|
lazyQuit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if lazy and nothing then quit (after at least one read)
|
||||||
|
}
|
||||||
|
|
||||||
|
processIn.close();
|
||||||
|
}
|
||||||
|
catch ( IOException e2 )
|
||||||
|
{
|
||||||
|
results.setThrowable( e2 );
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if ( interrupted.get( 0 ) )
|
||||||
|
{
|
||||||
|
results.setInterrupted();
|
||||||
|
}
|
||||||
|
|
||||||
|
results.setOutput( output.toString() );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read from the child process' error stream
|
||||||
|
// The process may get killed by the watcher at any time
|
||||||
|
try
|
||||||
|
{
|
||||||
|
while ( true )
|
||||||
|
{
|
||||||
|
if ( interrupted.get( 0 ) || lazyQuit )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// interrupted
|
||||||
|
c = processError.read();
|
||||||
|
|
||||||
|
if ( c == -1 )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// end of stream
|
||||||
|
output.write( c );
|
||||||
|
|
||||||
|
if ( lazy && ( processError.available() < 1 ) )
|
||||||
|
{
|
||||||
|
lazyQuit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if lazy and nothing then quit (after at least one read)
|
||||||
|
}
|
||||||
|
|
||||||
|
processError.close();
|
||||||
|
}
|
||||||
|
catch ( IOException e3 )
|
||||||
|
{
|
||||||
|
results.setThrowable( e3 );
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if ( interrupted.get( 0 ) )
|
||||||
|
{
|
||||||
|
results.setInterrupted();
|
||||||
|
}
|
||||||
|
|
||||||
|
results.setErrors( errors.toString() );
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait for the return value of the child process.
|
||||||
|
if ( !interrupted.get( 0 ) && !lazyQuit )
|
||||||
|
{
|
||||||
|
int returnCode = child.waitFor();
|
||||||
|
results.setReturnCode( returnCode );
|
||||||
|
|
||||||
|
if ( returnCode != successCode )
|
||||||
|
{
|
||||||
|
results.setError( ExecResults.BADRETURNCODE );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( InterruptedException i )
|
||||||
|
{
|
||||||
|
results.setInterrupted();
|
||||||
|
}
|
||||||
|
catch ( Throwable t )
|
||||||
|
{
|
||||||
|
results.setThrowable( t );
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if ( child != null )
|
||||||
|
{
|
||||||
|
child.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( results );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Execute an OS command and capture the output in an ExecResults.
|
||||||
|
* All exceptions are caught and stored in the ExecResults.
|
||||||
|
* @param String command is the OS command to execute
|
||||||
|
* @param String input is piped into the OS command
|
||||||
|
* @param int successCode is the expected return code if the command completes successfully
|
||||||
|
* @param int timeout is the number of milliseconds to wait before interrupting the command
|
||||||
|
* @param boolean quit tells the method to exit when there is no more output waiting
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param command Description of the Parameter
|
||||||
|
* @param input Description of the Parameter
|
||||||
|
* @param successCode Description of the Parameter
|
||||||
|
* @param timeout Description of the Parameter
|
||||||
|
* @param lazy Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
public static ExecResults execOptions( String command, String input, int successCode, int timeout, boolean lazy )
|
||||||
|
{
|
||||||
|
Process child = null;
|
||||||
|
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||||
|
ByteArrayOutputStream errors = new ByteArrayOutputStream();
|
||||||
|
ExecResults results = new ExecResults( command, input, successCode, timeout );
|
||||||
|
BitSet interrupted = new BitSet( 1 );
|
||||||
|
boolean lazyQuit = false;
|
||||||
|
ThreadWatcher watcher;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// start the command
|
||||||
|
child = Runtime.getRuntime().exec( command );
|
||||||
|
|
||||||
|
// get the streams in and out of the command
|
||||||
|
InputStream processIn = child.getInputStream();
|
||||||
|
InputStream processError = child.getErrorStream();
|
||||||
|
OutputStream processOut = child.getOutputStream();
|
||||||
|
|
||||||
|
// start the clock running
|
||||||
|
if ( timeout > 0 )
|
||||||
|
{
|
||||||
|
watcher = new ThreadWatcher( child, interrupted, timeout );
|
||||||
|
new Thread( watcher ).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write to the child process' input stream
|
||||||
|
if ( ( input != null ) && !input.equals( "" ) )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
processOut.write( input.getBytes() );
|
||||||
|
processOut.flush();
|
||||||
|
processOut.close();
|
||||||
|
}
|
||||||
|
catch ( IOException e1 )
|
||||||
|
{
|
||||||
|
results.setThrowable( e1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read from the child process' output stream
|
||||||
|
// The process may get killed by the watcher at any time
|
||||||
|
int c = 0;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
while ( true )
|
||||||
|
{
|
||||||
|
if ( interrupted.get( 0 ) || lazyQuit )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// interrupted
|
||||||
|
c = processIn.read();
|
||||||
|
|
||||||
|
if ( c == -1 )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// end of stream
|
||||||
|
output.write( c );
|
||||||
|
|
||||||
|
if ( lazy && ( processIn.available() < 1 ) )
|
||||||
|
{
|
||||||
|
lazyQuit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if lazy and nothing then quit (after at least one read)
|
||||||
|
}
|
||||||
|
|
||||||
|
processIn.close();
|
||||||
|
}
|
||||||
|
catch ( IOException e2 )
|
||||||
|
{
|
||||||
|
results.setThrowable( e2 );
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if ( interrupted.get( 0 ) )
|
||||||
|
{
|
||||||
|
results.setInterrupted();
|
||||||
|
}
|
||||||
|
|
||||||
|
results.setOutput( output.toString() );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read from the child process' error stream
|
||||||
|
// The process may get killed by the watcher at any time
|
||||||
|
try
|
||||||
|
{
|
||||||
|
while ( true )
|
||||||
|
{
|
||||||
|
if ( interrupted.get( 0 ) || lazyQuit )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// interrupted
|
||||||
|
c = processError.read();
|
||||||
|
|
||||||
|
if ( c == -1 )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// end of stream
|
||||||
|
output.write( c );
|
||||||
|
|
||||||
|
if ( lazy && ( processError.available() < 1 ) )
|
||||||
|
{
|
||||||
|
lazyQuit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if lazy and nothing then quit (after at least one read)
|
||||||
|
}
|
||||||
|
|
||||||
|
processError.close();
|
||||||
|
}
|
||||||
|
catch ( IOException e3 )
|
||||||
|
{
|
||||||
|
results.setThrowable( e3 );
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if ( interrupted.get( 0 ) )
|
||||||
|
{
|
||||||
|
results.setInterrupted();
|
||||||
|
}
|
||||||
|
|
||||||
|
results.setErrors( errors.toString() );
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait for the return value of the child process.
|
||||||
|
if ( !interrupted.get( 0 ) && !lazyQuit )
|
||||||
|
{
|
||||||
|
int returnCode = child.waitFor();
|
||||||
|
results.setReturnCode( returnCode );
|
||||||
|
|
||||||
|
if ( returnCode != successCode )
|
||||||
|
{
|
||||||
|
results.setError( ExecResults.BADRETURNCODE );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( InterruptedException i )
|
||||||
|
{
|
||||||
|
results.setInterrupted();
|
||||||
|
}
|
||||||
|
catch ( Throwable t )
|
||||||
|
{
|
||||||
|
results.setThrowable( t );
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if ( child != null )
|
||||||
|
{
|
||||||
|
child.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( results );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param command Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
public static ExecResults execSimple( String[] command )
|
||||||
|
{
|
||||||
|
return ( execOptions( command, "", 0, 0, false ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param command Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
public static ExecResults execSimple( String command )
|
||||||
|
{
|
||||||
|
return ( execOptions( command, "", 0, 0, false ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param command Description of the Parameter
|
||||||
|
* @param args Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
public static ExecResults execSimple( String command, String args )
|
||||||
|
{
|
||||||
|
return ( execOptions( command, args, 0, 0, false ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
* @param command Description of the Parameter
|
||||||
|
* @param timeout Description of the Parameter
|
||||||
|
* @return Description of the Return Value
|
||||||
|
*/
|
||||||
|
public static ExecResults execTimeout( String command, int timeout )
|
||||||
|
{
|
||||||
|
return ( execOptions( command, "", 0, timeout, false ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The main program for the Exec class
|
||||||
|
*
|
||||||
|
* @param args The command line arguments
|
||||||
|
*/
|
||||||
|
public static void main( String[] args )
|
||||||
|
{
|
||||||
|
ExecResults results;
|
||||||
|
String sep = System.getProperty( "line.separator" );
|
||||||
|
System.out.println( "-------------------------------------------" + sep + "TEST 1: execSimple" );
|
||||||
|
results = Exec.execSimple( "c:/swarm-2.1.1/bin/whoami.exe" );
|
||||||
|
System.out.println( results );
|
||||||
|
System.out.println( "-------------------------------------------" + sep + "TEST 2: execSimple (with search)" );
|
||||||
|
results = Exec.execSimple( "netstat -r" );
|
||||||
|
System.out.println( results );
|
||||||
|
|
||||||
|
if ( results.outputContains( "localhost:1031" ) )
|
||||||
|
{
|
||||||
|
System.out.println( "ERROR: listening on 1031" );
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println( "-------------------------------------------" + sep + "TEST 3: execInput" );
|
||||||
|
results = Exec.execInput( "find \"cde\"", "abcdefg1\nhijklmnop\nqrstuv\nabcdefg2" );
|
||||||
|
System.out.println( results );
|
||||||
|
System.out.println( "-------------------------------------------" + sep + "TEST 4:execTimeout" );
|
||||||
|
results = Exec.execTimeout( "ping -t 127.0.0.1", 5 * 1000 );
|
||||||
|
System.out.println( results );
|
||||||
|
System.out.println( "-------------------------------------------" + sep + "TEST 5:execLazy" );
|
||||||
|
results = Exec.execLazy( "ping -t 127.0.0.1" );
|
||||||
|
System.out.println( results );
|
||||||
|
System.out.println( "-------------------------------------------" + sep + "TEST 6:ExecTimeout process never outputs" );
|
||||||
|
results = Exec.execTimeout( "c:/swarm-2.1.1/bin/sleep.exe 20", 5 * 1000 );
|
||||||
|
System.out.println( results );
|
||||||
|
System.out.println( "-------------------------------------------" + sep + "TEST 7:ExecTimeout process waits for input" );
|
||||||
|
results = Exec.execTimeout( "c:/swarm-2.1.1/bin/cat", 5 * 1000 );
|
||||||
|
System.out.println( results );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
320
webgoat/main/project/org/owasp/webgoat/util/ExecResults.java
Normal file
320
webgoat/main/project/org/owasp/webgoat/util/ExecResults.java
Normal file
@ -0,0 +1,320 @@
|
|||||||
|
package org.owasp.webgoat.util;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2002 Free Software Foundation developed under the custody of
|
||||||
|
* the Open Web Application Security Project (http://www.owasp.org) This
|
||||||
|
* software package org.owasp.webgoat.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>
|
||||||
|
*/
|
||||||
|
public class ExecResults
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Description of the Field
|
||||||
|
*/
|
||||||
|
public final static int BADRETURNCODE = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Field
|
||||||
|
*/
|
||||||
|
public final static int THROWABLE = 1;
|
||||||
|
private String myCommand;
|
||||||
|
private boolean myError = false;
|
||||||
|
private int myErrorType = 0;
|
||||||
|
private String myErrors = null;
|
||||||
|
private String myInput;
|
||||||
|
private boolean myInterrupted = false;
|
||||||
|
private String myOutput = null;
|
||||||
|
private int myReturnCode = 0;
|
||||||
|
private int mySuccessCode;
|
||||||
|
private Throwable myThrowable = null;
|
||||||
|
private int myTimeout;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for the ExecResults object
|
||||||
|
*
|
||||||
|
*@param command Description of the Parameter
|
||||||
|
*@param input Description of the Parameter
|
||||||
|
*@param successCode Description of the Parameter
|
||||||
|
*@param timeout Description of the Parameter
|
||||||
|
*/
|
||||||
|
public ExecResults(String command, String input, int successCode, int timeout)
|
||||||
|
{
|
||||||
|
myCommand = command.trim();
|
||||||
|
myInput = input.trim();
|
||||||
|
mySuccessCode = successCode;
|
||||||
|
myTimeout = timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
*@param haystack Description of the Parameter
|
||||||
|
*@param needle Description of the Parameter
|
||||||
|
*@param fromIndex Description of the Parameter
|
||||||
|
*@return Description of the Return Value
|
||||||
|
*/
|
||||||
|
private boolean contains(String haystack, String needle, int fromIndex)
|
||||||
|
{
|
||||||
|
return (haystack.trim().toLowerCase().indexOf(needle.trim().toLowerCase(), fromIndex) != -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
*@param value Description of the Parameter
|
||||||
|
*@return Description of the Return Value
|
||||||
|
*/
|
||||||
|
public boolean errorsContains(String value)
|
||||||
|
{
|
||||||
|
return (errorsContains(value, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
*@param value Description of the Parameter
|
||||||
|
*@param fromIndex Description of the Parameter
|
||||||
|
*@return Description of the Return Value
|
||||||
|
*/
|
||||||
|
public boolean errorsContains(String value, int fromIndex)
|
||||||
|
{
|
||||||
|
return (contains(myErrors, value, fromIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the error attribute of the ExecResults object
|
||||||
|
*
|
||||||
|
*@return The error value
|
||||||
|
*/
|
||||||
|
public boolean getError()
|
||||||
|
{
|
||||||
|
return (myError);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the errorMessage attribute of the ExecResults object
|
||||||
|
*
|
||||||
|
*@return The errorMessage value
|
||||||
|
*/
|
||||||
|
public String getErrorMessage()
|
||||||
|
{
|
||||||
|
switch (getErrorType())
|
||||||
|
{
|
||||||
|
case THROWABLE:
|
||||||
|
return ("Exception: " + myThrowable.getMessage());
|
||||||
|
|
||||||
|
case BADRETURNCODE:
|
||||||
|
return ("Bad return code (expected " + mySuccessCode + ")");
|
||||||
|
|
||||||
|
default:
|
||||||
|
return ("Unknown error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the errorType attribute of the ExecResults object
|
||||||
|
*
|
||||||
|
*@return The errorType value
|
||||||
|
*/
|
||||||
|
public int getErrorType()
|
||||||
|
{
|
||||||
|
return (myErrorType);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the errors attribute of the ExecResults object
|
||||||
|
*
|
||||||
|
*@return The errors value
|
||||||
|
*/
|
||||||
|
public String getErrors()
|
||||||
|
{
|
||||||
|
return (myErrors);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the interrupted attribute of the ExecResults object
|
||||||
|
*
|
||||||
|
*@return The interrupted value
|
||||||
|
*/
|
||||||
|
public boolean getInterrupted()
|
||||||
|
{
|
||||||
|
return (myInterrupted);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the output attribute of the ExecResults object
|
||||||
|
*
|
||||||
|
*@return The output value
|
||||||
|
*/
|
||||||
|
public String getOutput()
|
||||||
|
{
|
||||||
|
return (myOutput);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the returnCode attribute of the ExecResults object
|
||||||
|
*
|
||||||
|
*@return The returnCode value
|
||||||
|
*/
|
||||||
|
public int getReturnCode()
|
||||||
|
{
|
||||||
|
return (myReturnCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the throwable attribute of the ExecResults object
|
||||||
|
*
|
||||||
|
*@return The throwable value
|
||||||
|
*/
|
||||||
|
public Throwable getThrowable()
|
||||||
|
{
|
||||||
|
return (myThrowable);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
*@param value Description of the Parameter
|
||||||
|
*@return Description of the Return Value
|
||||||
|
*/
|
||||||
|
public boolean outputContains(String value)
|
||||||
|
{
|
||||||
|
return (outputContains(value, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
*@param value Description of the Parameter
|
||||||
|
*@param fromIndex Description of the Parameter
|
||||||
|
*@return Description of the Return Value
|
||||||
|
*/
|
||||||
|
public boolean outputContains(String value, int fromIndex)
|
||||||
|
{
|
||||||
|
return (contains(myOutput, value, fromIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the error attribute of the ExecResults object
|
||||||
|
*
|
||||||
|
*@param value The new error value
|
||||||
|
*/
|
||||||
|
public void setError(int value)
|
||||||
|
{
|
||||||
|
myError = true;
|
||||||
|
myErrorType = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the errors attribute of the ExecResults object
|
||||||
|
*
|
||||||
|
*@param errors The new errors value
|
||||||
|
*/
|
||||||
|
public void setErrors(String errors)
|
||||||
|
{
|
||||||
|
myErrors = errors.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the interrupted attribute of the ExecResults object
|
||||||
|
*/
|
||||||
|
public void setInterrupted()
|
||||||
|
{
|
||||||
|
myInterrupted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the output attribute of the ExecResults object
|
||||||
|
*
|
||||||
|
*@param value The new output value
|
||||||
|
*/
|
||||||
|
public void setOutput(String value)
|
||||||
|
{
|
||||||
|
myOutput = value.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the returnCode attribute of the ExecResults object
|
||||||
|
*
|
||||||
|
*@param value The new returnCode value
|
||||||
|
*/
|
||||||
|
public void setReturnCode(int value)
|
||||||
|
{
|
||||||
|
myReturnCode = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the throwable attribute of the ExecResults object
|
||||||
|
*
|
||||||
|
*@param value The new throwable value
|
||||||
|
*/
|
||||||
|
public void setThrowable(Throwable value)
|
||||||
|
{
|
||||||
|
setError(THROWABLE);
|
||||||
|
myThrowable = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Method
|
||||||
|
*
|
||||||
|
*@return Description of the Return Value
|
||||||
|
*/
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
String sep = System.getProperty("line.separator");
|
||||||
|
StringBuffer value = new StringBuffer();
|
||||||
|
value.append("ExecResults for \'" + myCommand + "\'" + sep);
|
||||||
|
|
||||||
|
if ((myInput != null) && !myInput.equals(""))
|
||||||
|
{
|
||||||
|
value.append(sep + "Input..." + sep + myInput + sep);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((myOutput != null) && !myOutput.equals(""))
|
||||||
|
{
|
||||||
|
value.append(sep + "Output..." + sep + myOutput + sep);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((myErrors != null) && !myErrors.equals(""))
|
||||||
|
{
|
||||||
|
value.append(sep + "Errors..." + sep + myErrors + sep);
|
||||||
|
}
|
||||||
|
|
||||||
|
value.append(sep);
|
||||||
|
|
||||||
|
if (myInterrupted)
|
||||||
|
{
|
||||||
|
value.append("Command timed out after " + (myTimeout / 1000) + " seconds " + sep);
|
||||||
|
}
|
||||||
|
|
||||||
|
value.append("Returncode: " + myReturnCode + sep);
|
||||||
|
|
||||||
|
if (myError)
|
||||||
|
{
|
||||||
|
value.append(getErrorMessage() + sep);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (value.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user