WebGoat/ webgoat/main/project/org/owasp/webgoat/lessons/DefaultLessonAction.java

363 lines
9.9 KiB
Java

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();
}
}