modified CSRF to add an actual attack

git-svn-id: http://webgoat.googlecode.com/svn/trunk@49 4033779f-a91e-0410-96ef-6bf7bf53c507
This commit is contained in:
sherif.fathy 2006-12-28 16:59:02 +00:00
parent 5e061d5bad
commit 37c56c748d
2 changed files with 228 additions and 44 deletions

View File

@ -1,77 +1,251 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.StringElement; import org.apache.ecs.StringElement;
import org.apache.ecs.html.A;
import org.apache.ecs.html.B;
import org.apache.ecs.html.H1;
import org.apache.ecs.html.HR;
import org.apache.ecs.html.Input; import org.apache.ecs.html.Input;
import org.apache.ecs.html.P; import org.apache.ecs.html.P;
import org.apache.ecs.html.TD; import org.apache.ecs.html.TD;
import org.apache.ecs.html.TR; import org.apache.ecs.html.TR;
import org.apache.ecs.html.Table; import org.apache.ecs.html.Table;
import org.apache.ecs.html.TextArea; import org.apache.ecs.html.TextArea;
import org.owasp.webgoat.session.DatabaseUtilities;
import org.owasp.webgoat.session.ECSFactory; import org.owasp.webgoat.session.ECSFactory;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
import org.owasp.webgoat.util.HtmlEncoder;
public class CSRF extends LessonAdapter { public class CSRF extends LessonAdapter {
private final static String MESSAGE = "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 String TITLE = "title";
private final static int TITLE_COL = 2;
private static Connection connection = null;
private static int count = 1;
private final static int USER_COL = 4; // Added by Chuck Willis - used to show user who posted message
/**
* Adds a feature to the Message attribute of the MessageBoardScreen object
*
* @param s The feature to be added to the Message attribute
*/
protected void addMessage( WebSession s )
{
try
{
String title = HtmlEncoder.encode( s.getParser().getRawParameter( TITLE, "" ) );
String message = s.getParser().getRawParameter( MESSAGE, "" );
if ( connection == null )
{
connection = DatabaseUtilities.makeConnection( s );
}
String query = "INSERT INTO messages VALUES (?, ?, ?, ? )";
PreparedStatement statement = connection.prepareStatement( query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY );
statement.setInt(1, count++);
statement.setString(2, title);
statement.setString(3, message);
statement.setString(4, s.getUserName());
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" );
}
}
}
@Override @Override
protected Element createContent(WebSession s) { protected Element createContent(WebSession s) {
ElementContainer ec = new ElementContainer(); ElementContainer ec = new ElementContainer();
String emailBody = null;
try{ addMessage( s );
Table t = new Table( 0 ).setCellSpacing( 0 ).setCellPadding( 0 ).setBorder( 0 ); ec.addElement( makeInput( s ) );
TR row1 = new TR(); ec.addElement( new HR() );
TR row2 = new TR(); ec.addElement( makeCurrent( s ) );
row1.addElement( new TD( new StringElement( "Title: " ) ) ); ec.addElement( new HR() );
ec.addElement( makeList( s ) );
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" );
ec = new ElementContainer();
ec.addElement( t );
ec.addElement( new P().addElement( b ) );
emailBody = new String( s.getParser().getRawParameter( MESSAGE, "" ) );
}
catch (Exception e)
{
s.setMessage( "Error generating " + this.getClass().getName() );
e.printStackTrace();
}
if (emailBody.length() != 0 &&
emailBody.indexOf( "<img" ) >=0 &&
emailBody.indexOf( "src=") > 0 &&
emailBody.indexOf( "height=\"1\"" ) > 0 &&
emailBody.indexOf( "width=\"1\"" ) > 0)
{
makeSuccess( s );
}
return ec; 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 );
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 );
}
/**
* 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 );
}
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
String transferFunds = s.getParser().getRawParameter("transferFunds" , "");
if (transferFunds.length() != 0)
{
makeSuccess(s);
}
}
else
{
if ( messageNum != 0 )
{
ec.addElement( new P().addElement( "Could not find message " + messageNum ) );
}
}
}
catch ( Exception e )
{
s.setMessage( "Error generating " + this.getClass().getName() );
e.printStackTrace();
}
return ( ec );
}
@Override @Override
protected Category getDefaultCategory() { protected Category getDefaultCategory() {
return AbstractLesson.A4; return AbstractLesson.A4;
@ -105,4 +279,14 @@ public class CSRF extends LessonAdapter {
return ( "How to Perform Cross Site Request Forgery (CSRF)" ); return ( "How to Perform Cross Site Request Forgery (CSRF)" );
} }
private static String getNameroot( String name )
{
String nameroot = name;
if (nameroot.indexOf('-') != -1)
{
nameroot = nameroot.substring(0, nameroot.indexOf('-'));
}
return nameroot;
}
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

After

Width:  |  Height:  |  Size: 27 KiB