Added some files required to build OWASP release.

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

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

View File

@ -9,12 +9,34 @@ 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.
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @created October 28, 2003
@ -23,204 +45,216 @@ import org.owasp.webgoat.session.WebSession;
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"};
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 )
/**
* 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
{
ElementContainer ec = new ElementContainer();
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());
try
// 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"))
{
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 );
}
makeSuccess(s);
}
catch ( Exception e )
{
s.setMessage( "Error generating " + this.getClass().getName() );
e.printStackTrace();
}
return ( ec );
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
*/
/**
* Gets the category attribute of the RoleBasedAccessControl object
*
* @return The category value
*/
protected Category getDefaultCategory()
protected Category getDefaultCategory()
{
return AbstractLesson.A2;
}
/**
* Gets the hints attribute of the RoleBasedAccessControl object
*
* @return The hints value
*/
protected List getHints()
{
List<String> hints = new ArrayList<String>();
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<String> list = new ArrayList<String>();
if (rl.contains(roles[0]))
{
return AbstractLesson.A2;
list.add(resources[0]);
}
/**
* Gets the hints attribute of the RoleBasedAccessControl object
*
* @return The hints value
*/
protected List getHints()
if (rl.contains(roles[1]))
{
List<String> hints = new ArrayList<String>();
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;
list.add(resources[1]);
list.add(resources[5]);
}
private final static Integer DEFAULT_RANKING = new Integer(120);
protected Integer getDefaultRanking()
if (rl.contains(roles[2]))
{
return DEFAULT_RANKING;
list.add(resources[2]);
list.add(resources[3]);
}
/**
* Gets the resources attribute of the RoleBasedAccessControl object
*
* @param rl Description of the Parameter
* @return The resources value
*/
private List getResources( List rl )
if (rl.contains(roles[3]))
{
// return the resources allowed for these roles
ArrayList<String> list = new ArrayList<String>();
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;
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
*/
/**
* Gets the role attribute of the RoleBasedAccessControl object
*
* @param user Description of the Parameter
* @return The role value
*/
private List getRoles( String user )
private List getRoles(String user)
{
ArrayList<String> list = new ArrayList<String>();
if (user.equals(users[0]))
{
ArrayList<String> list = new ArrayList<String>();
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;
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]);
}
/**
* 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));
return list;
}
/**
* 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
*/
/**
* Gets the title attribute of the AccessControlScreen object
*
* @return The title value
*/
private boolean isAllowed( String user, String resource )
{
List roles = getRoles( user );
List resources = getResources( roles );
return ( resources.contains( resource ) );
}
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));
}
}

View File

@ -22,203 +22,272 @@ import org.apache.ecs.html.Table;
import org.owasp.webgoat.session.DatabaseUtilities;
import org.owasp.webgoat.session.WebSession;
public class BackDoors extends LessonAdapter {
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*/
public class BackDoors extends LessonAdapter
{
private static Connection connection = null;
private final static Integer DEFAULT_RANKING = new Integer(80);
private final static String USERNAME = "username";
private final static String SELECT_ST = "select userid, password, ssn, salary from employee where userid=";
protected Element createContent( WebSession s )
{
return super.createStagedContent(s);
}
protected Element doStage1( WebSession s ) throws Exception
{
return concept1( s );
}
protected Element doStage2( WebSession s ) throws Exception
{
return concept2( s);
}
private static Connection connection = null;
private final static Integer DEFAULT_RANKING = new Integer(80);
private final static String USERNAME = "username";
private final static String SELECT_ST = "select userid, password, ssn, salary from employee where userid=";
protected Element concept1( WebSession s) throws Exception
protected Element createContent(WebSession s)
{
return super.createStagedContent(s);
}
protected Element doStage1(WebSession s) throws Exception
{
return concept1(s);
}
protected Element doStage2(WebSession s) throws Exception
{
return concept2(s);
}
protected Element concept1(WebSession s) throws Exception
{
ElementContainer ec = new ElementContainer();
ec.addElement(makeUsername(s));
try
{
ElementContainer ec = new ElementContainer();
ec.addElement( makeUsername(s));
try
String userInput = s.getParser().getRawParameter(USERNAME, "");
if (!userInput.equals(""))
{
userInput = SELECT_ST + userInput;
String[] arrSQL = userInput.split(";");
Connection conn = getConnection(s);
Statement statement = conn.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
if (arrSQL.length == 2)
{
String userInput = s.getParser().getRawParameter(USERNAME, "");
if (!userInput.equals(""))
{
userInput = SELECT_ST + userInput;
String[] arrSQL = userInput.split(";");
Connection conn = getConnection(s);
Statement statement = conn.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY );
if (arrSQL.length == 2)
{
statement.executeUpdate( arrSQL[1] );
getLessonTracker(s).setStage(2);
s.setMessage("You have succeeded in exploiting the vulnerable query and created another SQL statement. Now move to stage 2 to learn how to create a backdoor or a DB worm");
}
ResultSet rs = statement.executeQuery( arrSQL[0]);
if (rs.next())
{
Table t = new Table( 0 ).setCellSpacing( 0 ).setCellPadding( 0 ).setBorder( 1 );
TR tr = new TR();
tr.addElement( new TD("User ID"));
tr.addElement( new TD("Password"));
tr.addElement( new TD("SSN"));
tr.addElement( new TD("Salary"));
t.addElement(tr);
tr = new TR();
tr.addElement( new TD(rs.getString("userid")));
tr.addElement( new TD(rs.getString("password")));
tr.addElement( new TD(rs.getString("ssn")));
tr.addElement( new TD(rs.getString("salary")));
t.addElement(tr);
ec.addElement(t);
}
}
statement.executeUpdate(arrSQL[1]);
getLessonTracker(s).setStage(2);
s
.setMessage("You have succeeded in exploiting the vulnerable query and created another SQL statement. Now move to stage 2 to learn how to create a backdoor or a DB worm");
}
catch(Exception ex)
ResultSet rs = statement.executeQuery(arrSQL[0]);
if (rs.next())
{
ec.addElement( new PRE(ex.getMessage()) );
Table t = new Table(0).setCellSpacing(0).setCellPadding(0)
.setBorder(1);
TR tr = new TR();
tr.addElement(new TD("User ID"));
tr.addElement(new TD("Password"));
tr.addElement(new TD("SSN"));
tr.addElement(new TD("Salary"));
t.addElement(tr);
tr = new TR();
tr.addElement(new TD(rs.getString("userid")));
tr.addElement(new TD(rs.getString("password")));
tr.addElement(new TD(rs.getString("ssn")));
tr.addElement(new TD(rs.getString("salary")));
t.addElement(tr);
ec.addElement(t);
}
return ec;
}
}
protected Element concept2( WebSession s) throws Exception
catch (Exception ex)
{
ElementContainer ec = new ElementContainer();
ec.addElement(makeUsername(s));
String userInput = s.getParser().getRawParameter(USERNAME, "");
if (!userInput.equals(""))
ec.addElement(new PRE(ex.getMessage()));
}
return ec;
}
protected Element concept2(WebSession s) throws Exception
{
ElementContainer ec = new ElementContainer();
ec.addElement(makeUsername(s));
String userInput = s.getParser().getRawParameter(USERNAME, "");
if (!userInput.equals(""))
{
String[] arrSQL = userInput.split(";");
if (arrSQL.length == 2)
{
if (userInput.toUpperCase().indexOf("CREATE TRIGGER") != 0)
{
String[] arrSQL = userInput.split(";");
if (arrSQL.length == 2)
{
if ( userInput.toUpperCase().indexOf("CREATE TRIGGER") != 0)
{
makeSuccess(s);
}
}
makeSuccess(s);
}
return ec;
}
}
public String getInstructions(WebSession s)
}
return ec;
}
public String getInstructions(WebSession s)
{
String instructions = "";
if (!getLessonTracker(s).getCompleted())
{
String instructions = "";
if (!getLessonTracker(s).getCompleted())
{
switch (getStage(s))
{
case 1:
instructions = "Stage " + getStage(s) + ": Use String SQL Injection to execute more than one SQL Statement. ";
instructions = instructions + " The first stage of this lesson is to teach you how to use a vulnerable field to create two SQL ";
instructions = instructions + " statements. The first is the system's while the second is totally yours.";
instructions = instructions + " Your account ID is 101. This page allows you to see your password, ssn and salary.";
instructions = instructions + " Try to inject another update to update salary to something higher";
break;
case 2:
instructions = "Stage " + getStage(s) + ": Use String SQL Injection to inject a backdoor. " ;
instructions = instructions + " The second stage of this lesson is to teach you how to use a vulneable fields to inject the DB work or the backdoor." ;
instructions = instructions + " Now try to use the same technique to inject a trigger that would act as " ;
instructions = instructions + " SQL backdoor, the syntax of a trigger is: <br>";
instructions = instructions + " CREATE TRIGGER myBackDoor BEFORE INSERT ON employee FOR EACH ROW BEGIN UPDATE employee SET email='john@hackme.com'WHERE userid = NEW.userid<br>";
instructions = instructions + " Note that nothing will actually be executed because the current underlying DB doesn't support triggers.";
break;
}
}
return instructions;
switch (getStage(s))
{
case 1:
instructions = "Stage "
+ getStage(s)
+ ": Use String SQL Injection to execute more than one SQL Statement. ";
instructions = instructions
+ " The first stage of this lesson is to teach you how to use a vulnerable field to create two SQL ";
instructions = instructions
+ " statements. The first is the system's while the second is totally yours.";
instructions = instructions
+ " Your account ID is 101. This page allows you to see your password, ssn and salary.";
instructions = instructions
+ " Try to inject another update to update salary to something higher";
break;
case 2:
instructions = "Stage "
+ getStage(s)
+ ": Use String SQL Injection to inject a backdoor. ";
instructions = instructions
+ " The second stage of this lesson is to teach you how to use a vulneable fields to inject the DB work or the backdoor.";
instructions = instructions
+ " Now try to use the same technique to inject a trigger that would act as ";
instructions = instructions
+ " SQL backdoor, the syntax of a trigger is: <br>";
instructions = instructions
+ " CREATE TRIGGER myBackDoor BEFORE INSERT ON employee FOR EACH ROW BEGIN UPDATE employee SET email='john@hackme.com'WHERE userid = NEW.userid<br>";
instructions = instructions
+ " Note that nothing will actually be executed because the current underlying DB doesn't support triggers.";
break;
}
}
protected Element makeUsername(WebSession s)
return instructions;
}
protected Element makeUsername(WebSession s)
{
ElementContainer ec = new ElementContainer();
StringBuffer script = new StringBuffer();
script.append("<STYLE TYPE=\"text/css\"> ");
script.append(".blocklabel { margin-top: 8pt; }");
script.append(".myClass { color:red;");
script.append(" font-weight: bold;");
script.append("padding-left: 1px;");
script.append("padding-right: 1px;");
script.append("background: #DDDDDD;");
script.append("border: thin black solid; }");
script.append("LI { margin-top: 10pt; }");
script.append("</STYLE>");
ec.addElement(new StringElement(script.toString()));
ec.addElement(new StringElement("User ID: "));
Input username = new Input(Input.TEXT, "username", "");
ec.addElement(username);
String userInput = s.getParser().getRawParameter("username", "");
ec.addElement(new BR());
ec.addElement(new BR());
String formattedInput = "<span class='myClass'>" + userInput
+ "</span>";
ec.addElement(new Div(SELECT_ST + formattedInput));
Input b = new Input();
b.setName("Submit");
b.setType(Input.SUBMIT);
b.setValue("Submit");
ec.addElement(new PRE(b));
return ec;
}
public static synchronized Connection getConnection(WebSession s)
throws SQLException, ClassNotFoundException
{
if (connection == null)
{
ElementContainer ec = new ElementContainer();
StringBuffer script = new StringBuffer();
script.append( "<STYLE TYPE=\"text/css\"> " );
script.append( ".blocklabel { margin-top: 8pt; }" );
script.append( ".myClass { color:red;" );
script.append( " font-weight: bold;" );
script.append( "padding-left: 1px;" );
script.append( "padding-right: 1px;" );
script.append( "background: #DDDDDD;" );
script.append( "border: thin black solid; }" );
script.append( "LI { margin-top: 10pt; }" );
script.append( "</STYLE>" );
ec.addElement( new StringElement(script.toString()));
ec.addElement( new StringElement( "User ID: " ) ) ;
Input username = new Input( Input.TEXT, "username", "" );
ec.addElement( username );
String userInput = s.getParser().getRawParameter("username" , "");
ec.addElement(new BR());
ec.addElement(new BR());
String formattedInput = "<span class='myClass'>" + userInput + "</span>";
ec.addElement( new Div(SELECT_ST + formattedInput ));
Input b = new Input();
b.setName("Submit");
b.setType(Input.SUBMIT);
b.setValue("Submit");
ec.addElement(new PRE( b ) );
return ec;
connection = DatabaseUtilities.makeConnection(s);
}
public static synchronized Connection getConnection(WebSession s)
throws SQLException, ClassNotFoundException
{
if ( connection == null )
{
connection = DatabaseUtilities.makeConnection( s );
}
return connection;
}
public Element getCredits() {
return new StringElement("Created by Sherif Koussa");
}
return connection;
}
protected List getHints() {
List<String> hints = new ArrayList<String>();
hints.add( "Your user id is 101. Use it to see your information" );
hints.add( "A semi-colon usually ends a SQL statement and starts a new one." );
hints.add( "Try this 101; update employee set salary=100000" );
hints.add( "For stage 2, Try 101; CREATE TRIGGER myBackDoor BEFORE INSERT ON customers FOR EACH ROW BEGIN UPDATE customers SET email='john@hackme.com'WHERE userid = NEW.userid");
return hints;
}
protected Category getDefaultCategory()
{
return AbstractLesson.A6;
}
public Element getCredits()
{
return new StringElement("Created by Sherif Koussa");
}
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
public String getTitle()
{
return ( "How to Use Database Backdoors " );
}
protected List getHints()
{
List<String> hints = new ArrayList<String>();
hints.add("Your user id is 101. Use it to see your information");
hints
.add("A semi-colon usually ends a SQL statement and starts a new one.");
hints.add("Try this 101; update employee set salary=100000");
hints
.add("For stage 2, Try 101; CREATE TRIGGER myBackDoor BEFORE INSERT ON customers FOR EACH ROW BEGIN UPDATE customers SET email='john@hackme.com'WHERE userid = NEW.userid");
return hints;
}
protected Category getDefaultCategory()
{
return AbstractLesson.A6;
}
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
public String getTitle()
{
return ("How to Use Database Backdoors ");
}
}

View File

@ -15,11 +15,34 @@ 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.
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003
@ -27,237 +50,284 @@ import org.owasp.webgoat.session.WebSession;
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";
/**
* 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
{
ElementContainer ec = new ElementContainer();
private static final String EMPTY_STRING = "";
String headerName = null;
String headerValue = null;
try
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";
/**
* 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
{
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))
{
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 );
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.");
}
catch ( Exception e )
}
//<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)))
{
s.setMessage( "Error generating " + this.getClass().getName() );
e.printStackTrace();
// 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("&nbsp;&nbsp;- Now you must try to make WebGoat reauthenticate you as: ");
s.setMessage("&nbsp;&nbsp;&nbsp;&nbsp;- username: basic");
s.setMessage("&nbsp;&nbsp;&nbsp;&nbsp;- password: basic");
return ( ec );
}
protected Element doStage2( WebSession s ) throws Exception
{
ElementContainer ec = new ElementContainer();
try
// 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)))
{
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("&nbsp;&nbsp;- Now you must try to make WebGoat reauthenticate you as: ");
s.setMessage("&nbsp;&nbsp;&nbsp;&nbsp;- username: basic");
s.setMessage("&nbsp;&nbsp;&nbsp;&nbsp;- 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>" +
"&nbsp;&nbsp;&nbsp;&nbsp;user name: basic<br> " +
"&nbsp;&nbsp;&nbsp;&nbsp;password: basic<br>");
}
else
{
ec.addElement("Use the hints! One at a time...");
}
}
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.");
}
catch ( Exception e )
else if (!originalSessionId.equals(s.getCookie(JSESSIONID)))
{
s.setMessage( "Error generating " + this.getClass().getName() );
e.printStackTrace();
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>"
+ "&nbsp;&nbsp;&nbsp;&nbsp;user name: basic<br> "
+ "&nbsp;&nbsp;&nbsp;&nbsp;password: basic<br>");
}
else
{
ec.addElement("Use the hints! One at a time...");
}
}
return ( ec );
}
/**
* Gets the category attribute of the ForgotPassword object
*
* @return The category value
*/
protected Category getDefaultCategory()
catch (Exception e)
{
return AbstractLesson.A3;
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
/**
* Gets the hints attribute of the HelloScreen object
*
* @return The hints value
*/
public List getHints()
{
List<String> hints = new ArrayList<String>();
// 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;
}
return (ec);
}
private final static Integer DEFAULT_RANKING = new Integer(100);
/**
* Gets the category attribute of the ForgotPassword object
*
* @return The category value
*/
protected Category getDefaultCategory()
{
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
return AbstractLesson.A3;
}
/**
* Gets the title attribute of the HelloScreen object
*
* @return The title value
*/
public String getTitle()
{
return ( "Basic Authentication" );
}
/**
* Gets the hints attribute of the HelloScreen object
*
* @return The hints value
*/
public List getHints()
{
List<String> hints = new ArrayList<String>();
// 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");
}
}

View File

@ -16,255 +16,332 @@ 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.
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author 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;
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 )
/**
* 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
{
ElementContainer ec = new ElementContainer();
if (connection == null)
{
connection = DatabaseUtilities.makeConnection(s);
}
try
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)))
{
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."));
}
makeSuccess(s);
}
catch ( Exception e )
else
{
s.setMessage( "Error generating " + this.getClass().getName() );
e.printStackTrace();
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"));
}
}
return ( ec );
}
catch (SQLException sqle)
{
ec.addElement(new P()
.addElement("An error occurred, please try again."));
}
}
/**
* Gets the category attribute of the SqlInjection object
*
* @return The category value
*/
protected Category getDefaultCategory()
catch (Exception e)
{
return AbstractLesson.A6;
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
return (ec);
}
/**
* Gets the credits attribute of the AbstractLesson object
*
* @return The credits value
*/
public Element getCredits()
/**
* Gets the category attribute of the SqlInjection object
*
* @return The category value
*/
protected Category getDefaultCategory()
{
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 new StringElement("By Chuck Willis (edited 14 Dec 05 - Hints need to updated for non-Windows systems)");
return true;
}
/**
*
* 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()
else
{
List<String> hints = new ArrayList<String>();
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>&gt and &lt - 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>&gt and &lt - 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;
return false;
}
}
/**
* Gets the instructions attribute of the SqlInjection object
*
* @return The instructions value
*/
public String getInstructions(WebSession s)
/**
* Gets the hints attribute of the DatabaseFieldScreen object
*
* @return The hints value
*/
protected List getHints()
{
List<String> hints = new ArrayList<String>();
if (runningOnWindows())
{
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 );
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>&gt and &lt - 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.");
}
private final static Integer DEFAULT_RANKING = new Integer(70);
protected Integer getDefaultRanking()
else
{
return DEFAULT_RANKING;
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>&gt and &lt - 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 title attribute of the DatabaseFieldScreen object
*
* @return The title value
*/
public String getTitle()
/**
* 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
{
return ( "How to Perform Blind SQL Injection" );
super.handleRequest(s);
if (connection == null)
{
connection = DatabaseUtilities.makeConnection(s);
}
}
/**
* Constructor for the DatabaseFieldScreen object
*
* @param s Description of the Parameter
*/
public void handleRequest( WebSession s )
catch (Exception e)
{
try
{
super.handleRequest( s );
if ( connection == null )
{
connection = DatabaseUtilities.makeConnection( s );
}
}
catch ( Exception e )
{
System.out.println( "Exception caught: " + e );
e.printStackTrace( System.out );
}
System.out.println("Exception caught: " + e);
e.printStackTrace(System.out);
}
}
}

View File

@ -8,11 +8,34 @@ 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.
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003
@ -20,67 +43,68 @@ import org.owasp.webgoat.session.WebSession;
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);
}
/**
* 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()
{
/**
* 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<String> hints = new ArrayList<String>();
hints.add( "Lesson Hint 1" );
hints.add( "Lesson Hint 2" );
return hints;
}
return AbstractLesson.A5;
}
/**
* Gets the hints attribute of the HelloScreen object
*
* @return The hints value
*/
public List getHints()
{
List<String> hints = new ArrayList<String>();
hints.add("Lesson Hint 1");
hints.add("Lesson Hint 2");
private final static Integer DEFAULT_RANKING = new Integer(15);
return hints;
}
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
private final static Integer DEFAULT_RANKING = new Integer(15);
/**
* 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");
}
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");
}
}

View File

@ -24,7 +24,35 @@ import org.owasp.webgoat.session.DatabaseUtilities;
import org.owasp.webgoat.session.ECSFactory;
import org.owasp.webgoat.session.WebSession;
import org.owasp.webgoat.util.HtmlEncoder;
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*/
public class CSRF extends LessonAdapter {
private final static String MESSAGE = "message";

View File

@ -1,60 +1,91 @@
package org.owasp.webgoat.lessons;
/**
* 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.
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003
*/
public class Category implements Comparable
{
private String category;
private Integer ranking;
public Category( String category, Integer ranking )
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)
{
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();
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();
}
}

View File

@ -18,284 +18,352 @@ 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.
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @created October 28, 2003
*/
public class CommandInjection extends LessonAdapter
{
private final static String HELP_FILE = "HelpFile";
private String osName = System.getProperty( "os.name" );
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 )
/**
* 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
{
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)
{
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(';');
}
index = index + 1;
int helpFileLen = helpFile.length() -1; // subtract 1 for the closing quote
System.out.println("Command = [" + helpFile.substring(index, helpFileLen).trim().toLowerCase() + "]");
if (( osName.indexOf( "Windows" ) != -1 &&
( helpFile.substring(index, helpFileLen).trim().toLowerCase().equals("netstat -a") ||
helpFile.substring(index, helpFileLen).trim().toLowerCase().equals("dir") ||
helpFile.substring(index, helpFileLen).trim().toLowerCase().equals("ls") ||
helpFile.substring(index, helpFileLen).trim().toLowerCase().equals("ifconfig") ||
helpFile.substring(index, helpFileLen).trim().toLowerCase().equals("ipconfig") )) ||
(helpFile.substring(index, helpFileLen).trim().toLowerCase().equals("netstat -a #") ||
helpFile.substring(index, helpFileLen).trim().toLowerCase().equals("dir #") ||
helpFile.substring(index, helpFileLen).trim().toLowerCase().equals("ls #") ||
helpFile.substring(index, helpFileLen).trim().toLowerCase().equals("ls -l #") ||
helpFile.substring(index, helpFileLen).trim().toLowerCase().equals("ifconfig #") ||
helpFile.substring(index, helpFileLen).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 ? "&lt;select file from list below&gt;" : 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>")));
}
index = helpFile.indexOf(';');
}
catch ( Exception e )
index = index + 1;
int helpFileLen = helpFile.length() - 1; // subtract 1 for the closing quote
System.out.println("Command = ["
+ helpFile.substring(index, helpFileLen).trim()
.toLowerCase() + "]");
if ((osName.indexOf("Windows") != -1 && (helpFile.substring(
index, helpFileLen).trim().toLowerCase().equals(
"netstat -a")
|| helpFile.substring(index, helpFileLen).trim()
.toLowerCase().equals("dir")
|| helpFile.substring(index, helpFileLen).trim()
.toLowerCase().equals("ls")
|| helpFile.substring(index, helpFileLen).trim()
.toLowerCase().equals("ifconfig") || helpFile
.substring(index, helpFileLen).trim().toLowerCase()
.equals("ipconfig")))
|| (helpFile.substring(index, helpFileLen).trim()
.toLowerCase().equals("netstat -a #")
|| helpFile.substring(index, helpFileLen)
.trim().toLowerCase().equals("dir #")
|| helpFile.substring(index, helpFileLen)
.trim().toLowerCase().equals("ls #")
|| helpFile.substring(index, helpFileLen)
.trim().toLowerCase().equals("ls -l #")
|| helpFile.substring(index, helpFileLen)
.trim().toLowerCase().equals(
"ifconfig #") || helpFile
.substring(index, helpFileLen).trim()
.toLowerCase().equals("ipconfig #")))
{
s.setMessage( "Error generating " + this.getClass().getName() );
e.printStackTrace();
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 ? "&lt;select file from list below&gt;"
: 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);
}
return ( ec );
}
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>")));
private String parseResults( String results )
}
}
catch (Exception e)
{
return results.replaceAll("(?s).*Output...\\s","").replaceAll("(?s)Returncode.*","");
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
public static int upDirCount( String fileName )
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)
{
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;
count++;
startIndex = fileName.indexOf("..", startIndex + 1);
}
/**
* 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 )
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())
{
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() );
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 )
/**
* 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())
{
System.out.println("Executing OS command: " + Arrays.asList(command));
ExecResults er = Exec.execSimple( command );
if ( !er.getError() )
{
makeSuccess( s );
}
return ( er.toString() );
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 )
/**
* 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())
{
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 );
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 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" );
/**
* 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;
}
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.";
/**
* 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 );
}
return (instructions);
}
private final static Integer DEFAULT_RANKING = new Integer(40);
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
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";
}
/**
* Gets the title attribute of the DirectoryScreen object
*
* @return The title value
*/
public String getTitle()
{
return "How to Perform Command Injection";
}
}

