diff --git a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/CrossSiteScripting/CrossSiteScripting.java b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/CrossSiteScripting/CrossSiteScripting.java index 36aef5b28..4daa93a29 100644 --- a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/CrossSiteScripting/CrossSiteScripting.java +++ b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/CrossSiteScripting/CrossSiteScripting.java @@ -291,12 +291,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 (STAGE4.equals(getStage(s)) && text.indexOf("") > -1) { + setStageComplete(s, STAGE4); s.setMessage( "Welcome to stage 5 -- exploiting the data layer" ); - setStageComplete(s, STAGE5); } return HtmlEncoder.encode(text); diff --git a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/CrossSiteScripting/UpdateProfile.java b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/CrossSiteScripting/UpdateProfile.java index 193ce168a..8fe7f40b0 100644 --- a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/CrossSiteScripting/UpdateProfile.java +++ b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/CrossSiteScripting/UpdateProfile.java @@ -83,9 +83,8 @@ public class UpdateProfile extends DefaultLessonAction { if (CrossSiteScripting.STAGE2.equals(getStage(s))) { - s - .setMessage("Welcome to stage 3 - demonstrate Stored XSS again"); setStageComplete(s, CrossSiteScripting.STAGE2); + s.setMessage("Welcome to stage 3 - demonstrate Stored XSS again"); } throw e; } diff --git a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/CrossSiteScripting/ViewProfile.java b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/CrossSiteScripting/ViewProfile.java index 9b2e6e47b..44d3ecde1 100644 --- a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/CrossSiteScripting/ViewProfile.java +++ b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/CrossSiteScripting/ViewProfile.java @@ -220,9 +220,8 @@ public class ViewProfile extends DefaultLessonAction && address1.indexOf("alert") > -1 && address1.indexOf("") > -1) { - s - .setMessage("Welcome to stage 2 - implement input validation"); setStageComplete(s, CrossSiteScripting.STAGE1); + s.setMessage("Welcome to stage 2 - implement input validation"); } } else if (CrossSiteScripting.STAGE3.equals(stage)) diff --git a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/DBCrossSiteScripting/UpdateProfile.java b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/DBCrossSiteScripting/UpdateProfile.java index bcbee54b5..00f39cd0c 100755 --- a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/DBCrossSiteScripting/UpdateProfile.java +++ b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/DBCrossSiteScripting/UpdateProfile.java @@ -115,7 +115,6 @@ public class UpdateProfile extends DefaultLessonAction if (pass) { setStageComplete(s, DBCrossSiteScripting.STAGE1); - s.setMessage("Congratulations, you have completed " + DBCrossSiteScripting.STAGE1); } } } diff --git a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/DBSQLInjection/Login.java b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/DBSQLInjection/Login.java index aba2472c9..f09eb173d 100755 --- a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/DBSQLInjection/Login.java +++ b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/DBSQLInjection/Login.java @@ -157,7 +157,6 @@ public class Login extends DefaultLessonAction DBSQLInjection.PRIZE_EMPLOYEE_ID == Integer.parseInt(userId)) { setStageComplete(s, DBSQLInjection.STAGE1); - s.setMessage("Congratulations, you have completed " + DBSQLInjection.STAGE1); } } catch (SQLException sqle) diff --git a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/RandomLessonAdapter.java b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/RandomLessonAdapter.java index 7bdf5f540..37efa3e23 100755 --- a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/RandomLessonAdapter.java +++ b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/RandomLessonAdapter.java @@ -20,9 +20,9 @@ public abstract class RandomLessonAdapter extends LessonAdapter { RandomLessonTracker lt = getLessonTracker(s); lt.setStageComplete(stage, true); if (lt.getCompleted()) { - s.setMessage("Congratulations, you have completed this lesson"); + s.setMessage("Congratulations, you have completed this lab"); } else { - String message = "You have completed stage " + stage + "."; + String message = "You have completed " + stage + "."; if (! stage.equals(lt.getStage())) message = message + " Welcome to " + lt.getStage(); s.setMessage(message); diff --git a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/RoleBasedAccessControl/DeleteProfile.java b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/RoleBasedAccessControl/DeleteProfile.java index 017d74f3c..0417b732a 100644 --- a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/RoleBasedAccessControl/DeleteProfile.java +++ b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/RoleBasedAccessControl/DeleteProfile.java @@ -169,9 +169,8 @@ public class DeleteProfile extends DefaultLessonAction if (!isAuthorized(s, userId, RoleBasedAccessControl.DELETEPROFILE_ACTION)) { - s - .setMessage("Welcome to stage 2 -- protecting the business layer"); setStageComplete(s, RoleBasedAccessControl.STAGE1); + s.setMessage("Welcome to stage 2 -- protecting the business layer"); } } catch (ParameterNotFoundException e) diff --git a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/RoleBasedAccessControl/RoleBasedAccessControl.java b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/RoleBasedAccessControl/RoleBasedAccessControl.java index 5f5b99e62..1334332ae 100644 --- a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/RoleBasedAccessControl/RoleBasedAccessControl.java +++ b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/RoleBasedAccessControl/RoleBasedAccessControl.java @@ -240,8 +240,8 @@ public class RoleBasedAccessControl extends GoatHillsFinancial if (RoleBasedAccessControl.DELETEPROFILE_ACTION.equals(requestedActionName) && !isAuthorized(s, getUserId(s), RoleBasedAccessControl.DELETEPROFILE_ACTION)) { - s.setMessage( "Welcome to stage 3 -- exploiting the data layer" ); setStageComplete(s, STAGE2); + s.setMessage( "Welcome to stage 3 -- exploiting the data layer" ); } } catch (ParameterNotFoundException pnfe) { diff --git a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/RoleBasedAccessControl/ViewProfile.java b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/RoleBasedAccessControl/ViewProfile.java index 75d5f8bef..46a0ffd9a 100644 --- a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/RoleBasedAccessControl/ViewProfile.java +++ b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/RoleBasedAccessControl/ViewProfile.java @@ -98,8 +98,8 @@ public class ViewProfile extends DefaultLessonAction if (RoleBasedAccessControl.STAGE3.equals(getStage(s)) && !isAuthorizedForEmployee(s, userId, employeeId)) { - s.setMessage("Welcome to stage 4 -- protecting the data layer"); setStageComplete(s, RoleBasedAccessControl.STAGE3); + s.setMessage("Welcome to stage 4 -- protecting the data layer"); } } catch (ParameterNotFoundException e) diff --git a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/SQLInjection/Login.java b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/SQLInjection/Login.java index 62a0d30b0..90ad0120f 100644 --- a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/SQLInjection/Login.java +++ b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/SQLInjection/Login.java @@ -276,7 +276,6 @@ public class Login extends DefaultLessonAction if (Integer.parseInt(employeeId) == SQLInjection.PRIZE_EMPLOYEE_ID && isAuthenticated(s)) { - s.setMessage("Welcome to stage 2"); setStageComplete(s, SQLInjection.STAGE1); } } diff --git a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/SQLInjection/ViewProfile.java b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/SQLInjection/ViewProfile.java index 84cfd1672..3ffcdbee0 100644 --- a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/SQLInjection/ViewProfile.java +++ b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/SQLInjection/ViewProfile.java @@ -234,7 +234,6 @@ public class ViewProfile extends DefaultLessonAction && !isAuthorizedForEmployee(s, Integer .parseInt(userId), employee.getId())) { - s.setMessage("Welcome to stage 4"); setStageComplete(s, SQLInjection.STAGE3); } } diff --git a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/instructor/RoleBasedAccessControl/RoleBasedAccessControl_i.java b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/instructor/RoleBasedAccessControl/RoleBasedAccessControl_i.java index af0cc2d30..525b19306 100644 --- a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/instructor/RoleBasedAccessControl/RoleBasedAccessControl_i.java +++ b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/instructor/RoleBasedAccessControl/RoleBasedAccessControl_i.java @@ -1 +1 @@ -package org.owasp.webgoat.lessons.instructor.RoleBasedAccessControl; import org.apache.ecs.ElementContainer; import org.owasp.webgoat.lessons.GoatHillsFinancial.DefaultLessonAction; import org.owasp.webgoat.lessons.GoatHillsFinancial.GoatHillsFinancial; import org.owasp.webgoat.lessons.GoatHillsFinancial.LessonAction; 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; /** * 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. * */ /* STAGE 2 FIXES Solution Summary: Edit RoleBasedAccessControl.java and change handleRequest(). Modify handleRequest() with lines denoted by // STAGE 2 - FIX. Solution Steps: 1. This solution adds an access control check in the controller. Point out that their architecture may require the check to occur in the business function. 2. Look at the RoleBasedAccessControl class identify where execution happens of an action. a. action.handleRequest(s); is not protected by an access control check. b. look at handleRequest(s) to determine where access control check should occur. c. add protection by a programmatic authorization check before dispatching to the action: 1. Add an isAuthorized() call before dispatching to the action, and throw an unauthorized exception. Tell student this exception exists. Use eclipse command completion to find the isAuthorized() call on the action. From command completion - determine calling arguments of isAuthorized() int userId = action.getUserId(s); if (action.isAuthorized(s, userId, action.getActionName())) { action.handleRequest(s); } else throw new UnauthorizedException(); Repeat stage 1 and note that the function fails with a "Not authorized" message. Tom will be in the list again, because the DB is reset when lesson restarts. Adding the access check in the RoleBasedAccessControl:handleRequest() is putting the check in the “Controller” The access check can also be added to DeleteProfile.deleteEmployeeProfile(), which is putting the check in the “Business Function” */ public class RoleBasedAccessControl_i extends RoleBasedAccessControl { public void handleRequest(WebSession s) { //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) { // Missing the action - send them back to login. requestedActionName = LOGIN_ACTION; } try { LessonAction action = getAction(requestedActionName); if (action != null) { // FIXME: This code has gotten much uglier //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); // STAGE 2 - FIX // action.getActionName() returns the user requested function which // is tied to the button click from the listStaff jsp // // Checking isAuthorized() for the requested action if (action.isAuthorized(s, userId, action.getActionName())) // STAGE 2 - FIX { // Calling the handleRequest() method for the requested action action.handleRequest(s); } else throw new UnauthorizedException(); // STAGE 2 - FIX } else throw new UnauthenticatedException(); } } else setCurrentAction(s, ERROR_ACTION); } catch (ParameterNotFoundException pnfe) { System.out.println("Missing parameter"); pnfe.printStackTrace(); setCurrentAction(s, ERROR_ACTION); } catch (ValidationException ve) { System.out.println("Validation failed"); ve.printStackTrace(); setCurrentAction(s, ERROR_ACTION); } catch (UnauthenticatedException ue) { s.setMessage("Login failed"); System.out.println("Authentication failure"); ue.printStackTrace(); } catch (UnauthorizedException ue2) { String stage = getStage(s); // Update lesson status if necessary. if (STAGE2.equals(stage)) { try { if (GoatHillsFinancial.DELETEPROFILE_ACTION.equals(requestedActionName) && !isAuthorized(s, getUserId(s), GoatHillsFinancial.DELETEPROFILE_ACTION)) { s.setMessage( "Welcome to stage 3 -- exploiting the data layer" ); setStageComplete(s, STAGE2); } } catch (ParameterNotFoundException pnfe) { pnfe.printStackTrace(); } } //System.out.println("isAuthorized() exit stage: " + getStage(s)); // Update lesson status if necessary. if (STAGE4.equals(stage)) { try { //System.out.println("Checking for stage 4 completion"); DefaultLessonAction action = (DefaultLessonAction) getAction(getCurrentAction(s)); int userId = Integer.parseInt((String)s.getRequest().getSession().getAttribute(getLessonName() + "." + GoatHillsFinancial.USER_ID)); int employeeId = s.getParser().getIntParameter( GoatHillsFinancial.EMPLOYEE_ID); if (!action.isAuthorizedForEmployee(s, userId, employeeId)) { s.setMessage("Congratulations. You have successfully completed this lesson."); setStageComplete(s, STAGE4); } } catch (Exception e) { // swallow this - shouldn't happen inthe normal course // e.printStackTrace(); } } s.setMessage("You are not authorized to perform this function"); System.out.println("Authorization failure"); setCurrentAction(s, ERROR_ACTION); ue2.printStackTrace(); } // All this does for this lesson is ensure that a non-null content exists. setContent(new ElementContainer()); } } \ No newline at end of file +package org.owasp.webgoat.lessons.instructor.RoleBasedAccessControl; import org.apache.ecs.ElementContainer; import org.owasp.webgoat.lessons.GoatHillsFinancial.DefaultLessonAction; import org.owasp.webgoat.lessons.GoatHillsFinancial.GoatHillsFinancial; import org.owasp.webgoat.lessons.GoatHillsFinancial.LessonAction; 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; /** * 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. * */ /* STAGE 2 FIXES Solution Summary: Edit RoleBasedAccessControl.java and change handleRequest(). Modify handleRequest() with lines denoted by // STAGE 2 - FIX. Solution Steps: 1. This solution adds an access control check in the controller. Point out that their architecture may require the check to occur in the business function. 2. Look at the RoleBasedAccessControl class identify where execution happens of an action. a. action.handleRequest(s); is not protected by an access control check. b. look at handleRequest(s) to determine where access control check should occur. c. add protection by a programmatic authorization check before dispatching to the action: 1. Add an isAuthorized() call before dispatching to the action, and throw an unauthorized exception. Tell student this exception exists. Use eclipse command completion to find the isAuthorized() call on the action. From command completion - determine calling arguments of isAuthorized() int userId = action.getUserId(s); if (action.isAuthorized(s, userId, action.getActionName())) { action.handleRequest(s); } else throw new UnauthorizedException(); Repeat stage 1 and note that the function fails with a "Not authorized" message. Tom will be in the list again, because the DB is reset when lesson restarts. Adding the access check in the RoleBasedAccessControl:handleRequest() is putting the check in the “Controller” The access check can also be added to DeleteProfile.deleteEmployeeProfile(), which is putting the check in the “Business Function” */ public class RoleBasedAccessControl_i extends RoleBasedAccessControl { public void handleRequest(WebSession s) { //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) { // Missing the action - send them back to login. requestedActionName = LOGIN_ACTION; } try { LessonAction action = getAction(requestedActionName); if (action != null) { // FIXME: This code has gotten much uglier //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); // STAGE 2 - FIX // action.getActionName() returns the user requested function which // is tied to the button click from the listStaff jsp // // Checking isAuthorized() for the requested action if (action.isAuthorized(s, userId, action.getActionName())) // STAGE 2 - FIX { // Calling the handleRequest() method for the requested action action.handleRequest(s); } else throw new UnauthorizedException(); // STAGE 2 - FIX } else throw new UnauthenticatedException(); } } else setCurrentAction(s, ERROR_ACTION); } catch (ParameterNotFoundException pnfe) { System.out.println("Missing parameter"); pnfe.printStackTrace(); setCurrentAction(s, ERROR_ACTION); } catch (ValidationException ve) { System.out.println("Validation failed"); ve.printStackTrace(); setCurrentAction(s, ERROR_ACTION); } catch (UnauthenticatedException ue) { s.setMessage("Login failed"); System.out.println("Authentication failure"); ue.printStackTrace(); } catch (UnauthorizedException ue2) { String stage = getStage(s); // Update lesson status if necessary. if (STAGE2.equals(stage)) { try { if (GoatHillsFinancial.DELETEPROFILE_ACTION.equals(requestedActionName) && !isAuthorized(s, getUserId(s), GoatHillsFinancial.DELETEPROFILE_ACTION)) { setStageComplete(s, STAGE2); s.setMessage( "Welcome to stage 3 -- exploiting the data layer" ); } } catch (ParameterNotFoundException pnfe) { pnfe.printStackTrace(); } } //System.out.println("isAuthorized() exit stage: " + getStage(s)); // Update lesson status if necessary. if (STAGE4.equals(stage)) { try { //System.out.println("Checking for stage 4 completion"); DefaultLessonAction action = (DefaultLessonAction) getAction(getCurrentAction(s)); int userId = Integer.parseInt((String)s.getRequest().getSession().getAttribute(getLessonName() + "." + GoatHillsFinancial.USER_ID)); int employeeId = s.getParser().getIntParameter( GoatHillsFinancial.EMPLOYEE_ID); if (!action.isAuthorizedForEmployee(s, userId, employeeId)) { s.setMessage("Congratulations. You have successfully completed this lesson."); setStageComplete(s, STAGE4); } } catch (Exception e) { // swallow this - shouldn't happen inthe normal course // e.printStackTrace(); } } s.setMessage("You are not authorized to perform this function"); System.out.println("Authorization failure"); setCurrentAction(s, ERROR_ACTION); ue2.printStackTrace(); } // All this does for this lesson is ensure that a non-null content exists. setContent(new ElementContainer()); } } \ No newline at end of file