1
Jackson State University
Department of Computer Science
CSC 439-01/539-02 Advanced Information Security
Spring 2013
Lab Project # 3
Use of CAPTCHA (Image Identification Strategy) to Prevent XSRF Attacks
Due: March 25, 2013, 7.30 PM
Maximum Points: 100
In this exercise, you will be presented with an online banking web application. It will be your task
to implement a user-acknowledgment system similar to CAPTCHA. If you are using a lab computer,
copy the XAMPP installer from the Shared Users folder to the folder corresponding to your particular
account and then install it (Refer to Step 2). If you do not have a copy of XAMPP in your system,
download it as mentioned in Step 1.
1. Download XAMPP for your operating system
Visit the XAMPP website (http://www.apachefriends.org/en/xampp.html) and download the latest
version of XAMPP installer for your operating system and start the installation process.
2. Install XAMPP for your operating system
Once the download of the installer has completed, follow the installation instructions given. Make
sure to install xampp directly under the C:\drive by creating a folder named xampp’. It is better NOT
to install Apache and MySQL as services during installation.
3. Download the online banking application archive (from course website)
4. Install the online banking application archive
In the online banking application archive file you have downloaded in Step 3, you can find two
folders, “Content” and “Data.” Open the “Data” folder and copy the folder it contains
(hometown_bank) to the /mysql/data/ folder within the XAMPP installation folder on your machine.
You should now have a folder /mysql/data/hometown_bank/ containing a number of files.
Open the “Content” folder and copy its contents to the HometownBank folder created within the
/htdocs/ folder of the XAMPP installation folder on your machine. You should now have a folder
/htdocs/HometownBank/ containing a number of files.
5. Start the XAMPP Services
Start the XAMPP Control Panel (file named: xampp-control, located in the main XAMPP folder)
Click the “Start” button next to Apache. It will shortly change to a “Stop” button and display a green
“Running” bar. Once Apache is running, click the “Start” button next to MySql. When it has started,
the “Start” button will change to a “Stop” button and the green Running” bar will be displayed next to
2
the MySql label.
To test that XAMPP has been installed properly, open a web browser and navigate to
http://localhost. If you see the XAMPP web page, Apache has been installed correctly. Also navigate
to http://localhost/phpmyadmin to ensure that MySql has been installed correctly.
6. Open the Online Banking Application in Your Browser
Open a web browser and navigate to http://localhost/HometownBank/ . You should see the
Hometown Bank homepage. You should notice that the site contains several pages: Home,” “Login,”
View Account,” and “Transfer Funds.” You will also notice that you cannot view the “View Account”
and “Transfer Funds” pages without logging in.
There is one user account already created within the system. To view the information for this
account, open a new browser tab or window and navigate to http://localhost/phpmyadmin . This should
display a page with a number of databases listed on the left-hand side. Select the “hometown_bank”
database in the list on the left-hand side. Once you have selected the “hometown_bank” database,
select the “accounts” table from the list on the left-hand side of the page and click on the icon next to it
(placing your mouse on the top of the icon will display ‘Browse’). This should take you to a new page
where you may browse the contents of the “accounts” table.
Now, select Insert” at the top of the page. Fill in the fields with login and imaginary account
information for yourself. The username should be your school ID number (J#), and you may enter any
password you like. The account number (should be 9-digits long) and the Amount field should be a
value equal to 1000 plus the last 4 digits of your J#. You should also create three additional fictional
user accounts. For these, you may enter any information you like. When you are done, there should be
five accounts in the database, the one that was originally in the database, the account you created for
yourself, and the three additional accounts you created.
Screenshot # 1: Once you have created the accounts, take a screenshot of the updated “accounts”
table to include in your report.
Now that you have created your own user account, return to the browser window containing the
bank app and log into your account using the information you just inserted into the database. Once you
are logged in, you may click on the “View Account” link at the top. You should now be able to view
the information you have just entered into the database.
Screenshot # 2: Take a screenshot of the “View Account” page displaying your account
information to include in your report.
7. Intro to Cross-Site Request Forgery
Now click on the “Transfer Funds” link. On this page you may transfer funds from the account
you are logged into, to another account. You will first be transferring $200.00 from your account to
Gregg McDonald’s account. His account number is 1000000001. You may also find his account
number by viewing the contents of the database. To transfer these funds, enter his account number in
the “Transfer To:” field and enter “200.00” in the “Amount” field. When you have done this, click the
Submitbutton.
3
Screenshot # 3: Once you have transferred the funds to Gregg McDonald’s account, take a
screenshot of the Transfer Verification page to include in your report.
Once again, use the “Transfer Funds” page to transfer money. This time, transfer $200.00 from
one of the fictional accounts you created to your own account. To do this, you will need to be logged in
as the fictional account and transfer to the account number of your own account. When you have
completed the funds transfer, you should have the same account balance as you did when you started.
Screenshot # 4: Once you have transferred funds from the fictional account to your own account,
take a screenshot of the Transfer Verification page to include in your report.
Notice the URL of the Funds Transfer verification page. It will appear something like:
http://localhost/HometownBank/transfer_action.php?TransferTarget=1000000026&TransferAmount=200.00
where the TransferTarget is the account to which you wished to transfer money and the
TransferAmount is the amount you transferred.
Before proceeding, make sure you log back in to your own account.
Suppose you receive an email with the following text:
Click here to claim your new computer!
Press Ctrl and Click on the link above and answer the following questions:
Note: If nothing works by clicking the above line, click on the link below:
http://localhost/HometownBank/transfer_action.php?TransferTarget=1000000001&TransferAmount=2
00.00
Questions 1 through 6:
1. Where does the link take you?
2. What is the URL of the link?
3. What does the link do?
4. What is your new account balance?
5. Why does the link work?
6. Examine the URL of the page that the link directed you to. Modify this URL to transfer
$200.00 to one of the fictional accounts you created and navigate to that URL in the
browser. Did the amount of $200.00 get transferred from your account to the fictional
account?
Screenshot # 5: Once you have activated the above URL, take a screenshot of your new account
balance. You may access this by clicking the “View Account” link at the top of the Hometown
Bank page.
You have just been the victim of a cross-site request forgery attack (XSRF). XSRF attacks
successfully occur when a website wrongfully believes that a request being made to it is being willfully
triggered by the user.
In this case, the bank’s website wrongfully trusts that any request to the transfer_action.php page is
being willfully executed by you, the authorized user. That is not necessarily true here. While you did
willfully click the link, you most likely did not intend to transfer all of your money to someone else’s
account.
One way to prevent such attacks from the point of view of a web developer is to ensure that
4
whenever any kind of transactions or changes are made to a users account, the user acknowledges the
transaction. When you clicked the link above, if you had been displayed a page that said “Are you sure
you wish to transfer $20,000 to Account Number 1000000026?” you probably would have said “No.”
8. Implementing a CAPTCHA-type Scheme
Now imagine that you are a web developer. You get a call from Hometown Bank saying that they
have discovered an enormous security flaw in their online banking system, and they need you to fix it
for them. They tell you about users falling victim to an email scam that transfers money from their
accounts.
You know just how to solve the problem. You will implement a scheme like the CAPTCHA
technology with which you are probably familiar. The CAPTCHA system is a challenge-response
system which displays a series of characters and requires the user to read and enter the characters
displayed in a box to verify the users humanity (and acknowledgement of the transaction).
The system that you will be implementing will be a little simpler, but should work pretty well.
The first thing that you will need to do will be to find 10 simple pictures online by searching
http://images.google.com . The pictures may be of anything, but each picture should only include one
thing, for example:
A hat
A car
A dog
You should avoid pictures with more than one object in them (a picture containing a horse and a truck),
or multiple pictures of the same item (2 pictures of cats). You should also avoid obscure objects that
members of the general public might not recognize, or might misidentify. You should also try to pick
pictures that are roughly square-shaped.
Once you have found your 10 images, save them to the /HometownBank/images/ directory in your
XAMPP install. You will now need to rename the images so that the image names are not descriptive
of what is in the picture. Randomly mashing on the keyboard should give you a pretty unrecognizable
sequence of characters for a file name. Make sure that there are no punctuation marks or spaces in the
file name, only letters between A and Z. The filenames should also be around 10-12 characters long.
Once you are done you should have renamed your 10 images to things like:
eajjeagkajeg.jpg
yturuyozya.png
behaleghgh.gif
Now that your images have been renamed, you will have to add them to the database. To do this,
navigate to http://localhost/phpmyadmin . Once there, click on the “hometown_bank” database on the
left side. You will see that there are two tables in this database, accounts” and “image data”. Click on
the “image_data” table. You will see that this table contains two fields: “URL” and “Description”.
You will now need to add the data for your images into this table. To do this, click “Insert” at the top
of the page. This will take you to a page where you may insert the information for your images, one
image at a time. In the “URL” field, insert the filename of your image. Be sure to include the
extension (.jpg, .gif, .ping, etc.) with the proper case (yes, it is case-sensitive!!) or your application
will not work. In the “Description” field, enter a one-to-two word description of the image (cat, house,
donut, etc.). Once you have done this, click the “Go” button, and continue inserting the information
5
until you have inserted the data for all of your images.
9. Implementation of the CAPTCHA Strategy
We will employ the following strategy to implement the user verification with pictures: Whenever a
user wants to transfer funds, he or she will be presented with an image and must correctly name the
image. If the correct name of the image is not given, or if no name is given at all, the funds transfer
will not take place. This will require that we make some changes to the transfer.html page and the
transfer_action.php page.
9.1.1 Edit transfer.html
We will edit our transfer.html page first to include some PHP code that will randomly select a
single image from our database. This image will be displayed to the user. Under the image, there will
be a text input field for the user to enter the name of the displayed object.
The first thing that we will need to do will be to rename transfer.html to transfer.php. Once you
have renamed the file, open it in a text editor. Scroll down to line 66, which says:
<input type=”submit” value=”Submit” />
We will be placing all of our PHP code before this line, so everything that you insert should come
immediately after the </table> tag on line 65 and before the <input> tag that is currently on line 66.
To start a PHP code segment, you need to create your beginning and ending PHP tags. The tag to
begin a PHP code segment is
<?php
and the tag to end a PHP code segment is
?>
You will now need to insert the code to access the database. Inside your PHP start/end tags, insert
the following code:
$host = “localhost”;
$user = “root”;
$password = “”;
$dbname = “hometown_bank”;
$connection = mysql_connect( $host, $user, $password );
$database = mysql_select_db( $dbname, $connection );
The first line stores the hostname where the database is located. The second and third lines store the
username and password used for access to the database. The fourth line stores the name of the
particular database that we will be using. The fifth line creates a connection object on the host with the
specified username and password. The sixth line selects the specific database that we want on the
created connection.
Now write an SQL query to get the entire contents of the “image_data” table and store it as the
variable $query. When you have completed this, your code thus far should look like:
<?php
$host = “localhost”;
6
$user = “root”;
$password = “”;
$dbname = “hometown_bank”;
$connection = mysql_connect( $host, $user, $password );
$database = mysql_select_db( $dbname, $connection );
$query = “SELECT * FROM image_data i”;
?>
Extend the above PHP code (<?php …………. ?>) further as explained below:
Insert two blank lines as follows:
echo '<br /> <br />';
Now you will need to execute the query on the database in order to retrieve the results and store
them in a variable. This is done with the line:
$result = mysql_query( $query, $connection );
Once the database is set up, we will need to create a random number generator and get a random
number between 0 and 9 (because there are 10 items in our database). This is done with the following
code:
srand(time());
$random = (rand()%10);
It is now necessary to get the URL of the selected item from the database. This can be done with
the following line:
$url = mysql_result($result, $random, “URL”);
where $url is the variable that the URL value is being saved to, $result is the result of the SQL query,
$random is the random row we want to pull from, and “URL” is the name of the field we want to
retrieve.
We should now give directions to the user and display the image. HTML tags can be written to the
browser window in PHP by using the echo command:
echo ‘<br />Name the item in the picture below and click Submit to complete your transfer.’;
echo ‘<br /><br />’;
echo '<img src="./images/';
echo $url;
echo '" height="100" width="100" />';
It is now necessary to include the URL of the item we have displayed in the form so that it may be
transmitted to the transfer_action.php page and used to check whether or not the user has entered the
correct name. This will be done using an input element of the “hidden” type:
echo ‘<input type=”hidden” name=”ObjectURL” value=”’;
echo $url;
echo ‘” />’;
Now we must insert the text box for the user to enter the name of the item in the picture. This will
be done using an input element of type “text”:
echo ‘<br /><br />Name of the Item: ‘;
echo ‘<input type=”text” name=”ObjectDescription” maxlength=”25” />’;
7
echo ‘<br /><br />’;
That concludes the PHP additions for the transfer.php page. Now we must update our
transfer_action.php page.
9.1.2 Edit transfer_action.php
A. Retrieve the passed parameters
To retrieve the two required values from the form, we will use the $_GET[] method. The syntax
of these two lines will be:
$UserDescription = $_GET[‘ObjectDescription’];
$ObjectURL = $_GET[‘ObjectURL’];
where $ObjectToFind and $ObjectURL are PHP variables and ‘ObjectToFind’ and ‘ObjectURL are the
“name” values of the input elements from the form.
You need to insert the above two lines after line # 66 in the transfer_action.php file, immediately
following the “$amount = $_GET[‘TransferAmount’]” line.
One additional consideration here is that if no values are passed to this page for
‘ObjectDescription’ and ‘ObjectURL’, PHP will display a notice stating thatNotice: Undefined index:
ObjectDescription in transfer_action.php on line 71” and also a notice regarding the fact that
‘ObjectURL has an undefined index.
B. Determine if user input has been passed
Now we need to determine whether or not values for the ‘ObjectDescription’ and ‘ObjectURL
variables have actually been passed to the form. If the transfer_action.php page were accessed from
any page other than the appropriate transfer.php page, or directly from a URL as in the example of the
XSRF link in section 7, then these values would not be present.
We will insert the code to check these parameters inside the first if statement (currently if (false)).
Edit the if (false) statement to read:
if ($UserDescription == “” || $ObjectURL == “” || $UserDescription == null ||
$ObjectURL==null)
This will determine whether any of our variables is empty or null. If either of them is not specified, we
need to display an appropriate message to the user.
Inside the if( ) block you just edited, you will see the text
//this will be executed if no valid parameters are passed
Here you will need to use the echo command to insert a message to the user warning that there was an
error in processing the transfer request and that he or she should return to the transfer page.
C. Retrieve results from the database
Now insert code that will execute a query on the database and retrieve the results. This code
should be inserted immediately following the $result = null line. The query should get the rows from
the image_data table for which the URL in the table is equal to the $ObjectURL variable.
8
$query = "SELECT * FROM image_data i WHERE (i.URL = '$ObjectURL')";
$result = mysql_query($query, $connection);
D. Check for a matching database row
Now that we have performed the query on the database, we need to check whether or not there are
actually any rows of results in the $result variable. We will need to revise the if statement that
currently reads
if(false) //if the number of rows is zero
{
//this will be executed if the result contains zero rows
}
The first thing to do will be to update the contents of the if() statement. Replace the word “false” with:
mysql_numrows($result) == 0
Now, we need to fill in the contents of the if() block. Replace the line that currently reads
//this will be executed if the result contains zero rows
with
$validinput = false;
Immediately following that if() block, you will find a line which reads $result_object = null; . We need
to replace this with the MySQL command which will retrieve the value of the “Description” field from
the first row of our result. To do this, change this line to read
$result_object = mysql_result($result, 0, “Description”);
E. Check that the database value matches the user-specified value
Now we must check whether or not this description from the database is equal to the description
provided by the user. This will be done by the if() statement that currently reads:
if (false) //if the values of the parameters match
We must change this to test whether the value of the description from the database ($result_object) is
equal to the description specified by the user ($UserDescription). To do this, replace the “false” in the
if () statement with:
if ($UserDescription == $result_object)
Inside this if() block, we need to signal to the program that the input matches, so insert the
following line into the if() block:
$validinput = true;
If the input given by the user did not match that retrieved from the database, we need to signal that
the input is invalid. This is done in the else statement immediately following the if() statement you just
edited. Currently, the contents of the else block are
//this will be executed if the values of the parameters do not match
Immediately following this line, you need to add the line:
$validinput = false;
F. Check whether the input has been validated overall
Now, we have addressed the various ways in which invalid input could be passed to the program.
9
The inputs overall validity is represented by the $validinput variable. We now need to check the value
of this variable. This is done in the if() statement that currently reads
if(true) //if the user entered proper information on the transfer.php page
We need to replace the word true with $validinput == true so that we will know if the input is valid.
If the $validinput is true, then the transfer will take place. If the value of $validinput is false, then
we need to issue a warning to the user that the transfer cannot take place. Scroll down to the bottom of
the transfer_action.php code and find the section that says
else
{
//this will be executed if there are no matches
}//end else
Inside of this else block, you will need to enter an echo statement which notifies the user of a problem
and suggests they return to the transfer.php page to try again. The code for this might look like:
else
{
echo 'There was a problem with the transfer, please click <a href="./default.html">here</a>
to return to the Transfer page and try again.</br><br />';
}//end else
10. Update Links to transfer.php
After you have added the PHP code to your transfer.php page, you will need to update the other
pages so that they link to the appropriate page (at the beginning of this section, you changed the name
from transfer.html to transfer.php). In turn, open each of the following pages in a text editor and
change the two references to “transfer.html” to transfer.php”. The line numbers at which these
references occur are given below, but you can also search within the document and find them.
default.html (lines 30 and 52)
login.html (lines 30 and 61)
transfer.php (line 44 and the 12
th
line from the bottom)
transfer_action.php (lines 44, the 11
th
from the bottom, and several other locations)
view.php (lines 44 and 172)
login.php (lines 32 and 136)
Screenshot # 6: When you have completed this step, take a screenshot of your new transfer.php
page.
Screenshot # 7: Now take 2 series’ of screenshots. In the first series, take screenshots of:
valid data entered into the transfer.php page
the resulting transfer_action.php page
Screenshot # 8: In the second series, take screenshots of:
invalid data (say a negative number for the Amount to be transferred) entered into the
transfer.php page
the resulting transfer_action.php page
Screenshot # 9: Click on the XSRF link in section 7 again and take a screenshot of the resulting
10
page
11. Further Problems
There are still a number of bugs in the transfer system’s code. You will now need to fix these
bugs. Some of these bugs which need to be addressed are:
If a users account balance is negative, he can still transfer money to another account. If a user
does have a negative account balance, he should not be able to transfer money.
If a users account balance is less than the amount she wishes to transfer, she is still allowed to
make the transfer (which will result in her having a negative balance). This should no occur.
Users are able to transfer money to their own accounts. This is unnecessary and should not
occur.
Users are able to transfer a negative amount of money to someone else’s account (thereby
increasing the amount of money in their own at someone else’s expense).
These issues are fairly simple and can be easily fixed. We will now walk through the process of
fixing the first one together. After that, you will need to fix the remaining two bugs.
The first bug is that a user can transfer money to another account even when he has a negative
account balance. To fix this, we simply need to check the users account balance before we initiate any
transfer.
In the transfer_action.php code, scroll down to the line that says
if (false) //if the source account has a negative balance
We will need to use this if statement to compare the source account’s balance with zero to determine if
the amount in the account is less than or equal to zero. A look at the code reveals that there is a
variable named “$source_balance”. This is the variable that holds the amount of money in the source
account. We will need to replace the contents of the if() statement to be:
if ($source_balance <= 0)
We will then need to insert a line into the if() block which will issue a message to the user if this
condition has occurred. Immediately following the line that says
//check the source account balance
Insert the following line:
echo ‘<br />The source account has a negative balance. No transfer will occur.<br />’;
Now save the transfer_action.php code and return to the application. To test the fix, you will need
to alter the data in the database (http://localhost/phpmyadmin) to give your account a negative balance.
Screenshots # 10: Once you have done this, you will take three screenshots: a screenshot of the
database contents showing your negative balance, one of the transfer.php page in which you
request to transfer money, and a screenshot of the resulting transfer_action.php page which
should deny you the ability to transfer funds due to your negative balance.
Screenshots # 11, 12, 13:
After you have proceeded so far, fix the three remaining bugs. For each bug that you fix, you
will need to take a set of three screenshots:
11
A screenshot of the database contents showing the initial conditions,
A screenshot of the transfer.php page where you try to enter improper data related to
the bug you have fixed, and
A screenshot of the resulting transfer_action.php page which should deny you the
ability to transfer funds based on the conditions related to the bug you have fixed
Screenshot # 14: Take a final screenshot of the contents of your “Accounts” table showing the
details of each account.
WHAT TO TURN IN:
Summary of the project: Summarize in about a page the whole project and what you
learnt from it.
Screenshots 1 through 14 as described above
The transfer.php code after all of your modifications
The transfer_action.php code after all of your modifications
Trace the structure of your transfer_action.php code and briefly explain why you were able
to easily fix the above four bugs by just replacing the false boolean value with an
appropriate condition in the if statement.