View File

@ -25,331 +25,432 @@ 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.
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
*/
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";
public final static String DESCRIPTION = "description";
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);
public final static String DISCIPLINARY_DATE = "disciplinaryDate";
private static Connection connection = null;
public final static String DISCIPLINARY_NOTES = "disciplinaryNotes";
private Map lessonFunctions = new Hashtable();
public static synchronized Connection getConnection(WebSession s)
throws SQLException, ClassNotFoundException
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)
{
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<String> hints = new ArrayList<String>();
// 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: &lt;script language=\"javascript\" type=\"text/javascript\"&gt;alert(\"Ha Ha Ha\");&lt;/script&gt; in message fields.");
hints
.add("Enter this: &lt;script&gtalert(\"document.cookie\");&lt;/script&gt; in message fields.");
// Stage 2
hints
.add("Many scripts rely on the use of special characters such as: &lt;");
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)
{
connection = DatabaseUtilities.makeConnection( s );
if (!action.requiresAuthentication()
|| action.isAuthenticated(s))
{
action.handleRequest(s);
//setCurrentAction(s, action.getNextPage(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<String> hints = new ArrayList<String>();
// 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: &lt;script language=\"javascript\" type=\"text/javascript\"&gt;alert(\"Ha Ha Ha\");&lt;/script&gt; in message fields." );
hints.add( "Enter this: &lt;script&gtalert(\"document.cookie\");&lt;/script&gt; in message fields." );
// Stage 2
hints.add( "Many scripts rely on the use of special characters such as: &lt;" );
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())
else
{
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;
}
setCurrentAction(s, ERROR_ACTION);
}
return instructions;
}
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);
}
}
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;
}
// All this does for this lesson is ensure that a non-null content exists.
setContent(new ElementContainer());
}
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;
}
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)";
}
/**
* 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();
// 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();
}
}

View File

@ -12,146 +12,184 @@ import org.owasp.webgoat.session.UnauthenticatedException;
import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*/
public class EditProfile extends DefaultLessonAction
{
public EditProfile(AbstractLesson lesson, String lessonName, String actionName)
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))
{
super(lesson, lessonName, actionName);
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();
}
public void handleRequest( WebSession s )
throws ParameterNotFoundException, UnauthenticatedException, UnauthorizedException
{
getLesson().setCurrentAction(s, getActionName());
return profile;
}
if (isAuthenticated(s))
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())
{
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();
// 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();
}
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;
}
return profile;
}
}

View File

@ -18,192 +18,242 @@ import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.ValidationException;
import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*/
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
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))
{
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)
{
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();
}
}
setSessionAttribute(s, getLessonName() + "."
+ CrossSiteScripting.SEARCHRESULT_ATTRIBUTE_KEY,
"Employee " + searchName + " not found.");
}
else
throw new UnauthenticatedException();
}
public String getNextPage(WebSession s)
{
String page = CrossSiteScripting.SEARCHSTAFF_ACTION;
}
catch (ValidationException e)
{
if (getStage(s) == 6)
{
s
.setMessage("Congratulations. You have successfully completed this lesson");
getLesson().getLessonTracker(s).setCompleted(true);
}
throw e;
}
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
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
{
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();
}
chainedAction.handleRequest(s);
}
catch ( Exception e )
catch (UnauthenticatedException ue1)
{
s.setMessage( "Error finding employee profile" );
e.printStackTrace();
System.out.println("Internal server error");
ue1.printStackTrace();
}
return profile;
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();
}
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;
}
return profile;
}
protected static Map patterns = new HashMap();
static
private boolean foundEmployee(WebSession s)
{
boolean found = false;
try
{
patterns.put(CrossSiteScripting.SEARCHNAME, Pattern.compile("[a-zA-Z ]{0,20}"));
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}"));
}
}

View File

@ -19,337 +19,398 @@ import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.ValidationException;
import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*/
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
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))
{
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)
{
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();
}
s
.setMessage("Welcome to stage 3 - demonstrate Stored XSS again");
setStage(s, 3);
}
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;
}
throw e;
}
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;
}
if (subjectId > 0)
{
this.changeEmployeeProfile(s, userId, subjectId, employee);
setRequestAttribute(s, getLessonName() + "."
+ CrossSiteScripting.EMPLOYEE_ID, Integer
.toString(subjectId));
}
else
this.createEmployeeProfile(s, userId, 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();
}
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 void createEmployeeProfile(WebSession s, int userId, Employee employee)
throws UnauthorizedException
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
{
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();
}
}
// 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();
}
public void createEmployeeProfile_BACKUP(WebSession s, int userId, Employee employee)
throws UnauthorizedException
}
catch (Exception e)
{
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();
}
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
public void doChangeEmployeeProfile_BACKUP(WebSession s, int userId,
int subjectId, Employee employee) throws UnauthorizedException
{
try
{
Matcher matcher = pattern.matcher(parameter);
if (!matcher.matches())
throw new ValidationException();
return parameter;
// 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;
}
}

View File

@ -13,191 +13,240 @@ import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.ValidationException;
import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*/
public class ViewProfile extends DefaultLessonAction
{
public ViewProfile(AbstractLesson lesson, String lessonName, String actionName)
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))
{
super(lesson, lessonName, actionName);
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();
}
public void handleRequest( WebSession s )
throws ParameterNotFoundException, UnauthenticatedException, UnauthorizedException, ValidationException
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
{
getLesson().setCurrentAction(s, getActionName());
String query = "SELECT * FROM employee WHERE userid = "
+ subjectUserId;
if (isAuthenticated(s))
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())
{
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();
// 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();
}
public String getNextPage(WebSession s)
{
return CrossSiteScripting.VIEWPROFILE_ACTION;
}
return profile;
}
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
private void updateLessonStatus(WebSession s, Employee employee)
{
switch (getStage(s))
{
// 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
case 1:
String address1 = employee.getAddress1().toLowerCase();
if (address1.indexOf("<script>") > -1
&& address1.indexOf("alert") > -1
&& address1.indexOf("</script>") > -1)
{
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();
}
s
.setMessage("Welcome to stage 2 - implement input validation");
setStage(s, 2);
}
catch ( Exception e )
break;
case 3:
String address2 = employee.getAddress1().toLowerCase();
if (address2.indexOf("<script>") > -1
&& address2.indexOf("alert") > -1
&& address2.indexOf("</script>") > -1)
{
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("&lt;") > -1)
{
s.setMessage( "Welcome to stage 5 - demonstrate reflected XSS" );
setStage(s, 5);
}
break;
default:
break;
s
.setMessage("Welcome to stage 4 - implement output encoding");
setStage(s, 4);
}
break;
case 4:
if (employee.getAddress1().toLowerCase().indexOf("&lt;") > -1)
{
s
.setMessage("Welcome to stage 5 - demonstrate reflected XSS");
setStage(s, 5);
}
break;
default:
break;
}
}
}

View File

@ -15,126 +15,177 @@ import org.apache.ecs.html.TR;
import org.apache.ecs.html.Table;
import org.owasp.webgoat.session.WebSession;
public class DOMInjection extends LessonAdapter {
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Sherif Koussa <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2006
*/
private final static Integer DEFAULT_RANKING = new Integer(10);
private final static String KEY = "key";
protected Element createContent(WebSession s) {
String key = "K1JFWP8BSO8HI52LNPQS8F5L01N";
ElementContainer ec = new ElementContainer();
public class DOMInjection extends LessonAdapter
{
try
{
String userKey = s.getParser().getRawParameter(KEY, "");
String fromAJAX = s.getParser().getRawParameter("from" , "");
if (fromAJAX.equalsIgnoreCase("ajax") && userKey.length()!= 0 && userKey.equals(key))
{
s.getResponse().setContentType("text/html");
s.getResponse().setHeader("Cache-Control", "no-cache");
PrintWriter out = new PrintWriter(s.getResponse().getOutputStream());
out.print("document.forms[0].SUBMIT.disabled = false;");
out.flush();
out.close();
return ec;
}
if (s.getRequest().getMethod().equalsIgnoreCase("POST"))
{
makeSuccess(s);
}
}
catch(Exception e)
{
s.setMessage( "Error generating " + this.getClass().getName() );
e.printStackTrace();
}
String lineSep = System.getProperty("line.separator");
String script = "<script>" + lineSep +
"function validate() {" + lineSep +
"var keyField = document.getElementById('key');" + lineSep +
"var url = '/WebGoat/attack?Screen=" + String.valueOf(getScreenId()) +
"&menu=" + getDefaultCategory().getRanking().toString() +
"&from=ajax&key=' + encodeURIComponent(keyField.value);" + lineSep +
"if (typeof XMLHttpRequest != 'undefined') {" + lineSep +
"req = new XMLHttpRequest();" + lineSep +
"} else if (window.ActiveXObject) {" + lineSep +
"req = new ActiveXObject('Microsoft.XMLHTTP');" + lineSep +
" }" + lineSep +
" req.open('GET', url, true);" + lineSep +
" req.onreadystatechange = callback;" + lineSep +
" req.send(null);" + lineSep +
"}" + lineSep +
"function callback() {" + lineSep +
" if (req.readyState == 4) { " + lineSep +
" if (req.status == 200) { " + lineSep +
" var message = req.responseText;" + lineSep +
" eval(message);" + lineSep +
" }}}" + lineSep +
"</script>" + lineSep;
ec.addElement( new StringElement(script));
ec.addElement( new BR().addElement (new H1().addElement( "Welcome to WebGoat Registration Page:")));
ec.addElement( new BR().addElement ("Please enter the license key that was emailed to you to start using the application."));
ec.addElement( new BR());
ec.addElement( new BR());
Table t1 = new Table().setCellSpacing(0).setCellPadding(0).setBorder(0).setWidth("70%").setAlign("center");
TR tr = new TR();
tr.addElement( new TD( new StringElement( "License Key: " ) ));
Input input1 = new Input( Input.TEXT, KEY , "" );
input1.addAttribute("onkeyup", "validate();");
tr.addElement( new TD( input1 ) );
t1.addElement( tr );
private final static Integer DEFAULT_RANKING = new Integer(10);
tr = new TR();
tr.addElement( new TD( "&nbsp;" ).setColSpan(2));
t1.addElement( tr );
tr = new TR();
Input b = new Input();
b.setType( Input.SUBMIT );
b.setValue( "Activate!" );
b.setName("SUBMIT");
b.setDisabled(true);
tr.addElement(new TD( "&nbsp;" ));
tr.addElement( new TD( b ) );
t1.addElement(tr);
ec.addElement( t1 );
return ec ;
private final static String KEY = "key";
protected Element createContent(WebSession s)
{
String key = "K1JFWP8BSO8HI52LNPQS8F5L01N";
ElementContainer ec = new ElementContainer();
try
{
String userKey = s.getParser().getRawParameter(KEY, "");
String fromAJAX = s.getParser().getRawParameter("from", "");
if (fromAJAX.equalsIgnoreCase("ajax") && userKey.length() != 0
&& userKey.equals(key))
{
s.getResponse().setContentType("text/html");
s.getResponse().setHeader("Cache-Control", "no-cache");
PrintWriter out = new PrintWriter(s.getResponse()
.getOutputStream());
out.print("document.forms[0].SUBMIT.disabled = false;");
out.flush();
out.close();
return ec;
}
if (s.getRequest().getMethod().equalsIgnoreCase("POST"))
{
makeSuccess(s);
}
}
catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
public Element getCredits() {
return new StringElement("Created by Sherif Koussa");
}
String lineSep = System.getProperty("line.separator");
String script = "<script>" + lineSep + "function validate() {"
+ lineSep + "var keyField = document.getElementById('key');"
+ lineSep + "var url = '/WebGoat/attack?Screen="
+ String.valueOf(getScreenId()) + "&menu="
+ getDefaultCategory().getRanking().toString()
+ "&from=ajax&key=' + encodeURIComponent(keyField.value);"
+ lineSep + "if (typeof XMLHttpRequest != 'undefined') {"
+ lineSep + "req = new XMLHttpRequest();" + lineSep
+ "} else if (window.ActiveXObject) {" + lineSep
+ "req = new ActiveXObject('Microsoft.XMLHTTP');" + lineSep
+ " }" + lineSep + " req.open('GET', url, true);" + lineSep
+ " req.onreadystatechange = callback;" + lineSep
+ " req.send(null);" + lineSep + "}" + lineSep
+ "function callback() {" + lineSep
+ " if (req.readyState == 4) { " + lineSep
+ " if (req.status == 200) { " + lineSep
+ " var message = req.responseText;" + lineSep
+ " eval(message);" + lineSep + " }}}" + lineSep
+ "</script>" + lineSep;
protected Category getDefaultCategory() {
return AJAX_SECURITY;
}
ec.addElement(new StringElement(script));
ec.addElement(new BR().addElement(new H1()
.addElement("Welcome to WebGoat Registration Page:")));
ec
.addElement(new BR()
.addElement("Please enter the license key that was emailed to you to start using the application."));
ec.addElement(new BR());
ec.addElement(new BR());
Table t1 = new Table().setCellSpacing(0).setCellPadding(0).setBorder(0)
.setWidth("70%").setAlign("center");
protected Integer getDefaultRanking() {
return DEFAULT_RANKING;
}
TR tr = new TR();
tr.addElement(new TD(new StringElement("License Key: ")));
protected List getHints() {
List<String> hints = new ArrayList<String>();
hints.add( "This page is using XMLHTTP to comunicate with the server." );
hints.add( "Try to find a way to inject the DOM to enable the Activate button." );
hints.add( "Intercept the reply and replace the body withx document.forms[0].SUBMIT.disabled = false;" );
return hints;
}
Input input1 = new Input(Input.TEXT, KEY, "");
input1.addAttribute("onkeyup", "validate();");
tr.addElement(new TD(input1));
t1.addElement(tr);
public String getTitle() {
return "DOM Injection";
}
tr = new TR();
tr.addElement(new TD("&nbsp;").setColSpan(2));
t1.addElement(tr);
tr = new TR();
Input b = new Input();
b.setType(Input.SUBMIT);
b.setValue("Activate!");
b.setName("SUBMIT");
b.setDisabled(true);
tr.addElement(new TD("&nbsp;"));
tr.addElement(new TD(b));
t1.addElement(tr);
ec.addElement(t1);
return ec;
}
public Element getCredits()
{
return new StringElement("Created by Sherif Koussa");
}
protected Category getDefaultCategory()
{
return AJAX_SECURITY;
}
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
protected List getHints()
{
List<String> hints = new ArrayList<String>();
hints.add("This page is using XMLHTTP to comunicate with the server.");
hints
.add("Try to find a way to inject the DOM to enable the Activate button.");
hints
.add("Intercept the reply and replace the body withx document.forms[0].SUBMIT.disabled = false;");
return hints;
}
public String getTitle()
{
return "DOM Injection";
}
}

View File

@ -23,206 +23,246 @@ 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.
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @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 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 )
/**
* 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
{
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))
{
String username = "";
String password = "";
username = s.getParser().getRawParameter( USERNAME );
password = s.getParser().getRawParameter( PASSWORD );
ResultSetMetaData resultsMetaData = results.getMetaData();
ec.addElement(DatabaseUtilities.writeTable(results,
resultsMetaData));
results.last();
// don;t allow user name from other lessons. it would be too simple.
if ( username.equals( "jeff" ) || username.equals( "dave" ) )
// 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))
{
ec.addElement( new H2( "Login Failed: 'jeff' and 'dave' are not valid for this lesson" ));
return ( ec.addElement( makeLogin( s ) ) );
String insertData1 = "INSERT INTO user_login VALUES ( '"
+ username
+ "', '"
+ s.getUserName()
+ "' )";
statement.executeUpdate(insertData1);
}
// Check if the login is valid
if ( connection == null )
// 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)
{
connection = DatabaseUtilities.makeConnection( s );
makeSuccess(s);
String deleteData1 = "DELETE from user_login WHERE webgoat_user = '"
+ s.getUserName() + "'";
statement.executeUpdate(deleteData1);
return (new H1("Congratulations! Lesson Completed"));
}
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();
}
ec.addElement(new H2(
"Login Succeeded: Total login count: "
+ results.getRow()));
}
}
catch ( Exception e )
else
{
s.setMessage( "Error generating " + this.getClass().getName() );
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()));
}
return ( ec.addElement( makeLogin( s ) ) );
}
catch (SQLException sqle)
{
ec.addElement(new P().addElement(sqle.getMessage()));
sqle.printStackTrace();
}
}
/**
* Gets the category attribute of the WeakAuthenticationCookie object
*
* @return The category value
*/
protected Category getDefaultCategory()
catch (Exception e)
{
return AbstractLesson.A9;
s.setMessage("Error generating " + this.getClass().getName());
}
return (ec.addElement(makeLogin(s)));
}
/**
* Gets the hints attribute of the CookieScreen object
*
* @return The hints value
*/
protected List getHints()
/**
* 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 &quot;dont_care' or '1' = '1&quot; 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())
{
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 &quot;dont_care' or '1' = '1&quot; in the password field");
return hints;
t.setBorder(1);
}
private final static Integer DEFAULT_RANKING = new Integer(90);
TR row1 = new TR();
TR row2 = new TR();
row1.addElement(new TD(new StringElement("User Name: ")));
row2.addElement(new TD(new StringElement("Password: ")));
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
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);
/**
* 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 );
}
Element b = ECSFactory.makeButton("Login");
t.addElement(new TR(new TD(b)));
ec.addElement(t);
return (ec);
}
}

View File

@ -11,7 +11,35 @@ import org.owasp.webgoat.session.UnauthenticatedException;
import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.ValidationException;
import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*/
public abstract class DefaultLessonAction implements LessonAction
{
// FIXME: We could parse this class name to get defaults for these fields.

View File

@ -33,11 +33,34 @@ 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.
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @created October 28, 2003

View File

@ -6,152 +6,180 @@ 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.
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @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 )
/**
* 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)
{
boolean logout = s.getParser().getBooleanParameter( LOGOUT, false );
s.setMessage("Goodbye!");
s.eatCookies();
if ( logout )
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( "Goodbye!" );
s.eatCookies();
s.setMessage("Invalid username and password entered.");
return ( makeLogin( s ) );
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.");
}
try
{
String username = "";
String password = "";
return (makeLogin(s));
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 ) );
// 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."));
}
}
/**
* Gets the category attribute of the FailOpenAuthentication object
*
* @return The category value
*/
public Category getDefaultCategory()
catch (Exception e)
{
return AbstractLesson.A7;
s.setMessage("Error generating " + this.getClass().getName());
}
/**
* Gets the hints attribute of the AuthenticateScreen object
*
* @return The hints value
*/
protected List getHints()
{
List<String> hints = new ArrayList<String>();
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;
}
return (makeLogin(s));
}
/**
* 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.";
}
/**
* 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<String> hints = new ArrayList<String>();
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;
}
private final static Integer DEFAULT_RANKING = new Integer(20);
/**
* 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.";
}
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" );
}
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");
}
}

View File

@ -6,121 +6,152 @@ 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.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.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.
*
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
* @author Sherif Koussa <a href="http://www.macadamian.com">Macadamian Technologies.</a>
* @created November 02, 2006
*/
public class ForcedBrowsing extends LessonAdapter
{
private final static String SUCCEEDED = "succeeded";
/**
* Description of the Method
*
* @param s Description of the Parameter
* @return Description of the Return Value
*/
protected Element createContent( WebSession s )
private final static String SUCCEEDED = "succeeded";
/**
* 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 success = new String(s.getParser().getStringParameter(SUCCEEDED,
""));
if (success.length() != 0 && success.equals("yes"))
{
ElementContainer ec = new ElementContainer();
String success = new String( s.getParser().getStringParameter( SUCCEEDED, "" ) );
if ( success.length()!= 0 && success.equals("yes") )
{
ec.addElement( new BR().addElement (new H1().addElement( "Welcome to WebGoat Configuration Page")));
ec.addElement( new BR());
Table t1 = new Table().setCellSpacing(0).setCellPadding(0).setBorder(0).setWidth("90%").setAlign("center");
TR tr = new TR();
tr.addElement( new TD( new StringElement( "Set Admin Privileges for: " ) ));
Input input1 = new Input( Input.TEXT, "", "" );
tr.addElement( new TD( input1 ) );
t1.addElement( tr );
tr = new TR();
tr.addElement( new TD( new StringElement ( "Set Admin Password:" )));
input1 = new Input( Input.PASSWORD, "", "");
tr.addElement( new TD(input1));
t1.addElement( tr );
Element b = ECSFactory.makeButton( "Submit" );
t1.addElement( new TR( new TD( b ).setColSpan(2).setAlign("right") ) );
ec.addElement(t1);
makeSuccess( s );
}
else
{
ec.addElement( "Can you try to force browse to the config page which "
+ "should only be accessed by maintenance personnel.");
}
return ec;
ec.addElement(new BR().addElement(new H1()
.addElement("Welcome to WebGoat Configuration Page")));
ec.addElement(new BR());
Table t1 = new Table().setCellSpacing(0).setCellPadding(0)
.setBorder(0).setWidth("90%").setAlign("center");
TR tr = new TR();
tr.addElement(new TD(
new StringElement("Set Admin Privileges for: ")));
Input input1 = new Input(Input.TEXT, "", "");
tr.addElement(new TD(input1));
t1.addElement(tr);
tr = new TR();
tr.addElement(new TD(new StringElement("Set Admin Password:")));
input1 = new Input(Input.PASSWORD, "", "");
tr.addElement(new TD(input1));
t1.addElement(tr);
Element b = ECSFactory.makeButton("Submit");
t1.addElement(new TR(new TD(b).setColSpan(2).setAlign("right")));
ec.addElement(t1);
makeSuccess(s);
}
/**
* Gets the category attribute of the ForgotPassword object
*
* @return The category value
*/
protected Category getDefaultCategory()
else
{
return AbstractLesson.A10;
ec
.addElement("Can you try to force browse to the config page which "
+ "should only be accessed by maintenance personnel.");
}
return ec;
}
/**
* Gets the hints attribute of the HelloScreen object
*
* @return The hints value
*/
public List getHints()
{
List<String> hints = new ArrayList<String>();
hints.add( "Try to guess the URL for the config page" );
hints.add( "The config page is guessable and hackable" );
hints.add( "Play with the URL and try to guess what the can you replace 'attack' with." );
hints.add( "Try to navigate to http://localhost/WebGoat/config" );
return hints;
}
/**
* Gets the category attribute of the ForgotPassword object
*
* @return The category value
*/
protected Category getDefaultCategory()
{
return AbstractLesson.A10;
}
private final static Integer DEFAULT_RANKING = new Integer(15);
/**
* Gets the hints attribute of the HelloScreen object
*
* @return The hints value
*/
public List getHints()
{
List<String> hints = new ArrayList<String>();
hints.add("Try to guess the URL for the config page");
hints.add("The config page is guessable and hackable");
hints
.add("Play with the URL and try to guess what the can you replace 'attack' with.");
hints.add("Try to navigate to http://localhost/WebGoat/config");
return hints;
}
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("Created by Sherif Koussa");
}
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("Created by Sherif Koussa");
}
}

