Jump to content

SalientAnimal

Members
  • Posts

    366
  • Joined

  • Last visited

Everything posted by SalientAnimal

  1. Ok, that seems to be working now. I updated Rule 3 to be: else { $error = true; $show = 'securityForm'; $securityUser = $_POST['user_id']; } I also changed the below as you suggested. Should I change this back now, or leave as is. So at this point of the form, I am given the security link, which I can then follow to the form where I change my password. However, if I copy the link into a new window, rather than just clicking on the link displayed (Remember I'm not e-mailing the link, I'm just displaying it to them onscreen at the current moment) I get a HTTP 404 Not Found Error. I then complete the form with the new desired password, and on clicking submit I get the security user notice again Notice: Undefined variable: securityUser in C:\htdocs\includes\resetpwd.php on line 166 This is line 166 <p>Welcome back, <?= getUserName($securityUser=='' ? $_POST['user_id'] : $securityUser); ?>.</p> I am also still able to login with the old password, which would mean that the able was not updated.
  2. Firstly, sorry for taking so long to reply, I was stuck in a meeting for the remainder of the day. The security question is pulled from the database. On registration the user is asked to select a security question, so they will always get the same question. When answering the question correctly, the user is displayed a link onscreen that is hashed. If I however answer the question incorrectly, the form displays as per-usual, except this line is added: "You must answer the security question correctly to receive your lost password." If I try submitting a blank answer: The security question is removed, but the form is still displayed, with this message "You must answer the security question correctly to receive your lost password." And these messages are displayed: Notice: Undefined variable: securityUser in C:\htdocs\includes\resetpwd.php on line 134 Notice: Undefined index: in C:\htdocs\includes\functions.php on line 392 At this point, not matter if I fill in a answer on the second attempt, it can not submit it correctly. I am assuming this is because it is not longer storing the "securityUser"? I'm trying the step-by-step approach this time with the form, to identify and fix any errors before moving onto the next step. Would it be advisable to then, on rule 3, maybe add an error message rather than un-setting the security user?
  3. Thanks for that. So with my limited knowledge, what I do understand is the variable needs to be set. What I don't understand though is that if I go through the entire form and complete all the fields "Correctly" there are no error messages. The form displays the user name where needed, security question as needed etc... Why is it though that if I submit a field incorrectly, it seems to all of a sudden "forget" the set variable? Here is the entire code of the form: <?php include_once 'db_connect.php'; include_once 'functions.php'; include_once 'formatting_includes.php'; sec_session_start(); if (login_check($mysqli) == true) { $logged = 'in'; } $show = 'emailForm'; //which form step to show by default if(!isset($_SESSION['lockout'])) $_SESSION['lockout'] = false; if (isset($_SESSION['lockout']) && $_SESSION['lockout'] == true && (mktime() > $_SESSION['lastTime'] + 900)) { $_SESSION['lockout'] = false; $_SESSION['badCount'] = 0; } if (isset($_POST['subStep']) && !isset($_GET['a']) && $_SESSION['lockout'] != true) { switch($_POST['subStep']) { case 1: //we just submitted an email or username for verification $result = checkUNEmail($_POST['username'],$_POST['email']); if ($result['status'] == false ) { $error = true; $show = 'userNotFound'; } else { $error = false; $show = 'securityForm'; $securityUser = $result['id']; } break; case 2: //we just submitted the security question for verification if ($_POST['user_id'] != "" && $_POST['security_a'] != "") { $result = checkSecAnswer($_POST['user_id'],$_POST['security_a']); if ($result == true) { //answer was right $error = false; $show = 'successPage'; $passwordMessage = sendPasswordEmail($_POST['user_id']); $_SESSION['badCount'] = 0; } else { //answer was wrong $error = true; $show = 'securityForm'; $securityUser = $_POST['user_id']; $_SESSION['badCount']++; } } else { $error = true; $show = 'securityForm'; } break; case 3: //we are submitting a new password (only for encrypted) if ($_POST['user_id'] == '' || $_POST['security_key'] == '') header("location: ../login.php"); if (strcmp($_POST['password'],$_POST['confirmpwd']) != 0 || trim($_POST['password']) == '') { $error = true; $show = 'recoverForm'; } else { $error = false; $show = 'recoverSuccess'; updateUserPassword($_POST['user_id'],$_POST['password'],$_POST['security_key']); } break; } } elseif (isset($_GET['a']) && $_GET['a'] == 'recover' && $_GET['email'] != "") { $show = 'invalidKey'; $result = checkEmailKey($_GET['email'],urldecode(base64_decode($_GET['u']))); if ($result == false) { $error = true; $show = 'invalidKey'; } elseif ($result['status'] == true) { $error = false; $show = 'recoverForm'; $securityUser = $result['user_id']; } } if (isset($_SESSION['badCount']) && ($_SESSION['badCount'] >= 3)) { $show = 'speedLimit'; $_SESSION['lockout'] = true; $_SESSION['lastTime'] = '' ? mktime() : $_SESSION['lastTime']; } ?> <!doctype html> <meta http-equiv="X-UA-Compatible" content="IE=Edge"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Password Recovery</title> <link href="css/styles.css" rel="stylesheet" type="text/css"> </head> <body> <div id="header"></div> <div id="page"> <?php switch($show) { case 'emailForm': ?> <h2>Password Recovery</h2> <p>You can use this form to recover your password if you have forgotten it. Because your password is securely encrypted in our database, it is impossible actually recover your password, but we will email you a link that will enable you to reset it securely. Enter either your username or your email address below to get started.</p> <form action="<?= $_SERVER['PHP_SELF']; ?>" method="post"> <div class="fieldGroup"><label for="username">Username</label><div class="field"><input type="text" name="username" id="username" value="" maxlength="20"></div></div> <div class="fieldGroup"><label>- OR -</label></div> <div class="fieldGroup"><label for="email">Email</label><div class="field"><input type="text" name="email" id="email" value="" maxlength="255"></div></div> <input type="hidden" name="subStep" value="1" /> <div class="fieldGroup"><input type="submit" value="Submit" style="margin-left: 150px;" /></div> <div class="clear"></div> </form> <?php break; case 'securityForm': ?> <h2>Password Recovery</h2> <p>Please answer the security question below:</p> <?php if ($error == true) { ?><span class="error">You must answer the security question correctly to receive your lost password.</span><?php } ?> <form action="<?= $_SERVER['PHP_SELF']; ?>" method="post"> <div class="fieldGroup"> <label>Question</label> <div class="field"><?= getSecurityQuestion($securityUser); ?></div> </div> <div class="fieldGroup"> <label for="security_a">Answer</label> <div class="field"><input type="text" name="security_a" id="security_a" value="" maxlength="255"></div> </div> <input type="hidden" name="subStep" value="2" /> <input type="hidden" name="user_id" value="<?= $securityUser; ?>" /> <div class="fieldGroup"><input type="submit" value="Submit" style="margin-left: 150px;" /></div> <div class="clear"></div> </form> <?php break; case 'userNotFound': ?><br> <h2>Password Recovery</h2><br> <p>The username or email you entered was not found in our database.<br /><br /> <a href="?">Click here</a> to try again.</p><br> <?php break; case 'successPage': ?><br> <h2>Password Recovery</h2><br> <p>An email has been sent to you with instructions on how to reset your password. <strong>(Mail will not send unless you have an smtp server running locally.)</strong> <br /><br /><a href="../login.php">Return</a> to the login page. </p><br> <p>This is the message that would appear in the email:</p><br> <div class="message"><?= $passwordMessage;?></div><br> <?php break; case 'recoverForm': ?> <h2>Password Recovery</h2> <p>Welcome back, <?= getUserName($securityUser=='' ? $_POST['user_id'] : $securityUser); ?>.</p> <p>In the fields below, enter your new password.</p> <?php if ($error == true) { ?><span class="error">The new passwords must match and must not be empty.</span><?php } ?> <form action="<?= $_SERVER['PHP_SELF']; ?>" method="post"> <div class="fieldGroup"><label for="password">New Password</label><div class="field"><input type="password" class="input" name="password" id="password" value="" maxlength="20"></div></div> <div class="fieldGroup"><label for="confirmpwd">Confirm Password</label><div class="field"><input type="password" class="input" name="confirmpwd" id="confirmpwd" value="" maxlength="20"></div></div> <input type="hidden" name="subStep" value="3" /> <input type="hidden" name="user_id" value="<?= $securityUser=='' ? $_POST['user_id'] : $securityUser; ?>" /> <input type="hidden" name="security_key" value="<?= $_GET['email']=='' ? $_POST['security_key'] : $_GET['email']; ?>" /> <input class="bt_login" type="button" value="Reset" onClick="return resetformhash(this.form,this.form.password,this.form.confirmpwd);" style="margin-left: 150px;"/> <div class="clear"></div> </form> <?php break; case 'invalidsecurity_key': ?> <h2>Invalid security_key</h2> <p>The security_key that you entered was invalid. Either you did not copy the entire security_key from the email, you are trying to use the security_key after it has expired (3 days after request), or you have already used the security_key in which case it is deactivated.<br /><br /><a href="login.php">Return</a> to the login page. </p> <?php break; case 'recoverSuccess': ?> <h2>Password Reset</h2> <p>Congratulations! your password has been reset successfully.</p><br /><br /><a href="login.php">Return</a> to the login page. </p> <?php break; case 'speedLimit': ?> <h2>Warning</h2> <p>You have answered the security question wrong too many times. You will be locked out for 15 minutes, after which you can try again.</p><br /><br /><a href="login.php">Return</a> to the login page. </p> <?php break; } ob_flush(); $mysqli->close(); ?> <!--PAGE CONTENT--> </div> </body> </html> Password Form Functions: function checkUNEmail($username,$email) { global $mysqli; $error = array('status'=>false,'user_id'=>0); if (isset($email) && trim($email) != '') { //email was entered if ($stmt = $mysqli->prepare("SELECT id FROM members WHERE email = ? LIMIT 1")) { $stmt->bind_param('s',trim($email)); $stmt->execute(); $stmt->store_result(); $numRows = $stmt->num_rows(); $stmt->bind_result($user_id); $stmt->fetch(); $stmt->close(); if ($numRows >= 1) return array('status'=>true,'id'=>$user_id); } else { return $error; } } elseif (isset($username) && trim($username) != '') { //username was entered if ($stmt = $mysqli->prepare("SELECT id FROM members WHERE username = ? LIMIT 1")) { $stmt->bind_param('s',trim($username)); $stmt->execute(); $stmt->store_result(); $numRows = $stmt->num_rows(); $stmt->bind_result($user_id); $stmt->fetch(); $stmt->close(); if ($numRows >= 1) return array('status'=>true,'id'=>$user_id); } else { return $error; } } else { //nothing was entered; return $error; } } function getSecurityQuestion($user_id) { global $mysqli; $questions = array(); $questions[0] = "What is your mother's maiden name?"; $questions[1] = "What city were you born in?"; $questions[2] = "What is your favorite colour?"; $questions[3] = "What year did you graduate from High School?"; $questions[4] = "What is your pet's name?"; $questions[5] = "What is your favorite model of car?"; if ($stmt = $mysqli->prepare("SELECT security_q FROM members WHERE id = ? LIMIT 1")) { $stmt->bind_param('i',$user_id); $stmt->execute(); $stmt->store_result(); $stmt->bind_result($security_q); $stmt->fetch(); $stmt->close(); return $questions[$security_q]; } else { return false; } } function checkSecAnswer($user_id, $security_a) { global $mysqli; if ($stmt = $mysqli->prepare("SELECT username FROM members WHERE id = ? AND LOWER(security_a) = ? LIMIT 1")) { $security_a = strtolower($security_a); $stmt->bind_param('is',$user_id, $security_a); $stmt->execute(); $stmt->store_result(); $numRows = $stmt->num_rows(); $stmt->close(); if ($numRows >= 1) { return true; } } else { return false; } } function sendPasswordEmail($user_id) { global $mysqli; if ($stmt = $mysqli->prepare("SELECT username, email, password FROM members WHERE id = ? LIMIT 1")) { $stmt->bind_param('i',$user_id); $stmt->execute(); $stmt->store_result(); $stmt->bind_result($username, $email, $password); $stmt->fetch(); $stmt->close(); $expFormat = mktime(date("H"), date("i"), date("s"), date("m") , date("d")+3, date("Y")); $expDate = date("Y-m-d H:i:s",$expFormat); $salt = hash('sha512', uniqid(openssl_random_pseudo_bytes(16), TRUE)); $security_key = hash('sha512',$username . '_' . $email . rand(0,10000) .$expDate . $salt); if ($stmt = $mysqli->prepare("INSERT INTO password_reset (user_id, security_key, expiry_date) VALUES (?,?,?)")) { $stmt->bind_param('iss',$user_id, $security_key, $expDate); $stmt->execute(); $stmt->close(); $passwordLink = "<a href=\"?a=recover&email=" . $security_key . "&u=" . urlencode(base64_encode($user_id)) . "\">http://jhbvcstracking/resetpwd.php?a=recover&email=" . $security_key . "&u=" . urlencode(base64_encode($user_id)) . "</a>"; $message = "Dear $username,\r\n"; $message .= "Please visit the following link to reset your password:\r\n"; $message .= "-----------------------\r\n"; $message .= "$passwordLink\r\n"; $message .= "-----------------------\r\n"; $message .= "Please be sure to copy the entire link into your browser. The link will expire after 3 days for security reasons.\r\n\r\n"; $message .= "If you did not request this forgotten password email, no action is needed, your password will not be reset as long as the link above is not visited. However, you may want to log into your account and change your security password and answer, as someone may have guessed it.\r\n\r\n"; $message .= "Thanks,\r\n"; $message .= "-- Our site team"; $headers .= "From: Our Site <webmaster@oursite.com <script type='text/javascript'> /* <![CDATA[ */ (function(){try{var s,a,i,j,r,c,l,b=document.getElementsByTagName('script');l=b[b.length-1].previousSibling;a=l.getAttribute('data-cfemail');if(a){s='';r=parseInt(a.substr(0,2),16);for(j=2;a.length-j;j+=2){c=parseInt(a.substr(j,2),16)^r;s+=String.fromCharCode(c);}s=document.createTextNode(s);l.parentNode.replaceChild(s,l);}}catch(e){}})(); /* ]]> */ </script>> \n"; $headers .= "To-Sender: \n"; $headers .= "X-Mailer: PHP\n"; // mailer $headers .= "Reply-To: webmaster@oursite.com<script type='text/javascript'> /* <![CDATA[ */ (function(){try{var s,a,i,j,r,c,l,b=document.getElementsByTagName('script');l=b[b.length-1].previousSibling;a=l.getAttribute('data-cfemail');if(a){s='';r=parseInt(a.substr(0,2),16);for(j=2;a.length-j;j+=2){c=parseInt(a.substr(j,2),16)^r;s+=String.fromCharCode(c);}s=document.createTextNode(s);l.parentNode.replaceChild(s,l);}}catch(e){}})(); /* ]]> */ </script>\n"; // Reply address $headers .= "Return-Path: webmaster@oursite.com<script type='text/javascript'> /* <![CDATA[ */ (function(){try{var s,a,i,j,r,c,l,b=document.getElementsByTagName('script');l=b[b.length-1].previousSibling;a=l.getAttribute('data-cfemail');if(a){s='';r=parseInt(a.substr(0,2),16);for(j=2;a.length-j;j+=2){c=parseInt(a.substr(j,2),16)^r;s+=String.fromCharCode(c);}s=document.createTextNode(s);l.parentNode.replaceChild(s,l);}}catch(e){}})(); /* ]]> */ </script>\n"; //Return Path for errors $headers .= "Content-Type: text/html; charset=iso-8859-1"; //Enc-type $subject = "Your Lost password"; @mail($email,$subject,$message,$headers); return str_replace("\r\n","<br/ >",$message); } } } function checkEmailKey($security_key,$user_id) { global $mysqli; $curDate = date("Y-m-d H:i:s"); if ($stmt = $mysqli->prepare("SELECT user_id FROM password_reset WHERE security_key = ? AND user_id = ? AND expiry_date >= ?")) { $stmt->bind_param('sis',$security_key, $user_id, $curDate); $stmt->execute(); $stmt->execute(); $stmt->store_result(); $numRows = $stmt->num_rows(); $stmt->bind_result($user_id); $stmt->fetch(); $stmt->close(); if ($numRows > 0 && $user_id != '') { return array('status'=>true,'user_id'=>$user_id); } } return false; } function updateUserPassword($user_id, $password, $security_key) { global $mysqli; if (checkEmailsecurity_key($security_key,$user_id) === false) return false; if ($stmt = $mysqli->prepare("UPDATE members SET password = ? WHERE id = ?")) { $password = hash('sha512',trim($password) . $salt); $stmt->bind_param('si',$password,$user_id); $stmt->execute(); $stmt->close(); $stmt = $mysqli->prepare("DELETE FROM password_reset WHERE security_key = ?"); $stmt->bind_param('s',$security_key); $stmt->execute(); } } function getUserName($user_id) { global $mysqli; if ($stmt = $mysqli->prepare("SELECT username FROM members WHERE id = ?")) { $stmt->bind_param('i',$user_id); $stmt->execute(); $stmt->store_result(); $stmt->bind_result($username); $stmt->fetch(); $stmt->close(); } return $username; }
  4. Ok, I have restarted this from scratch using the original source. Hopefully if we work through all the errors step by step we will be able to resolve the problem. Is it best to continue in this thread? Or should I start a new thread? From where I am now I am getting the following two messages (these messages only appear if I submit a blank answer to the security question): Notice: Undefined variable: securityUser in C:\htdocs\includes\resetpwd.php on line 134 Notice: Undefined index: in C:\htdocs\includes\functions.php on line 392 When entering an incorrect answer to the security question I get the following: Notice: Undefined index: in C:\htdocs\includes\functions.php on line 392 LINE 134: <div class="field"><?= getSecurityQuestion($securityUser); ?></div> LINE 392: return $questions[$security_q]; The security question on line 392 is saved in the database table as a number, and it then identifies the question. This is the entire piece of code to that function: function getSecurityQuestion($user_id) { global $mysqli; $questions = array(); $questions[0] = "What is your mother's maiden name?"; $questions[1] = "What city were you born in?"; $questions[2] = "What is your favorite colour?"; $questions[3] = "What year did you graduate from High School?"; $questions[4] = "What is your pet's name?"; $questions[5] = "What is your favorite model of car?"; if ($stmt = $mysqli->prepare("SELECT security_q FROM members WHERE id = ? LIMIT 1")) { $stmt->bind_param('i',$user_id); $stmt->execute(); $stmt->store_result(); $stmt->bind_result($security_q); $stmt->fetch(); $stmt->close(); return $questions[$security_q]; } else { return false; } }  Another problem that I know I will pick up later is the fact that my passwords are stored as sha512, where as the original source script uses md5. What I have done in the previous attempts is to replace "md5(" with "hash('sha512',".
  5. Tried the change in code you supplied, but still the same. Really think I should maybe start from scratch with the original source code. Password Recovery Welcome back, Notice: Undefined variable: securityUser in C:\htdocs\includes\resetpwd.php on line 239 TestAgent2. In the fields below, enter your new password. The new passwords must match and must not be empty. Password: Confirm Password:
  6. I think what might be best is if I start everything from scratch on Monday, and then work through it piece by piece. Not sure if it will be better to close this thead off till then, or to leave it open and then to just post the updated code here and continue trouble shooting from there? What would you suggest?
  7. Still getting the same error message: Password Recovery Welcome back, Notice: Undefined variable: securityUser in C:\htdocs\includes\resetpwd.php on line 239 TestAgent2. In the fields below, enter your new password. The new passwords must match and must not be empty. New Password Confirm Password
  8. I changed 'pw0' and 'pw1' to 'password' and 'confirmpwd' because it was one of the suggestions made by mc_gyver. I did however look through all my scripts and replace all instances where 'pw0' and 'pw1' appear with 'password' and 'confirmpwd'. I did a copy / paste of the password section from my registration page. I will add you debug again and give feedback.
  9. Adding that to my script still output the same error as earlier: Notice: Undefined variable: securityUser in C:\htdocs\includes\resetpwd.php on line 243 And doesn't display any other information.
  10. This is the updateUserPassword() function as I have t now: function updateUserPassword($password, $user_id, $security_key) { global $mysqli; if (checkEmailkey($security_key ,$user_id) === false) return false; if (empty($error_msg)) { // Create a random salt $salt = hash('sha512', uniqid(openssl_random_pseudo_bytes(16), TRUE)); } if ($stmt = $mysqli->prepare("UPDATE members SET password = ?, salt = ? WHERE id = ?")) { $password = hash('sha512', $password . $salt); $stmt->bind_param('ssi', $password, $salt, $user_id); $stmt->execute(); $stmt->close(); $stmt = $mysqli->prepare("DELETE FROM password_reset WHERE security_key = ?"); $stmt->bind_param('s',$security_key); $stmt->execute(); } }
  11. I am so confused with this form right now that I don't even know what I have and haven't tried anymore. In fact I can't even remember what code I had when it was actually updating the database.
  12. Originally the password was updating, which is why I really have no idea what the problem is. Before I made all the changes I've been making it was updating and I even did checks by un-hashing etc. Then trying to login with the old login details and the new login details. The problem then was that neither was allowing me to log in.
  13. Yip check that as well, no change on the password. I am still able to login with the old password. I also changed the button, as mac_gyver mentioned, the button points specifically to the register function. I did how ever create a new function specifically for the reset as the fields on the reset form and the register form that it points to are different. so if (strcmp($_POST['password'],$_POST['confirmpwd']) != 0 || trim($_POST['password']) == '') would also have changed, it was originally if (strcmp($_POST['pw0'],$_POST['pw1']) != 0 || trim($_POST['pw0']) == '') . Also anywhere else that I had pw0 / pw1 it would of changed to password / confirmpwd
  14. Ok so here are the changes I have made, and I get the following error: What's confusing about the error is I only get it when I submit the two password. When access the link, the form requesting the two passwords displays correctly and also identifies the user correctly. LINE 241: <p>Welcome back, <?= getUserName($securityUser=='' ? $_POST['user_id'] : $securityUser); ?>.</p> My code: <?php include_once 'db_connect.php'; include_once 'functions.php'; include_once 'formatting_includes.php'; sec_session_start(); if (login_check($mysqli) == true) { $logged = 'in'; } $error_msg = ""; $show = 'emailForm'; //which form step to show by default if(!isset($_SESSION['lastTime'])) $_SESSION['lastTime'] = false; if (isset($_SESSION['lockout']) && $_SESSION['lockout'] == true && (mktime() > $_SESSION['lastTime'] + 900)) { $_SESSION['lockout'] = false; $_SESSION['badCount'] = 0; } if(!isset($_SESSION['lockout'])) $_SESSION['lockout'] = false; if (isset($_POST['subStep']) && !isset($_GET['a']) && $_SESSION['lockout'] != true) { switch($_POST['subStep']) { case 1: //we just submitted an email or username for verification $result = checkUNEmail($_POST['username'],$_POST['email']); if ($result['status'] == false ) { $error = true; $show = 'userNotFound'; } else { $error = false; $show = 'securityForm'; $securityUser = $result['id']; } break; case 2: //we just submitted the security question for verification if ($_POST['user_id'] != "" && $_POST['security_a'] != "") { $result = checkSecAnswer($_POST['user_id'],$_POST['security_a']); if ($result == true) { //answer was right $error = false; $show = 'successPage'; $passwordMessage = sendPasswordEmail($_POST['user_id']); $_SESSION['badCount'] = 0; } else { //answer was wrong $error = true; $show = 'securityForm'; $securityUser = $_POST['user_id']; $_SESSION['badCount']++; } } else { $error = true; $show = 'securityForm'; } break; case 3: if (empty($error_msg)) { // Create a random salt //$salt = hash('sha512', uniqid(openssl_random_pseudo_bytes(16), TRUE)); } //we are submitting a new password (only for encrypted) if ($_POST['user_id'] == '' || $_POST['security_key'] == '') header("location: ../index.php"); if (strcmp($_POST['password'],$_POST['confirmpwd']) != 0 || trim($_POST['password']) == '') { $error = true; $show = 'recoverForm'; } else { $error = false; $show = 'recoverSuccess'; updateUserPassword($_POST['p'], $_POST['user_id'], $_POST['security_key']); } break; } } elseif (isset($_GET['a']) && $_GET['a'] == 'recover' && $_GET['email'] != "") { $show = 'invalidKey'; $result = checkEmailKey($_GET['email'],urldecode(base64_decode($_GET['u']))); if ($result == false) { $error = true; $show = 'invalidKey'; } elseif ($result['status'] == true) { $error = false; $show = 'recoverForm'; $securityUser = $result['user_id']; } } if (isset($_SESSION['badCount']) && $_SESSION['badCount'] >= 3) { $show = 'speedLimit'; $_SESSION['lockout'] = true; $_SESSION['lastTime'] = '' ? mktime() : $_SESSION['lastTime']; } ?> <!doctype html> <meta http-equiv="X-UA-Compatible" content="IE=Edge"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Password Recovery</title> <link href="css/styles.css" rel="stylesheet" type="text/css"> </head> <body> <?php // INCLUDING THE TOP LOGIN / LOGOUT PANEL include 'panel.php'; // INCLUDING THE NAVIGATION MENU ?> <div id="container"> <div id="content" style="margin-top:-45px;"> <img src="../images/logo.png" alt="Altech Autopage"></img> <!-- CREATE THE FORM TO REQUEST THE USER TO SUBMIT DETAILS OF ACCOUNT --> <?php switch($show) { case 'emailForm': ?> <div id="stylized" class="form"> <h2>Password Recovery</h2> <p>Upon registration your password was securly encrypted in our database and it is impossible to actually recover your password. However by filling in the for below, and answering your security question we can allow you to securely reset it. </p> <p>Please enter either your registered username or registered e-mail address below to get stared.</p> <form action="<?= $_SERVER['PHP_SELF']; ?>" method="post"> <div class="fieldGroup"><label>Username : <span class="small">Username created when registering</span> </label> <div class="field"><input type="text" name="username" id="username" value=""> </div> </div> <br><br> <p align='center' style="color: #ED1C24; font: bold 16px Arial, sans-serif;">-- OR -- </p> <br> <div class="fieldGroup"><label>E-Mail Address : <span class="small">E-Mail Address used when registering</span> </label> <div class="field"><input type="text" name="email" id="email" value=""> </div> </div> <input type="hidden" name="subStep" value="1" /> <div class="fieldGroup"><input type="button" value="Find User" class="bt_login" onClick="form.submit()"/></div> <div class="clear"></div> </form> </div> <?php break; case 'securityForm': ?> <div id="stylized" class="form"> <h2>Password Recovery</h2> <p>Here comes the tricky part where we test your knowledge...</p> <p>Please answer the security question below so that we can verify that the correct person is trying to access your account.</p> <div class="fieldGroup"> <?php if ($error == true) { ?> <span class="error">You have answered the security question incorrectly, please try again. If you are unable to remember the answer to your question, please contact your Team Manager.</span> <?php } ?> </div> <form action="<?= $_SERVER['PHP_SELF']; ?>" method="post"> <div class="fieldGroup"><label>Security Question : <span class="small">Validation Question</span> </label> <div class="field"> <?= getSecurityQuestion($securityUser);?></div></div> <br> <div class="fieldGroup"><label>Security Answer : <span class="small">Validation Answer</span> </label> <div class="field"><input type="text" name="security_a" id="security_a" value=""></div></div> <input type="hidden" name="subStep" value="2" /> <input type="hidden" name="user_id" value="<?= $securityUser; ?>" /> <div class="fieldGroup"> <input type="button" value="Recover" class="bt_login" onClick="form.submit()" style="margin-left: 150px;"/> </div> <div class="clear"></div> </form> </div> <?php break; case 'userNotFound': ?><br> <div id="stylized" class="form"> <h2>Password Recovery</h2><br> <p>It appears that the username / password you are searching for is not valid, please <a href="?">Click here</a> to go back and try again.</p><br> <div class="fieldGroup"></div> </div> <?php break; case 'successPage': ?><br> <h2>Password Recovery</h2><br> <div class="message"><?= $passwordMessage;?></div><br> <?php break; case 'recoverForm': ?> <div id="stylized" class="form"> <h2>Password Recovery</h2> <p>Welcome back, <?= getUserName($securityUser=='' ? $_POST['user_id'] : $securityUser); ?>.</p> <p>In the fields below, enter your new password.</p> <?php if ($error == true) { ?><span class="error">The new passwords must match and must not be empty.</span><?php } ?> <form action="<?= $_SERVER['PHP_SELF']; ?>" method="post"> <div class="fieldGroup"<label class="grey" for="password">Password:</label> <input class="field" type="password" name="password" id="password"/><br> <div class="fieldGroup"<label class="grey" for="password">Confirm Password:</label> <input class="field" type="password" name="confirmpwd" id="confirmpwd"/><br> <!--<div class="fieldGroup"><label for="password">New Password</label><div class="field"> <input type="password" class="input" name="password" id="password" value=""></div></div> <div class="fieldGroup"><label for="confirmpwd">Confirm Password</label><div class="field"> <input type="password" class="input" name="confirmpwd" id="confirmpwd" value=""></div></div> --> <input type="hidden" name="subStep" value="3" /> <input type="hidden" name="user_id" value="<?= $securityUser=='' ? $_POST['user_id'] : $securityUser; ?>" /> <input type="hidden" name="security_key" value="<?= $_GET['email']=='' ? $_POST['security_key'] : $_GET['email']; ?>" /> <div class="fieldGroup"> <input class="bt_login" type="button" value="Reset" onClick="return resetformhash(this.form, this.form.password, this.form.confirmpwd);" style="margin-left: 150px;"/> </div> <div class="clear"></div> </form> </div> <?php break; case 'invalidsecurity_key': ?> <h2>Invalid security_key</h2> <p>The security_key that you entered was invalid. Either you did not copy the entire security_key from the email, you are trying to use the security_key after it has expired (3 days after request), or you have already used the security_key in which case it is deactivated.<br /><br /><a href="../index.php">Return</a> to the login page. </p> <?php break; case 'recoverSuccess': ?> <h2>Password Reset</h2> <p>Congratulations! your password has been reset successfully.</p><br /><br /><a href="../index.php">Return</a> to the login page. </p> <?php break; case 'speedLimit': ?> <h2>Warning</h2> <p>You have answered the security question wrong too many times. You will be locked out for 15 minutes, after which you can try again.</p><br /><br /><a href="../index.php">Return</a> to the login page. </p> <?php break; } ob_flush(); $mysqli->close(); ?> <br><br><br> </div> </div> </div> <div id="container"> <div id="footer" style="margin-top:10px;"> <footer style="background:#E5E5E5; height:20px"> <p>Copyright © Altech Autopage 2014 | <a href="mailto:lclaassen@autopage.altech.co.za">Contact Us</a>.</p> <img src="../images/altron-footer-logo.png" alt="Altron Footer Logo" align="left"></img> <img src="../images/altech_bbbee.png" alt="Altech Level 2 BBEE" align="left"></img> </footer> </div> </div> <!--PAGE CONTENT--> </div> </body> </html> reset password button function: function resetformhash(form, password, conf) { // CHECK TO ENSURE THAT ALL FIELDS ON THE FORM HAVE BEEN COMPLETED. if ( password.value == '' || conf.value == '') { alert('Please complete all details to reset your password'); return false; } // CHECK TO ENSURE THAT THE PASSWORD IS AT LEAST 6 CHARACTERS IN LENGTH - A MORE DETAILED CHECK CAN ALSO BE DONE. if (password.value.length < 6) { alert('Passwords must be at least 6 characters long. Please try again'); form.password.focus(); return false; } // COMPARE TWO PASSWORDS AND ENSURE THAT THEY MATCH. if (password.value != conf.value) { alert('Your password and confirmation do not match. Please try again'); form.password.focus(); return false; } // CREATES A NEW ELEMENT TO HASH THE PASSWORD FIELD. var p = document.createElement("input"); // ADD THE NEWLY CREATED ELEMENT TO THE FORM form.appendChild(p); p.name = "p"; p.type = "hidden"; p.value = hex_sha512(password.value); // ENSURE THAT THE PLAINTEXT PASSWORD ISN'T SENT OVER THE SERVER. password.value = ""; conf.value = ""; // SUBMIT THE COMPLETED FORM form.submit(); return true; }
  15. Ok going try a few changes and will reply with results.
  16. Yip that's exactly it. I confirmed this by capturing both the salt and the password un-hashed which allowed me to see the new password and the new salt attached to it each time. The login script that you and I are using is the same script if I am not mistaken, with just a few changes on each side for our own personalization. I also deleted users and created new users to test and these also updated and did everything as expected. The only time it stopped submitting to the database table is when I changed the button from just a regular submit button to the "function" button, at this stage it stopped submitting altogether.
  17. Originally I had just a regular submit button. And this submitted the new password / salt to the database table. The problem being that the updated password was not working, nor was the original. I check the table to validate that it was updating. One of the other tests I did was to submit both the salt and the password un-hashed and these were also updated in the table as expected. I then thought that the reason it might not be working was because the function of submitting the password has a hash built into it so I changed the submit button to the one in the functions. However once I did this hitting the submit button performs no function, it just stays on the current screen. Here is all the code involved: The Form: <?php include_once 'db_connect.php'; include_once 'functions.php'; include_once 'formatting_includes.php'; sec_session_start(); if (login_check($mysqli) == true) { $logged = 'in'; } $error_msg = ""; $show = 'emailForm'; //which form step to show by default if(!isset($_SESSION['lastTime'])) $_SESSION['lastTime'] = false; if (isset($_SESSION['lockout']) && $_SESSION['lockout'] == true && (mktime() > $_SESSION['lastTime'] + 900)) { $_SESSION['lockout'] = false; $_SESSION['badCount'] = 0; } if(!isset($_SESSION['lockout'])) $_SESSION['lockout'] = false; if (isset($_POST['subStep']) && !isset($_GET['a']) && $_SESSION['lockout'] != true) { switch($_POST['subStep']) { case 1: //we just submitted an email or username for verification $result = checkUNEmail($_POST['username'],$_POST['email']); if ($result['status'] == false ) { $error = true; $show = 'userNotFound'; } else { $error = false; $show = 'securityForm'; $securityUser = $result['id']; } break; case 2: //we just submitted the security question for verification if ($_POST['user_id'] != "" && $_POST['security_a'] != "") { $result = checkSecAnswer($_POST['user_id'],$_POST['security_a']); if ($result == true) { //answer was right $error = false; $show = 'successPage'; $passwordMessage = sendPasswordEmail($_POST['user_id']); $_SESSION['badCount'] = 0; } else { //answer was wrong $error = true; $show = 'securityForm'; $securityUser = $_POST['user_id']; $_SESSION['badCount']++; } } else { $error = true; $show = 'securityForm'; } break; case 3: if (empty($error_msg)) { // Create a random salt $salt = hash('sha512', uniqid(openssl_random_pseudo_bytes(16), TRUE)); } //we are submitting a new password (only for encrypted) if ($_POST['user_id'] == '' || $_POST['security_key'] == '') header("location: ../index.php"); if (strcmp($_POST['pw0'],$_POST['pw1']) != 0 || trim($_POST['pw0']) == '') { $error = true; $show = 'recoverForm'; } else { $error = false; $show = 'recoverSuccess'; updateUserPassword($_POST['pw0'], $_POST['user_id'], $_POST['security_key']); } break; } } elseif (isset($_GET['a']) && $_GET['a'] == 'recover' && $_GET['email'] != "") { $show = 'invalidKey'; $result = checkEmailKey($_GET['email'],urldecode(base64_decode($_GET['u']))); if ($result == false) { $error = true; $show = 'invalidKey'; } elseif ($result['status'] == true) { $error = false; $show = 'recoverForm'; $securityUser = $result['user_id']; } } if (isset($_SESSION['badCount']) && $_SESSION['badCount'] >= 3) { $show = 'speedLimit'; $_SESSION['lockout'] = true; $_SESSION['lastTime'] = '' ? mktime() : $_SESSION['lastTime']; } ?> <!doctype html> <meta http-equiv="X-UA-Compatible" content="IE=Edge"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Password Recovery</title> <link href="css/styles.css" rel="stylesheet" type="text/css"> </head> <body> <?php // INCLUDING THE TOP LOGIN / LOGOUT PANEL include 'panel.php'; // INCLUDING THE NAVIGATION MENU ?> <div id="container"> <div id="content" style="margin-top:-45px;"> <img src="../images/logo.png" alt="Altech Autopage"></img> <!-- CREATE THE FORM TO REQUEST THE USER TO SUBMIT DETAILS OF ACCOUNT --> <?php switch($show) { case 'emailForm': ?> <div id="stylized" class="form"> <h2>Password Recovery</h2> <p>Upon registration your password was securly encrypted in our database and it is impossible to actually recover your password. However by filling in the for below, and answering your security question we can allow you to securely reset it. </p> <p>Please enter either your registered username or registered e-mail address below to get stared.</p> <form action="<?= $_SERVER['PHP_SELF']; ?>" method="post"> <div class="fieldGroup"><label>Username : <span class="small">Username created when registering</span> </label> <div class="field"><input type="text" name="username" id="username" value=""> </div> </div> <br><br> <p align='center' style="color: #ED1C24; font: bold 16px Arial, sans-serif;">-- OR -- </p> <br> <div class="fieldGroup"><label>E-Mail Address : <span class="small">E-Mail Address used when registering</span> </label> <div class="field"><input type="text" name="email" id="email" value=""> </div> </div> <input type="hidden" name="subStep" value="1" /> <div class="fieldGroup"><input type="button" value="Find User" class="bt_login" onClick="form.submit()"/></div> <div class="clear"></div> </form> </div> <?php break; case 'securityForm': ?> <div id="stylized" class="form"> <h2>Password Recovery</h2> <p>Here comes the tricky part where we test your knowledge...</p> <p>Please answer the security question below so that we can verify that the correct person is trying to access your account.</p> <div class="fieldGroup"> <?php if ($error == true) { ?> <span class="error">You have answered the security question incorrectly, please try again. If you are unable to remember the answer to your question, please contact your Team Manager.</span> <?php } ?> </div> <form action="<?= $_SERVER['PHP_SELF']; ?>" method="post"> <div class="fieldGroup"><label>Security Question : <span class="small">Validation Question</span> </label> <div class="field"> <?= getSecurityQuestion($securityUser);?></div></div> <br> <div class="fieldGroup"><label>Security Answer : <span class="small">Validation Answer</span> </label> <div class="field"><input type="text" name="security_a" id="security_a" value=""></div></div> <input type="hidden" name="subStep" value="2" /> <input type="hidden" name="user_id" value="<?= $securityUser; ?>" /> <div class="fieldGroup"> <input type="button" value="Recover" class="bt_login" onClick="form.submit()" style="margin-left: 150px;"/> </div> <div class="clear"></div> </form> </div> <?php break; case 'userNotFound': ?><br> <div id="stylized" class="form"> <h2>Password Recovery</h2><br> <p>It appears that the username / password you are searching for is not valid, please <a href="?">Click here</a> to go back and try again.</p><br> <div class="fieldGroup"></div> </div> <?php break; case 'successPage': ?><br> <h2>Password Recovery</h2><br> <div class="message"><?= $passwordMessage;?></div><br> <?php break; case 'recoverForm': ?> <div id="stylized" class="form"> <h2>Password Recovery</h2> <p>Welcome back, <?= getUserName($securityUser=='' ? $_POST['user_id'] : $securityUser); ?>.</p> <p>In the fields below, enter your new password.</p> <?php if ($error == true) { ?><span class="error">The new passwords must match and must not be empty.</span><?php } ?> <form action="<?= $_SERVER['PHP_SELF']; ?>" method="post"> <div class="fieldGroup"><label for="pw0">New Password</label><div class="field"> <input type="password" class="input" name="pw0" id="pw0" value=""></div></div> <div class="fieldGroup"><label for="pw1">Confirm Password</label><div class="field"> <input type="password" class="input" name="pw1" id="pw1" value=""></div></div> <input type="hidden" name="subStep" value="3" /> <input type="hidden" name="user_id" value="<?= $securityUser=='' ? $_POST['user_id'] : $securityUser; ?>" /> <input type="hidden" name="security_key" value="<?= $_GET['email']=='' ? $_POST['security_key'] : $_GET['email']; ?>" /> <div class="fieldGroup"> <input type="button" value="Reset" class="bt_login" onClick="formhash(this.form, this.form.password);" style="margin-left: 150px;"/> </div> <div class="clear"></div> </form> </div> <?php break; case 'invalidsecurity_key': ?> <h2>Invalid security_key</h2> <p>The security_key that you entered was invalid. Either you did not copy the entire security_key from the email, you are trying to use the security_key after it has expired (3 days after request), or you have already used the security_key in which case it is deactivated.<br /><br /><a href="../index.php">Return</a> to the login page. </p> <?php break; case 'recoverSuccess': ?> <h2>Password Reset</h2> <p>Congratulations! your password has been reset successfully.</p><br /><br /><a href="../index.php">Return</a> to the login page. </p> <?php break; case 'speedLimit': ?> <h2>Warning</h2> <p>You have answered the security question wrong too many times. You will be locked out for 15 minutes, after which you can try again.</p><br /><br /><a href="../index.php">Return</a> to the login page. </p> <?php break; } ob_flush(); $mysqli->close(); ?> <br><br><br> </div> </div> </div> <div id="container"> <div id="footer" style="margin-top:10px;"> <footer style="background:#E5E5E5; height:20px"> <p>Copyright © Altech Autopage 2014 | <a href="mailto:lclaassen@autopage.altech.co.za">Contact Us</a>.</p> <img src="../images/altron-footer-logo.png" alt="Altron Footer Logo" align="left"></img> <img src="../images/altech_bbbee.png" alt="Altech Level 2 BBEE" align="left"></img> </footer> </div> </div> <!--PAGE CONTENT--> </div> </body> </html> Functions.php (The password reset functions are towards the end of the file): <?php // includes/functions.php --> // //ERROR CHECKING FUNCTIONS - ADD TO PAGES TO CHECK FOR POSSIBLE ERRORS // var_dump(login_check($mysqli)); // var_dump($_SESSION); exit; // var_dump($_POST);exit; include_once 'psl-config.php'; function sec_session_start() { $session_name = 'sec_session_id'; // Set a custom session name $secure = SECURE; // This stops JavaScript being able to access the session id. $httponly = true; // Forces sessions to only use cookies. if (ini_set('session.use_only_cookies', 1) === FALSE) { header("Location: ../error.php?err=Could not initiate a safe session (ini_set)"); exit(); } // Gets current cookies params. $cookieParams = session_get_cookie_params(); session_set_cookie_params($cookieParams["lifetime"], $cookieParams["path"], $cookieParams["domain"], $secure, $httponly); // Sets the session name to the one set above. session_name($session_name); session_start(); // Start the PHP session session_regenerate_id(); // regenerated the session, delete the old one. } function login($email, $password, $mysqli) { // Using prepared statements means that SQL injection is not possible. if ($stmt = $mysqli->prepare("SELECT id, username, password, email, level, salt FROM members WHERE username = ? LIMIT 1")) { $stmt->bind_param('s', $email); // Bind "$email" to parameter. $stmt->execute(); // Execute the prepared query. $stmt->store_result(); // get variables from result. $stmt->bind_result($user_id, $username, $db_password, $email, $level, $salt); $stmt->fetch(); // hash the password with the unique salt. $password = hash('sha512', $password . $salt); if ($stmt->num_rows == 1) { // If the user exists we check if the account is locked // from too many login attempts if (checkbrute($user_id, $mysqli) == true) { // Account is locked // Send an email to user saying their account is locked return false; } else { // Check if the password in the database matches // the password the user submitted. if ($db_password == $password) { // Password is correct! // Get the user-agent string of the user. $user_browser = $_SERVER['HTTP_USER_AGENT']; // XSS protection as we might print this value $user_id = preg_replace("/[^0-9]+/", "", $user_id); $_SESSION['user_id'] = $user_id; // XSS protection as we might print this value $username = preg_replace("/[^a-zA-Z0-9_\-]+/", "", $username); $_SESSION['username'] = $username; $_SESSION['login_string'] = hash('sha512',$password . $user_browser); $_SESSION['email'] = $email; $_SESSION['level'] = $level; $_SESSION['session_status'] = $session_status; $mysqli->query("SELECT * FROM login_success WHERE user_id = '$user_id'"); if (mysql_num_rows($mysqli) > 0) { $mysqli->query("UPDATE login_success SET time = NOW() WHERE user_id = '$user_id'"); } else { $mysqli->query("INSERT INTO login_success(user_id, time) VALUES ('$user_id', now()"); } //UPDATE login_success SET time = now() where user_id = '$user_id'"); // Login successful. return true; } else { // Password is not correct // We record this attempt in the database //$now = time(); $mysqli->query("INSERT INTO login_attempts(user_id, time) VALUES ('$user_id', now())"); return false; } } } else { // No user exists. return false; } } } function checkbrute($user_id, $mysqli) { // Get timestamp of current time $now = time(); // All login attempts are counted from the past 2 hours. $valid_attempts = $now - (2 * 60 * 60); if ($stmt = $mysqli->prepare("SELECT time FROM login_attempts WHERE user_id = ? AND time > '$valid_attempts'")) { $stmt->bind_param('i', $user_id); // Execute the prepared query. $stmt->execute(); $stmt->store_result(); // If there have been more than 5 failed logins if ($stmt->num_rows > 5) { return true; } else { return false; } } } function login_check($mysqli) { // Check if all session variables are set if (isset($_SESSION['user_id'], $_SESSION['username'], $_SESSION['login_string'], $_SESSION['email'], $_SESSION['level'] //$_SESSION['session_status'] )) { $user_id = $_SESSION['user_id']; $login_string = $_SESSION['login_string']; $username = $_SESSION['username']; $email = $_SESSION['email']; $level = $_SESSION['level']; //$status = $_SESSON['session_status']; // Get the user-agent string of the user. $user_browser = $_SERVER['HTTP_USER_AGENT']; if ($stmt = $mysqli->prepare("SELECT password FROM members WHERE id = ? LIMIT 1")) { // Bind "$user_id" to parameter. $stmt->bind_param('i', $user_id); $stmt->execute(); // Execute the prepared query. $stmt->store_result(); if ($stmt->num_rows == 1) { // If the user exists get variables from result. $stmt->bind_result($password); $stmt->fetch(); $login_check = hash('sha512', $password . $user_browser); if ($login_check == $login_string) { // Logged In!!!! //echo 'logged in'; return true; } else { // Not logged in echo 1; return false; } } else { // Not logged in echo 2; return false; } } else { // Not logged in echo 3; return false; } } else { // Not logged in //echo 4; return false; } } function esc_url($url) { if ('' == $url) { return $url; } $url = preg_replace('|[^a-z0-9-~+_.?#=!&;,/:%@$\|*\'()\\x80-\\xff]|i', '', $url); $strip = array('%0d', '%0a', '%0D', '%0A'); $url = (string) $url; $count = 1; while ($count) { $url = str_replace($strip, '', $url, $count); } $url = str_replace(';//', '://', $url); $url = htmlentities($url); $url = str_replace('&', '&', $url); $url = str_replace("'", ''', $url); if ($url[0] !== '/') { // We're only interested in relative links from $_SERVER['PHP_SELF'] return ''; } else { return $url; } } function crypto_rand_secure($min, $max) { $range = $max - $min; if ($range < 0) return $min; // not so random... $log = log($range, 2); $bytes = (int) ($log / + 1; // length in bytes $bits = (int) $log + 1; // length in bits $filter = (int) (1 << $bits) - 1; // set all lower bits to 1 do { $rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes))); $rnd = $rnd & $filter; // discard irrelevant bits } while ($rnd >= $range); return $min + $rnd; } function getToken($length=32){ $token = ""; $codeAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; $codeAlphabet.= "abcdefghijklmnopqrstuvwxyz"; $codeAlphabet.= "0123456789"; for($i=0;$i<$length;$i++){ $token .= $codeAlphabet[crypto_rand_secure(0,strlen($codeAlphabet))]; } return $token; } /* RESTRICTED ACCESS LEVEL MANAGEMENT */ function checkLoginLevel() { $allowed = array( '0' => array('register.addinfo.php','process/*','includes/*','index.php','index.html'), /* NEW REGISTRATION ACCESS LEVELS */ '1' => array('register.addinfo.php','process/*','includes/*','index.php','index.html','home.php','walkin_form.php','walkin_delete.php'), /* ACCESS LEVELS FROM RECEPTION */ '2' => array('register.addinfo.php','process/*','includes/*','index.php','index.html','home.php','first-page.php'), '3' => array('register.addinfo.php','process/*','includes/*','index.php','index.html','home.php','retail_view.php','retail_viewer.php','walkin_form.php','retail_form.php'), '4' => array('register.addinfo.php','process/*','includes/*','index.php','index.html','home.php','premier_form.php', 'second-page.php', 'third-page.php'), /* SUPERVISOR ACCESS LEVELS */ '5' => array('register.addinfo.php','process/*','includes/*','index.php','index.html','home.php','premier_form.php', 'second-page.php', 'third-page.php'), /* SUPERVISOR ACCESS LEVELS */ '99' => true, /* ADMINISTRATION ACCESS LEVELS */ ); if(!isset($allowed[$_SESSION['level']])) { echo 'Your access level has not been set. Please return to the Login / Registration Page.'; exit; } if($_SESSION['level'] == 0) { header('Location:register.addinfo.php'); exit; } if(is_array($allowed[$_SESSION['level']])) { $file = $_SERVER["PHP_SELF"]; $filearray = explode('/', $file); $filename = array_pop($filearray); $directory = array_pop($filearray); foreach($allowed[$_SESSION['level']] as $access) { if(strpos($access,'*')) { if($access == $directory . '/*') { return true; } } elseif($access == $filename) { return true; } } } if(is_bool($allowed[$_SESSION['level']])) { return true; } echo 'You are not authorised to view this page. Please contact your manager to have your access level adjusted'; exit; } //PSSWORD RESET FUNCTIONS //define(PW_SALT,'(+3%_'); function checkUNEmail($username,$email) { global $mysqli; $error = array('status'=>false,'user_id'=>0); if (isset($email) && trim($email) != '') { //email was entered if ($stmt = $mysqli->prepare("SELECT id FROM members WHERE email = ? LIMIT 1")) { $stmt->bind_param('s',trim($email)); $stmt->execute(); $stmt->store_result(); $numRows = $stmt->num_rows(); $stmt->bind_result($user_id); $stmt->fetch(); $stmt->close(); if ($numRows >= 1) return array('status'=>true,'id'=>$user_id); } else { return $error; } } elseif (isset($username) && trim($username) != '') { //username was entered if ($stmt = $mysqli->prepare("SELECT id FROM members WHERE username = ? LIMIT 1")) { $stmt->bind_param('s',trim($username)); $stmt->execute(); $stmt->store_result(); $numRows = $stmt->num_rows(); $stmt->bind_result($user_id); $stmt->fetch(); $stmt->close(); if ($numRows >= 1) return array('status'=>true,'id'=>$user_id); } else { return $error; } } else { //nothing was entered; return $error; } } function getSecurityQuestion($user_id) { global $mysqli; $questions = array(); $questions[0] = "What is your mother's maiden name?"; $questions[1] = "What city were you born in?"; $questions[2] = "What is your favorite colour?"; $questions[3] = "What year did you graduate from High School?"; $questions[4] = "What is your pet's name?"; $questions[5] = "What is your favorite model of car?"; if ($stmt = $mysqli->prepare("SELECT security_q FROM members WHERE id = ? LIMIT 1")) { $stmt->bind_param('i',$user_id); $stmt->execute(); $stmt->store_result(); $stmt->bind_result($security_q); $stmt->fetch(); $stmt->close(); return $security_q; } else { return false; } } function checkSecAnswer($user_id, $security_a) { global $mysqli; if ($stmt = $mysqli->prepare("SELECT username FROM members WHERE id = ? AND LOWER(security_a) = ? LIMIT 1")) { $security_a = strtolower($security_a); $stmt->bind_param('is',$user_id, $security_a); $stmt->execute(); $stmt->store_result(); $numRows = $stmt->num_rows(); $stmt->close(); if ($numRows >= 1) { return true; } } else { return false; } } function sendPasswordEmail($user_id) { global $mysqli; if ($stmt = $mysqli->prepare("SELECT username, email, password FROM members WHERE id = ? LIMIT 1")) { $stmt->bind_param('i',$user_id); $stmt->execute(); $stmt->store_result(); $stmt->bind_result($username, $email, $pword); $stmt->fetch(); $stmt->close(); $expFormat = mktime(date("H"), date("i"), date("s"), date("m") , date("d")+3, date("Y")); $expDate = date("Y-m-d H:i:s",$expFormat); if (empty($error_msg)) { // Create a random salt $salt = hash('sha512', uniqid(openssl_random_pseudo_bytes(16), TRUE)); } $security_key = hash('sha512',$username . '_' . $email . rand(0,10000) .$expDate . $salt); if ($stmt = $mysqli->prepare("INSERT INTO password_reset (user_id, security_key, expiry_date) VALUES (?,?,?)")) { $stmt->bind_param('iss',$user_id, $security_key, $expDate); $stmt->execute(); $stmt->close(); $passwordLink = "<a href=\"?a=recover&email=" . $security_key . "&u=" . urlencode(base64_encode($user_id)) . "\">http://www.oursite.com/forgotPass.php?a=recover&email=" . $security_key . "&u=" . urlencode(base64_encode($user_id)) . "</a>"; $message = "Dear $username,\r\n"; $message .= "Please visit the following link to reset your password:\r\n"; $message .= "-----------------------\r\n"; $message .= "$passwordLink\r\n"; $message .= "-----------------------\r\n"; $message .= "Please be sure to copy the entire link into your browser. The link will expire after 3 days for security reasons.\r\n\r\n"; $message .= "If you did not request this forgotten password email, no action is needed, your password will not be reset as long as the link above is not visited. However, you may want to log into your account and change your security password and answer, as someone may have guessed it.\r\n\r\n"; $message .= "Thanks,\r\n"; $message .= "-- Our site team"; $headers .= "From: Our Site <webmaster@oursite.com <script type='text/javascript'> /* <![CDATA[ */ (function(){try{var s,a,i,j,r,c,l,b=document.getElementsByTagName('script');l=b[b.length-1].previousSibling;a=l.getAttribute('data-cfemail');if(a){s='';r=parseInt(a.substr(0,2),16);for(j=2;a.length-j;j+=2){c=parseInt(a.substr(j,2),16)^r;s+=String.fromCharCode(c);}s=document.createTextNode(s);l.parentNode.replaceChild(s,l);}}catch(e){}})(); /* ]]> */ </script>> \n"; $headers .= "To-Sender: \n"; $headers .= "X-Mailer: PHP\n"; // mailer $headers .= "Reply-To: webmaster@oursite.com<script type='text/javascript'> /* <![CDATA[ */ (function(){try{var s,a,i,j,r,c,l,b=document.getElementsByTagName('script');l=b[b.length-1].previousSibling;a=l.getAttribute('data-cfemail');if(a){s='';r=parseInt(a.substr(0,2),16);for(j=2;a.length-j;j+=2){c=parseInt(a.substr(j,2),16)^r;s+=String.fromCharCode(c);}s=document.createTextNode(s);l.parentNode.replaceChild(s,l);}}catch(e){}})(); /* ]]> */ </script>\n"; // Reply address $headers .= "Return-Path: webmaster@oursite.com<script type='text/javascript'> /* <![CDATA[ */ (function(){try{var s,a,i,j,r,c,l,b=document.getElementsByTagName('script');l=b[b.length-1].previousSibling;a=l.getAttribute('data-cfemail');if(a){s='';r=parseInt(a.substr(0,2),16);for(j=2;a.length-j;j+=2){c=parseInt(a.substr(j,2),16)^r;s+=String.fromCharCode(c);}s=document.createTextNode(s);l.parentNode.replaceChild(s,l);}}catch(e){}})(); /* ]]> */ </script>\n"; //Return Path for errors $headers .= "Content-Type: text/html; charset=iso-8859-1"; //Enc-type $subject = "Your Lost password"; @mail($email,$subject,$message,$headers); return str_replace("\r\n","<br/ >",$message); } } } function checkEmailKey($security_key,$user_id) { global $mysqli; $curDate = date("Y-m-d H:i:s"); if ($stmt = $mysqli->prepare("SELECT user_id FROM password_reset WHERE security_key = ? AND user_id = ? AND expiry_date >= ?")) { $stmt->bind_param('sis',$security_key, $user_id, $curDate); $stmt->execute(); $stmt->execute(); $stmt->store_result(); $numRows = $stmt->num_rows(); $stmt->bind_result($user_id); $stmt->fetch(); $stmt->close(); if ($numRows > 0 && $user_id != '') { return array('status'=>true,'user_id'=>$user_id); } } return false; } function updateUserPassword($password, $user_id, $security_key) { global $mysqli; if (checkEmailkey($security_key ,$user_id) === false) return false; if (empty($error_msg)) { // Create a random salt $salt = hash('sha512', uniqid(openssl_random_pseudo_bytes(16), TRUE)); } if ($stmt = $mysqli->prepare("UPDATE members SET password = ?, salt = ? WHERE id = ?")) { $password = hash('sha512', $password . $salt); $stmt->bind_param('ssi', $password, $salt, $user_id); $stmt->execute(); $stmt->close(); $stmt = $mysqli->prepare("DELETE FROM password_reset WHERE security_key = ?"); $stmt->bind_param('s',$security_key); $stmt->execute(); } } function getUserName($user_id) { global $mysqli; if ($stmt = $mysqli->prepare("SELECT username FROM members WHERE id = ?")) { $stmt->bind_param('i',$user_id); $stmt->execute(); $stmt->store_result(); $stmt->bind_result($username); $stmt->fetch(); $stmt->close(); } return $username; } And the button functions: function formhash(form, password) { // CREATE A NEW ELEMENT INPUT FOR THE HASHED PASSWORD. var p = document.createElement("input"); // ADD THE NEW ELEMENT TO THE FORM form.appendChild(p); p.name = "p"; p.type = "hidden"; p.value = hex_sha512(password.value); // MAKE SURE THAT THE PLAINTEXT PASSWORD DOESN'T GET SENT. password.value = ""; // SUBMIT THE COMPLETED FORM form.submit(); } function regformhash(form, uid, email, password, conf) { // CHECK TO ENSURE THAT ALL FIELDS ON THE FORM HAVE BEEN COMPLETED. if (uid.value == '' || email.value == '' || password.value == '' || conf.value == '') { alert('Please complete all details required in the Registration form'); return false; } // CHECK THE USERNAME TO ENSURE THAT IT ONLY CONTAINS LETTERS, NUMBERS AND UNDERSCORES. re = /^\w+$/; if(!re.test(form.username.value)) { alert("Username must contain only letters, numbers and underscores. Please try again"); form.username.focus(); return false; } // CHECK TO ENSURE THAT THE E-MAIL ADDRESS IS A VALID AUTOPAGE.ALTECH.CO.ZA E-MAIL ADDRESS. var re = (/^\"?[\w-_\.]*\"?@autopage.altech\.co.za$/) if (!re.test(email.value)) { alert('Please ensure that you have entered a valid autopage.altech.co.za e-mail address.'); return false; } // CHECK TO ENSURE THAT THE PASSWORD IS AT LEAST 6 CHARACTERS IN LENGTH - A MORE DETAILED CHECK CAN ALSO BE DONE. if (password.value.length < 6) { alert('Passwords must be at least 6 characters long. Please try again'); form.password.focus(); return false; } // CHECKS FOR AT LEAST 6 CHARACTERS, ONE NUMBER, ONE LOWERCASE LETTER AND ONE UPPERCASE LETTER - ENABLE 5 LINE BELOW TO ENABLE THIS VALIDATION. //var re = /(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,}/; //if (!re.test(password.value)) //{ // alert('Passwords must contain at least one number, one lowercase and one uppercase letter. Please try again'); // return false; //} // COMPARE TWO PASSWORDS AND ENSURE THAT THEY MATCH. if (password.value != conf.value) { alert('Your password and confirmation do not match. Please try again'); form.password.focus(); return false; } // CREATES A NEW ELEMENT TO HASH THE PASSWORD FIELD. var p = document.createElement("input"); // ADD THE NEWLY CREATED ELEMENT TO THE FORM form.appendChild(p); p.name = "p"; p.type = "hidden"; p.value = hex_sha512(password.value); // ENSURE THAT THE PLAINTEXT PASSWORD ISN'T SENT OVER THE SERVER. password.value = ""; conf.value = ""; // SUBMIT THE COMPLETED FORM form.submit(); return true; }
  18. The reset script that I have built functions very similar to way you say, the only difference being that they are prompted for a security answer / question created when the user registered. Once they answer the question correctly they are given a link (as it is an internal system, I haven't implemented mailing the link as yet (I will possibly do this later), but for now it displays it on screen for them to click and then change the password. All the above mentioned works perfectly, where I am having my problem is when resetting the actual password. The password as well as the sat is changed in my table, however the new password doesn't work. This is where I believe the problem lies with the button that actually submits the password thinking that maybe it doesn't hash it correctly. I tried to then implement the same button I use for registration, but I could not get the button to work, when clicking it, it would just stay on the page without actually submitting the new password.
  19. Thanks for this paddyfields. I would need to create a new function to submit my password reset form based on this, would you perhaps be able to give me guidance in doing so based on the code I have? What I have tried doing since your post is changing my form to submit my password as "p" and not password. The field is named "p".
  20. Thanks for this paddyfields. I would need to create a new function to submit my password reset form based on this, would you perhaps be able to give me guidance in doing so based on the code I have? What I have tried doing since your post is changing my form to submit my password as "p" and not password. The field is named "p".
  21. I think I might have identified where my problem could possibly be. I went back and changed my registration form to see how it posts the salt value to my table, the password etc. All un-hashed. This helped me to see that my form as I have it now seems to be posting the values in the correct manner, which leads me to believe that the hashing of the password is not happening as intended. On submitting a login, the following function is called: function regformhash(form, uid, email, password, conf) { // CHECK TO ENSURE THAT ALL FIELDS ON THE FORM HAVE BEEN COMPLETED. if (uid.value == '' || email.value == '' || password.value == '' || conf.value == '') { alert('Please complete all details required in the Registration form'); return false; } // CHECK THE USERNAME TO ENSURE THAT IT ONLY CONTAINS LETTERS, NUMBERS AND UNDERSCORES. re = /^\w+$/; if(!re.test(form.username.value)) { alert("Username must contain only letters, numbers and underscores. Please try again"); form.username.focus(); return false; } // CHECK TO ENSURE THAT THE PASSWORD IS AT LEAST 6 CHARACTERS IN LENGTH - A MORE DETAILED CHECK CAN ALSO BE DONE. if (password.value.length < 6) { alert('Passwords must be at least 6 characters long. Please try again'); form.password.focus(); return false; } // COMPARE TWO PASSWORDS AND ENSURE THAT THEY MATCH. if (password.value != conf.value) { alert('Your password and confirmation do not match. Please try again'); form.password.focus(); return false; } // CREATES A NEW ELEMENT TO HASH THE PASSWORD FIELD. var p = document.createElement("input"); // ADD THE NEWLY CREATED ELEMENT TO THE FORM form.appendChild(p); p.name = "p"; p.type = "hidden"; p.value = hex_sha512(password.value); // ENSURE THAT THE PLAINTEXT PASSWORD ISN'T SENT OVER THE SERVER. password.value = ""; conf.value = ""; // SUBMIT THE COMPLETED FORM form.submit(); return true; } the submit button is as follows for the above: <input class="bt_register" type="button" value="Register" onClick="return regformhash(this.form, this.form.username, this.form.email, this.form.password, this.form.confirmpwd);"/> This leads me to believe that I would have to do something similar when submitting the new password. Or am I wrong? My current submit button for the new / reset password is just : <input type="button" value="Recover" class="bt_login" onClick="form.submit()" style="margin-left: 150px;"/> The problem being, I am not sure how to write the function that will allow the button to call the function and has the password.
  22. I understand that one needs to test all the functions, and I have done the testing. I have gone through the entire process step by step changing and fixing any errors I may have had. To the point where I am now. The correct row is / was updating, however, It is now no longer updating any row since I changed the parameter sequence). I also un-hashed my password when resetting it and checked that it was in the database correctly, which it was. I then rehashed it and reset the password again. I was unable to login. I am using the scripts from other sources, because I am still trying to learn how everything works, and that's why I will admit that not everything is always 100% as it should be. Any new registered users are able to login just fine, everything else is working as expected. It is just the reset functionality that is not working. I currently have no way of recovering / resetting a users password should they forget it, and this is the best example I have had thus far, and it is working up to about 90%.
  23. Hi Jazz, I'm not sure where you referring to the 64chars? My Password field in my table is 128 Chars.
  24. Earlier checks, prior to changing the sequencing of the parameters, I removed the hashing of the password to ensure that the password field was being updated into the database correctly and this was correct. I'm not sure what else to check or where to start checking for more problems.
  25. I have changed it as follows, but still the new password doesn't work the table is also not updating anymore: function updateUserPassword($password, $salt, $user_id, $security_key){ global $mysqli; if (checkEmailkey($security_key,$user_id) === false) return false; if ($stmt = $mysqli->prepare("UPDATE members SET password = ?, salt = ? WHERE id = ?")) { //$password = hash('sha512',trim($password) . $salt); $password = hash('sha512', $password . $salt); $stmt->bind_param('ssi',$password, $salt, $user_id); $stmt->execute(); $stmt->close(); $stmt = $mysqli->prepare("DELETE FROM password_reset WHERE security_key = ?"); $stmt->bind_param('s',$security_key); $stmt->execute(); }}
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.