Migrate the labs to direct/Random access stages
git-svn-id: http://webgoat.googlecode.com/svn/trunk@158 4033779f-a91e-0410-96ef-6bf7bf53c507
This commit is contained in:
parent
f5e56c7081
commit
2bda4a81f3
@ -54,6 +54,18 @@ public class CrossSiteScripting extends GoatHillsFinancial
|
||||
{
|
||||
private final static Integer DEFAULT_RANKING = new Integer(100);
|
||||
|
||||
public final static String STAGE1 = "Stage 1";
|
||||
|
||||
public final static String STAGE2 = "Stage 2";
|
||||
|
||||
public final static String STAGE3 = "Stage 3";
|
||||
|
||||
public final static String STAGE4 = "Stage 4";
|
||||
|
||||
public final static String STAGE5 = "Stage 5";
|
||||
|
||||
public final static String STAGE6 = "Stage 6";
|
||||
|
||||
protected void registerActions(String className)
|
||||
{
|
||||
registerAction(new ListStaff(this, className, LISTSTAFF_ACTION));
|
||||
@ -140,52 +152,47 @@ public class CrossSiteScripting extends GoatHillsFinancial
|
||||
|
||||
if (!getLessonTracker(s).getCompleted())
|
||||
{
|
||||
switch (getStage(s))
|
||||
String stage = getStage(s);
|
||||
if (STAGE1.equals(stage))
|
||||
{
|
||||
case 1:
|
||||
instructions = "Stage "
|
||||
+ getStage(s)
|
||||
instructions = 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)
|
||||
}
|
||||
else if (STAGE2.equals(stage))
|
||||
{
|
||||
instructions = 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)
|
||||
}
|
||||
else if (STAGE3.equals(stage))
|
||||
{
|
||||
instructions = 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)
|
||||
}
|
||||
else if (STAGE4.equals(stage))
|
||||
{
|
||||
instructions = 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)
|
||||
}
|
||||
else if (STAGE5.equals(stage))
|
||||
{
|
||||
instructions = 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)
|
||||
}
|
||||
else if (STAGE6.equals(stage))
|
||||
{
|
||||
instructions = 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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -194,8 +201,8 @@ public class CrossSiteScripting extends GoatHillsFinancial
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStageCount() {
|
||||
return 6;
|
||||
public String[] getStages() {
|
||||
return new String[] {STAGE1, STAGE2, STAGE3, STAGE4, STAGE5, STAGE6};
|
||||
}
|
||||
|
||||
public void handleRequest(WebSession s)
|
||||
@ -290,12 +297,11 @@ public class CrossSiteScripting extends GoatHillsFinancial
|
||||
public String htmlEncode(WebSession s, String text)
|
||||
{
|
||||
//System.out.println("Testing for stage 4 completion in lesson " + getCurrentLesson().getName());
|
||||
if (getStage(s) == 4 &&
|
||||
if (STAGE4.equals(getStage(s)) &&
|
||||
text.indexOf("<script>") > -1 && text.indexOf("alert") > -1 && text.indexOf("</script>") > -1)
|
||||
{
|
||||
s.setMessage( "Welcome to stage 5 -- exploiting the data layer" );
|
||||
// Set a phantom stage value to setup for the 4-5 transition
|
||||
setStage(s, 1005);
|
||||
setStageComplete(s, STAGE5);
|
||||
}
|
||||
|
||||
return HtmlEncoder.encode(text);
|
||||
|
@ -88,23 +88,23 @@ public class FindProfile extends DefaultLessonAction
|
||||
}
|
||||
catch (ValidationException e)
|
||||
{
|
||||
if (getStage(s) == 6)
|
||||
if (CrossSiteScripting.STAGE6.equals(getStage(s)))
|
||||
{
|
||||
s
|
||||
.setMessage("Congratulations. You have successfully completed this lesson");
|
||||
getLesson().getLessonTracker(s).setCompleted(true);
|
||||
setStageComplete(s, CrossSiteScripting.STAGE6);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
||||
if (getStage(s) == 5)
|
||||
if (CrossSiteScripting.STAGE5.equals(getStage(s)))
|
||||
{
|
||||
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);
|
||||
setStageComplete(s, CrossSiteScripting.STAGE5);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -81,11 +81,11 @@ public class UpdateProfile extends DefaultLessonAction
|
||||
}
|
||||
catch (ValidationException e)
|
||||
{
|
||||
if (getStage(s) == 2)
|
||||
if (CrossSiteScripting.STAGE2.equals(getStage(s)))
|
||||
{
|
||||
s
|
||||
.setMessage("Welcome to stage 3 - demonstrate Stored XSS again");
|
||||
setStage(s, 3);
|
||||
setStageComplete(s, CrossSiteScripting.STAGE2);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
@ -212,9 +212,9 @@ public class ViewProfile extends DefaultLessonAction
|
||||
|
||||
private void updateLessonStatus(WebSession s, Employee employee)
|
||||
{
|
||||
switch (getStage(s))
|
||||
String stage = getStage(s);
|
||||
if (CrossSiteScripting.STAGE1.equals(stage))
|
||||
{
|
||||
case 1:
|
||||
String address1 = employee.getAddress1().toLowerCase();
|
||||
if (address1.indexOf("<script>") > -1
|
||||
&& address1.indexOf("alert") > -1
|
||||
@ -222,10 +222,11 @@ public class ViewProfile extends DefaultLessonAction
|
||||
{
|
||||
s
|
||||
.setMessage("Welcome to stage 2 - implement input validation");
|
||||
setStage(s, 2);
|
||||
setStageComplete(s, CrossSiteScripting.STAGE1);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
}
|
||||
else if (CrossSiteScripting.STAGE3.equals(stage))
|
||||
{
|
||||
String address2 = employee.getAddress1().toLowerCase();
|
||||
if (address2.indexOf("<script>") > -1
|
||||
&& address2.indexOf("alert") > -1
|
||||
@ -233,19 +234,17 @@ public class ViewProfile extends DefaultLessonAction
|
||||
{
|
||||
s
|
||||
.setMessage("Welcome to stage 4 - implement output encoding");
|
||||
setStage(s, 4);
|
||||
setStageComplete(s, CrossSiteScripting.STAGE3);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
}
|
||||
else if (CrossSiteScripting.STAGE4.equals(stage))
|
||||
{
|
||||
if (employee.getAddress1().toLowerCase().indexOf("<") > -1)
|
||||
{
|
||||
s
|
||||
.setMessage("Welcome to stage 5 - demonstrate reflected XSS");
|
||||
setStage(s, 5);
|
||||
setStageComplete(s, CrossSiteScripting.STAGE4);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -312,12 +312,16 @@ public abstract class DefaultLessonAction implements LessonAction
|
||||
return authorized;
|
||||
}
|
||||
|
||||
protected void setStage(WebSession s, int stage)
|
||||
protected void setStage(WebSession s, String stage)
|
||||
{
|
||||
getLesson().setStage(s, stage);
|
||||
}
|
||||
|
||||
protected int getStage(WebSession s)
|
||||
protected void setStageComplete(WebSession s, String stage) {
|
||||
getLesson().setStageComplete(s, stage);
|
||||
}
|
||||
|
||||
protected String getStage(WebSession s)
|
||||
{
|
||||
return getLesson().getStage(s);
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import org.apache.ecs.Element;
|
||||
import org.apache.ecs.ElementContainer;
|
||||
import org.apache.ecs.html.A;
|
||||
import org.apache.ecs.html.IMG;
|
||||
import org.owasp.webgoat.lessons.SequentialLessonAdapter;
|
||||
import org.owasp.webgoat.lessons.RandomLessonAdapter;
|
||||
import org.owasp.webgoat.session.ParameterNotFoundException;
|
||||
import org.owasp.webgoat.session.UnauthenticatedException;
|
||||
import org.owasp.webgoat.session.UnauthorizedException;
|
||||
@ -45,7 +45,7 @@ import org.owasp.webgoat.session.WebSession;
|
||||
*
|
||||
* For details, please see http://code.google.com/p/webgoat/
|
||||
*/
|
||||
public class GoatHillsFinancial extends SequentialLessonAdapter
|
||||
public class GoatHillsFinancial extends RandomLessonAdapter
|
||||
{
|
||||
public final static A ASPECT_LOGO = new A().setHref("http://www.aspectsecurity.com").addElement(new IMG("images/logos/aspect.jpg").setAlt("Aspect Security").setBorder(0).setHspace(0).setVspace(0));
|
||||
|
||||
@ -161,6 +161,10 @@ public class GoatHillsFinancial extends SequentialLessonAdapter
|
||||
lessonFunctions.put(action.getActionName(), action);
|
||||
}
|
||||
|
||||
public String[] getStages() {
|
||||
return new String[] {};
|
||||
}
|
||||
|
||||
protected List<String> getHints(WebSession s)
|
||||
{
|
||||
return new ArrayList<String>();
|
||||
|
@ -0,0 +1,45 @@
|
||||
package org.owasp.webgoat.lessons;
|
||||
|
||||
import org.owasp.webgoat.session.LessonTracker;
|
||||
import org.owasp.webgoat.session.RandomLessonTracker;
|
||||
import org.owasp.webgoat.session.WebSession;
|
||||
|
||||
public abstract class RandomLessonAdapter extends LessonAdapter {
|
||||
|
||||
public abstract String[] getStages();
|
||||
|
||||
public void setStage(WebSession s, String stage) {
|
||||
getLessonTracker(s).setStage(stage);
|
||||
}
|
||||
|
||||
public String getStage(WebSession s) {
|
||||
return getLessonTracker(s).getStage();
|
||||
}
|
||||
|
||||
public void setStageComplete(WebSession s, String stage) {
|
||||
getLessonTracker(s).setStageComplete(stage, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RandomLessonTracker getLessonTracker(WebSession s) {
|
||||
return (RandomLessonTracker) super.getLessonTracker(s);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RandomLessonTracker getLessonTracker(WebSession s, AbstractLesson lesson) {
|
||||
return (RandomLessonTracker) super.getLessonTracker(s, lesson);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RandomLessonTracker getLessonTracker(WebSession s, String userNameOverride) {
|
||||
return (RandomLessonTracker) super.getLessonTracker(s, userNameOverride);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LessonTracker createLessonTracker() {
|
||||
return new RandomLessonTracker(getStages());
|
||||
}
|
||||
|
||||
}
|
@ -160,7 +160,7 @@ public class DeleteProfile extends DefaultLessonAction
|
||||
private void updateLessonStatus(WebSession s)
|
||||
{
|
||||
// If the logged in user is not authorized to be here, stage 1 is complete.
|
||||
if (getStage(s) == 1)
|
||||
if (RoleBasedAccessControl.STAGE1.equals(getStage(s)))
|
||||
try
|
||||
{
|
||||
int userId = getIntSessionAttribute(s, getLessonName() + "."
|
||||
@ -171,7 +171,7 @@ public class DeleteProfile extends DefaultLessonAction
|
||||
{
|
||||
s
|
||||
.setMessage("Welcome to stage 2 -- protecting the business layer");
|
||||
setStage(s, 2);
|
||||
setStageComplete(s, RoleBasedAccessControl.STAGE1);
|
||||
}
|
||||
}
|
||||
catch (ParameterNotFoundException e)
|
||||
|
@ -52,6 +52,14 @@ public class RoleBasedAccessControl extends GoatHillsFinancial
|
||||
{
|
||||
private final static Integer DEFAULT_RANKING = new Integer(125);
|
||||
|
||||
public final static String STAGE1 = "Stage 1";
|
||||
|
||||
public final static String STAGE2 = "Stage 2";
|
||||
|
||||
public final static String STAGE3 = "Stage 3";
|
||||
|
||||
public final static String STAGE4 = "Stage 4";
|
||||
|
||||
protected void registerActions(String className) {
|
||||
registerAction(new ListStaff(this, className, LISTSTAFF_ACTION));
|
||||
registerAction(new SearchStaff(this, className, SEARCHSTAFF_ACTION));
|
||||
@ -114,8 +122,8 @@ public class RoleBasedAccessControl extends GoatHillsFinancial
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStageCount() {
|
||||
return 4;
|
||||
public String[] getStages() {
|
||||
return new String[] {STAGE1, STAGE2, STAGE3, STAGE4};
|
||||
}
|
||||
|
||||
/**
|
||||
@ -129,41 +137,40 @@ public class RoleBasedAccessControl extends GoatHillsFinancial
|
||||
|
||||
if (!getLessonTracker(s).getCompleted())
|
||||
{
|
||||
switch (getStage(s))
|
||||
String stage = getStage(s);
|
||||
if (STAGE1.equals(stage))
|
||||
{
|
||||
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:
|
||||
}
|
||||
else if (STAGE2.equals(stage))
|
||||
{
|
||||
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:
|
||||
}
|
||||
else if (STAGE3.equals(stage))
|
||||
{
|
||||
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:
|
||||
}
|
||||
else if (STAGE4.equals(stage))
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -236,7 +243,8 @@ public class RoleBasedAccessControl extends GoatHillsFinancial
|
||||
catch (UnauthorizedException ue2)
|
||||
{
|
||||
// Update lesson status if necessary.
|
||||
if (getStage(s) == 2)
|
||||
String stage = getStage(s);
|
||||
if (STAGE2.equals(stage))
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -244,7 +252,7 @@ public class RoleBasedAccessControl extends GoatHillsFinancial
|
||||
!isAuthorized(s, getUserId(s), RoleBasedAccessControl.DELETEPROFILE_ACTION))
|
||||
{
|
||||
s.setMessage( "Welcome to stage 3 -- exploiting the data layer" );
|
||||
setStage(s, 3);
|
||||
setStageComplete(s, STAGE2);
|
||||
}
|
||||
} catch (ParameterNotFoundException pnfe)
|
||||
{
|
||||
@ -253,7 +261,7 @@ public class RoleBasedAccessControl extends GoatHillsFinancial
|
||||
}
|
||||
//System.out.println("isAuthorized() exit stage: " + getStage(s));
|
||||
// Update lesson status if necessary.
|
||||
if (getStage(s) == 4)
|
||||
if (STAGE4.equals(stage))
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -267,7 +275,7 @@ public class RoleBasedAccessControl extends GoatHillsFinancial
|
||||
if (!action.isAuthorizedForEmployee(s, userId, employeeId))
|
||||
{
|
||||
s.setMessage("Congratulations. You have successfully completed this lesson.");
|
||||
getLessonTracker( s ).setCompleted( true );
|
||||
setStageComplete(s, STAGE4);
|
||||
}
|
||||
} catch (Exception e)
|
||||
{
|
||||
@ -370,8 +378,9 @@ public class RoleBasedAccessControl extends GoatHillsFinancial
|
||||
}
|
||||
catch (UnauthorizedException ue2)
|
||||
{
|
||||
String stage = getStage(s);
|
||||
// Update lesson status if necessary.
|
||||
if (getStage(s) == 2)
|
||||
if (STAGE2.equals(stage))
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -379,7 +388,7 @@ public class RoleBasedAccessControl extends GoatHillsFinancial
|
||||
!isAuthorized(s, getUserId(s), RoleBasedAccessControl.DELETEPROFILE_ACTION))
|
||||
{
|
||||
s.setMessage( "Welcome to stage 3 -- exploiting the data layer" );
|
||||
setStage(s, 3);
|
||||
setStageComplete(s, STAGE2);
|
||||
}
|
||||
} catch (ParameterNotFoundException pnfe)
|
||||
{
|
||||
@ -388,7 +397,7 @@ public class RoleBasedAccessControl extends GoatHillsFinancial
|
||||
}
|
||||
//System.out.println("isAuthorized() exit stage: " + getStage(s));
|
||||
// Update lesson status if necessary.
|
||||
if (getStage(s) == 4)
|
||||
if (STAGE4.equals(stage))
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -402,7 +411,7 @@ public class RoleBasedAccessControl extends GoatHillsFinancial
|
||||
if (!action.isAuthorizedForEmployee(s, userId, employeeId))
|
||||
{
|
||||
s.setMessage("Congratulations. You have successfully completed this lesson.");
|
||||
getLessonTracker( s ).setCompleted( true );
|
||||
setStageComplete(s, STAGE4);
|
||||
}
|
||||
} catch (Exception e)
|
||||
{
|
||||
|
@ -95,11 +95,11 @@ public class ViewProfile extends DefaultLessonAction
|
||||
int employeeId = s.getParser().getIntParameter(
|
||||
RoleBasedAccessControl.EMPLOYEE_ID);
|
||||
|
||||
if (getStage(s) == 3
|
||||
if (RoleBasedAccessControl.STAGE3.equals(getStage(s))
|
||||
&& !isAuthorizedForEmployee(s, userId, employeeId))
|
||||
{
|
||||
s.setMessage("Welcome to stage 4 -- protecting the data layer");
|
||||
setStage(s, 4);
|
||||
setStageComplete(s, RoleBasedAccessControl.STAGE3);
|
||||
}
|
||||
}
|
||||
catch (ParameterNotFoundException e)
|
||||
|
@ -270,28 +270,26 @@ public class Login extends DefaultLessonAction
|
||||
SQLInjection.EMPLOYEE_ID);
|
||||
String password = s.getParser().getRawParameter(
|
||||
SQLInjection.PASSWORD);
|
||||
switch (getStage(s))
|
||||
String stage = getStage(s);
|
||||
if (SQLInjection.STAGE1.equals(stage))
|
||||
{
|
||||
case 1:
|
||||
if (Integer.parseInt(employeeId) == SQLInjection.PRIZE_EMPLOYEE_ID
|
||||
&& isAuthenticated(s))
|
||||
{
|
||||
s.setMessage("Welcome to stage 2");
|
||||
setStage(s, 2);
|
||||
setStageComplete(s, SQLInjection.STAGE1);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
}
|
||||
else if (SQLInjection.STAGE2.equals(stage))
|
||||
{
|
||||
// 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);
|
||||
setStageComplete(s, SQLInjection.STAGE2);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (ParameterNotFoundException pnfe)
|
||||
|
@ -55,6 +55,14 @@ public class SQLInjection extends GoatHillsFinancial
|
||||
|
||||
public final static String PRIZE_EMPLOYEE_NAME = "Neville Bartholomew";
|
||||
|
||||
public final static String STAGE1 = "Stage 1";
|
||||
|
||||
public final static String STAGE2 = "Stage 2";
|
||||
|
||||
public final static String STAGE3 = "Stage 3";
|
||||
|
||||
public final static String STAGE4 = "Stage 4";
|
||||
|
||||
public void registerActions(String className)
|
||||
{
|
||||
registerAction(new ListStaff(this, className, LISTSTAFF_ACTION));
|
||||
@ -122,8 +130,8 @@ public class SQLInjection extends GoatHillsFinancial
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStageCount() {
|
||||
return 4;
|
||||
public String[] getStages() {
|
||||
return new String[] {STAGE1, STAGE2, STAGE3, STAGE4};
|
||||
}
|
||||
|
||||
/**
|
||||
@ -137,9 +145,9 @@ public class SQLInjection extends GoatHillsFinancial
|
||||
|
||||
if (!getLessonTracker(s).getCompleted())
|
||||
{
|
||||
switch (getStage(s))
|
||||
String stage = getStage(s);
|
||||
if (STAGE1.equals(stage))
|
||||
{
|
||||
case 1:
|
||||
instructions = "Stage "
|
||||
+ getStage(s)
|
||||
+ ": Use String SQL Injection to bypass authentication. "
|
||||
@ -147,32 +155,31 @@ public class SQLInjection extends GoatHillsFinancial
|
||||
+ PRIZE_EMPLOYEE_NAME
|
||||
+ ", who is in the Admin group. "
|
||||
+ "You do not have the password, but the form is SQL injectable.";
|
||||
break;
|
||||
case 2:
|
||||
}
|
||||
else if (STAGE2.equals(stage))
|
||||
{
|
||||
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:
|
||||
}
|
||||
else if (STAGE3.equals(stage))
|
||||
{
|
||||
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:
|
||||
}
|
||||
else if (STAGE4.equals(stage))
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -224,9 +224,9 @@ public class ViewProfile extends DefaultLessonAction
|
||||
+ SQLInjection.USER_ID);
|
||||
String employeeId = s.getParser().getRawParameter(
|
||||
SQLInjection.EMPLOYEE_ID);
|
||||
switch (getStage(s))
|
||||
String stage = getStage(s);
|
||||
if (SQLInjection.STAGE3.equals(stage))
|
||||
{
|
||||
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
|
||||
@ -235,10 +235,11 @@ public class ViewProfile extends DefaultLessonAction
|
||||
.parseInt(userId), employee.getId()))
|
||||
{
|
||||
s.setMessage("Welcome to stage 4");
|
||||
setStage(s, 4);
|
||||
setStageComplete(s, SQLInjection.STAGE3);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
}
|
||||
else if (SQLInjection.STAGE4.equals(stage))
|
||||
{
|
||||
// If we were denied the employee to view, and we would have been able to view it
|
||||
// in the broken state, the stage is completed.
|
||||
// This assumes the student hasn't modified getEmployeeProfile_BACKUP().
|
||||
@ -257,12 +258,9 @@ public class ViewProfile extends DefaultLessonAction
|
||||
{
|
||||
s
|
||||
.setMessage("Congratulations. You have successfully completed this lesson");
|
||||
getLesson().getLessonTracker(s).setCompleted(true);
|
||||
setStageComplete(s, SQLInjection.STAGE4);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (ParameterNotFoundException pnfe)
|
||||
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,86 @@
|
||||
package org.owasp.webgoat.session;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
public class RandomLessonTracker extends LessonTracker {
|
||||
|
||||
private String[] stages;
|
||||
|
||||
private String stage;
|
||||
|
||||
private Map<String, Boolean> completed = new HashMap<String, Boolean>();
|
||||
|
||||
public RandomLessonTracker(String[] stages) {
|
||||
if (stages == null)
|
||||
stages = new String[0];
|
||||
this.stages = stages;
|
||||
}
|
||||
|
||||
public void setStage(String stage) {
|
||||
this.stage = stage;
|
||||
}
|
||||
|
||||
public String getStage() {
|
||||
if (this.stage == null && stages.length > 0)
|
||||
return stages[0];
|
||||
return this.stage;
|
||||
}
|
||||
|
||||
public void setStageComplete(String stage, boolean complete) {
|
||||
completed.put(stage, Boolean.valueOf(complete));
|
||||
for (int i=0; i<stages.length-1; i++)
|
||||
if (stages[i].equals(stage))
|
||||
setStage(stages[i+1]);
|
||||
}
|
||||
|
||||
public boolean hasCompleted(String stage) {
|
||||
Boolean complete = completed.get(stage);
|
||||
return complete == null ? false : complete.booleanValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getCompleted() {
|
||||
for (int i=0; i<stages.length; i++)
|
||||
if (!hasCompleted(stages[i]))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCompleted(boolean complete) {
|
||||
throw new UnsupportedOperationException("Use individual stage completion instead");
|
||||
}
|
||||
|
||||
protected void setProperties(Properties props, Screen screen) {
|
||||
super.setProperties(props, screen);
|
||||
for (int i=0; i<stages.length; i++) {
|
||||
String p = props.getProperty(screen.getTitle() + "." + stages[i] + ".completed");
|
||||
if (p != null) {
|
||||
setStageComplete(stages[i], Boolean.valueOf(p));
|
||||
}
|
||||
}
|
||||
setStage(props.getProperty(screen.getTitle() + ".stage"));
|
||||
}
|
||||
|
||||
public void store(WebSession s, Screen screen, String user) {
|
||||
for (int i=0; i<stages.length; i++) {
|
||||
if (hasCompleted(stages[i]))
|
||||
lessonProperties.setProperty(screen.getTitle() + "." + stages[i] + ".completed", Boolean.TRUE.toString());
|
||||
}
|
||||
lessonProperties.setProperty(screen.getTitle() + ".stage", getStage());
|
||||
super.store(s, screen, user);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer buff = new StringBuffer();
|
||||
buff.append(super.toString());
|
||||
for (int i=0; i<stages.length; i++) {
|
||||
buff.append(" - completed " + stages[i] + " :....... " + hasCompleted(stages[i]) + "\n");
|
||||
}
|
||||
buff.append(" - currentStage:....... " + getStage() + "\n");
|
||||
return buff.toString();
|
||||
}
|
||||
|
||||
}
|
@ -22,6 +22,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.owasp.webgoat.lessons.AbstractLesson;
|
||||
import org.owasp.webgoat.lessons.Category;
|
||||
import org.owasp.webgoat.lessons.RandomLessonAdapter;
|
||||
import org.owasp.webgoat.lessons.SequentialLessonAdapter;
|
||||
|
||||
/*******************************************************************************
|
||||
@ -916,6 +917,17 @@ public class WebSession
|
||||
if (stage > 0 && stage <= sla.getStageCount())
|
||||
sla.setStage(this, stage);
|
||||
}
|
||||
else if (al instanceof RandomLessonAdapter)
|
||||
{
|
||||
try
|
||||
{
|
||||
RandomLessonAdapter rla = (RandomLessonAdapter) al;
|
||||
int stage = myParser.getIntParameter(STAGE) - 1;
|
||||
String[] stages = rla.getStages();
|
||||
if (stage>0 && stage <= stages.length)
|
||||
rla.setStage(this, stages[stage]);
|
||||
} catch (ParameterNotFoundException pnfe) {}
|
||||
}
|
||||
}
|
||||
// else update global variables for the current screen
|
||||
else
|
||||
|
0
webgoat/main/project/WebContent/WEB-INF/web.xml
Normal file → Executable file
0
webgoat/main/project/WebContent/WEB-INF/web.xml
Normal file → Executable file
0
webgoat/main/project/WebContent/WEB-INF/webgoat.properties
Normal file → Executable file
0
webgoat/main/project/WebContent/WEB-INF/webgoat.properties
Normal file → Executable file
@ -9,6 +9,7 @@ AbstractLesson currentLesson = webSession.getCurrentLesson();
|
||||
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<%@page import="org.owasp.webgoat.lessons.SequentialLessonAdapter"%>
|
||||
<%@page import="org.owasp.webgoat.lessons.RandomLessonAdapter"%>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
|
||||
@ -199,6 +200,7 @@ StringBuffer buildList = new StringBuffer();
|
||||
</div>
|
||||
<%
|
||||
AbstractLesson al = webSession.getCurrentLesson();
|
||||
System.out.println("AL is a " + al.getClass().getName());
|
||||
if (al instanceof SequentialLessonAdapter)
|
||||
{
|
||||
SequentialLessonAdapter sla = (SequentialLessonAdapter) al;
|
||||
@ -215,6 +217,22 @@ StringBuffer buildList = new StringBuffer();
|
||||
%></select></form><%
|
||||
}
|
||||
}
|
||||
else if (al instanceof RandomLessonAdapter)
|
||||
{
|
||||
RandomLessonAdapter rla = (RandomLessonAdapter) al;
|
||||
String[] stages = rla.getStages();
|
||||
if (stages != null && stages.length > 0) {
|
||||
%><form method="post" action="attack?menu=<%=webSession.getCurrentMenu()%>">
|
||||
<select name="<%= WebSession.STAGE %>" onchange="this.form.submit();">
|
||||
<%
|
||||
String stage = rla.getStage(webSession);
|
||||
for (int i=0; i<stages.length;i++) {
|
||||
%><option <% if (stages[i].equals(stage)) out.print("selected"); %> value="<%= i+1 %>">Stage <%= i+1 %></option>
|
||||
<%
|
||||
}
|
||||
%></select></form><%
|
||||
}
|
||||
}
|
||||
%>
|
||||
<div id="lessonContent"><%=webSession.getInstructions()%></div>
|
||||
<div id="message" class="info"><%=webSession.getMessage()%></div>
|
||||
|
Loading…
x
Reference in New Issue
Block a user