View File

@ -20,287 +20,340 @@ 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.
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author 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()
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())
{
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("&nbsp;").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("&nbsp;").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;
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);
/**
* Gets the category attribute of the ForgotPassword object
*
* @return The category value
*/
protected Category getDefaultCategory()
tr = new TR();
tr.addElement(new TD().addElement("*Required Fields").setWidth("30%"));
t.addElement(tr);
tr = new TR();
tr.addElement(new TD().addElement("&nbsp;").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())
{
return AbstractLesson.A3;
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);
/**
* Gets the hints attribute of the HelloScreen object
*
* @return The hints value
*/
public List getHints()
tr = new TR();
tr.addElement(new TD().addElement("*Required Fields").setWidth("20%"));
t.addElement(tr);
tr = new TR();
tr.addElement(new TD().addElement("&nbsp;").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())
{
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;
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);
private final static Integer DEFAULT_RANKING = new Integer(15);
tr = new TR();
tr.addElement(new TD().addElement(new StringElement("Color: "
+ COLOR_RESPONSE)));
t.addElement(tr);
protected Integer getDefaultRanking()
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"))
{
return DEFAULT_RANKING;
makeSuccess(s);
}
/**
* Gets the title attribute of the HelloScreen object
*
* @return The title value
*/
public String getTitle()
else if (!USERNAME_RESPONSE.equals("webgoat")
&& USERS.containsKey(USERNAME_RESPONSE))
{
return ( "Forgot Password" );
s
.setMessage("Close. Now try to get the password of a privileged account.");
}
public Element getCredits()
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)
{
return super.getCustomCredits("The Intern", ASPECT_LOGO);
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);
}
}

View File

@ -18,175 +18,213 @@ 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.
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @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";
private final static String PRICE = "Price";
/**
* Constructor for the HiddenFieldScreen object
*/
public HiddenFieldTampering() { }
private final static String PRICE_TV = "2999.99";
/**
* Description of the Method
*
* @param s Description of the Parameter
* @return Description of the Return Value
*/
protected Element createContent( WebSession s )
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
{
ElementContainer ec = new ElementContainer();
String price = s.getParser().getRawParameter(PRICE, PRICE_TV);
float quantity = s.getParser().getFloatParameter("QTY", 1.0f);
float total = quantity * Float.parseFloat(price);
try
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())
{
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();
t.setBorder(1);
}
return ( ec );
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."));
}
}
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
protected Category getDefaultCategory()
catch (Exception e)
{
return AbstractLesson.A1;
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
/**
* Gets the hints attribute of the HiddenFieldScreen object
*
* @return The hints value
*/
protected List getHints()
{
List<String> hints = new ArrayList<String>();
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;
}
return (ec);
}
/**
* 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 );
}
/**
* 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<String> hints = new ArrayList<String>();
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;
}
private final static Integer DEFAULT_RANKING = new Integer(50);
/**
* 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.";
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
return (instructions);
}
/**
* Gets the title attribute of the HiddenFieldScreen object
*
* @return The title value
*/
public String getTitle()
{
return ( "How to Exploit Hidden Fields" );
}
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");
}
}

View File

@ -19,199 +19,234 @@ 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.
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @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 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
* @return Description of the Return Value
*/
protected Element createContent( WebSession s )
/**
* 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())
{
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 );
t.setBorder(1);
}
/**
* 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 ) );
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);
return ( ec );
}
tr = new TR();
tr.addElement(new TD().addElement("*Required Fields").setWidth("30%"));
t.addElement(tr);
tr = new TR();
tr.addElement(new TD().addElement("&nbsp;").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);
}
protected Element makeLogin( WebSession s )
{
ElementContainer ec = new ElementContainer();
/**
* Gets the hints attribute of the CluesScreen object
*
* @return The hints value
*/
protected List getHints()
{
List<String> hints = new ArrayList<String>();
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.");
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("&nbsp;").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<String> hints = new ArrayList<String>();
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;
}
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.";
/**
* 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 );
}
return (instructions);
}
private final static Integer DEFAULT_RANKING = new Integer(30);
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
private final static Integer DEFAULT_RANKING = new Integer(30);
/**
* Gets the category attribute of the FailOpenAuthentication object
*
* @return The category value
*/
protected Category getDefaultCategory()
{
return AbstractLesson.CODE_QUALITY;
}
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" );
}
/**
* Gets the title attribute of the CluesScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("How to Discover Clues in the HTML");
}
}

View File

@ -9,100 +9,127 @@ 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.
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @created October 28, 2003
*/
public class HttpBasics extends LessonAdapter
{
private final static String PERSON = "person";
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 )
/**
* 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
{
ElementContainer ec = new ElementContainer();
ec.addElement(new StringElement("Enter your name: "));
StringBuffer person = null;
try
{
ec.addElement( new StringElement( "Enter your name: " ) );
person = new StringBuffer(s.getParser().getStringParameter(PERSON,
""));
person.reverse();
person = new StringBuffer( s.getParser().getStringParameter( PERSON, "" ) );
person.reverse();
Input input = new Input(Input.TEXT, PERSON, person.toString());
ec.addElement(input);
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 );
Element b = ECSFactory.makeButton("Go!");
ec.addElement(b);
}
catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
/**
* Gets the hints attribute of the HelloScreen object
*
* @return The hints value
*/
public List getHints()
if (!person.toString().equals("")
&& getLessonTracker(s).getNumVisits() > 3)
{
List<String> hints = new ArrayList<String>();
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;
makeSuccess(s);
}
/**
* 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;
}
return (ec);
}
/**
* Gets the title attribute of the HelloScreen object
*
* @return The title value
*/
public String getTitle()
{
return ( "Http Basics" );
}
/**
* Gets the hints attribute of the HelloScreen object
*
* @return The hints value
*/
public List getHints()
{
List<String> hints = new ArrayList<String>();
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");
}
}

View File

