iblackedout Posted November 16, 2008 Share Posted November 16, 2008 Hi, I have a problem with a php script that I put together that uses mysql. Basically, it is a forgot password script that generates a new random password, emails it to a user then encrypts the password and stores it into the database so that the user may log in with it. I set up a page called forgot.php with a form that asks the user to enter his/her email address. It uses the post method to run a few lines of php in a file called doreset.php. When I run the script, nothing seems to happen yet I don't get any error messages. I can't seem to isolate the problem. Here is the code for doreset.php: <?php //Start session session_start(); //Include database connection details require_once('config.php'); //Array to store validation errors $errmsg_arr = array(); //Validation error flag $errflag = false; //Connect to mysql server $link = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD); if(!$link) { die('Failed to connect to server: ' . mysql_error()); } //Select database $db = mysql_select_db(DB_DATABASE); if(!$db) { die("Unable to select database"); } //Function to sanitize values received from the form. Prevents SQL injection function clean($str) { $str = @trim($str); if(get_magic_quotes_gpc()) { $str = stripslashes($str); } return mysql_real_escape_string($str); } //Sanitize the POST values $email = clean($_POST['email']); $valmail = "^([_a-z0-9-]+)(\.[_a-z0-9-]+)*@([a-z0-9-]+)(\.[a-z0-9-]+)*(\.[a-z]{2,4})$"; //Input Validations if (eregi($valmail, $email)) { if($email == '') { $errmsg_arr[] = 'Email address missing'; $errflag = true; } } else { $errmsg_arr[] = 'Email address is not valid'; $errflag = true; } //Check to see if email is linked to an account if($email != '') { $qry = "SELECT * FROM members WHERE email='$email'"; $result = mysql_query($qry); if($result) { if(mysql_num_rows($result) < 1) { $errmsg_arr[] = 'Email address entered is not linked to an account'; $errflag = true; } @mysql_free_result($result); } else { die("Query failed"); } } //If there are input validations, redirect back to the registration form if($errflag) { $_SESSION['ERRMSG_ARR'] = $errmsg_arr; session_write_close(); header("location: forgot.php"); exit(); } //Get username linked to email so it can be emailed along with password $qry = "SELECT username FROM members WHERE email='$email'"; $username = mysql_query($qry); function randomPassword ($length = { // start with a blank password $randpw = ""; // define possible characters $charlist = "0123456789bcdfghjkmnpqrstvwxyz"; // set up a counter $i = 0; // add random characters to $randpw until $length is reached while ($i < $length) { // pick a random character from the possible ones $char = substr($charlist, mt_rand(0, strlen($charlist)-1), 1); // we don't want this character if it's already in the password if (!strstr($randpw, $char)) { $randpw .= $char; $i++; } } // email the random password to the email address the user entered mail($email,"Account Login Details","Your username is $username and your new password is $randpw","From: noreply@jammontreal.com"); // use md5 to encrypt the random password and store it in database $encpw = md5($randpw); $qry = "UPDATE members SET password ='$encpw' WHERE email ='$email'"; $result = @mysql_query($qry); //Check whether the query was successful or not if($result) { header("location: sentpw.php"); exit(); } else { echo "Error. Please Contact Webmaster"; } } ?> Can anyone see where I went wrong? (Probably in a few places, I'm not an expert with PHP) Quote Link to comment https://forums.phpfreaks.com/topic/132992-solved-problem-with-forgot-password-script/ Share on other sites More sharing options...
gaza165 Posted November 16, 2008 Share Posted November 16, 2008 try turning on error_reporting and see if u get any errors or anything?? at the top of your page add error_reporting(E_ALL); Quote Link to comment https://forums.phpfreaks.com/topic/132992-solved-problem-with-forgot-password-script/#findComment-691678 Share on other sites More sharing options...
Maq Posted November 17, 2008 Share Posted November 17, 2008 When I run the script, nothing seems to happen yet I don't get any error messages. I can't seem to isolate the problem. What do you mean nothing happens? In this piece of code you have to do either two things, redirect to sentpw.php or echo, "Error. Please Contact Webmaster". if($result) { header("location: sentpw.php"); exit(); } else { echo "Error. Please Contact Webmaster"; } Please turn on errors like gaza said: ini_set ("display_errors", "1"); error_reporting(E_ALL); I don't really see a problem with your code. You should echo out your variables and queries to ensure that they have the correct values. It may be something to do with the mail configuration. Try emailing something to yourself. Quote Link to comment https://forums.phpfreaks.com/topic/132992-solved-problem-with-forgot-password-script/#findComment-691749 Share on other sites More sharing options...
iblackedout Posted November 17, 2008 Author Share Posted November 17, 2008 I added the error reporting to the top of the page yet it still yields the same result: a blank page with no error messages. I'm very confused... Quote Link to comment https://forums.phpfreaks.com/topic/132992-solved-problem-with-forgot-password-script/#findComment-691805 Share on other sites More sharing options...
PFMaBiSmAd Posted November 17, 2008 Share Posted November 17, 2008 Blank pages are either caused by parse errors, fatal runtime errors, or code that does not output anything. For a parse error, putting the two lines in your code to set error_reporting to E_ALL and to set display_errors to ON won't help because the code is never executed. When learning php, developing php code, or debugging php code, these two settings should be turned on in php.ini Quote Link to comment https://forums.phpfreaks.com/topic/132992-solved-problem-with-forgot-password-script/#findComment-691808 Share on other sites More sharing options...
sKunKbad Posted November 17, 2008 Share Posted November 17, 2008 Before you go too far with this script, you might want to think about security issues regarding emailing users their passwords. In my opinion, you would be better off emailing the user a special link with a query string that is unique to them. This query string could contain the users current encrypted password concatenated with their user ID, and perhaps a salt. When the user follows the link in their email, you would simply evaluate the query string, and allow the user to create their own password. This is more secure for a number of reasons, and the user doesn't have to change their password to something they can remember after you create a new password for them that is hard to remember. Quote Link to comment https://forums.phpfreaks.com/topic/132992-solved-problem-with-forgot-password-script/#findComment-691812 Share on other sites More sharing options...
iblackedout Posted November 17, 2008 Author Share Posted November 17, 2008 Before you go too far with this script, you might want to think about security issues regarding emailing users their passwords. In my opinion, you would be better off emailing the user a special link with a query string that is unique to them. This query string could contain the users current encrypted password concatenated with their user ID, and perhaps a salt. When the user follows the link in their email, you would simply evaluate the query string, and allow the user to create their own password. This is more secure for a number of reasons, and the user doesn't have to change their password to something they can remember after you create a new password for them that is hard to remember. I had considered this option but decided to go with the random password scenario because I didn't know where to start with the query string method. You're absolutely right that I shouldn't compromise my members' security because I am too lazy to implement the hyperlink/query string method. So, can anybody link to some documentation to help me get started? Quote Link to comment https://forums.phpfreaks.com/topic/132992-solved-problem-with-forgot-password-script/#findComment-692255 Share on other sites More sharing options...
closed_tag Posted November 18, 2008 Share Posted November 18, 2008 I don't know if this helps, I echo all of my variables most specifically the query. then I paste it on the SQL. maybe your queries doesn't display anything. Quote Link to comment https://forums.phpfreaks.com/topic/132992-solved-problem-with-forgot-password-script/#findComment-692450 Share on other sites More sharing options...
iblackedout Posted November 18, 2008 Author Share Posted November 18, 2008 Ok I echo'd everything and got some errors: SELECT * FROM members WHERE email='example@domain.com'SELECT username FROM members WHERE email='example@domain.com' Notice: Undefined variable: encpw in /home/noel695/domains/noeljourneaux.com/public_html/login/doreset.php on line 125 UPDATE members SET password ='' WHERE email ='example@domain.com' Notice: Undefined variable: randpw in /home/noel695/domains/noeljourneaux.com/public_html/login/doreset.php on line 126 Resource id #5 Basically, it's saying $randpw isn't defined and since $encpw depends entirely of $randpw, it also isn't defined. Looking back at the code I pasted originally, can someone show me where I failed to define $randpw? Quote Link to comment https://forums.phpfreaks.com/topic/132992-solved-problem-with-forgot-password-script/#findComment-692522 Share on other sites More sharing options...
iblackedout Posted November 18, 2008 Author Share Posted November 18, 2008 It seems I had forgotten to define my variable outside of the randomPassword() function. The following was placed before the mail function: $randpw = randomPassword(); I also had to completely overhaul the randomPassword() function because it didn't seem to be working. I used one I found online instead. Quote Link to comment https://forums.phpfreaks.com/topic/132992-solved-problem-with-forgot-password-script/#findComment-693009 Share on other sites More sharing options...
sKunKbad Posted November 19, 2008 Share Posted November 19, 2008 So, can anybody link to some documentation to help me get started? I'm working on a script that is sort of specialized to my own login system, but I'll copy and paste the code here, and you can check it out as an example. <?php /* This script allows a user to recover their username, and reset their password if desired. A password reset link is sent to the user via email, and if followed, they have an opportunity to reset their password. The script is pretty complex, and could probably use some refining, but it does work well. CODE BY R.B.Gottier - www.brianswebdesign.com */ require_once("../app_top.inc.php"); if(!isset($get_p) && !isset($post_change_p)){ // If the user has just come to this page, OR the email address has been submitted for username or password recovery $fail = 0; if (isset($post_submit)){ // If the email address has been submitted if ($post_email == FALSE || $post_email == NULL){ $fail = 1; } if($fail != 1){ // If validation of the email variable was OK, check the database for the email address to see if there is a match, and return a user_id, hashed password, and firstname if available $clean_email = clean_for_query($post_email); $a = mysqli_query($db , "SELECT u.user_id,u.password,ua.firstname FROM users AS u,user_accounts AS ua WHERE u.user_id = ua.user_id AND ua.email = '$clean_email' LIMIT 1"); $numrows = mysqli_num_rows($a); if ($numrows == 0){ // If not match $fail = 1; }else{ // If there was a match then send an email to the user $row = mysqli_fetch_assoc($a); $password_half = str_split($row['password'] , 16); $reassembled_password = $password_half[1] . $password_half[0]; $reassembled_password .= "{$row['user_id']}"; $random_hash = md5(date('r', time())); $to = $clean_email; $subject = 'Your ' . SITE_NAME . ' account'; $headers = "From: " . SITE_NAME . " <" . ADMIN_EMAIL . ">\r\nReply-To: " . ADMIN_EMAIL . "\r\nReturn-Path: " . ADMIN_EMAIL; $headers .= "\r\nContent-Type: multipart/alternative; boundary=\"PHP-alt-".$random_hash."\""; $plain_text_content = "Hi {$row['firstname']},\n\n\nCopy and paste the following link into your browser if you can't click on it:\n\n" . this_page() . "?p=$reassembled_password\n\nYou can then reset your password, and gain access to your " . SITE_NAME . " account.\n\nThank you,\n\n" . SITE_NAME; $html_content = "Hi {$row['firstname']},<br />Follow the link provided below:<br><a href='" . this_page() . "?p=$reassembled_password'>RESET</a>.<br>You can then reset your password, and gain access to your " . SITE_NAME . " account.<br>Thank you,<br>" . SITE_NAME; //THIS MUST STAY PARKED OVER ON THE LEFT SIDE OF THE CODE *** DO NOT INDENT THIS TO KEEP THE CODE PRETTY OR IT WILL NOT WORK! $message = " --PHP-alt-$random_hash Content-Type: text/plain; charset=\"iso-8859-1\" Content-Transfer-Encoding: 7bit $plain_text_content --PHP-alt-$random_hash Content-Type: text/html; charset=\"iso-8859-1\" Content-Transfer-Encoding: 7bit $html_content --PHP-alt-$random_hash-- "; // END MESSAGE BODY AREA // The following line of code is only for development purposes: echo $to . "<br>" . $subject . "<br>" . $message . "<br>" . $headers . "<br>"; // Uncomment the following line in the production environment: //mail( $to, $subject, $message, $headers ); echo "<h2>Email Sent</h2><p>We have emailed you at $clean_email! This email will provide instructions on how to log in to your account.</p><p>If you don't receive this email shortly, check your spam/bulk email folder, or repeat this process.</p>"; mysqli_free_result($a); } } } if (!isset($post_submit) || $fail == 1){ //If the email address has not been submitted, or if the email address was not in the database if ($fail == 1){ // If the email address was not in the database echo '<h2 class="errorH2">Bad Email Address</h2> <div class="errorDiv"> <p style="padding-bottom:0px;">Your email address was not in our system. Please review the address you tried, try again, or call us directly.</p> </div>'; } // Display the form for either a user coming to the page for the first time, or if they didn't provide an email address that was in the database, prefill the email form field (prefill only works if the email address passed filtering) echo "<form action='" . this_page() . "' method='POST'> <h2>Forgot your login?</h2> <p>If your email address is in our database, we will send you information on how to reset your login.</p> <label for='email'>What is your email address?<label> <input id='email' name='email' type='text' maxlength='50'"; echo (isset($post_email) && $post_email != '') ? " value='" . htmlentities($post_email) . "'>" : ">"; echo " <input type='submit' name='submit' value='submit' /> </form>"; } }else{ // The user has followed the link in their email OR has submitted a new password if(isset($post_new_p) && $post_new_p != NULL && isset($post_change_p) && $post_change_p != '' && $post_new_p == $post_new_p_conf){ // If the user has submitted a new password and the password and password confirmation fields match if( strlen( $post_new_p ) > MAX_PASSWORD_LENGTH || strlen( $post_new_p ) < MIN_PASSWORD_LENGTH ){ // If the newly submitted password is more than 12 characters, or less than 7, send the user back to the form to change it echo "<h2 class='errorH2'>Password is too long or too short.</h2> <div class='errorDiv'> <p style='padding-bottom:0px;'>Your password must be between " . MIN_PASSWORD_LENGTH . " and " . MAX_PASSWORD_LENGTH . " characters in length.</p> <form action='" . this_page() . "' method='POST'> <label for='new_p'>Choose a new password (" . MIN_PASSWORD_LENGTH . " min / " . MAX_PASSWORD_LENGTH . " max)<label> <input id='new_p' name='new_p' type='text' /> <label for='new_p_conf'>Confirm new password<label> <input id='new_p_conf' name='new_p_conf' type='text' /> <input name='username' value='" . htmlentities($post_username) . "' type='hidden' /> <input name='old_p' value='$get_p' type='hidden' /> <input type='submit' name='change_p' value='submit' /> </form> </div>"; }else{ // The password is between MIN_PASSWORD_LENGTH and MAX_PASSWORD_LENGTH characters, and will be processed and updated in the database $password_half = str_split($post_old_p , 16); $reassembled_password = $password_half[1] . $password_half[0]; $clean_old_p = clean_for_query($reassembled_password); $enc_password = clean_for_query(md5(PASSWORD_SALT . $post_new_p)); if( strlen( $post_username ) > MAX_USERNAME_LENGTH ){ // At this point, a posted username that has more characters than MAX_USERNAME_LENGTH is an attack, since the value of $post_username comes from a hidden form field. die(); }else{ $clean_username = clean_for_query($post_username); } mysqli_query($db , "UPDATE `users` SET password='$enc_password' WHERE username='$clean_username' AND password='$clean_old_p'"); echo "<h2>Password Reset Confirmation</h2> <p>Once again, your username is <b>" . htmlentities($post_username) . "</b>. <br />Your new password is <b>" . htmlentities($post_new_p). "</b>. <br />Please write them down and proceed to login.</p> <p><a href='$thisDomain'>Continue</a></p>"; } }else{ // The user has either followed the link in the email, or the password and password confirmation fields DID NOT match if ( (isset($post_new_p) && isset($post_new_p_conf) && $post_new_p != $post_new_p_conf ) || (isset($post_new_p) && $post_new_p == '') || (isset($post_new_p_conf) && $post_new_p_conf == '') ) { // If the password and password confirmation fields didn't match, or if they were blank, an error message is shown echo "<p style='background-color:yellow;'>Password and confirmed password were not the same, or one or both were blank.</p>"; }else{ // If the user has followed the link in their email echo "<p style='background-color:white;'> </p>"; } $clean_get_p = clean_for_query($get_p); $password_half = str_split($clean_get_p , 16); $reassembled_password = $password_half[1] . $password_half[0]; $users_number = clean_for_query($password_half[2]); $z = mysqli_query($db , "SELECT u.user_id,u.username,ua.firstname FROM users AS u,user_accounts AS ua WHERE u.user_id = '$users_number' AND ua.user_id = '$users_number' AND password = '$reassembled_password' LIMIT 1"); $zrows = mysqli_num_rows($z); // Checks to see if anything is in the db. if ($zrows != 1){ // If the user could not be determined die(); }else{ // The user was determined by the get variable in the email link $row = mysqli_fetch_assoc($z); // The form is displayed so the user can reset their password echo "<p>Hi {$row['firstname']},<br><br>Your username is <b>{$row['username']}</b>. You will need this, so write it down.</p> <form action='" . this_page() . "' method='POST'> <label for='new_p'>Choose a new password (" . MIN_PASSWORD_LENGTH . " min / " . MAX_PASSWORD_LENGTH . " max)<label> <input id='new_p' name='new_p' type='text' maxlength='50' /> <label for='new_p_conf'>Confirm new password<label> <input id='new_p_conf' name='new_p_conf' type='text' maxlength='50' /> <input name='username' value='{$row['username']}' type='hidden' /> <input name='old_p' value='$get_p' type='hidden' /> <input type='submit' name='change_p' value='submit' /> </form>"; mysqli_free_result($z); } } } mysqli_close($db); ?> Quote Link to comment https://forums.phpfreaks.com/topic/132992-solved-problem-with-forgot-password-script/#findComment-693201 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.