Sunday, April 15, 2012

Day Thirty Five: Password Recovery in RMH Homebase

The assignment for this class is exercise 8.1 in the Software Development textbook.

Exercise 8.1.A:
You should never assume that a user will change his or her default password. For security purposes, you write code that asks users to change their passwords when they login for the first time. There should also be a conditional that checks to see if the new password is a valid password (can't be the same as the default password).

Exercise 8.1.B:
The simplest solution is to have a question, or a set of questions, that the users answer when they login for the first time. For example, a question could be "What is your mother's maiden name?" If a user forgets his or her password, he should be prompted with the question and should only be allowed to change his or her password if he or she answers the question correctly. This is not the most secure way, but it is easier than validating an email account or calling a phone number to verify the changes.

Exercise 8.1.C:
I looked around to get some ideas on how to start implementing my idea and found Jennifer's blog post. I don't want to copy/paste code or steal anyone else's ideas, but some of her code fits my needs perfectly.

First, add a password_answer variable to Person.php. We don't really need a setter, but I went ahead and added a setter and a getter.

private $password_answer; //answer to the password reset question
...

function get_password_answer(){
return $this->password_answer;
}
...

function set_password_answer($pwa){
$this->password_answer = md5($pwa);
}

Next, add a new function to dbPersons.php (be sure to add a password_answer field to the query in the setup function and add a null value to the end of the admin constructor) :


function change_password_answer($id,$answer){
connect();
$query = 'UPDATE dbPersons SET password_answer = "'.$answer.'" WHERE id = "'.$id.'"';
$result = mysql_query($query);
mysql_close();
return $result;
}


Next, make the changes to login_form.php:

if($person['password']==$person['first_name'] . $person['phone1']){
echo('<table><form method="post">
<tr><td>Please reset your password.</td></tr>
<tr><td>New Password: </td><td><input type="password"name="newpass"></td></tr>
<tr><td>Confirm New Password: </td><td><input type="password"name="newpassconf"></td></tr>
<tr><td>Please provide the following for future password recovery:</td></tr>
<tr><td>Mothers maiden name: </td><td><input type="password"name="maidenname"></td></tr>
<tr><td>Confirm answer: </td><td><input type="password"name="maidennameconf"></td></tr>
<tr><td colspan="2" align="center"><input type="submit" name="SetPassword" value="SetPassword"></td></tr></form></table>');
$db_new_pass = md5($_POST['newpass']);
$db_new_pass_conf = md5($_POST['newpassconf']);
if(maidenname == maidennameconf){
if($db_new_pass == $db_new_pass_conf){
change_password($db_id, $db_new_pass);
$db_pass_answer = md5($_POST['maidenname']);
change_password_answer($db_id, $db_pass_answer);
}
else {
echo('<div><p>Error: Passwords do not match. Please try again.</p></div>    ');
}
}
else {
echo('<div><p>Error: The answers do not match. Please try again.</p></div>    ');
}
}
$_SESSION['logged_in']=1;
$type_array = explode(",",$person['type']);
if (in_array('applicant', $type_array))
$_SESSION['access_level'] = 0;
else if (in_array('manager', $type_array))
$_SESSION['access_level'] = 2;
else $_SESSION['access_level'] = 1;
$_SESSION['f_name']=$person['first_name'];
$_SESSION['l_name']=$person['last_name'];
$_SESSION['_id']=$_POST['user'];
echo "<script type=\"text/javascript\">window.location = \"index.php\";</script>";
}
else {
echo('<div align="left"><p class="error">Error: invalid username/password<br />if you cannot remember your password, ask a house manager to reset it for you.</p><p>Access to RMH Homebase requires a Username and a Password. <p>For guest access, enter Username <strong>guest</strong> and no Password.</p>');
echo('<p>If you are a volunteer, your Username is your first name followed by your phone number with no spaces. ' . 'For instance, if your first name were John and your phone number were (207)-123-4567, ' . 'then your Username would be <strong>John2071234567</strong>.  ');
echo('If you do not remember your password, please enter your mothers maiden name:');
    echo('<table><form method="post"><input type="password" name="passanswer"></table>');
echo('<p><table><form method="post"><input type="hidden" name="_submit_check" value="true"><tr><td>Username:</td><td><input type="text" name="user" tabindex="1"></td></tr><tr><td>Password:</td><td><input type="password" name="pass" tabindex="2"></td></tr><tr><td colspan="2" align="center"><input type="submit" name="Login" value="Login"></td></tr></table>');
$input_answer=md5($_POST['passanswer']);
if ($person['password_answer']==$input_answer){
echo('<table><form method="post">
<tr><td>Please reset your password.</td></tr>
<tr><td>New Password: </td><td><input type="password"name="newpass"></td></tr>
<tr><td>Confirm New Password: </td><td><input type="password"name="newpassconf"></td></tr>
<tr><td colspan="2" align="center"><input type="submit" name="Set
Password" value="SetPassword"></td></tr></form></table>');
$db_new_pass = md5($_POST['newpass']);
$db_new_pass_conf = md5($_POST['newpassconf']);
if($db_new_pass == $db_new_pass_conf){
change_password($db_id, $db_new_pass);
}
else {
echo('<div><p>Error: Passwords do not match. Please try again.</p></div>    ');
}
}
else {
return 'The answer does not match the one we have on file.';
}
...

The new function works when I unit tested it, but the actual logic still needs to be tested. I have a sandbox setup. I will copy my work from my workspace into my sandbox and give it a try later.



No comments:

Post a Comment