@ -18,7 +18,35 @@ import org.apache.ecs.html.Table;
import org.owasp.webgoat.session.WebSession;
import sun.misc.BASE64Encoder;
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*/
public class HttpOnly extends LessonAdapter {
private final static Integer DEFAULT_RANKING = new Integer(125);

View File

@ -1,4 +1,5 @@
package org.owasp.webgoat.lessons;
import java.io.PrintWriter;
import java.net.URLDecoder;
import java.text.DateFormat;
@ -12,224 +13,283 @@ import org.apache.ecs.html.*;
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 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 part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author sherif@macadamian.com
* @created September 30, 2006
*/
public class HttpSplitting extends LessonAdapter {
private final static String LANGUAGE = "language";
private final static String REDIRECT = "fromRedirect";
private static String STAGE = "stage";
/**
* Description of the Method
*
* @param s Current WebSession
*/
public void handleRequest( WebSession s )
{
//Setting a special action to be able to submit to redirect.jsp
Form form = new Form( "/WebGoat/lessons/General/redirect.jsp?" +
"Screen=" + String.valueOf(getScreenId()) +
"&menu=" + getDefaultCategory().getRanking().toString()
, Form.POST ).setName( "form" ).setEncType( "" );
public class HttpSplitting extends LessonAdapter
{
form.addElement( createContent( s ) );
private final static String LANGUAGE = "language";
setContent(form);
}
protected Element doHTTPSplitting(WebSession s)
private final static String REDIRECT = "fromRedirect";
private static String STAGE = "stage";
/**
* Description of the Method
*
* @param s Current WebSession
*/
public void handleRequest(WebSession s)
{
//Setting a special action to be able to submit to redirect.jsp
Form form = new Form("/WebGoat/lessons/General/redirect.jsp?"
+ "Screen=" + String.valueOf(getScreenId()) + "&menu="
+ getDefaultCategory().getRanking().toString(), Form.POST)
.setName("form").setEncType("");
form.addElement(createContent(s));
setContent(form);
}
protected Element doHTTPSplitting(WebSession s)
{
ElementContainer ec = new ElementContainer();
String lang = null;
try
{
ElementContainer ec = new ElementContainer();
String lang = null;
try
ec.addElement(createAttackEnvironment(s));
lang = URLDecoder.decode(s.getParser()
.getRawParameter(LANGUAGE, ""), "UTF-8");
//Check if we are coming from the redirect page
String fromRedirect = s.getParser().getStringParameter(
"fromRedirect", "");
if (lang.length() != 0 && fromRedirect.length() != 0)
{
//Split by the line separator line.separator is platform independant
String lineSep = System.getProperty("line.separator");
String[] arrTokens = lang.toString().toUpperCase().split(
lineSep);
//Check if the user ended the first request and wrote the second malacious reply
if (Arrays.binarySearch(arrTokens, "CONTENT-LENGTH: 0") >= 0
&& Arrays.binarySearch(arrTokens, "HTTP/1.1 200 OK") >= 0)
{
ec.addElement(createAttackEnvironment(s));
lang = URLDecoder.decode(s.getParser().getRawParameter( LANGUAGE, "" ), "UTF-8") ;
//Check if we are coming from the redirect page
String fromRedirect = s.getParser().getStringParameter ( "fromRedirect" , "");
if ( lang.length() != 0 && fromRedirect.length() != 0 )
{
//Split by the line separator line.separator is platform independant
String lineSep = System.getProperty("line.separator");
String[] arrTokens = lang.toString().toUpperCase().split(lineSep);
//Check if the user ended the first request and wrote the second malacious reply
if (Arrays.binarySearch(arrTokens, "CONTENT-LENGTH: 0") >= 0 &&
Arrays.binarySearch(arrTokens, "HTTP/1.1 200 OK") >= 0 )
{
HttpServletResponse res = s.getResponse();
res.setContentType( "text/html" );
PrintWriter out = new PrintWriter( res.getOutputStream() );
String message = lang.substring(lang.indexOf("<html>"));
out.print(message);
out.flush();
out.close();
getLessonTracker(s).setStage(2);
StringBuffer msg = new StringBuffer();
msg.append("Good Job! ");
msg.append("This lesson has detected your successfull attack, ");
msg.append("time to elevate your attack to a higher level. ");
msg.append("Try again and add Last-Modified header, intercept");
msg.append("the reply and replace it with a 304 reply.");
s.setMessage(msg.toString());
}
}
HttpServletResponse res = s.getResponse();
res.setContentType("text/html");
PrintWriter out = new PrintWriter(res.getOutputStream());
String message = lang.substring(lang.indexOf("<html>"));
out.print(message);
out.flush();
out.close();
getLessonTracker(s).setStage(2);
StringBuffer msg = new StringBuffer();
msg.append("Good Job! ");
msg
.append("This lesson has detected your successfull attack, ");
msg
.append("time to elevate your attack to a higher level. ");
msg
.append("Try again and add Last-Modified header, intercept");
msg.append("the reply and replace it with a 304 reply.");
s.setMessage(msg.toString());
}
catch (Exception e)
}
}
catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
return (ec);
}
protected Element createContent(WebSession s)
{
return super.createStagedContent(s);
}
protected Element doStage1(WebSession s) throws Exception
{
return doHTTPSplitting(s);
}
protected Element doStage2(WebSession s) throws Exception
{
return doCachePoisining(s);
}
protected Element createAttackEnvironment(WebSession s) throws Exception
{
ElementContainer ec = new ElementContainer();
String lang = null;
if (getLessonTracker(s).getStage() == 1)
{
ec.addElement(new H3("Stage 1: HTTP Splitting:<br><br>"));
}
else
{
ec.addElement(new H3("Stage 2: Cache Poisoning:<br><br>"));
}
ec.addElement(new StringElement("Search by country : "));
lang = URLDecoder.decode(s.getParser().getRawParameter(LANGUAGE, ""),
"UTF-8");
//add the search by field
Input input = new Input(Input.TEXT, LANGUAGE, lang.toString());
ec.addElement(input);
Element b = ECSFactory.makeButton("Search!");
ec.addElement(b);
return ec;
}
protected Element doCachePoisining(WebSession s) throws Exception
{
ElementContainer ec = new ElementContainer();
try
{
s
.setMessage("Now that you have successfully performed an HTTP Splitting, now try to poison"
+ " the victim's cache. Type 'restart' in the input field if you wish to "
+ " to return to the HTTP Splitting lesson.<br><br>");
if (s.getParser().getRawParameter(LANGUAGE, "YOUR_NAME").equals(
"restart"))
{
getLessonTracker(s).getLessonProperties().setProperty(STAGE,
"1");
return (doHTTPSplitting(s));
}
ec.addElement(createAttackEnvironment(s));
String lang = URLDecoder.decode(s.getParser().getRawParameter(
LANGUAGE, ""), "UTF-8");
String fromRedirect = s.getParser()
.getStringParameter(REDIRECT, "");
if (lang.length() != 0 && fromRedirect.length() != 0)
{
String lineSep = System.getProperty("line.separator");
String dateStr = lang.substring(lang.indexOf("Last-Modified:")
+ "Last-Modified:".length(), lang.indexOf(lineSep, lang
.indexOf("Last-Modified:")));
if (dateStr.length() != 0)
{
s.setMessage( "Error generating " + this.getClass().getName() );
e.printStackTrace();
Calendar cal = Calendar.getInstance();
DateFormat sdf = new SimpleDateFormat(
"EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
if (sdf.parse(dateStr.trim()).after(cal.getTime()))
{
makeSuccess(s);
}
}
return ( ec );
}
}
protected Element createContent(WebSession s)
catch (Exception ex)
{
return super.createStagedContent(s);
ec.addElement(new P().addElement(ex.getMessage()));
}
return ec;
}
protected Element doStage1( WebSession s ) throws Exception
{
return doHTTPSplitting( s );
}
protected Element doStage2( WebSession s ) throws Exception
{
return doCachePoisining( s);
}
protected Element createAttackEnvironment(WebSession s ) throws Exception
{
ElementContainer ec = new ElementContainer();
String lang = null;
if (getLessonTracker(s).getStage() == 1)
{
ec.addElement( new H3( "Stage 1: HTTP Splitting:<br><br>" ) );
}
else
{
ec.addElement( new H3( "Stage 2: Cache Poisoning:<br><br>" ) );
}
ec.addElement( new StringElement( "Search by country : " ) );
protected Category getDefaultCategory()
{
return AbstractLesson.GENERAL;
}
lang = URLDecoder.decode(s.getParser().getRawParameter( LANGUAGE, "" ), "UTF-8") ;
//add the search by field
Input input = new Input( Input.TEXT, LANGUAGE, lang.toString() );
ec.addElement( input );
Element b = ECSFactory.makeButton( "Search!" );
ec.addElement( b );
return ec;
}
protected Element doCachePoisining( WebSession s ) throws Exception
{
ElementContainer ec = new ElementContainer();
try
{
s.setMessage("Now that you have successfully performed an HTTP Splitting, now try to poison" +
" the victim's cache. Type 'restart' in the input field if you wish to " +
" to return to the HTTP Splitting lesson.<br><br>");
if ( s.getParser().getRawParameter( LANGUAGE, "YOUR_NAME" ).equals("restart"))
{
getLessonTracker(s).getLessonProperties().setProperty(STAGE,"1");
return( doHTTPSplitting(s));
}
ec.addElement(createAttackEnvironment(s));
String lang = URLDecoder.decode(s.getParser().getRawParameter( LANGUAGE, "" ), "UTF-8") ;
String fromRedirect = s.getParser().getStringParameter ( REDIRECT , "");
if ( lang.length() != 0 && fromRedirect.length() != 0 )
{
String lineSep = System.getProperty("line.separator");
String dateStr = lang.substring(lang.indexOf("Last-Modified:") + "Last-Modified:".length(),
lang.indexOf(lineSep, lang.indexOf("Last-Modified:") ));
if (dateStr.length() != 0 )
{
Calendar cal = Calendar.getInstance();
DateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
protected List getHints()
{
if (sdf.parse(dateStr.trim()).after(cal.getTime()))
{
makeSuccess(s);
}
}
}
}
catch (Exception ex)
{
ec.addElement( new P().addElement( ex.getMessage() ) );
}
return ec;
}
protected Category getDefaultCategory()
{
return AbstractLesson.GENERAL;
}
List<String> hints = new ArrayList<String>();
hints.add("Enter a language for the system to search by.");
hints.add("Use CR (%0d) and LF (%0a) for a new line");
hints
.add("The Content-Length: 0 will tell the server that the first request is over.");
hints.add("A 200 OK message looks like this: HTTP/1.1 200 OK");
hints
.add("Try: language=?foobar%0d%0aContent-Length:%200%0d%0a%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aContent-Length:%2047%0d%0a%0d%0a&lt;html&gt;Insert undesireable content here&lt;/html&gt;");
hints
.add("Cache Poisoning starts with including 'Last-Modified' header in the hijacked page and setting it to a future date.");
hints
.add("Try language=?foobar%0d%0aContent-Length:%200%0d%0a%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aLast-Modified:%20Mon,%2027%20Oct%202003%2014:50:18%20GMT%0d%0aContent-Length:%2047%0d%0a%0d%0a&lt;html&gt;Insert undesireable content here&lt;/html&gt;");
hints
.add("'Last-Modified' header forces the browser to send a 'If-Modified-Since' header. Some cache servers will take the bait and keep serving the hijacked page");
hints
.add("Try to intercept the reply and add HTTP/1.1 304 Not Modified0d%0aDate:%20Mon,%2027%20Oct%202030%2014:50:18%20GMT");
return hints;
protected List getHints()
{
List<String> hints = new ArrayList<String>();
hints.add( "Enter a language for the system to search by." );
hints.add( "Use CR (%0d) and LF (%0a) for a new line" );
hints.add( "The Content-Length: 0 will tell the server that the first request is over." );
hints.add( "A 200 OK message looks like this: HTTP/1.1 200 OK" );
hints.add( "Try: language=?foobar%0d%0aContent-Length:%200%0d%0a%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aContent-Length:%2047%0d%0a%0d%0a&lt;html&gt;Insert undesireable content here&lt;/html&gt;" );
hints.add( "Cache Poisoning starts with including 'Last-Modified' header in the hijacked page and setting it to a future date." );
hints.add( "Try language=?foobar%0d%0aContent-Length:%200%0d%0a%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aLast-Modified:%20Mon,%2027%20Oct%202003%2014:50:18%20GMT%0d%0aContent-Length:%2047%0d%0a%0d%0a&lt;html&gt;Insert undesireable content here&lt;/html&gt;" );
hints.add( "'Last-Modified' header forces the browser to send a 'If-Modified-Since' header. Some cache servers will take the bait and keep serving the hijacked page");
hints.add( "Try to intercept the reply and add HTTP/1.1 304 Not Modified0d%0aDate:%20Mon,%2027%20Oct%202030%2014:50:18%20GMT");
return hints;
}
}
private final static Integer DEFAULT_RANKING = new Integer(20);
private final static Integer DEFAULT_RANKING = new Integer(20);
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
/**
* Gets the title attribute of the HelloScreen object
*
* @return The title value
*/
public String getTitle()
{
return ( "HTTP Splitting" );
}
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
public Element getCredits() {
return new StringElement("Created by Sherif Koussa");
}
/**
* Gets the title attribute of the HelloScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("HTTP Splitting");
}
public Element getCredits()
{
return new StringElement("Created by Sherif Koussa");
}
}

View File

@ -17,207 +17,295 @@ import java.io.PrintWriter;
import java.util.List;
import java.util.ArrayList;
public class JSONInjection extends LessonAdapter {
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author sherif@macadamian.com
* @created December 25, 2006
*/
private final static Integer DEFAULT_RANKING = new Integer(30);
private final static String TRAVEL_FROM = "travelFrom";
private final static String TRAVEL_TO = "travelTo";
public class JSONInjection extends LessonAdapter
{
/**
* 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 sherif@macadamian.com
* @created December 25, 2006
*/
private final static Integer DEFAULT_RANKING = new Integer(30);
public void handleRequest(WebSession s) {
try
{
if(s.getParser().getRawParameter("from", "").equals("ajax"))
{
String lineSep = System.getProperty("line.separator");
String jsonStr = "{" + lineSep +
"\"From\": \"Boston\"," + lineSep +
"\"To\": \"Seattle\", " + lineSep +
"\"flights\": [" + lineSep +
"{\"stops\": \"0\", \"transit\" : \"N/A\", \"price\": \"600$\"}," + lineSep +
"{\"stops\": \"2\", \"transit\" : \"Newark,Chicago\", \"price\": \"300$\"} " + lineSep +
"]" + lineSep +
"}" ;
s.getResponse().setContentType("text/html");
s.getResponse().setHeader("Cache-Control", "no-cache");
PrintWriter out = new PrintWriter(s.getResponse().getOutputStream());
out.print(jsonStr);
out.flush();
out.close();
return;
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
Form form = new Form( getFormAction(), Form.POST ).setName( "form" ).setEncType( "" );
form.setOnSubmit("check();");
private final static String TRAVEL_FROM = "travelFrom";
form.addElement( createContent( s ) );
private final static String TRAVEL_TO = "travelTo";
setContent(form);
}
/**
* Description of the Method
*
* @param s Current WebSession
*/
protected Element createContent(WebSession s)
public void handleRequest(WebSession s)
{
try
{
ElementContainer ec = new ElementContainer();
if (s.getParser().getRawParameter("from", "").equals("ajax"))
{
String lineSep = System.getProperty("line.separator");
String script = "<script>" + lineSep +
"function getFlights() {" + lineSep +
"var fromField = document.getElementById('" + TRAVEL_FROM + "');" + lineSep +
"if (fromField.value.length < 3 ) { return; }" + lineSep +
"var toField = document.getElementById('" + TRAVEL_TO + "');" + lineSep +
"if (toField.value.length < 3 ) { return; }" + lineSep +
"var url = '/WebGoat/attack?Screen=" + String.valueOf(getScreenId()) +
"&menu=" + getDefaultCategory().getRanking().toString() +
"&from=ajax&" + TRAVEL_FROM + "=' + encodeURIComponent(fromField.value) +" +
"'&" + TRAVEL_TO + "=' + encodeURIComponent(toField.value);" + lineSep +
"if (typeof XMLHttpRequest != 'undefined') {" + lineSep +
"req = new XMLHttpRequest();" + lineSep +
"} else if (window.ActiveXObject) {" + lineSep +
"req = new ActiveXObject('Microsoft.XMLHTTP');" + lineSep +
" }" + lineSep +
" req.open('GET', url, true);" + lineSep +
" req.onreadystatechange = callback;" + lineSep +
" req.send(null);" + lineSep +
"}" + lineSep +
"function callback() {" + lineSep +
" if (req.readyState == 4) { " + lineSep +
" if (req.status == 200) { " + lineSep +
" var card = eval('(' + req.responseText + ')');" + lineSep +
" var flightsDiv = document.getElementById('flightsDiv');" + lineSep +
" flightsDiv.innerHTML = '';" + lineSep +
" var strHTML='';"+ lineSep +
" strHTML = '<tr><td>&nbsp;</td><td>No of Stops</td>';" + lineSep +
" strHTML = strHTML + '<td>Stops</td><td>Prices</td></tr>';" + lineSep +
" for(var i=0; i<card.flights.length; i++){" + lineSep +
" var node = card.flights[i];" + lineSep +
" strHTML = strHTML + '<tr><td><input name=\"radio' + i +'\" type=\"radio\"></td><td>';" + lineSep +
" strHTML = strHTML + card.flights[i].stops + '</td><td>';" + lineSep +
" strHTML = strHTML + card.flights[i].transit + '</td><td>';" + lineSep +
" strHTML = strHTML + '<div name=\"priceID'+i+'\" id=\"priceID'+i+'\">' + card.flights[i].price + '</div></td></tr>';" + lineSep +
" }" + lineSep +
" strHTML = '<table border=\"1\">' + strHTML + '</table>';" + lineSep +
" flightsDiv.innerHTML = strHTML;"+ lineSep +
" }}}" + lineSep +
"function check(){" + lineSep +
" if ( document.getElementById('radio0').checked )" + lineSep +
" { document.getElementById('price2Submit').value = document.getElementById('priceID0').innerText; }" + lineSep +
" else if ( document.getElementById('radio1').checked )" + lineSep +
" { document.getElementById('price2Submit').value = document.getElementById('priceID1').innerText; }" + lineSep +
" else " + lineSep +
" { alert('Please choose one flight'); }" + lineSep +
"}" + lineSep +
"</script>" + lineSep;
ec.addElement( new StringElement(script));
Table t1 = new Table().setCellSpacing(0).setCellPadding(0).setBorder(0).setWidth("90%").setAlign("center");
TR tr = new TR();
tr.addElement( new TD("From: "));
Input in = new Input( Input.TEXT , TRAVEL_FROM ,"" );
in.addAttribute("onkeyup", "getFlights();");
tr.addElement( new TD(in) );
t1.addElement( tr );
tr = new TR();
tr.addElement( new TD("To: "));
in = new Input( Input.TEXT , TRAVEL_TO ,"" );
in.addAttribute("onkeyup", "getFlights();");
tr.addElement( new TD(in) );
t1.addElement( tr );
ec.addElement(t1);
ec.addElement(new BR());
ec.addElement(new BR());
Div div = new Div();
div.addAttribute("name", "flightsDiv");
div.addAttribute("id", "flightsDiv");
ec.addElement(div);
Input b = new Input();
b.setType( Input.SUBMIT );
b.setValue( "Submit" );
b.setName("SUBMIT");
ec.addElement(b);
Input price2Submit = new Input();
price2Submit.setType( Input.HIDDEN);
price2Submit.setName("price2Submit");
ec.addElement( price2Submit );
if (s.getParser().getRawParameter("radio0" , "").equals("on"))
{
String price = s.getParser().getRawParameter("price2Submit" , "");
price = price.replace("$", "");
if (Integer.parseInt(price) < 600)
{
makeSuccess(s);
}
else
{
s.setMessage("You are close, try to set the price for the non-stop flight to be less than 600$");
}
}
return ec;
String jsonStr = "{"
+ lineSep
+ "\"From\": \"Boston\","
+ lineSep
+ "\"To\": \"Seattle\", "
+ lineSep
+ "\"flights\": ["
+ lineSep
+ "{\"stops\": \"0\", \"transit\" : \"N/A\", \"price\": \"600$\"},"
+ lineSep
+ "{\"stops\": \"2\", \"transit\" : \"Newark,Chicago\", \"price\": \"300$\"} "
+ lineSep + "]" + lineSep + "}";
s.getResponse().setContentType("text/html");
s.getResponse().setHeader("Cache-Control", "no-cache");
PrintWriter out = new PrintWriter(s.getResponse()
.getOutputStream());
out.print(jsonStr);
out.flush();
out.close();
return;
}
}
protected Category getDefaultCategory()
catch (Exception ex)
{
return AbstractLesson.AJAX_SECURITY;
ex.printStackTrace();
}
protected List getHints()
{
List<String> hints = new ArrayList<String>();
hints.add( "JSON stands for JavaScript Object Notation." );
hints.add( "JSON is a way of representing data just like XML." );
hints.add( "The JSON payload is easily interceptable." );
hints.add( "Intercept the reply, change the 600$ to 25$." );
return hints;
}
Form form = new Form(getFormAction(), Form.POST).setName("form")
.setEncType("");
form.setOnSubmit("check();");
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
form.addElement(createContent(s));
/**
* Gets the title attribute of the HelloScreen object
*
* @return The title value
*/
public String getTitle()
setContent(form);
}
/**
* Description of the Method
*
* @param s Current WebSession
*/
protected Element createContent(WebSession s)
{
ElementContainer ec = new ElementContainer();
String lineSep = System.getProperty("line.separator");
String script = "<script>"
+ lineSep
+ "function getFlights() {"
+ lineSep
+ "var fromField = document.getElementById('"
+ TRAVEL_FROM
+ "');"
+ lineSep
+ "if (fromField.value.length < 3 ) { return; }"
+ lineSep
+ "var toField = document.getElementById('"
+ TRAVEL_TO
+ "');"
+ lineSep
+ "if (toField.value.length < 3 ) { return; }"
+ lineSep
+ "var url = '/WebGoat/attack?Screen="
+ String.valueOf(getScreenId())
+ "&menu="
+ getDefaultCategory().getRanking().toString()
+ "&from=ajax&"
+ TRAVEL_FROM
+ "=' + encodeURIComponent(fromField.value) +"
+ "'&"
+ TRAVEL_TO
+ "=' + encodeURIComponent(toField.value);"
+ lineSep
+ "if (typeof XMLHttpRequest != 'undefined') {"
+ lineSep
+ "req = new XMLHttpRequest();"
+ lineSep
+ "} else if (window.ActiveXObject) {"
+ lineSep
+ "req = new ActiveXObject('Microsoft.XMLHTTP');"
+ lineSep
+ " }"
+ lineSep
+ " req.open('GET', url, true);"
+ lineSep
+ " req.onreadystatechange = callback;"
+ lineSep
+ " req.send(null);"
+ lineSep
+ "}"
+ lineSep
+ "function callback() {"
+ lineSep
+ " if (req.readyState == 4) { "
+ lineSep
+ " if (req.status == 200) { "
+ lineSep
+ " var card = eval('(' + req.responseText + ')');"
+ lineSep
+ " var flightsDiv = document.getElementById('flightsDiv');"
+ lineSep
+ " flightsDiv.innerHTML = '';"
+ lineSep
+ " var strHTML='';"
+ lineSep
+ " strHTML = '<tr><td>&nbsp;</td><td>No of Stops</td>';"
+ lineSep
+ " strHTML = strHTML + '<td>Stops</td><td>Prices</td></tr>';"
+ lineSep
+ " for(var i=0; i<card.flights.length; i++){"
+ lineSep
+ " var node = card.flights[i];"
+ lineSep
+ " strHTML = strHTML + '<tr><td><input name=\"radio' + i +'\" type=\"radio\"></td><td>';"
+ lineSep
+ " strHTML = strHTML + card.flights[i].stops + '</td><td>';"
+ lineSep
+ " strHTML = strHTML + card.flights[i].transit + '</td><td>';"
+ lineSep
+ " strHTML = strHTML + '<div name=\"priceID'+i+'\" id=\"priceID'+i+'\">' + card.flights[i].price + '</div></td></tr>';"
+ lineSep
+ " }"
+ lineSep
+ " strHTML = '<table border=\"1\">' + strHTML + '</table>';"
+ lineSep
+ " flightsDiv.innerHTML = strHTML;"
+ lineSep
+ " }}}"
+ lineSep
+
"function check(){"
+ lineSep
+ " if ( document.getElementById('radio0').checked )"
+ lineSep
+ " { document.getElementById('price2Submit').value = document.getElementById('priceID0').innerText; }"
+ lineSep
+ " else if ( document.getElementById('radio1').checked )"
+ lineSep
+ " { document.getElementById('price2Submit').value = document.getElementById('priceID1').innerText; }"
+ lineSep + " else " + lineSep
+ " { alert('Please choose one flight'); }" + lineSep + "}"
+ lineSep + "</script>" + lineSep;
ec.addElement(new StringElement(script));
Table t1 = new Table().setCellSpacing(0).setCellPadding(0).setBorder(0)
.setWidth("90%").setAlign("center");
TR tr = new TR();
tr.addElement(new TD("From: "));
Input in = new Input(Input.TEXT, TRAVEL_FROM, "");
in.addAttribute("onkeyup", "getFlights();");
tr.addElement(new TD(in));
t1.addElement(tr);
tr = new TR();
tr.addElement(new TD("To: "));
in = new Input(Input.TEXT, TRAVEL_TO, "");
in.addAttribute("onkeyup", "getFlights();");
tr.addElement(new TD(in));
t1.addElement(tr);
ec.addElement(t1);
ec.addElement(new BR());
ec.addElement(new BR());
Div div = new Div();
div.addAttribute("name", "flightsDiv");
div.addAttribute("id", "flightsDiv");
ec.addElement(div);
Input b = new Input();
b.setType(Input.SUBMIT);
b.setValue("Submit");
b.setName("SUBMIT");
ec.addElement(b);
Input price2Submit = new Input();
price2Submit.setType(Input.HIDDEN);
price2Submit.setName("price2Submit");
ec.addElement(price2Submit);
if (s.getParser().getRawParameter("radio0", "").equals("on"))
{
return ( "JSON Injection" );
String price = s.getParser().getRawParameter("price2Submit", "");
price = price.replace("$", "");
if (Integer.parseInt(price) < 600)
{
makeSuccess(s);
}
else
{
s
.setMessage("You are close, try to set the price for the non-stop flight to be less than 600$");
}
}
return ec;
}
public Element getCredits() {
return new StringElement("Created by Sherif Koussa");
}
protected Category getDefaultCategory()
{
return AbstractLesson.AJAX_SECURITY;
}
protected List getHints()
{
List<String> hints = new ArrayList<String>();
hints.add("JSON stands for JavaScript Object Notation.");
hints.add("JSON is a way of representing data just like XML.");
hints.add("The JSON payload is easily interceptable.");
hints.add("Intercept the reply, change the 600$ to 25$.");
return hints;
}
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
/**
* Gets the title attribute of the HelloScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("JSON Injection");
}
}

View File

@ -14,12 +14,34 @@ 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.
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @created October 28, 2003
@ -28,237 +50,276 @@ import org.owasp.webgoat.session.WebSession;
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 )
/**
* 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);
ElementContainer ec = new ElementContainer();
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);
// Regular expressions in Java and JavaScript compatible form
// 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
// Note: if you want to use the regex=new RegExp(\"" + regex + "\");" syntax
int err = 0;
String msg = "";
// you'll have to use \\\\d to indicate a digit for example -- one escaping for Java and one for JavaScript
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.";
}
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 );
if (!pattern3.matcher(param3).matches())
{
err++;
msg += "<BR>Server side validation violation: You succeeded for Field3.";
}
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 );
if (!pattern4.matcher(param4).matches())
{
err++;
msg += "<BR>Server side validation violation: You succeeded for Field4.";
}
// 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
if (!pattern5.matcher(param5).matches())
{
err++;
msg += "<BR>Server side validation violation: You succeeded for Field5.";
}
int err = 0;
String msg = "";
if (!pattern6.matcher(param6).matches())
{
err++;
msg += "<BR>Server side validation violation: You succeeded for Field6.";
}
if ( !pattern1.matcher( param1 ).matches() )
{
err++;
msg += "<BR>Server side validation violation: You succeeded for Field1.";
}
if (!pattern7.matcher(param7).matches())
{
err++;
msg += "<BR>Server side validation violation: You succeeded for Field7.";
}
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 );
if (err > 0)
{
s.setMessage(msg);
}
if (err >= 7)
{
// This means they defeated all the client side checks
makeSuccess(s);
}
}
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
protected Category getDefaultCategory()
catch (Exception e)
{
return AbstractLesson.A1;
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
return (ec);
}
/**
* 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;
}
/**
* 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>();
/**
* 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 );
}
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;
}
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" );
}
/**
* Gets the title attribute of the AccessControlScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("How to Bypass Client Side JavaScript Validation");
}
}

View File

@ -18,316 +18,368 @@ 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.
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003
*/
public abstract class LessonAdapter extends AbstractLesson
{
final static IMG WEBGOAT_LOGO = new IMG( "images/logos/WebGoat.jpg" ).setAlt( "WebGoat Logo" ).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. &nbsp;&nbsp;" +
"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>&nbsp;&nbsp;" +
"If you would prefer, send your lesson ideas to " + s.getFeedbackAddress() ) );
String fileName = s.getContext().getRealPath( "doc/New Lesson Instructions.txt");
if ( fileName != null )
final static IMG WEBGOAT_LOGO = new IMG("images/logos/WebGoat.jpg").setAlt(
"WebGoat Logo").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. &nbsp;&nbsp;"
+ "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>&nbsp;&nbsp;"
+ "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)
{
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 ){}
pre.addElement(line + "\n");
}
return ( ec );
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 createStagedContent( WebSession s )
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<String> hints = new ArrayList<String>();
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()
{
if (getClass().getResource("images/logos/WebGoat.jpg") != null)
{
try
{
int stage = getLessonTracker(s).getStage();
//int stage = Integer.parseInt( getLessonTracker(s).getLessonProperties().getProperty(WebSession.STAGE,"1"));
return getCustomCredits("Presented by&nbsp;", WEBGOAT_LOGO);
}
else
{
return new StringElement();
}
}
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();
/**
* 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 ( 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;
}
return buff.toString();
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<String> hints = new ArrayList<String>();
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()
{
if (getClass().getResource("images/logos/WebGoat.jpg") != null )
{
return getCustomCredits("Presented by&nbsp;", WEBGOAT_LOGO);
}
else
{
return new StringElement();
}
}
/**
* 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();
}
/**
* 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 );
}
public String getCurrentAction(WebSession s)
{
return s.getLessonSession(this).getCurrentLessonScreen();
}
/**
* Gets the credits attribute of the AbstractLesson object
*
* @return The credits value
*/
protected Element getCustomCredits(String text, IMG logo)
{
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);
public void setCurrentAction(WebSession s, String lessonScreen)
{
s.getLessonSession(this).setCurrentLessonScreen(lessonScreen);
}
return t;
}
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)
{
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;
}
}

View File

@ -17,110 +17,155 @@ 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.
*
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Sherif Koussa <a href="http://www.macadamian.com">Macadamian Technologies</a>
* @created October 28, 2006
*/
public class LogSpoofing extends LessonAdapter {
public class LogSpoofing extends LessonAdapter
{
private static final String USERNAME = "username";
private static final String PASSWORD = "password";
protected Element createContent(WebSession s) {
ElementContainer ec = null;
String inputUsername = null;
try{
Table t = new Table( 0 ).setCellSpacing( 0 ).setCellPadding( 0 ).setBorder( 0 );
TR row1 = new TR();
TR row2 = new TR();
TR row3 = new TR();
row1.addElement( new TD( new StringElement( "Username: " ) ) );
Input username = new Input( Input.TEXT, USERNAME, "" );
row1.addElement( new TD( username ) );
private static final String USERNAME = "username";
row2.addElement( new TD(new StringElement( "Password: ") ) );
Input password = new Input ( Input.PASSWORD, PASSWORD, "");
row2.addElement( new TD (password));
Element b = ECSFactory.makeButton( "Login" );
row3.addElement( new TD (new StringElement( "&nbsp; ")));
row3.addElement( new TD(b) ).setAlign("right");
t.addElement(row1);
t.addElement(row2);
t.addElement(row3);
ec = new ElementContainer();
ec.addElement( t );
inputUsername = new String( s.getParser().getRawParameter( USERNAME, "" ) );
if ( inputUsername.length() != 0)
{
inputUsername = URLDecoder.decode( inputUsername, "UTF-8");
}
ec.addElement( new PRE(" "));
Table t2 = new Table( 0 ).setCellSpacing( 0 ).setCellPadding( 0 ).setBorder( 0 );
TR row4 = new TR();
row4.addElement( new TD(new PRE ("Login failed for username: " + inputUsername ))).setBgColor( HtmlColor.GRAY);
t2.addElement(row4);
ec.addElement( t2 );
private static final String PASSWORD = "password";
if ( inputUsername.length() != 0 &&
inputUsername.toUpperCase().indexOf( System.getProperty("line.separator") + "LOGIN SUCCEEDED FOR USERNAME:") >= 0)
{
makeSuccess(s);
}
}
catch (UnsupportedEncodingException e)
{
s.setMessage( "Error generating " + this.getClass().getName() );
e.printStackTrace();
}
return ec;
protected Element createContent(WebSession s)
{
ElementContainer ec = null;
String inputUsername = null;
try
{
Table t = new Table(0).setCellSpacing(0).setCellPadding(0)
.setBorder(0);
TR row1 = new TR();
TR row2 = new TR();
TR row3 = new TR();
row1.addElement(new TD(new StringElement("Username: ")));
Input username = new Input(Input.TEXT, USERNAME, "");
row1.addElement(new TD(username));
row2.addElement(new TD(new StringElement("Password: ")));
Input password = new Input(Input.PASSWORD, PASSWORD, "");
row2.addElement(new TD(password));
Element b = ECSFactory.makeButton("Login");
row3.addElement(new TD(new StringElement("&nbsp; ")));
row3.addElement(new TD(b)).setAlign("right");
t.addElement(row1);
t.addElement(row2);
t.addElement(row3);
ec = new ElementContainer();
ec.addElement(t);
inputUsername = new String(s.getParser().getRawParameter(USERNAME,
""));
if (inputUsername.length() != 0)
{
inputUsername = URLDecoder.decode(inputUsername, "UTF-8");
}
ec.addElement(new PRE(" "));
Table t2 = new Table(0).setCellSpacing(0).setCellPadding(0)
.setBorder(0);
TR row4 = new TR();
row4.addElement(
new TD(new PRE("Login failed for username: "
+ inputUsername))).setBgColor(HtmlColor.GRAY);
t2.addElement(row4);
ec.addElement(t2);
if (inputUsername.length() != 0
&& inputUsername.toUpperCase().indexOf(
System.getProperty("line.separator")
+ "LOGIN SUCCEEDED FOR USERNAME:") >= 0)
{
makeSuccess(s);
}
}
private final static Integer DEFAULT_RANKING = new Integer(72);
protected Integer getDefaultRanking() {
return DEFAULT_RANKING;
catch (UnsupportedEncodingException e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
return ec;
}
@Override
protected List getHints() {
List<String> hints = new ArrayList<String>();
hints.add( "Try to fool the humane eye by using new lines." );
hints.add( "Use CR (%0d) and LF (%0a) for a new line." );
hints.add( "Try: Smith%0d%0aLogin Succeeded for username: admin" );
hints.add( "Try: Smith%0d%0aLogin Succeeded for username: admin&lt;script&gt;alert(document.cookie)&lt;/script&gt;" );
private final static Integer DEFAULT_RANKING = new Integer(72);
return hints;
}
@Override
public String getTitle() {
return "How to Perform Log Spoofing";
}
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
@Override
protected Category getDefaultCategory() {
return AbstractLesson.A6;
}
public Element getCredits() {
return new StringElement("Created by Sherif Koussa");
}
@Override
protected List getHints()
{
List<String> hints = new ArrayList<String>();
hints.add("Try to fool the humane eye by using new lines.");
hints.add("Use CR (%0d) and LF (%0a) for a new line.");
hints.add("Try: Smith%0d%0aLogin Succeeded for username: admin");
hints
.add("Try: Smith%0d%0aLogin Succeeded for username: admin&lt;script&gt;alert(document.cookie)&lt;/script&gt;");
return hints;
}
@Override
public String getTitle()
{
return "How to Perform Log Spoofing";
}
@Override
protected Category getDefaultCategory()
{
return AbstractLesson.A6;
}
public Element getCredits()
{
return new StringElement("Created by Sherif Koussa");
}
}

View File

@ -5,58 +5,87 @@ 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.
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Sherif Koussa <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003
*/
public class NewLesson 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.
makeSuccess(s);
return( new StringElement( "Welcome to the WebGoat hall of fame !!" ) );
}
/**
* Gets the category attribute of the NEW_LESSON object
*
* @return The category value
*/
protected Category getDefaultCategory()
{
return AbstractLesson.NEW_LESSON;
}
private final static Integer DEFAULT_RANKING = new Integer(10);
/**
* 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.
makeSuccess(s);
return (new StringElement("Welcome to the WebGoat hall of fame !!"));
}
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
/**
* Gets the title attribute of the DirectoryScreen object
*
* @return The title value
*/
public String getTitle()
{
return ( "How to add a new WebGoat lesson" );
}
/**
* Gets the category attribute of the NEW_LESSON object
*
* @return The category value
*/
protected Category getDefaultCategory()
{
return AbstractLesson.NEW_LESSON;
}
public Element getCredits() {
return new StringElement("Created by Sherif Koussa");
}
private final static Integer DEFAULT_RANKING = new Integer(10);
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
/**
* Gets the title attribute of the DirectoryScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("How to add a new WebGoat lesson");
}
public Element getCredits()
{
return new StringElement("Created by Sherif Koussa");
}
}

View File

@ -18,245 +18,286 @@ 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.
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003
*/
public class PathBasedAccessControl extends LessonAdapter
{
private final static String FILE = "File";
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 )
/**
* 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
{
ElementContainer ec = new ElementContainer();
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
{
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("<\\?", "&lt;")
.replaceAll("<(r|u|t)", "&lt;$1")));
}
catch (Exception e)
{
ec.addElement( new BR() );
ec.addElement("The following error occurred while accessing the file: <");
ec.addElement( e.getMessage() );
}
}
// 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("<\\?",
"&lt;").replaceAll("<(r|u|t)", "&lt;$1")));
}
catch ( Exception e )
catch (Exception e)
{
s.setMessage( "Error generating " + this.getClass().getName() );
e.printStackTrace();
ec.addElement(new BR());
ec
.addElement("The following error occurred while accessing the file: <");
ec.addElement(e.getMessage());
}
return ( ec );
}
}
private int upDirCount( String fileName )
catch (Exception e)
{
int count = 0;
int startIndex = fileName.indexOf("..");
while ( startIndex != -1 )
{
count++;
startIndex = fileName.indexOf("..", startIndex+1);
}
return count;
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
protected Category getDefaultCategory()
return (ec);
}
private int upDirCount(String fileName)
{
int count = 0;
int startIndex = fileName.indexOf("..");
while (startIndex != -1)
{
return AbstractLesson.A2;
count++;
startIndex = fileName.indexOf("..", startIndex + 1);
}
return count;
}
/**
* 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;
}
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
protected Category getDefaultCategory()
{
return AbstractLesson.A2;
}
/**
* 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";
/**
* 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 ( instructions );
}
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);
private final static Integer DEFAULT_RANKING = new Integer(120);
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
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" );
}
/**
* 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");
}
}

View File

@ -19,13 +19,34 @@ 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.
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003
@ -34,202 +55,240 @@ import org.owasp.webgoat.util.HtmlEncoder;
public class ReflectedXSS extends LessonAdapter
{
/**
* Description of the Method
*
* @param s Description of the Parameter
* @return Description of the Return Value
*/
/**
* Description of the Method
*
* @param s Description of the Parameter
* @return Description of the Return Value
*/
protected Element createContent( WebSession s )
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;
ElementContainer ec = new ElementContainer();
String regex1 = "^[0-9]{3}$";// any three digits
Pattern pattern1 = Pattern.compile( regex1 );
try
// test input field1
if (!pattern1.matcher(param1).matches())
{
if (param1.toLowerCase().indexOf("script") != -1)
{
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( "&nbsp;" ).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%") );
makeSuccess(s);
}
catch ( Exception e )
{
s.setMessage( "Error generating " + this.getClass().getName() );
e.printStackTrace();
}
return ( ec );
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("&nbsp;").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%"));
}
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
protected Category getDefaultCategory()
catch (Exception e)
{
return AbstractLesson.A4;
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
return (ec);
}
/**
* Gets the hints attribute of the AccessControlScreen object
*
* @return The hints value
*/
protected List getHints()
{
List<String> hints = new ArrayList<String>();
hints.add( "A simple script is &lt;SCRIPT&gt;alert('bang!');&lt;/SCRIPT&gt;." );
hints.add( "Can you get the script to disclose the JSESSIONID cookie?" );
hints.add( "You can use &lt;SCRIPT&gt;alert(document.cookie);&lt;/SCRIPT&gt; 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>" +
"&lt;script type=\"text/javascript\"&gt;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\",\"&lt;br&gt;\"); " +
"document.write(str1);}&lt;/script&gt;");
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 );
}
/**
* 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("A simple script is &lt;SCRIPT&gt;alert('bang!');&lt;/SCRIPT&gt;.");
hints.add("Can you get the script to disclose the JSESSIONID cookie?");
hints
.add("You can use &lt;SCRIPT&gt;alert(document.cookie);&lt;/SCRIPT&gt; 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>"
+ "&lt;script type=\"text/javascript\"&gt;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\",\"&lt;br&gt;\"); "
+ "document.write(str1);}&lt;/script&gt;");
return hints;
}
private final static Integer DEFAULT_RANKING = new Integer(120);
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
// <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);
}
/**
* 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";
}
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";
}
}

View File

@ -7,11 +7,34 @@ 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.
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003
@ -19,77 +42,78 @@ import org.owasp.webgoat.session.WebSession;
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 )
/**
* 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())
{
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;
makeSuccess(s);
}
/**
* Gets the category attribute of the ForgotPassword object
*
* @return The category value
*/
protected Category getDefaultCategory()
else
{
return AbstractLesson.A2;
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 hints attribute of the HelloScreen object
*
* @return The hints value
*/
public List getHints()
{
List<String> hints = new ArrayList<String>();
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;
}
}
/**
* Gets the category attribute of the ForgotPassword object
*
* @return The category value
*/
protected Category getDefaultCategory()
{
private final static Integer DEFAULT_RANKING = new Integer(15);
return AbstractLesson.A2;
}
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" );
}
/**
* Gets the hints attribute of the HelloScreen object
*
* @return The hints value
*/
public List getHints()
{
List<String> hints = new ArrayList<String>();
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");
}
}

View File

@ -13,125 +13,168 @@ import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.ValidationException;
import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*/
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());
private LessonAction chainedAction;
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();
}
}
public DeleteProfile(AbstractLesson lesson, String lessonName,
String actionName, LessonAction chainedAction)
{
super(lesson, lessonName, actionName);
this.chainedAction = chainedAction;
}
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)
{
}
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)
{}
}
}

View File

@ -12,149 +12,187 @@ import org.owasp.webgoat.session.UnauthenticatedException;
import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*/
public class EditProfile extends DefaultLessonAction
{
public EditProfile(AbstractLesson lesson, String lessonName, String actionName)
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))
{
super(lesson, lessonName, actionName);
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();
}
public void handleRequest( WebSession s )
throws ParameterNotFoundException, UnauthenticatedException, UnauthorizedException
{
getLesson().setCurrentAction(s, getActionName());
return profile;
}
if (isAuthenticated(s))
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())
{
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();
// 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();
}
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;
}
return profile;
}
}

View File

@ -14,138 +14,180 @@ import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.ValidationException;
import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*/
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);
private LessonAction chainedAction;
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;
public FindProfile(AbstractLesson lesson, String lessonName,
String actionName, LessonAction chainedAction)
{
super(lesson, lessonName, actionName);
this.chainedAction = chainedAction;
}
if (foundEmployee(s))
page = RoleBasedAccessControl.VIEWPROFILE_ACTION;
return page;
}
private boolean foundEmployee(WebSession s)
public void handleRequest(WebSession s) throws ParameterNotFoundException,
UnauthenticatedException, UnauthorizedException,
ValidationException
{
if (isAuthenticated(s))
{
boolean found = false;
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
{
int id = getIntRequestAttribute(s, getLessonName() + "." + RoleBasedAccessControl.EMPLOYEE_ID);
found = true;
chainedAction.handleRequest(s);
}
catch (ParameterNotFoundException e)
catch (UnauthenticatedException ue1)
{
System.out.println("Internal server error");
ue1.printStackTrace();
}
return found;
catch (UnauthorizedException ue2)
{
System.out.println("Internal server error");
ue2.printStackTrace();
}
}
}
public Employee findEmployeeProfile(WebSession s, int userId, String pattern)
throws UnauthorizedException
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
{
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;
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;
}
}

View File

@ -14,121 +14,162 @@ import org.owasp.webgoat.session.UnauthenticatedException;
import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*/
public class ListStaff extends DefaultLessonAction
{
public ListStaff(AbstractLesson lesson, String lessonName, String actionName)
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))
{
super(lesson, lessonName, actionName);
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();
}
public void handleRequest( WebSession s )
throws ParameterNotFoundException, UnauthenticatedException, UnauthorizedException
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
{
getLesson().setCurrentAction(s, getActionName());
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 + ")";
if (isAuthenticated(s))
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 userId = getIntSessionAttribute(s, getLessonName() + "." + RoleBasedAccessControl.USER_ID);
List employees = getAllEmployees(s, userId);
setSessionAttribute(s, getLessonName() + "." + RoleBasedAccessControl.STAFF_ATTRIBUTE_KEY, employees);
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);
}
else
throw new UnauthenticatedException();
}
catch (SQLException sqle)
{
s.setMessage("Error getting employees");
sqle.printStackTrace();
}
}
catch (Exception e)
{
s.setMessage("Error getting employees");
e.printStackTrace();
}
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;
}
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;
}
}

View File

@ -16,157 +16,207 @@ import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.ValidationException;
import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*/
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());
private LessonAction chainedAction;
List employees = getAllEmployees(s);
setSessionAttribute(s, getLessonName() + "." + RoleBasedAccessControl.STAFF_ATTRIBUTE_KEY, employees);
int employeeId = -1;
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
{
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");
chainedAction.handleRequest(s);
}
catch (ParameterNotFoundException pnfe)
catch (UnauthenticatedException ue1)
{
// No credentials offered, so we log them out
setSessionAttribute(s, getLessonName() + ".isAuthenticated", Boolean.FALSE);
System.out.println("Internal server error");
ue1.printStackTrace();
}
catch (UnauthorizedException ue2)
{
System.out.println("Internal server error");
ue2.printStackTrace();
}
}
else
s.setMessage("Login failed");
}
/**
* 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)
catch (ParameterNotFoundException pnfe)
{
String nextPage = RoleBasedAccessControl.LOGIN_ACTION;
if (isAuthenticated(s))
nextPage = chainedAction.getNextPage(s);
return nextPage;
// No credentials offered, so we log them out
setSessionAttribute(s, getLessonName() + ".isAuthenticated",
Boolean.FALSE);
}
}
}
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)
/**
* 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
{
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 * 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())
{
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();
setSessionAttribute(s,
getLessonName() + ".isAuthenticated", Boolean.TRUE);
setSessionAttribute(s, getLessonName() + "."
+ RoleBasedAccessControl.USER_ID, Integer
.toString(userId));
authenticated = true;
}
return employees;
}
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;
}
}

View File

@ -9,43 +9,79 @@ import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.ValidationException;
import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*/
public class Logout extends DefaultLessonAction
{
private LessonAction chainedAction;
public Logout(AbstractLesson lesson, String lessonName, String actionName, LessonAction chainedAction)
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
{
super(lesson, lessonName, actionName);
this.chainedAction = chainedAction;
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 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);
}
public String getNextPage(WebSession s)
{
return chainedAction.getNextPage(s);
}
}

View File

@ -19,422 +19,511 @@ 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.
*
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*/
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";
public final static String DESCRIPTION = "description";
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);
public final static String DISCIPLINARY_DATE = "disciplinaryDate";
private static Connection connection = null;
public final static String DISCIPLINARY_NOTES = "disciplinaryNotes";
private Map lessonFunctions = new Hashtable();
public static synchronized Connection getConnection(WebSession s)
throws SQLException, ClassNotFoundException
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)
{
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<String> hints = new ArrayList<String>();
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())
{
connection = DatabaseUtilities.makeConnection( s );
// Access to Login does not require authentication.
action.handleRequest(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<String> hints = new ArrayList<String>();
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())
else
{
switch (getStage(s))
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))
{
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();
}
int userId = action.getUserId(s);
if (action.isAuthorized(s, userId, action
.getActionName()))
{
action.handleRequest(s);
}
else
{
throw new UnauthorizedException();
}
}
else
setCurrentAction(s, ERROR_ACTION);
throw new UnauthenticatedException();
}
}
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());
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);
}
}
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);
// All this does for this lesson is ensure that a non-null content exists.
setContent(new ElementContainer());
}
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;
}
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";
}
/**
* 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();
// 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();
}
}

View File

@ -4,16 +4,48 @@ import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.lessons.DefaultLessonAction;
import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*/
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;
}
public SearchStaff(AbstractLesson lesson, String lessonName,
String actionName)
{
super(lesson, lessonName, actionName);
}
public String getNextPage(WebSession s)
{
return RoleBasedAccessControl.SEARCHSTAFF_ACTION;
}
}

View File

@ -14,241 +14,312 @@ import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.ValidationException;
import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*/
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 LessonAction chainedAction;
private int getNextUID(WebSession s)
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 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;
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();
}
}
public void createEmployeeProfile(WebSession s, int userId, Employee employee)
throws UnauthorizedException
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
{
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" );
}
// 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");
}
}
}

View File

@ -12,174 +12,220 @@ import org.owasp.webgoat.session.UnauthenticatedException;
import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*/
public class ViewProfile extends DefaultLessonAction
{
public ViewProfile(AbstractLesson lesson, String lessonName, String actionName)
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))
{
super(lesson, lessonName, actionName);
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();
}
public void handleRequest( WebSession s )
throws ParameterNotFoundException, UnauthenticatedException, UnauthorizedException
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
{
getLesson().setCurrentAction(s, getActionName());
String query = "SELECT * FROM employee WHERE userid = "
+ subjectUserId;
if (isAuthenticated(s))
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())
{
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);
// 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();
}
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;
}
return profile;
}
}

View File

@ -14,121 +14,162 @@ import org.owasp.webgoat.session.UnauthenticatedException;
import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*/
public class ListStaff extends DefaultLessonAction
{
public ListStaff(AbstractLesson lesson, String lessonName, String actionName)
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))
{
super(lesson, lessonName, actionName);
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<EmployeeStub> employees = new Vector<EmployeeStub>();
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();
}
public void handleRequest( WebSession s )
throws ParameterNotFoundException, UnauthenticatedException, UnauthorizedException
return employees;
}
public List getAllEmployees_BACKUP(WebSession s, int userId)
throws UnauthorizedException
{
// Query the database for all employees "owned" by the given employee
List<EmployeeStub> employees = new Vector<EmployeeStub>();
try
{
getLesson().setCurrentAction(s, getActionName());
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 + ")";
if (isAuthenticated(s))
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 userId = getIntSessionAttribute(s, getLessonName() + "." + SQLInjection.USER_ID);
List employees = getAllEmployees(s, userId);
setSessionAttribute(s, getLessonName() + "." + SQLInjection.STAFF_ATTRIBUTE_KEY, employees);
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);
}
else
throw new UnauthenticatedException();
}
catch (SQLException sqle)
{
s.setMessage("Error getting employees");
sqle.printStackTrace();
}
}
catch (Exception e)
{
s.setMessage("Error getting employees");
e.printStackTrace();
}
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<EmployeeStub> employees = new Vector<EmployeeStub>();
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<EmployeeStub> employees = new Vector<EmployeeStub>();
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;
}
return employees;
}
}

View File

@ -16,230 +16,286 @@ import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.ValidationException;
import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*/
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
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
{
//System.out.println("Login.handleRequest()");
getLesson().setCurrentAction(s, getActionName());
List employees = getAllEmployees(s);
setSessionAttribute(s, getLessonName() + "." + SQLInjection.STAFF_ATTRIBUTE_KEY, employees);
String employeeId = null;
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
{
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");
chainedAction.handleRequest(s);
}
catch (ParameterNotFoundException pnfe)
catch (UnauthenticatedException ue1)
{
// No credentials offered, so we log them out
setSessionAttribute(s, getLessonName() + ".isAuthenticated", Boolean.FALSE);
System.out.println("Internal server error");
ue1.printStackTrace();
}
}
public String getNextPage(WebSession s)
{
String nextPage = SQLInjection.LOGIN_ACTION;
if (isAuthenticated(s))
nextPage = chainedAction.getNextPage(s);
return nextPage;
catch (UnauthorizedException ue2)
{
System.out.println("Internal server error");
ue2.printStackTrace();
}
}
else
s.setMessage("Login failed");
}
public boolean requiresAuthentication()
catch (ParameterNotFoundException pnfe)
{
return false;
// No credentials offered, so we log them out
setSessionAttribute(s, getLessonName() + ".isAuthenticated",
Boolean.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)
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
{
List<EmployeeStub> employees = new Vector<EmployeeStub>();
// 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 * 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())
{
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();
}
setSessionAttribute(s,
getLessonName() + ".isAuthenticated", Boolean.TRUE);
setSessionAttribute(s, getLessonName() + "."
+ SQLInjection.USER_ID, userId);
authenticated = true;
}
catch ( Exception e )
}
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())
{
s.setMessage( "Error getting employees" );
e.printStackTrace();
setSessionAttribute(s,
getLessonName() + ".isAuthenticated", Boolean.TRUE);
setSessionAttribute(s, getLessonName() + "."
+ SQLInjection.USER_ID, userId);
authenticated = true;
}
return employees;
}
catch (SQLException sqle)
{
s.setMessage("Error logging in");
sqle.printStackTrace();
}
}
private void updateLessonStatus(WebSession s)
catch (Exception e)
{
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)
{
}
s.setMessage("Error logging in");
e.printStackTrace();
}
//System.out.println("Lesson login result: " + authenticated);
return authenticated;
}
public List getAllEmployees(WebSession s)
{
List<EmployeeStub> employees = new Vector<EmployeeStub>();
// 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)
{}
}
}

View File

@ -25,322 +25,414 @@ 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.
*
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*/
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";
public final static String DESCRIPTION = "description";
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 String DISCIPLINARY_DATE = "disciplinaryDate";
public final static int PRIZE_EMPLOYEE_ID = 112;
public final static String PRIZE_EMPLOYEE_NAME = "Neville Bartholomew";
public final static String DISCIPLINARY_NOTES = "disciplinaryNotes";
private static Connection connection = null;
public final static String CCN_LIMIT = "ccnLimit";
private Map lessonFunctions = new Hashtable();
public static synchronized Connection getConnection(WebSession s)
throws SQLException, ClassNotFoundException
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)
{
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<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 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)
{
connection = DatabaseUtilities.makeConnection( s );
//System.out.println("CrossSiteScripting.handleRequest() dispatching to: " + action.getActionName());
if (!action.requiresAuthentication()
|| action.isAuthenticated(s))
{
action.handleRequest(s);
//setCurrentAction(s, action.getNextPage(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;
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);
}
}
/**
* 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 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;
}
// All this does for this lesson is ensure that a non-null content exists.
setContent(new ElementContainer());
}
/**
* 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;
}
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);
}
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 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 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();
// 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();
}
}

View File

@ -12,213 +12,261 @@ import org.owasp.webgoat.session.UnauthenticatedException;
import org.owasp.webgoat.session.UnauthorizedException;
import org.owasp.webgoat.session.WebSession;
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*/
public class ViewProfile extends DefaultLessonAction
{
public ViewProfile(AbstractLesson lesson, String lessonName, String actionName)
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))
{
super(lesson, lessonName, actionName);
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();
}
public void handleRequest( WebSession s )
throws ParameterNotFoundException, UnauthenticatedException, UnauthorizedException
{
getLesson().setCurrentAction(s, getActionName());
return profile;
}
Employee employee = null;
if (isAuthenticated(s))
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())
{
String userId = getSessionAttribute(s, getLessonName() + "." + SQLInjection.USER_ID);
String employeeId = null;
// 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
{
// User selected employee
employeeId = s.getParser().getRawParameter(SQLInjection.EMPLOYEE_ID);
targetEmployee = getEmployeeProfile_BACKUP(s,
userId, employeeId);
}
catch (ParameterNotFoundException e)
catch (UnauthorizedException e)
{}
if (targetEmployee != null
&& targetEmployee.getId() == SQLInjection.PRIZE_EMPLOYEE_ID)
{
// May be an internally selected employee
employeeId = getRequestAttribute(s, getLessonName() + "." + SQLInjection.EMPLOYEE_ID);
s
.setMessage("Congratulations. You have successfully completed this lesson");
getLesson().getLessonTracker(s).setCompleted(true);
}
// 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)
{
}
}
break;
default:
break;
}
}
catch (ParameterNotFoundException pnfe)
{}
}
}

View File

@ -19,218 +19,294 @@ import org.apache.ecs.html.TR;
import org.apache.ecs.html.Table;
import org.owasp.webgoat.session.WebSession;
public class SilentTransactions extends LessonAdapter {
private final static Integer DEFAULT_RANKING = new Integer(40);
private final static Double CURRENT_BALANCE = 11987.09;
/**
* 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 sherif@macadamian.com
* @created December 26, 2006
*/
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Sherif Koussa <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created December 26, 2006
*/
public void handleRequest(WebSession s) {
try
public class SilentTransactions extends LessonAdapter
{
private final static Integer DEFAULT_RANKING = new Integer(40);
private final static Double CURRENT_BALANCE = 11987.09;
public void handleRequest(WebSession s)
{
try
{
if (s.getParser().getRawParameter("from", "").equals("ajax"))
{
if (s.getParser().getRawParameter("confirm", "").equals(
"Confirm"))
{
if(s.getParser().getRawParameter("from", "").equals("ajax"))
{
if (s.getParser().getRawParameter( "confirm", "").equals("Confirm"))
{
String amount = s.getParser().getRawParameter( "amount", "");
s.getResponse().setContentType("text/html");
s.getResponse().setHeader("Cache-Control", "no-cache");
PrintWriter out = new PrintWriter(s.getResponse().getOutputStream());
StringBuffer result = new StringBuffer();
result.append("<br><br>* Congratulations. You have successfully completed this lesson.<br>");
if (!amount.equals(""))
{
result.append("You have just silently authorized ");
result.append(amount);
result.append("$ without the user interaction.<br>");
}
result.append("Now you can send out a spam email containing this link and whoever clicks on it<br>");
result.append(" and happens to be logged in the same time will loose their money !!");
out.print(result.toString());
out.flush();
out.close();
getLessonTracker(s).setCompleted(true);
return;
}
else if (s.getParser().getRawParameter( "confirm", "").equals("Transferring"))
{
s.getResponse().setContentType("text/html");
s.getResponse().setHeader("Cache-Control", "no-cache");
PrintWriter out = new PrintWriter(s.getResponse().getOutputStream());
out.print("<br><br>The Transaction has Completed Successfully.");
out.flush();
out.close();
return;
}
}
String amount = s.getParser().getRawParameter("amount", "");
s.getResponse().setContentType("text/html");
s.getResponse().setHeader("Cache-Control", "no-cache");
PrintWriter out = new PrintWriter(s.getResponse()
.getOutputStream());
StringBuffer result = new StringBuffer();
result
.append("<br><br>* Congratulations. You have successfully completed this lesson.<br>");
if (!amount.equals(""))
{
result.append("You have just silently authorized ");
result.append(amount);
result.append("$ without the user interaction.<br>");
}
result
.append("Now you can send out a spam email containing this link and whoever clicks on it<br>");
result
.append(" and happens to be logged in the same time will loose their money !!");
out.print(result.toString());
out.flush();
out.close();
getLessonTracker(s).setCompleted(true);
return;
}
catch (Exception ex)
else if (s.getParser().getRawParameter("confirm", "").equals(
"Transferring"))
{
ex.printStackTrace();
s.getResponse().setContentType("text/html");
s.getResponse().setHeader("Cache-Control", "no-cache");
PrintWriter out = new PrintWriter(s.getResponse()
.getOutputStream());
out
.print("<br><br>The Transaction has Completed Successfully.");
out.flush();
out.close();
return;
}
Form form = new Form( getFormAction(), Form.POST ).setName( "form" ).setEncType( "" );
form.addElement( createContent( s ) );
setContent(form);
}
}
/**
* Description of the Method
*
* @param s Current WebSession
*/
protected Element createContent(WebSession s)
catch (Exception ex)
{
ElementContainer ec = new ElementContainer();
String lineSep = System.getProperty("line.separator");
String script = "<script>" + lineSep +
"function processData(){" + lineSep +
" var accountNo = document.getElementById('newAccount').value;" + lineSep +
" var amount = document.getElementById('amount').value;" + lineSep +
" if ( accountNo == ''){" + lineSep +
" alert('Please enter a valid account number to transfer to.')" + lineSep +
" return;" + lineSep +
"}" + lineSep +
" else if ( amount == ''){" + lineSep +
" alert('Please enter a valid amount to transfer.')" + lineSep +
" return;" + lineSep +
"}" + lineSep +
" var balanceValue = document.getElementById('balanceID').innerText;" + lineSep +
" balanceValue = balanceValue.replace( new RegExp('$') , '');" + lineSep +
" if ( parseFloat(amount) > parseFloat(balanceValue) ) {" + lineSep +
" alert('You can not transfer more funds than what is available in your balance.')" + lineSep +
" return;" + lineSep +
"}" + lineSep +
" document.getElementById('confirm').value = 'Transferring'" + lineSep +
"submitData(accountNo, amount);" + lineSep +
" document.getElementById('confirm').value = 'Confirm'" + lineSep +
"balanceValue = parseFloat(balanceValue) - parseFloat(amount);" + lineSep +
"balanceValue = balanceValue.toFixed(2);" + lineSep +
"document.getElementById('balanceID').innerText = balanceValue + '$';" + lineSep +
"}" + lineSep +
"function submitData(accountNo, balance) {" + lineSep +
"var url = '/WebGoat/attack?Screen=" + String.valueOf(getScreenId()) +
"&menu=" + getDefaultCategory().getRanking().toString() +
"&from=ajax&newAccount='+ accountNo+ '&amount=' + balance +'&confirm=' + document.getElementById('confirm').value; " + lineSep +
"if (typeof XMLHttpRequest != 'undefined') {" + lineSep +
"req = new XMLHttpRequest();" + lineSep +
"} else if (window.ActiveXObject) {" + lineSep +
"req = new ActiveXObject('Microsoft.XMLHTTP');" + lineSep +
" }" + lineSep +
" req.open('GET', url, true);" + lineSep +
" req.onreadystatechange = callback;" + lineSep +
" req.send(null);" + lineSep +
"}" + lineSep +
"function callback() {" + lineSep +
" if (req.readyState == 4) { " + lineSep +
" if (req.status == 200) { " + lineSep +
" var result = req.responseText ;" + lineSep +
" var resultsDiv = document.getElementById('resultsDiv');" + lineSep +
" resultsDiv.innerHTML = '';" + lineSep +
" resultsDiv.innerHTML = result;" + lineSep +
" }}}" + lineSep +
"</script>" + lineSep;
ec.addElement( new StringElement(script) );
ec.addElement( new H1("Welcome to WebGoat Banking System"));
ec.addElement( new BR() );
ec.addElement( new H3("Account Summary:"));
Table t1 = new Table().setCellSpacing(0).setCellPadding(0).setBorder(1).setWidth("70%").setAlign("left");
ec.addElement( new BR() );
TR tr = new TR();
tr.addElement( new TD( new StringElement( "Account Balance:" ) ));
tr.addElement( new TD( new StringElement( "<div id='balanceID'>" + CURRENT_BALANCE.toString() + "$</div>") ));
t1.addElement( tr );
tr = new TR();
tr.addElement( new TD( new StringElement( "Transfer to Account:" )));
Input newAccount = new Input();
newAccount.setType( Input.TEXT );
newAccount.setName( "newAccount" );
newAccount.setValue( "" );
tr.addElement( new TD( newAccount ));
t1.addElement( tr );
tr = new TR();
tr.addElement( new TD( new StringElement( "Transfer Amount:" )));
Input amount = new Input();
amount.setType( Input.TEXT );
amount.setName( "amount" );
amount.setValue( 0 );
tr.addElement( new TD( amount ));
t1.addElement( tr );
ec.addElement( t1 );
ec.addElement( new BR() );
ec.addElement( new BR() );
ec.addElement( new PRE() );
Input b = new Input();
b.setType( Input.BUTTON );
b.setName( "confirm" );
b.setValue( "Confirm" );
b.setOnClick( "processData();" );
ec.addElement( b );
ec.addElement( new BR());
Div div = new Div();
div.addAttribute("name", "resultsDiv");
div.addAttribute("id", "resultsDiv");
div.setStyle("font-weight: bold;color:red;");
ec.addElement(div);
return ec;
}
protected Category getDefaultCategory()
{
return AbstractLesson.AJAX_SECURITY;
ex.printStackTrace();
}
protected List getHints()
{
List<String> hints = new ArrayList<String>();
hints.add("Check the javascript in the HTML source.");
hints.add("Check how the application calls a specific javascript function to execute the transaction.");
hints.add("Check the javascript functions processData and submitData()");
hints.add("Function submitData() is the one responsible for actually ececuting the transaction.");
hints.add("Check if your browser supports running javascript from the address bar.");
hints.add("Try to navigate to 'javascript:submitData(1234556,11000);'");
return hints;
}
Form form = new Form(getFormAction(), Form.POST).setName("form")
.setEncType("");
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
form.addElement(createContent(s));
/**
* Gets the title attribute of the HelloScreen object
*
* @return The title value
*/
public String getTitle()
{
return ( "Silent Transactions Attacks" );
}
setContent(form);
public Element getCredits() {
return new StringElement("Created by Sherif Koussa");
}
}
/**
* Description of the Method
*
* @param s Current WebSession
*/
protected Element createContent(WebSession s)
{
ElementContainer ec = new ElementContainer();
String lineSep = System.getProperty("line.separator");
String script = "<script>"
+ lineSep
+ "function processData(){"
+ lineSep
+ " var accountNo = document.getElementById('newAccount').value;"
+ lineSep
+ " var amount = document.getElementById('amount').value;"
+ lineSep
+ " if ( accountNo == ''){"
+ lineSep
+ " alert('Please enter a valid account number to transfer to.')"
+ lineSep
+ " return;"
+ lineSep
+ "}"
+ lineSep
+ " else if ( amount == ''){"
+ lineSep
+ " alert('Please enter a valid amount to transfer.')"
+ lineSep
+ " return;"
+ lineSep
+ "}"
+ lineSep
+ " var balanceValue = document.getElementById('balanceID').innerText;"
+ lineSep
+ " balanceValue = balanceValue.replace( new RegExp('$') , '');"
+ lineSep
+ " if ( parseFloat(amount) > parseFloat(balanceValue) ) {"
+ lineSep
+ " alert('You can not transfer more funds than what is available in your balance.')"
+ lineSep
+ " return;"
+ lineSep
+ "}"
+ lineSep
+ " document.getElementById('confirm').value = 'Transferring'"
+ lineSep
+ "submitData(accountNo, amount);"
+ lineSep
+ " document.getElementById('confirm').value = 'Confirm'"
+ lineSep
+ "balanceValue = parseFloat(balanceValue) - parseFloat(amount);"
+ lineSep
+ "balanceValue = balanceValue.toFixed(2);"
+ lineSep
+ "document.getElementById('balanceID').innerText = balanceValue + '$';"
+ lineSep
+ "}"
+ lineSep
+ "function submitData(accountNo, balance) {"
+ lineSep
+ "var url = '/WebGoat/attack?Screen="
+ String.valueOf(getScreenId())
+ "&menu="
+ getDefaultCategory().getRanking().toString()
+ "&from=ajax&newAccount='+ accountNo+ '&amount=' + balance +'&confirm=' + document.getElementById('confirm').value; "
+ lineSep + "if (typeof XMLHttpRequest != 'undefined') {"
+ lineSep + "req = new XMLHttpRequest();" + lineSep
+ "} else if (window.ActiveXObject) {" + lineSep
+ "req = new ActiveXObject('Microsoft.XMLHTTP');" + lineSep
+ " }" + lineSep + " req.open('GET', url, true);" + lineSep
+ " req.onreadystatechange = callback;" + lineSep
+ " req.send(null);" + lineSep + "}" + lineSep
+ "function callback() {" + lineSep
+ " if (req.readyState == 4) { " + lineSep
+ " if (req.status == 200) { " + lineSep
+ " var result = req.responseText ;"
+ lineSep
+ " var resultsDiv = document.getElementById('resultsDiv');"
+ lineSep + " resultsDiv.innerHTML = '';" + lineSep
+ " resultsDiv.innerHTML = result;" + lineSep
+ " }}}" + lineSep + "</script>" + lineSep;
ec.addElement(new StringElement(script));
ec.addElement(new H1("Welcome to WebGoat Banking System"));
ec.addElement(new BR());
ec.addElement(new H3("Account Summary:"));
Table t1 = new Table().setCellSpacing(0).setCellPadding(0).setBorder(1)
.setWidth("70%").setAlign("left");
ec.addElement(new BR());
TR tr = new TR();
tr.addElement(new TD(new StringElement("Account Balance:")));
tr.addElement(new TD(new StringElement("<div id='balanceID'>"
+ CURRENT_BALANCE.toString() + "$</div>")));
t1.addElement(tr);
tr = new TR();
tr.addElement(new TD(new StringElement("Transfer to Account:")));
Input newAccount = new Input();
newAccount.setType(Input.TEXT);
newAccount.setName("newAccount");
newAccount.setValue("");
tr.addElement(new TD(newAccount));
t1.addElement(tr);
tr = new TR();
tr.addElement(new TD(new StringElement("Transfer Amount:")));
Input amount = new Input();
amount.setType(Input.TEXT);
amount.setName("amount");
amount.setValue(0);
tr.addElement(new TD(amount));
t1.addElement(tr);
ec.addElement(t1);
ec.addElement(new BR());
ec.addElement(new BR());
ec.addElement(new PRE());
Input b = new Input();
b.setType(Input.BUTTON);
b.setName("confirm");
b.setValue("Confirm");
b.setOnClick("processData();");
ec.addElement(b);
ec.addElement(new BR());
Div div = new Div();
div.addAttribute("name", "resultsDiv");
div.addAttribute("id", "resultsDiv");
div.setStyle("font-weight: bold;color:red;");
ec.addElement(div);
return ec;
}
protected Category getDefaultCategory()
{
return AbstractLesson.AJAX_SECURITY;
}
protected List getHints()
{
List<String> hints = new ArrayList<String>();
hints.add("Check the javascript in the HTML source.");
hints
.add("Check how the application calls a specific javascript function to execute the transaction.");
hints
.add("Check the javascript functions processData and submitData()");
hints
.add("Function submitData() is the one responsible for actually ececuting the transaction.");
hints
.add("Check if your browser supports running javascript from the address bar.");
hints.add("Try to navigate to 'javascript:submitData(1234556,11000);'");
return hints;
}
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
/**
* Gets the title attribute of the HelloScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Silent Transactions Attacks");
}
public Element getCredits()
{
return new StringElement("Created by Sherif Koussa");
}
}

View File

@ -27,394 +27,467 @@ import org.owasp.webgoat.session.ECSFactory;
import org.owasp.webgoat.session.ParameterNotFoundException;
import org.owasp.webgoat.session.WebSession;
/**
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author 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 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 &lt;operation&gt; tag contained within the &lt;portType&gt; section of the WSDL. <BR> Below is an example of a typical operation (getFirstName): <br><br>" +
"&lt;wsdl:portType name=\"SoapRequest\"&gt; <br>" +
"&lt;wsdl:<strong>operation name=\"getFirstName\"</strong>&gt;<br>" +
"&lt;wsdl:input message=\"impl:getFirstNameRequest\" name=\"getFirstNameRequest\" /&gt;<br>" +
"&lt;wsdl:output message=\"impl:getFirstNameResponse\" name=\"getFirstNameResponse\" /&gt;<br>" +
"&lt;wsdlsoap:operation soapAction=\"\" /&gt;" +
"&lt;/wsdl:portType&gt;<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 &lt;definitions&gt; 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 \"&lt;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>" +
"&lt;wsdl:message name=\"getFirstNameRequest\"<br><br>" +
"&lt;wsdl:<strong>part name=\"id\" type=\"xsd:int\"</strong> /&gt;<br>" +
"&lt;/wsdl:message&gt;<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 &quot;&quot; <br><br>" +
"The SOAP message body has the following format:<br>" +
"&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt; <br>" +
"&lt;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\"&gt; <br>" +
"&nbsp;&nbsp;&lt;SOAP-ENV:Body&gt; <br>" +
"&nbsp;&nbsp;&nbsp;&nbsp;&lt;ns1:getFirstName SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:ns1=\"http://lessons\"&gt; <br>" +
"&nbsp;&nbsp;&nbsp;&nbsp;&lt;id xsi:type=\"xsd:int\"&gt;101&lt;/id&gt; <br>"+
"&nbsp;&nbsp;&nbsp;&nbsp;&lt;/ns1:getFirstName&gt; <br>" +
"&nbsp;&nbsp;&lt;/SOAP-ENV:Body&gt; <br>" +
"&lt;/SOAP-ENV:Envelope&gt; <br><br>" +
"Intercept the HTTP request and try to create a SOAP request.";
soapEnv.replaceAll("(?s) ","&nbsp;");
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)
{
/** Reset function access counters **/
accessFirstName = accessLastName = accessCreditCard = accessLoginCount = 0;
//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;
{
return AbstractLesson.WEB_SERVICES;
}
protected List getHints()
{
List<String> hints = new ArrayList<String>();
hints
.add("Accessible operations are delimited by the &lt;operation&gt; tag contained within the &lt;portType&gt; section of the WSDL. <BR> Below is an example of a typical operation (getFirstName): <br><br>"
+ "&lt;wsdl:portType name=\"SoapRequest\"&gt; <br>"
+ "&lt;wsdl:<strong>operation name=\"getFirstName\"</strong>&gt;<br>"
+ "&lt;wsdl:input message=\"impl:getFirstNameRequest\" name=\"getFirstNameRequest\" /&gt;<br>"
+ "&lt;wsdl:output message=\"impl:getFirstNameResponse\" name=\"getFirstNameResponse\" /&gt;<br>"
+ "&lt;wsdlsoap:operation soapAction=\"\" /&gt;"
+ "&lt;/wsdl:portType&gt;<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 &lt;definitions&gt; 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 \"&lt;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>"
+ "&lt;wsdl:message name=\"getFirstNameRequest\"<br><br>"
+ "&lt;wsdl:<strong>part name=\"id\" type=\"xsd:int\"</strong> /&gt;<br>"
+ "&lt;/wsdl:message&gt;<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 &quot;&quot; <br><br>"
+ "The SOAP message body has the following format:<br>"
+ "&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt; <br>"
+ "&lt;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\"&gt; <br>"
+ "&nbsp;&nbsp;&lt;SOAP-ENV:Body&gt; <br>"
+ "&nbsp;&nbsp;&nbsp;&nbsp;&lt;ns1:getFirstName SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:ns1=\"http://lessons\"&gt; <br>"
+ "&nbsp;&nbsp;&nbsp;&nbsp;&lt;id xsi:type=\"xsd:int\"&gt;101&lt;/id&gt; <br>"
+ "&nbsp;&nbsp;&nbsp;&nbsp;&lt;/ns1:getFirstName&gt; <br>"
+ "&nbsp;&nbsp;&lt;/SOAP-ENV:Body&gt; <br>"
+ "&lt;/SOAP-ENV:Envelope&gt; <br><br>"
+ "Intercept the HTTP request and try to create a SOAP request.";
soapEnv.replaceAll("(?s) ", "&nbsp;");
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)
{
/** Reset function access counters **/
accessFirstName = accessLastName = accessCreditCard = accessLoginCount = 0;
//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;
}
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;
}
}

View File

@ -23,326 +23,382 @@ 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.
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</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 )
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
{
return super.createStagedContent(s);
}
protected Element doStage1( WebSession s ) throws Exception
{
return injectableQuery( s );
}
protected Element doStage2( WebSession s ) throws Exception
{
return parameterizedQuery( s);
}
ec.addElement(makeStationList(s));
protected Element injectableQuery( WebSession s )
{
ElementContainer ec = new ElementContainer();
String query;
try
{
station = s.getParser().getRawParameter(STATION_ID, null);
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)
{
query = "SELECT * FROM weather_data WHERE station = [station]";
}
else
{
query = "SELECT * FROM weather_data WHERE station = " + station;
}
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 );
ec.addElement(new PRE(query));
if (station == null)
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 )
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))
{
connection = DatabaseUtilities.makeConnection( s );
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.");
}
Map<String, String> stations = new TreeMap<String, String>();
String query = "SELECT DISTINCT station, name FROM WEATHER_DATA";
}
catch (SQLException sqle)
{
ec.addElement(new P().addElement(sqle.getMessage()));
}
}
catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
try
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))
{
Statement statement = connection.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY );
ResultSet results = statement.executeQuery( query );
ResultSetMetaData resultsMetaData = results.getMetaData();
ec.addElement(DatabaseUtilities.writeTable(results,
resultsMetaData));
results.last();
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();
}
// If they get back more than one row they succeeded
if (results.getRow() > 1)
{
makeSuccess(s);
}
}
catch ( SQLException sqle )
else
{
sqle.printStackTrace();
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>
}
return stations;
results.close();
}
}
/**
* Gets the category attribute of the SqNumericInjection object
*
* @return The category value
*/
protected Category getDefaultCategory()
catch (SQLException sqle)
{
return AbstractLesson.A6;
sqle.printStackTrace();
}
return stations;
}
/**
* Gets the hints attribute of the DatabaseFieldScreen object
*
* @return The hints value
*/
protected List getHints()
/**
* 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
{
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 ]." );
super.handleRequest(s);
return hints;
if (connection == null)
{
connection = DatabaseUtilities.makeConnection(s);
}
}
private final static Integer DEFAULT_RANKING = new Integer(70);
protected Integer getDefaultRanking()
catch (Exception e)
{
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 );
}
System.out.println("Exception caught: " + e);
e.printStackTrace(System.out);
}
}
}

View File

@ -19,257 +19,302 @@ 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.
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</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);
}
private final static String ACCT_NAME = "account_name";
protected Element injectableQuery( WebSession s )
{
ElementContainer ec = new ElementContainer();
private static Connection connection = null;
try
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))
{
if ( connection == null )
{
connection = DatabaseUtilities.makeConnection( s );
}
ResultSetMetaData resultsMetaData = results.getMetaData();
ec.addElement(DatabaseUtilities.writeTable(results,
resultsMetaData));
results.last();
ec.addElement( makeAccountLine( s ) );
// If they get back more than one user they succeeded
if (results.getRow() >= 6)
{
makeSuccess(s);
getLessonTracker(s).setStage(2);
String query = "SELECT * FROM user_data WHERE last_name = '" + accountName +"'";
ec.addElement( new PRE( query ) );
StringBuffer msg = new StringBuffer();
try
{
Statement statement = connection.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY );
ResultSet results = statement.executeQuery( query );
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.");
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() ) );
}
s.setMessage(msg.toString());
}
}
catch ( Exception e )
else
{
s.setMessage( "Error generating " + this.getClass().getName() );
e.printStackTrace();
ec.addElement("No results matched. Try Again.");
}
return ( ec );
}
catch (SQLException sqle)
{
ec.addElement(new P().addElement(sqle.getMessage()));
}
}
protected Element parameterizedQuery( WebSession s )
catch (Exception e)
{
ElementContainer ec = new ElementContainer();
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
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"))
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))
{
getLessonTracker(s).getLessonProperties().setProperty(STAGE,"1");
return( injectableQuery(s));
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);
}
}
ec.addElement( new BR() );
try
else
{
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() ) );
}
ec.addElement("No results matched. Try Again.");
}
catch ( Exception e )
{
s.setMessage( "Error generating " + this.getClass().getName() );
e.printStackTrace();
}
return ( ec );
}
catch (SQLException sqle)
{
ec.addElement(new P().addElement(sqle.getMessage()));
}
}
protected Element makeAccountLine( WebSession s )
catch (Exception e)
{
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;
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
/**
* Gets the category attribute of the SqNumericInjection object
*
* @return The category value
*/
protected Category getDefaultCategory()
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
{
return AbstractLesson.A6;
super.handleRequest(s);
if (connection == null)
{
connection = DatabaseUtilities.makeConnection(s);
}
}
/**
* Gets the hints attribute of the DatabaseFieldScreen object
*
* @return The hints value
*/
protected List getHints()
catch (Exception e)
{
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 );
}
System.out.println("Exception caught: " + e);
e.printStackTrace(System.out);
}
}
}

View File

@ -22,312 +22,362 @@ 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.
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @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
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 )
/**
* 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
{
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());
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<String> hints = new ArrayList<String>();
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: &lt;script language=\"javascript\" type=\"text/javascript\"&gt;alert(\"Ha Ha Ha\");&lt;/script&gt; in the message field.");
hints
.add("Enter this: &lt;script&gtalert(\"document.cookie\");&lt;/script&gt; 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)
{
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());
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<String> hints = new ArrayList<String>();
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: &lt;script language=\"javascript\" type=\"text/javascript\"&gt;alert(\"Ha Ha Ha\");&lt;/script&gt; in the message field." );
hints.add( "Enter this: &lt;script&gtalert(\"document.cookie\");&lt;/script&gt; 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();
makeSuccess(s);
}
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
}
else
{
if (messageNum != 0)
{
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 );
}
}
ec.addElement(new P().addElement("Could not find message "
+ messageNum));
}
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 )
catch (Exception e)
{
String nameroot = name;
if (nameroot.indexOf('-') != -1)
{
nameroot = nameroot.substring(0, nameroot.indexOf('-'));
}
return nameroot;
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;
}
}

View File

@ -14,168 +14,204 @@ 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.
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @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;
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 )
/**
* 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
{
ElementContainer ec = new ElementContainer();
if (connection == null)
{
connection = DatabaseUtilities.makeConnection(s);
}
try
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))
{
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 );
}
ec.addElement("Account information for user: "
+ originalUser + "<br><br>");
ResultSetMetaData resultsMetaData = results.getMetaData();
ec.addElement(DatabaseUtilities.writeTable(results,
resultsMetaData));
}
catch ( Exception e )
else
{
s.setMessage( "Error generating " + this.getClass().getName() );
e.printStackTrace();
s.setMessage("'" + currentUser
+ "' is not a user in the WebGoat database.");
}
}
if (!user1.equals(currentUser))
{
makeSuccess(s);
}
return ( ec );
}
/**
* Gets the hints attribute of the ConcurrencyScreen object
*
* @return The hints value
*/
protected List getHints()
catch (Exception e)
{
List<String> hints = new ArrayList<String>();
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;
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
return (ec);
}
/**
* Gets the instructions attribute of the ThreadSafetyProblem object
*
* @return The instructions value
*/
public String getInstructions(WebSession s)
/**
* Gets the hints attribute of the ConcurrencyScreen object
*
* @return The hints value
*/
protected List getHints()
{
List<String> hints = new ArrayList<String>();
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
{
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.";
super.handleRequest(s);
return (instructions );
if (connection == null)
{
connection = DatabaseUtilities.makeConnection(s);
}
}
private final static Integer DEFAULT_RANKING = new Integer(80);
protected Integer getDefaultRanking()
catch (Exception e)
{
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 );
}
System.out.println("Exception caught: " + e);
e.printStackTrace(System.out);
}
}
}

View File

@ -19,12 +19,34 @@ 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.
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003
@ -33,193 +55,232 @@ import org.owasp.webgoat.util.HtmlEncoder;
public class TraceXSS extends LessonAdapter
{
/**
* Description of the Method
*
* @param s Description of the Parameter
* @return Description of the Return Value
*/
/**
* Description of the Method
*
* @param s Description of the Parameter
* @return Description of the Return Value
*/
protected Element createContent( WebSession s )
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;
ElementContainer ec = new ElementContainer();
String regex1 = "^[0-9]{3}$";// any three digits
Pattern pattern1 = Pattern.compile( regex1 );
try
// test input field1
if (!pattern1.matcher(param1).matches())
{
if (param1.toLowerCase().indexOf("script") != -1
&& param1.toLowerCase().indexOf("trace") != -1)
{
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( "&nbsp;" ).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%") );
makeSuccess(s);
}
catch ( Exception e )
{
s.setMessage( "Error generating " + this.getClass().getName() );
e.printStackTrace();
}
return ( ec );
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("&nbsp;").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%"));
}
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
protected Category getDefaultCategory()
catch (Exception e)
{
return AbstractLesson.A4;
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>" +
"&lt;script type=\"text/javascript\"&gt;if ( navigator.appName.indexOf(\"Microsoft\") !=-1)" +
" {var xmlHttp = new ActiveXObject(\"Microsoft.XMLHTTP\");xmlHttp.open(\"GET\", \"./\", false);" +
" xmlHttp.send();str1=xmlHttp.responseText; " +
"document.write(str1);&lt;/script&gt;");
hints.add( "Try changing the HTTP GET to a HTTP TRACE" );
hints.add( "Try a cross site trace (XST) Command:<br>" +
"&lt;script type=\"text/javascript\"&gt;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\",\"&lt;br&gt;\"); " +
"document.write(str1);}&lt;/script&gt;");
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);
/**
* 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>"
+ "&lt;script type=\"text/javascript\"&gt;if ( navigator.appName.indexOf(\"Microsoft\") !=-1)"
+ " {var xmlHttp = new ActiveXObject(\"Microsoft.XMLHTTP\");xmlHttp.open(\"GET\", \"./\", false);"
+ " xmlHttp.send();str1=xmlHttp.responseText; "
+ "document.write(str1);&lt;/script&gt;");
hints.add("Try changing the HTTP GET to a HTTP TRACE");
hints
.add("Try a cross site trace (XST) Command:<br>"
+ "&lt;script type=\"text/javascript\"&gt;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\",\"&lt;br&gt;\"); "
+ "document.write(str1);}&lt;/script&gt;");
return hints;
}
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
// <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 title attribute of the AccessControlScreen object
*
* @return The title value
*/
public String getTitle()
{
return ( "How to Perform Cross Site Trace Attacks" );
}
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");
}
}

View File

@ -25,11 +25,34 @@ 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.
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003
@ -38,189 +61,204 @@ import org.owasp.webgoat.session.WebSession;
public class UncheckedEmail extends LessonAdapter
{
private final static String MESSAGE = "msg";
private final static String TO = "to";
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
*/
/**
* Description of the Method
*
* @param s Description of the Parameter
* @return Description of the Return Value
*/
protected Element createContent( WebSession s )
protected Element createContent(WebSession s)
{
ElementContainer ec = new ElementContainer();
try
{
String to = s.getParser().getRawParameter(TO, "");
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");
Table t = new Table().setCellSpacing( 0 ).setCellPadding( 2 ).setBorder( 0 ).setWidth("90%").setAlign("center");
if (s.isColor())
{
t.setBorder(1);
}
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( "&nbsp;").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( "&nbsp;"));
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( "&nbsp;"));
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 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( "&nbsp;").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( "&nbsp;"));
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( "&nbsp;"));
t.addElement( tr );
ec.addElement( t );
tr = new TR();
tr.addElement(new TD().addElement("&nbsp;").setColSpan(3));
t.addElement(tr);
// Eventually we could send the actually mail, but the point should already be made
//ec.addElement(exec( use java mail here + to));
tr = new TR();
tr.addElement(new TH().addElement(new H1("Contact Us")).setAlign(
"left").setWidth("55%").setVAlign("BOTTOM"));
tr.addElement(new TH().addElement("&nbsp;"));
tr.addElement(new TH().addElement(new H3("Contact Information:"))
.setAlign("left").setVAlign("BOTTOM"));
t.addElement(tr);
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
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("&nbsp;"));
tr.addElement(new TD().addElement(
"<b>OWASP</B><BR>" + "9175 Guilford Rd <BR> Suite 300 <BR>"
+ "Columbia, MD. 21046").setVAlign("top"));
t.addElement(tr);
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> &lt;webgoat@owasp.org&gt;"));
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 &lt;" + to+"&gt;; " + 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 &lt;webgoat@owasp.org&gt;"));
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 );
tr = new TR();
tr.addElement(new TD().addElement("&nbsp;").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("&nbsp;"));
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("&nbsp;"));
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> &lt;webgoat@owasp.org&gt;"));
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 &lt;" + to + "&gt;; "
+ 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 &lt;webgoat@owasp.org&gt;"));
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);
}
}
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
protected Category getDefaultCategory()
catch (Exception e)
{
return AbstractLesson.A1;
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
return (ec);
}
/**
* Gets the hints attribute of the EmailScreen object
*
* @return The hints value
*/
protected List getHints()
{
List<String> hints = new ArrayList<String>();
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 &lt;A href=\"http://www.aspectsecurity.com/webgoat.html\"&gt;Click here for Aspect&lt;/A&gt in the message field" );
hints.add( "Insert &lt;script&gt;alert(\"Bad Stuff\");&lt;/script&gt; in the message field" );
return hints;
}
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
protected Category getDefaultCategory()
{
return AbstractLesson.A1;
}
/**
* 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 );
}
/**
* Gets the hints attribute of the EmailScreen object
*
* @return The hints value
*/
protected List getHints()
{
List<String> hints = new ArrayList<String>();
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 &lt;A href=\"http://www.aspectsecurity.com/webgoat.html\"&gt;Click here for Aspect&lt;/A&gt in the message field");
hints
.add("Insert &lt;script&gt;alert(\"Bad Stuff\");&lt;/script&gt; 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);
private final static Integer DEFAULT_RANKING = new Integer(55);
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
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" );
}
/**
* Gets the title attribute of the EmailScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("How to Exploit Unchecked Email");
}
}

View File

@ -38,225 +38,312 @@ import org.owasp.webgoat.session.DatabaseUtilities;
import org.owasp.webgoat.session.ECSFactory;
import org.owasp.webgoat.session.WebSession;
/**
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author 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 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 );
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;
{
return AbstractLesson.WEB_SERVICES;
}
protected Element createContent(WebSession s)
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
{
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);
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;
}
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;
catch (RemoteException e)
{
e.printStackTrace();
}
public String getCreditCard(int id) {
String result = getResults(id, "cc_number");
if (result != null)
{
completed = true;
return result;
}
return null;
catch (ServiceException e)
{
e.printStackTrace();
}
public String getFirstName(int id) {
String result = getResults(id, "first_name");
if (result != null)
{
return result;
}
return null;
catch (Exception e)
{
e.printStackTrace();
}
public String getLastName(int id) {
String result = getResults(id, "last_name");
if (result != null)
{
return result;
}
return null;
return null;
}
public String getLoginCount(int id) {
String result = getResults(id, "login_count");
if (result != null)
{
return result;
}
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);
return super.getCustomCredits("By Alex Smolen", CREDITS_LOGO);
}
}

View File

@ -16,333 +16,369 @@ 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.
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @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 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
/**
* 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)
{
String cookie = getCookie( s );
if (cookie.equals(encode("webgoat12345")))
{
return ("webgoat");
}
if ( cookie != null )
{
if ( cookie.equals( encode( "webgoat12345" ) ) )
{
return ( "webgoat" );
}
if (cookie.equals(encode("aspect12345")))
{
return ("aspect");
}
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 );
if (cookie.equals(encode("alice12345")))
{
makeSuccess(s);
return ("alice");
}
else
{
s.setMessage("Invalid cookie");
s.eatCookies();
}
}
/**
* 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
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 username = s.getParser().getStringParameter( USERNAME, "" );
String password = s.getParser().getStringParameter( PASSWORD, "" );
String loginID = "";
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 );
if (username.equals("webgoat") && password.equals("webgoat"))
{
loginID = encode("webgoat12345");
}
else if (username.equals("aspect") && password.equals("aspect"))
{
loginID = encode("aspect12345");
}
return ( username );
}
else
{
s.setMessage( "Invalid username and password entered." );
}
}
if (loginID != "")
{
Cookie newCookie = new Cookie(AUTHCOOKIE, loginID);
s.setMessage("Your identity has been remembered");
s.getResponse().addCookie(newCookie);
return ( null );
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 )
/**
* 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)
{
boolean logout = s.getParser().getBooleanParameter( LOGOUT, false );
s.setMessage("Goodbye! Your password has been forgotten");
s.eatCookies();
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 ) );
return (makeLogin(s));
}
/**
* Description of the Method
*
* @param value Description of the Parameter
* @return Description of the Return Value
*/
private String encode( String value )
try
{
//<START_OMIT_SOURCE>
StringBuffer encoded = new StringBuffer();
String user = checkCookie(s);
for ( int i = 0; i < value.length(); i++ )
{
encoded.append( String.valueOf( (char) ( value.charAt( i ) + 1 ) ) );
}
if ((user != null) && (user.length() > 0))
{
return (makeUser(s, user, "COOKIE"));
}
return encoded.reverse().toString();
//<END_OMIT_SOURCE>
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));
}
/**
* Gets the category attribute of the WeakAuthenticationCookie object
*
* @return The category value
*/
protected Category getDefaultCategory()
/**
* 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++)
{
return AbstractLesson.A3;
encoded.append(String.valueOf((char) (value.charAt(i) + 1)));
}
return encoded.reverse().toString();
//<END_OMIT_SOURCE>
}
/**
* Gets the cookie attribute of the CookieScreen object
*
* @param s Description of the Parameter
* @return The cookie value
*/
protected String getCookie( WebSession s )
/**
* 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++)
{
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 );
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()
/**
* 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 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())
{
List<String> hints = new ArrayList<String>();
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;
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);
/**
* 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.";
tr = new TR();
tr.addElement(new TD().addElement("*Required Fields").setWidth("30%"));
t.addElement(tr);
return ( instructions );
}
tr = new TR();
tr.addElement(new TD().addElement("&nbsp;").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", "", "")));
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("&nbsp;").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 );
}
return (ec);
}
}

View File

@ -20,199 +20,254 @@ 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.
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Rogan Dawes <a href="http://dawes.za.net/rogan">Rogan Dawes</a>
* @created March 30, 2005
*/
public class WeakSessionID extends LessonAdapter {
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");
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);
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) );
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 );
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;
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 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;
}
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" );
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("&nbsp;").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 );
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("&nbsp;").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);
}
}

View File

@ -11,118 +11,153 @@ 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.
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @created October 28, 2003
*/
public class WelcomeScreen extends Screen
{
/**
* Constructor for the WelcomeScreen object
*
* @param s Description of the Parameter
*/
public WelcomeScreen( WebSession s )
/**
* 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)
{
setup( s );
return new StringElement("Invalid Session");
}
/**
* Constructor for the WelcomeScreen object
*/
public WelcomeScreen() { }
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);
}
public void setup( WebSession s )
{
// call createContent first so messages will go somewhere
/**
* 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));
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 );
}
return (ec);
}
/**
* Gets the title attribute of the WelcomeScreen object
*
* @return The title value
*/
public String getTitle()
{
return ( "Welcome to the Penetration Testing Course" );
}
public Element getCredits()
{
return new ElementContainer();
}
/* (non-Javadoc)
* @see session.Screen#getRole()
*/
public String getRole() {
return AbstractLesson.USER_ROLE;
}
/**
* 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;
}
}

View File

@ -29,152 +29,235 @@ import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;
/**
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author 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";
public class WsSAXInjection extends LessonAdapter
{
private String password;
private final static String PASSWORD = "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 String password;
private static String template2 = "</password>\n"
+ " </wsns1:changePassword>\n" + " </wsns0:Body>\n"
+ "</wsns0:Envelope>";
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'>";
static boolean completed;
private static String template2 = "</password>\n"
+ " </wsns1:changePassword>\n" + " </wsns0:Body>\n"
+ "</wsns0:Envelope>";
protected Category getDefaultCategory() {
return AbstractLesson.WEB_SERVICES;
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());
}
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;
public void characters(char[] ch, int start, int length)
throws SAXException
{
text.append(ch, start, length);
}
private final static Integer DEFAULT_RANKING = new Integer(150);
protected Integer getDefaultRanking() {
return DEFAULT_RANKING;
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 String getTitle() {
return "Web Service SAX Injection";
public void ignorableWhitespace(char[] ch, int start, int length)
throws SAXException
{
text.append(ch, start, length);
}
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;
public String getId()
{
return id;
}
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);
public String getPassword()
{
return password;
}
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;
}
}
}
}

View File

@ -27,191 +27,258 @@ import org.owasp.webgoat.session.DatabaseUtilities;
import org.owasp.webgoat.session.ECSFactory;
import org.owasp.webgoat.session.WebSession;
/**
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author 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 &quot;&quot;<br><br>" +
"The soap message body has the following format:<br>" +
"&lt;?xml version='1.0' encoding='UTF-8'?&gt; <br>" +
"&nbsp;&nbsp;&lt;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'&gt; <br>" +
"&nbsp;&nbsp;&nbsp;&nbsp;&lt;SOAP-ENV:Body&gt; <br>" +
"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ns1:getCreditCard SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' xmlns:ns1='http://lessons'&gt; <br>" +
"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;id xsi:type='xsd:string'&gt;101&lt;/id&gt; <br>" +
"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/ns1:getCreditCard&gt; <br>" +
"&nbsp;&nbsp;&nbsp;&nbsp;&lt;/SOAP-ENV:Body&gt; <br>" +
"&nbsp;&nbsp;&lt;/SOAP-ENV:Envelope&gt; <br>" +
"");
/* "&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt; <br>" +
" &lt;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\"&gt; <br>" +
" &lt;SOAP-ENV:Body&gt; <br>" +
" &lt;ns1:getCreditCard SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:ns1=\"http://lessons\"&gt; <br>" +
" &lt;id xsi:type=\"xsd:string\"&gt;101&lt;/id&gt; <br>"+
" &lt;/ns1:getCreditCard&gt; <br>" +
" &lt;/SOAP-ENV:Body&gt; <br>" +
" &lt;/SOAP-ENV:Envelope&gt; <br><br>" +
"Intercept the HTTP request and try to create a soap request."); */
return hints;
}
public class WsSqlInjection extends LessonAdapter
{
private final static Integer DEFAULT_RANKING = new Integer(150);
public final static String ccNumber = "cc_number";
protected Integer getDefaultRanking()
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 &quot;&quot;<br><br>"
+ "The soap message body has the following format:<br>"
+ "&lt;?xml version='1.0' encoding='UTF-8'?&gt; <br>"
+ "&nbsp;&nbsp;&lt;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'&gt; <br>"
+ "&nbsp;&nbsp;&nbsp;&nbsp;&lt;SOAP-ENV:Body&gt; <br>"
+ "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ns1:getCreditCard SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' xmlns:ns1='http://lessons'&gt; <br>"
+ "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;id xsi:type='xsd:string'&gt;101&lt;/id&gt; <br>"
+ "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/ns1:getCreditCard&gt; <br>"
+ "&nbsp;&nbsp;&nbsp;&nbsp;&lt;/SOAP-ENV:Body&gt; <br>"
+ "&nbsp;&nbsp;&lt;/SOAP-ENV:Envelope&gt; <br>" + "");
/* "&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt; <br>" +
" &lt;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\"&gt; <br>" +
" &lt;SOAP-ENV:Body&gt; <br>" +
" &lt;ns1:getCreditCard SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:ns1=\"http://lessons\"&gt; <br>" +
" &lt;id xsi:type=\"xsd:string\"&gt;101&lt;/id&gt; <br>"+
" &lt;/ns1:getCreditCard&gt; <br>" +
" &lt;/SOAP-ENV:Body&gt; <br>" +
" &lt;/SOAP-ENV:Envelope&gt; <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
{
return DEFAULT_RANKING;
}
if (connection == null)
{
connection = DatabaseUtilities.makeConnection(s);
}
ec.addElement(makeAccountLine(s));
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
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')
{
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 );
ec.addElement("Invalid account number. ");
accountNumber = "0";
}
catch (Exception e)
}
try
{
ResultSet results = getResults(accountNumber);
if ((results != null) && (results.first() == true))
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
ResultSetMetaData resultsMetaData = results.getMetaData();
ec.addElement(DatabaseUtilities.writeTable(results,
resultsMetaData));
results.last();
if (results.getRow() >= 6)
{
//this should never happen
}
}
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 )
else
{
ec.addElement("No results matched. Try Again.");
}
return null;
}
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);
}
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) {
}
}
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);
return super.getCustomCredits("By Alex Smolen", CREDITS_LOGO);
}
}

View File

@ -21,263 +21,370 @@ import org.apache.ecs.html.Div;
import org.apache.ecs.vxml.Initial;
import org.apache.ecs.StringElement;
import org.owasp.webgoat.session.WebSession;
public class XMLInjection extends LessonAdapter {
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*/
public class XMLInjection extends LessonAdapter
{
private final static Integer DEFAULT_RANKING = new Integer(20);
private final static String ACCOUNTID = "accountID";
private final static Integer DEFAULT_RANKING = new Integer(20);
public static HashMap rewardsMap = new HashMap();
protected static HashMap init()
private final static String ACCOUNTID = "accountID";
public static HashMap rewardsMap = new HashMap();
protected static HashMap init()
{
Reward r = new Reward();
r.setName("WebGoat t-shirt");
r.setPoints(50);
rewardsMap.put(1001, r);
r = new Reward();
r.setName("WebGoat Secure Kettle");
r.setPoints(30);
rewardsMap.put(1002, r);
r = new Reward();
r.setName("WebGoat Mug");
r.setPoints(20);
rewardsMap.put(1003, r);
r = new Reward();
r.setName("WebGoat Core Duo Laptop");
r.setPoints(2000);
rewardsMap.put(1004, r);
r = new Reward();
r.setName("WebGoat Hawaii Cruise");
r.setPoints(3000);
rewardsMap.put(1005, r);
return rewardsMap;
}
public void handleRequest(WebSession s)
{
try
{
Reward r = new Reward();
r.setName("WebGoat t-shirt");
r.setPoints(50);
rewardsMap.put( 1001 , r);
r = new Reward();
r.setName("WebGoat Secure Kettle");
r.setPoints(30);
rewardsMap.put( 1002 , r);
r = new Reward();
r.setName("WebGoat Mug");
r.setPoints(20);
rewardsMap.put( 1003 , r);
r = new Reward();
r.setName("WebGoat Core Duo Laptop");
r.setPoints(2000);
rewardsMap.put( 1004 , r);
r = new Reward();
r.setName("WebGoat Hawaii Cruise");
r.setPoints(3000);
rewardsMap.put( 1005 , r);
return rewardsMap;
}
public void handleRequest(WebSession s) {
try
if (s.getParser().getRawParameter("from", "").equals("ajax"))
{
if (s.getParser().getRawParameter(ACCOUNTID, "").equals(
"836239"))
{
if(s.getParser().getRawParameter("from", "").equals("ajax"))
{
if(s.getParser().getRawParameter(ACCOUNTID, "").equals("836239"))
{
String lineSep = System.getProperty("line.separator");
String xmlStr = "<root>" + lineSep +
"<reward>WebGoat t-shirt 20 Pts</reward>" + lineSep +
"<reward>WebGoat Secure Kettle 50 Pts</reward>" + lineSep +
"<reward>WebGoat Mug 30 Pts</reward>" + lineSep +
"</root>";
s.getResponse().setContentType("text/xml");
s.getResponse().setHeader("Cache-Control", "no-cache");
PrintWriter out = new PrintWriter(s.getResponse().getOutputStream());
out.print(xmlStr);
out.flush();
out.close();
return;
}
}
String lineSep = System.getProperty("line.separator");
String xmlStr = "<root>" + lineSep
+ "<reward>WebGoat t-shirt 20 Pts</reward>"
+ lineSep
+ "<reward>WebGoat Secure Kettle 50 Pts</reward>"
+ lineSep + "<reward>WebGoat Mug 30 Pts</reward>"
+ lineSep + "</root>";
s.getResponse().setContentType("text/xml");
s.getResponse().setHeader("Cache-Control", "no-cache");
PrintWriter out = new PrintWriter(s.getResponse()
.getOutputStream());
out.print(xmlStr);
out.flush();
out.close();
return;
}
catch (Exception ex)
{
ex.printStackTrace();
}
Form form = new Form( getFormAction(), Form.POST ).setName( "form" ).setEncType( "" );
form.addElement( createContent( s ) );
setContent(form);
}
}
protected Element createContent(WebSession s) {
ElementContainer ec = new ElementContainer();
boolean isDone = false;
init();
if (s.getParser().getRawParameter("done", "").equals("yes"))
{
isDone = true;
}
String lineSep = System.getProperty("line.separator");
String script = "<script>" + lineSep +
"function getRewards() {" + lineSep +
"var accountIDField = document.getElementById('" + ACCOUNTID + "');" + lineSep +
"if (accountIDField.value.length < 6 ) { return; }" + lineSep +
"var url = '/WebGoat/attack?Screen=" + String.valueOf(getScreenId()) +
"&menu=" + getDefaultCategory().getRanking().toString() +
"&from=ajax&" + ACCOUNTID + "=' + encodeURIComponent(accountIDField.value);" + lineSep +
"if (typeof XMLHttpRequest != 'undefined') {" + lineSep +
"req = new XMLHttpRequest();" + lineSep +
"} else if (window.ActiveXObject) {" + lineSep +
"req = new ActiveXObject('Microsoft.XMLHTTP');" + lineSep +
" }" + lineSep +
" req.open('GET', url, true);" + lineSep +
" req.onreadystatechange = callback;" + lineSep +
" req.send(null);" + lineSep +
"}" + lineSep +
"function callback() {" + lineSep +
" if (req.readyState == 4) { " + lineSep +
" if (req.status == 200) { " + lineSep +
" var rewards = req.responseXML.getElementsByTagName('root')[0];" + lineSep +
" var rewardsDiv = document.getElementById('rewardsDiv');" + lineSep +
" rewardsDiv.innerHTML = '';" + lineSep +
" var strHTML='';"+ lineSep +
" strHTML = '<tr><td>&nbsp;</td><td><b>Rewards</b></td></tr>';" + lineSep +
" for(var i=0; i< rewards.childNodes.length; i++){" + lineSep +
" var node = rewards.childNodes[i];" + lineSep +
" strHTML = strHTML + '<tr><td><input name=\"check' + (i+1001) +'\" type=\"checkbox\"></td><td>';" + lineSep +
" strHTML = strHTML + node.childNodes[0].nodeValue + '</td></tr>';" + lineSep +
" }" + lineSep +
" strHTML = '<table>' + strHTML + '</table>';" + lineSep +
" strHTML = 'Your account balance is now 100 points<br><br>' + strHTML;" + lineSep +
" rewardsDiv.innerHTML = strHTML;"+ lineSep +
" }}}" + lineSep +
"</script>" + lineSep;
if (!isDone)
{
ec.addElement( new StringElement(script));
}
ec.addElement( new BR().addElement (new H1().addElement( "Welcome to WebGoat-Miles Reward Miles Program.")));
ec.addElement( new BR());
ec.addElement( new BR().addElement (new H3().addElement( "Rewards available through the program:")));
ec.addElement( new BR());
Table t2 = new Table().setCellSpacing(0).setCellPadding(0).setBorder(0).setWidth("90%").setAlign("center");
TR trRewards = null;
for (int i=1001; i< 1001 + rewardsMap.size() ; i++)
{
trRewards = new TR();
Reward r = (Reward)rewardsMap.get(i);
trRewards.addElement( new TD("-" + r.getName() + r.getPoints() + " Pts") );
t2.addElement( trRewards);
}
ec.addElement( t2 );
ec.addElement( new BR());
ec.addElement( new H3().addElement( "Redeem your points:"));
ec.addElement( new BR());
Table t1 = new Table().setCellSpacing(0).setCellPadding(0).setBorder(0).setWidth("90%").setAlign("center");
TR tr = new TR();
tr.addElement( new TD("Please enter your account ID:") );
Input input1 = new Input( Input.TEXT, ACCOUNTID, "" );
input1.addAttribute("onkeyup", "getRewards();");
tr.addElement( new TD(input1));
t1.addElement( tr );
ec.addElement(t1);
ec.addElement(new BR());
ec.addElement(new BR());
ec.addElement(new BR());
Div div = new Div();
div.addAttribute("name", "rewardsDiv");
div.addAttribute("id", "rewardsDiv");
ec.addElement(div);
Input b = new Input();
b.setType( Input.SUBMIT );
b.setValue( "Submit" );
b.setName("SUBMIT");
ec.addElement(b);
if (s.getParser().getRawParameter("SUBMIT", "")!= "")
{
if(s.getParser().getRawParameter("check1004", "") != "")
{
makeSuccess(s);
}
else
{
StringBuffer shipment = new StringBuffer();
for (int i=1001; i< 1001 + rewardsMap.size() ; i++)
{
if (s.getParser().getRawParameter("check" + i, "") != "")
{
shipment.append( ((Reward)rewardsMap.get(i)).getName() + "<br>" );
}
}
shipment.insert(0, "<br><br><b>The following items will be shipped to your address:</b><br>");
ec.addElement( new StringElement(shipment.toString()));
}
}
return ec;
}
protected Element makeSuccess(WebSession s)
{
getLessonTracker( s ).setCompleted( true );
s.setMessage("Congratulations. You have successfully completed this lesson.");
return ( null );
}
public Element getCredits() {
return new StringElement("Created by Sherif Koussa");
}
protected Category getDefaultCategory() {
return AJAX_SECURITY;
}
protected Integer getDefaultRanking() {
return DEFAULT_RANKING;
}
protected List getHints() {
List<String> hints = new ArrayList<String>();
hints.add( "This page is using XMLHTTP to comunicate with the server." );
hints.add( "Try to intercept the reply and check the reply." );
hints.add( "Intercept the reply and try to inject some XML to add more rewards to yourself." );
return hints;
}
public String getTitle() {
return "XML Injection";
}
static class Reward
catch (Exception ex)
{
private String name;
private int points;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPoints() {
return points;
}
public void setPoints(int points) {
this.points = points;
}
ex.printStackTrace();
}
Form form = new Form(getFormAction(), Form.POST).setName("form")
.setEncType("");
form.addElement(createContent(s));
setContent(form);
}
protected Element createContent(WebSession s)
{
ElementContainer ec = new ElementContainer();
boolean isDone = false;
init();
if (s.getParser().getRawParameter("done", "").equals("yes"))
{
isDone = true;
}
String lineSep = System.getProperty("line.separator");
String script = "<script>"
+ lineSep
+ "function getRewards() {"
+ lineSep
+ "var accountIDField = document.getElementById('"
+ ACCOUNTID
+ "');"
+ lineSep
+ "if (accountIDField.value.length < 6 ) { return; }"
+ lineSep
+ "var url = '/WebGoat/attack?Screen="
+ String.valueOf(getScreenId())
+ "&menu="
+ getDefaultCategory().getRanking().toString()
+ "&from=ajax&"
+ ACCOUNTID
+ "=' + encodeURIComponent(accountIDField.value);"
+ lineSep
+ "if (typeof XMLHttpRequest != 'undefined') {"
+ lineSep
+ "req = new XMLHttpRequest();"
+ lineSep
+ "} else if (window.ActiveXObject) {"
+ lineSep
+ "req = new ActiveXObject('Microsoft.XMLHTTP');"
+ lineSep
+ " }"
+ lineSep
+ " req.open('GET', url, true);"
+ lineSep
+ " req.onreadystatechange = callback;"
+ lineSep
+ " req.send(null);"
+ lineSep
+ "}"
+ lineSep
+ "function callback() {"
+ lineSep
+ " if (req.readyState == 4) { "
+ lineSep
+ " if (req.status == 200) { "
+ lineSep
+ " var rewards = req.responseXML.getElementsByTagName('root')[0];"
+ lineSep
+ " var rewardsDiv = document.getElementById('rewardsDiv');"
+ lineSep
+ " rewardsDiv.innerHTML = '';"
+ lineSep
+ " var strHTML='';"
+ lineSep
+ " strHTML = '<tr><td>&nbsp;</td><td><b>Rewards</b></td></tr>';"
+ lineSep
+ " for(var i=0; i< rewards.childNodes.length; i++){"
+ lineSep
+ " var node = rewards.childNodes[i];"
+ lineSep
+ " strHTML = strHTML + '<tr><td><input name=\"check' + (i+1001) +'\" type=\"checkbox\"></td><td>';"
+ lineSep
+ " strHTML = strHTML + node.childNodes[0].nodeValue + '</td></tr>';"
+ lineSep
+ " }"
+ lineSep
+ " strHTML = '<table>' + strHTML + '</table>';"
+ lineSep
+ " strHTML = 'Your account balance is now 100 points<br><br>' + strHTML;"
+ lineSep + " rewardsDiv.innerHTML = strHTML;"
+ lineSep + " }}}" + lineSep + "</script>" + lineSep;
if (!isDone)
{
ec.addElement(new StringElement(script));
}
ec.addElement(new BR().addElement(new H1()
.addElement("Welcome to WebGoat-Miles Reward Miles Program.")));
ec.addElement(new BR());
ec.addElement(new BR().addElement(new H3()
.addElement("Rewards available through the program:")));
ec.addElement(new BR());
Table t2 = new Table().setCellSpacing(0).setCellPadding(0).setBorder(0)
.setWidth("90%").setAlign("center");
TR trRewards = null;
for (int i = 1001; i < 1001 + rewardsMap.size(); i++)
{
trRewards = new TR();
Reward r = (Reward) rewardsMap.get(i);
trRewards.addElement(new TD("-" + r.getName() + r.getPoints()
+ " Pts"));
t2.addElement(trRewards);
}
ec.addElement(t2);
ec.addElement(new BR());
ec.addElement(new H3().addElement("Redeem your points:"));
ec.addElement(new BR());
Table t1 = new Table().setCellSpacing(0).setCellPadding(0).setBorder(0)
.setWidth("90%").setAlign("center");
TR tr = new TR();
tr.addElement(new TD("Please enter your account ID:"));
Input input1 = new Input(Input.TEXT, ACCOUNTID, "");
input1.addAttribute("onkeyup", "getRewards();");
tr.addElement(new TD(input1));
t1.addElement(tr);
ec.addElement(t1);
ec.addElement(new BR());
ec.addElement(new BR());
ec.addElement(new BR());
Div div = new Div();
div.addAttribute("name", "rewardsDiv");
div.addAttribute("id", "rewardsDiv");
ec.addElement(div);
Input b = new Input();
b.setType(Input.SUBMIT);
b.setValue("Submit");
b.setName("SUBMIT");
ec.addElement(b);
if (s.getParser().getRawParameter("SUBMIT", "") != "")
{
if (s.getParser().getRawParameter("check1004", "") != "")
{
makeSuccess(s);
}
else
{
StringBuffer shipment = new StringBuffer();
for (int i = 1001; i < 1001 + rewardsMap.size(); i++)
{
if (s.getParser().getRawParameter("check" + i, "") != "")
{
shipment.append(((Reward) rewardsMap.get(i)).getName()
+ "<br>");
}
}
shipment
.insert(0,
"<br><br><b>The following items will be shipped to your address:</b><br>");
ec.addElement(new StringElement(shipment.toString()));
}
}
return ec;
}
protected Element makeSuccess(WebSession s)
{
getLessonTracker(s).setCompleted(true);
s
.setMessage("Congratulations. You have successfully completed this lesson.");
return (null);
}
public Element getCredits()
{
return new StringElement("Created by Sherif Koussa");
}
protected Category getDefaultCategory()
{
return AJAX_SECURITY;
}
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
protected List getHints()
{
List<String> hints = new ArrayList<String>();
hints.add("This page is using XMLHTTP to comunicate with the server.");
hints.add("Try to intercept the reply and check the reply.");
hints
.add("Intercept the reply and try to inject some XML to add more rewards to yourself.");
return hints;
}
public String getTitle()
{
return "XML Injection";
}
static class Reward
{
private String name;
private int points;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public int getPoints()
{
return points;
}
public void setPoints(int points)
{
this.points = points;
}
}
}

View File

@ -35,165 +35,228 @@ import org.apache.ecs.HtmlColor;
import org.owasp.webgoat.session.WebSession;
import org.owasp.webgoat.session.ECSFactory;
/**
* @author sherif
*
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Sherif Koussa <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created November 28, 2006
*/
public class XPATHInjection extends LessonAdapter {
private final static Integer DEFAULT_RANKING = new Integer(74);
private final static String USERNAME = "Username";
private final static String PASSWORD = "Password";
public class XPATHInjection extends LessonAdapter
{
protected Element createContent(WebSession s) {
private final static Integer DEFAULT_RANKING = new Integer(74);
NodeList nodes = null;
ElementContainer ec = new ElementContainer();
try{
ec.addElement( new BR().addElement (new H1().addElement( "Welcome to WebGoat employee intranet")));
ec.addElement( new BR());
Table t1 = new Table().setCellSpacing(0).setCellPadding(0).setBorder(0).setWidth("90%").setAlign("center");
TR tr = new TR();
tr.addElement( new TH().addElement("Please confirm your username and password before viewing your profile.").setColSpan(2).setAlign("left"));
t1.addElement(tr);
tr = new TR();
tr.addElement( new TD().addElement("*Required Fields").setWidth("30%").setColSpan(2).setAlign("left"));
t1.addElement(tr);
tr = new TR();
tr.addElement( new TD().addElement("&nbsp").setWidth("30%").setColSpan(2).setAlign("left"));
t1.addElement(tr);
private final static String USERNAME = "Username";
tr = new TR();
tr.addElement( new TD( new B( new StringElement( "*User Name: " ) ) ));
Input input1 = new Input( Input.TEXT, USERNAME, "" );
tr.addElement( new TD( input1 ) );
t1.addElement( tr );
private final static String PASSWORD = "Password";
tr = new TR();
tr.addElement( new TD( new B( new StringElement( "*Password: " ) ) ));
Input input2 = new Input( Input.PASSWORD, PASSWORD, "" );
tr.addElement( new TD( input2 ) );
t1.addElement( tr );
protected Element createContent(WebSession s)
{
Element b = ECSFactory.makeButton( "Submit" );
t1.addElement( new TR( new TD( b ) ) );
ec.addElement( t1 );
String username = s.getParser().getRawParameter(USERNAME , "");
if (username == null || username.length() == 0)
{
ec.addElement( new P().addElement( new StringElement("Username is a required field")));
return ec;
}
String password = s.getParser().getRawParameter(PASSWORD , "");
if (password == null || password.length() == 0)
{
ec.addElement( new P().addElement( new StringElement("Password is a required field")));
return ec;
}
String dir = s.getContext().getRealPath( "/lessons/XPATHInjection/EmployeesData.xml" );
File d = new File( dir );
XPathFactory factory = XPathFactory.newInstance();
XPath xPath = factory.newXPath();
InputSource inputSource = new InputSource(new FileInputStream(d));
String expression = "/employees/employee[loginID/text()='" + username + "' and passwd/text()='" + password + "']";
nodes = (NodeList)xPath.evaluate(expression, inputSource, XPathConstants.NODESET);
int nodesLength = nodes.getLength();
Table t2 = null;
if (nodesLength > 0)
{
t2 = new Table().setCellSpacing(0).setCellPadding(0).setBorder(1).setWidth("90%").setAlign("center");
tr = new TR();
tr.setBgColor( HtmlColor.GRAY );
tr.addElement( new TD().addElement("Username") );
tr.addElement( new TD().addElement("Account No.") );
tr.addElement( new TD().addElement("Salary") );
t2.addElement(tr);
}
for (int i=0; i<nodesLength; i++)
{
Node node = nodes.item(i);
String[] arrTokens = node.getTextContent().split("[\\t\\s\\n]+");
tr = new TR();
tr.addElement( new TD().addElement(arrTokens[1]) );
tr.addElement( new TD().addElement(arrTokens[2]) );
tr.addElement( new TD().addElement(arrTokens[4]) );
t2.addElement(tr);
}
if (nodes.getLength() > 1)
{
makeSuccess( s );
}
if (t2 != null)
{
ec.addElement( new PRE());
ec.addElement(t2);
}
}
catch (IOException e)
{
s.setMessage( "Error generating " + this.getClass().getName() );
e.printStackTrace();
}
catch (IllegalArgumentException e)
{
s.setMessage( "Error generating " + this.getClass().getName() );
e.printStackTrace();
}
catch (XPathExpressionException e)
{
s.setMessage( "Error generating " + this.getClass().getName() );
e.printStackTrace();
}
NodeList nodes = null;
ElementContainer ec = new ElementContainer();
try
{
ec.addElement(new BR().addElement(new H1()
.addElement("Welcome to WebGoat employee intranet")));
ec.addElement(new BR());
Table t1 = new Table().setCellSpacing(0).setCellPadding(0)
.setBorder(0).setWidth("90%").setAlign("center");
TR tr = new TR();
tr
.addElement(new TH()
.addElement(
"Please confirm your username and password before viewing your profile.")
.setColSpan(2).setAlign("left"));
t1.addElement(tr);
tr = new TR();
tr.addElement(new TD().addElement("*Required Fields").setWidth(
"30%").setColSpan(2).setAlign("left"));
t1.addElement(tr);
tr = new TR();
tr.addElement(new TD().addElement("&nbsp").setWidth("30%")
.setColSpan(2).setAlign("left"));
t1.addElement(tr);
tr = new TR();
tr.addElement(new TD(new B(new StringElement("*User Name: "))));
Input input1 = new Input(Input.TEXT, USERNAME, "");
tr.addElement(new TD(input1));
t1.addElement(tr);
tr = new TR();
tr.addElement(new TD(new B(new StringElement("*Password: "))));
Input input2 = new Input(Input.PASSWORD, PASSWORD, "");
tr.addElement(new TD(input2));
t1.addElement(tr);
Element b = ECSFactory.makeButton("Submit");
t1.addElement(new TR(new TD(b)));
ec.addElement(t1);
String username = s.getParser().getRawParameter(USERNAME, "");
if (username == null || username.length() == 0)
{
ec.addElement(new P().addElement(new StringElement(
"Username is a required field")));
return ec;
}
}
public Element getCredits() {
return new StringElement("Created by Sherif Koussa");
}
String password = s.getParser().getRawParameter(PASSWORD, "");
if (password == null || password.length() == 0)
{
ec.addElement(new P().addElement(new StringElement(
"Password is a required field")));
return ec;
}
protected Category getDefaultCategory() {
return AbstractLesson.A6;
}
String dir = s.getContext().getRealPath(
"/lessons/XPATHInjection/EmployeesData.xml");
File d = new File(dir);
XPathFactory factory = XPathFactory.newInstance();
XPath xPath = factory.newXPath();
InputSource inputSource = new InputSource(new FileInputStream(d));
String expression = "/employees/employee[loginID/text()='"
+ username + "' and passwd/text()='" + password + "']";
nodes = (NodeList) xPath.evaluate(expression, inputSource,
XPathConstants.NODESET);
int nodesLength = nodes.getLength();
protected boolean getDefaultHidden() {
// TODO Auto-generated method stub
return false;
}
Table t2 = null;
if (nodesLength > 0)
{
t2 = new Table().setCellSpacing(0).setCellPadding(0).setBorder(
1).setWidth("90%").setAlign("center");
tr = new TR();
tr.setBgColor(HtmlColor.GRAY);
tr.addElement(new TD().addElement("Username"));
tr.addElement(new TD().addElement("Account No."));
tr.addElement(new TD().addElement("Salary"));
t2.addElement(tr);
}
protected Integer getDefaultRanking() {
return DEFAULT_RANKING;
}
for (int i = 0; i < nodesLength; i++)
{
Node node = nodes.item(i);
String[] arrTokens = node.getTextContent()
.split("[\\t\\s\\n]+");
protected List getHints() {
// TODO Auto-generated method stub
List<String> hints = new ArrayList<String>();
hints.add( "Remember that the data is stored in XML format." );
hints.add( "The system is using XPath to query." );
hints.add( "XPath is almost the same thing as SQL, the same hacking techniques apply too." );
hints.add( "Try username: Smith' or 1=1 or 'a'='a and a password: anything " );
return hints;
}
tr = new TR();
tr.addElement(new TD().addElement(arrTokens[1]));
tr.addElement(new TD().addElement(arrTokens[2]));
tr.addElement(new TD().addElement(arrTokens[4]));
t2.addElement(tr);
}
if (nodes.getLength() > 1)
{
makeSuccess(s);
}
if (t2 != null)
{
ec.addElement(new PRE());
ec.addElement(t2);
}
public String getTitle() {
return "How to Perform XPATH Injection";
}
catch (IOException e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
catch (IllegalArgumentException e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
catch (XPathExpressionException e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
return ec;
}
public Element getCredits()
{
return new StringElement("Created by Sherif Koussa");
}
protected Category getDefaultCategory()
{
return AbstractLesson.A6;
}
protected boolean getDefaultHidden()
{
// TODO Auto-generated method stub
return false;
}
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
protected List getHints()
{
// TODO Auto-generated method stub
List<String> hints = new ArrayList<String>();
hints.add("Remember that the data is stored in XML format.");
hints.add("The system is using XPath to query.");
hints
.add("XPath is almost the same thing as SQL, the same hacking techniques apply too.");
hints
.add("Try username: Smith' or 1=1 or 'a'='a and a password: anything ");
return hints;
}
public String getTitle()
{
return "How to Perform XPATH Injection";
}
}

View File

@ -1,76 +1,104 @@
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.
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @created October 28, 2003
*/
public abstract class AdminScreen extends Screen
{
/**
* Description of the Field
*/
protected String query = null;
/**
* 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 );
/**
* 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?
}
// 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
*
* @param s Description of the Parameter
*/
public AdminScreen(WebSession s)
{}
/**
* Constructor for the AdminScreen object
*/
public AdminScreen() { }
/**
* 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" );
}
/**
* 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;
}
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;
}
}

View File

@ -12,94 +12,123 @@ 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.
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @created October 28, 2003
*/
public class ProductsAdminScreen extends LessonAdapter
{
private final static String QUERY = "SELECT * FROM product_system_data";
private static Connection connection = null;
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 )
/**
* 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
{
ElementContainer ec = new ElementContainer();
if (connection == null)
{
connection = DatabaseUtilities.makeConnection(s);
}
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);
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 );
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();
}
/**
* 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;
}
return (ec);
}
/**
* 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);
/**
* Gets the category attribute of the ProductsAdminScreen object
*
* @return The category value
*/
protected Category getDefaultCategory()
{
return ADMIN_FUNCTIONS;
}
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
/**
* 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;
}
}

View File

@ -12,132 +12,161 @@ 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.
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @created October 28, 2003
*/
public class RefreshDBScreen extends LessonAdapter
{
private final static String REFRESH = "Refresh";
private static Connection connection = null;
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 )
/**
* 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
{
ElementContainer ec = new ElementContainer();
boolean refresh = s.getParser().getBooleanParameter(REFRESH, false);
try
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())
{
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();
t.setBorder(1);
}
return ( ec );
t.addElement(row);
ec.addElement(t);
}
}
/**
* Gets the category attribute of the RefreshDBScreen object
*
* @return The category value
*/
protected Category getDefaultCategory()
catch (Exception e)
{
return ADMIN_FUNCTIONS;
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
private final static Integer DEFAULT_RANKING = new Integer(1000);
return (ec);
}
protected Integer getDefaultRanking()
/**
* 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
{
return DEFAULT_RANKING;
}
if (connection == null)
{
connection = DatabaseUtilities.makeConnection(s);
}
/**
* Gets the role attribute of the RefreshDBScreen object
*
* @return The role value
*/
public String getRole()
CreateDB db = new CreateDB();
db.makeDB(connection);
System.out.println("Successfully refreshed the database.");
}
catch (Exception e)
{
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();
}
s.setMessage("Error refreshing database "
+ this.getClass().getName());
e.printStackTrace();
}
}
}

View File

@ -20,259 +20,302 @@ 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.
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003
*/
public class ReportCardScreen extends LessonAdapter
{
/**
* Description of the Field
*/
protected final static String USERNAME = "Username";
/**
* 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 )
/**
* 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
{
ElementContainer ec = new ElementContainer();
if (s.getRequest().isUserInRole(WebSession.WEBGOAT_ADMIN))
{
user = s.getParser().getRawParameter(USERNAME);
}
else
{
user = s.getUserName();
}
}
catch (Exception e)
{}
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;
if (user == null)
{
user = s.getUserName();
}
ec.addElement(makeFeedback(s));
ec.addElement(makeReportCard(s, user));
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);
return ec;
}
protected Integer getDefaultRanking()
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())
{
return DEFAULT_RANKING;
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));
}
/**
* Gets the role attribute of the UserAdminScreen object
*
* @return The role value
*/
public String getRole()
// 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();)
{
return USER_ROLE;
Screen screen = (Screen) lessonIter.next();
t.addElement(makeLessonRow(s, user, screen));
}
/**
* Gets the title attribute of the UserAdminScreen object
*
* @return The title value
*/
public String getTitle()
// 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();)
{
return ( "Report Card" );
Screen screen = (Screen) lessonIter.next();
t.addElement(makeLessonRow(s, user, screen));
}
/**
* 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;
}
ec.addElement(t);
return (ec);
}
/**
* 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
*/
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
*
* @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();
/**
* Description of the Method
*
* @return Description of the Return Value
*/
private TR makeUserHeaderRow()
{
TR tr = new TR();
ec.addElement( makeUser( s, user ) );
Table t = new Table().setCellSpacing( 0 ).setCellPadding( 2 ).setBorder( 1 );
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"));
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;
}
return tr;
}
}

View File

@ -21,272 +21,317 @@ 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.
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @author Bruce mayhew <a href="http://code.google.com">WebGoat</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 )
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
{
ElementContainer ec = new ElementContainer();
if (s.getRequest().isUserInRole(WebSession.WEBGOAT_ADMIN))
{
Enumeration e = s.getParser().getParameterNames();
String selectedUser = null;
try
while (e.hasMoreElements())
{
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 );
}
}
}
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;
}
}
catch (Exception e)
{
e.printStackTrace();
}
protected Element makeSummary( WebSession s)
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())
{
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 );
t.setBorder(1);
}
t.addElement(makeUserSummaryHeader());
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 );
for (Iterator userIter = UserTracker.instance().getAllUsers(
WebSession.WEBGOAT_USER).iterator(); userIter.hasNext();)
{
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;
String user = (String) userIter.next();
t.addElement(makeUserSummaryRow(s, user));
}
private void deleteUser( String 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())
{
UserTracker.instance().deleteUser( user );
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);
}
/**
* 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;
}
return (tr);
}
/**
* 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;
}
public boolean isEnterprise()
{
return true;
}
}

View File

@ -12,95 +12,123 @@ 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.
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @created October 28, 2003
*/
public class UserAdminScreen extends LessonAdapter
{
private final static String QUERY = "SELECT * FROM user_system_data";
private static Connection connection = null;
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 )
/**
* 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
{
ElementContainer ec = new ElementContainer();
if (connection == null)
{
connection = DatabaseUtilities.makeConnection(s);
}
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);
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 );
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();
}
/**
* 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;
}
return (ec);
}
/**
* Gets the title attribute of the UserAdminScreen object
*
* @return The title value
*/
public String getTitle()
{
return ( "User Information" );
}
/**
* 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");
}
}

View File

@ -13,135 +13,166 @@ 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.
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @created October 28, 2003
*/
public class ViewDatabase extends LessonAdapter
{
private final static String SQL = "sql";
private static Connection connection = null;
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 )
/**
* 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
{
ElementContainer ec = new ElementContainer();
ec.addElement(new StringElement("Enter a SQL statement: "));
try
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))
{
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();
makeSuccess(s);
ResultSetMetaData resultsMetaData = results.getMetaData();
ec.addElement(DatabaseUtilities.writeTable(results,
resultsMetaData));
}
return ( ec );
}
}
/**
* Gets the category attribute of the DatabaseScreen object
*
* @return The category value
*/
protected Category getDefaultCategory()
catch (Exception e)
{
return ADMIN_FUNCTIONS;
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
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<String> hints = new ArrayList<String>();
hints.add( "There are no hints defined" );
return hints;
}
return (ec);
}
/**
* 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.";
/**
* Gets the category attribute of the DatabaseScreen object
*
* @return The category value
*/
protected Category getDefaultCategory()
{
return ADMIN_FUNCTIONS;
}
return ( instructions );
}
private final static Integer DEFAULT_RANKING = new Integer(1000);
/**
* Gets the role attribute of the ViewDatabase object
*
* @return The role value
*/
public String getRole()
{
return HACKED_ADMIN_ROLE;
}
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
/**
* Gets the title attribute of the DatabaseScreen object
*
* @return The title value
*/
public String getTitle()
{
return ( "Database Dump" );
}
/**
* Gets the hints attribute of the DatabaseScreen object
*
* @return The hints value
*/
protected List getHints()
{
List<String> hints = new ArrayList<String>();
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");
}
}

View File

@ -8,60 +8,84 @@ 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.
/*******************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @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
*
* @param s Description of the Parameter
*/
public WelcomeAdminScreen(WebSession s)
{
super(s);
}
/**
* Constructor for the WelcomeAdminScreen object
*/
public WelcomeAdminScreen() { }
/**
* 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();
/**
* 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));
ec.addElement( new Center( new H1( "You are logged on as an administrator" ) ) );
ec.addElement( super.createContent( s ) );
return ( ec );
}
return (ec);
}
/**
* Gets the title attribute of the WelcomeAdminScreen object
*
* @return The title value
*/
public String getTitle()
{
return ( "Admin Welcome" );
}
/**
* Gets the title attribute of the WelcomeAdminScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Admin Welcome");
}
}