Forgot Password Question?

Hi Everyone,

When I sign up for my website and use your typed in password. Everything works.

When a user changes their password from within their control panel, then logout, then log back in again with that same password. Everything works.

When you email a password to yourself (because you forgot it) and try to login with that password. My website does not want to allow the user to login. I’m not sure why. Thanks Everyone!

My php check login code when a user is signing in.

<?php
session_start();
include"connect_to_mysql3.php";
$loggedinuser = $_SESSION["id"];
$name = $_SESSION["name"];

if (isset( $_POST['name'], $_POST['password'] )){

    $name = $_POST['name'];
	$password = $_POST['password'];
	
	$name = mysql_real_escape_string($name);
    $password = mysql_real_escape_string($password);
	
    $password = sha1($password);
	$password = substr($password, 0,15);
	
	$sql_id = mysql_query("SELECT * FROM practice WHERE name='$name' AND password='$password'");
    while($row = mysql_fetch_array($sql_id)){
    $id = $row["id"];
    }
	
	$sql = ("SELECT id FROM practice WHERE name='$name' AND password='$password'");
	
	//$password = sha1($password);
	//$password = substr($password, 0,15);

	$result = mysql_query($sql);
	
	$count=mysql_num_rows($result);
	
	if($count==1){


    $_SESSION["name"] = $name;
    $_SESSION["id"] = $id;

   header("location:heythere.php");

   } else {
   echo "Wrong Username and Password. <a href=\\"http://whatsmyowncarworth.com/class-work/sign3/valchecklogin.php\\">Click Here</a> to login";
  }
}

?> 

Below is my forgot password code

<?php
// connect to database
include"connect_to_mysql3.php";

$email = $_POST['email'];
$submit = $_POST['submit'];

if ($submit){

   // check is email exists
   $email_check = mysql_query("SELECT * FROM practice WHERE email='".$email."'");
   $count = mysql_num_rows($email_check);

   if ($count != 0){
    // generate new password
	$password = rand();
	$password = sha1($password);
	$password = substr($password, 0,15);
	
	// update database with new password
	mysql_query("UPDATE practice SET password='".$password."' WHERE email='".$email."'");
	
	// send the password to the user
	$subject = "Login Information";
	$message = "Your password has been changed to $password ";
	$from = "From: myemail@yahoo.com";
	
	mail($email, $subject, $message, $from);
	echo "Your new password has emailed to you.";
	
   } else {
      echo "The email does not exist";
   }

}

?>

It is because you are sending the encrypted password in the e-mail instead of the unencrypted version (which is what they would enter in your site).

It’s because the $password is not the password itself but a 15 character substring sha1 representation of that password.
The way your code would work to fix the problem at hand would be to use it like this:


// ...
$password = rand(); 
$db_password = sha1($password); 
$db_password = substr($password, 0,15); 

mysql_query("UPDATE practice SET password='".$db_password."' WHERE email='".$email."'"); 
     
$subject = "Login Information"; 
$message = "Your password has been changed to $password "; 

// ...

HOWEVER:

  1. Why are you using only the first 15 characters of the SHA1? That makes no sense at all, and makes the system a lot weaker than it should be.
  2. if ($count != 0) is incorrect, since it allows for multiple users to have the same email. When that happens, which one will the system pick? Should it even be allowed?
  3. In the forgot password code you are not using mysql_real_escape_string, which, combined with step (2) makes it trivial to change the password if all the users in your system to a known value. This is a serious issue, and I urge you to fix it before this hits production!

Hey cpradio and ScallioXTX,

Thanks for your responses. I took your advice and changed a few things around. My syntax is below, tell me what you think.

Why are you using only the first 15 characters of the SHA1? That makes no sense at all, and makes the system a lot weaker than it should be.

Corrected.

if ($count != 0) is incorrect, since it allows for multiple users to have the same email. When that happens, which one will the system pick? Should it even be allowed?

Because I configured my mysql database as having every email as unique. No duplicate emails.

In the forgot password code you are not using mysql_real_escape_string, which, combined with step (2) makes it trivial to change the password if all the users in your system to a known value. This is a serious issue, and I urge you to fix it before this hits production!

Corrected.

<?php
// connect to database
include"connect_to_mysql3.php";

$email = $_POST['email'];
$submit = $_POST['submit'];

if ($submit){

   // check is email exists
   // $email_check = mysql_query("SELECT * FROM practice WHERE email='$email'");
   $email_check = mysql_query("SELECT * FROM practice WHERE email='".$email."'");
   $count = mysql_num_rows($email_check);

   if ($count != 0){
    // generate new password
    $password = rand();
    $db_password = sha1($password);
	
	$db_password = mysql_real_escape_string($db_password);
	
	// update database with new password
	// mysql_query("UPDATE practice SET password='$new_password' WHERE email='$email'");
	mysql_query("UPDATE practice SET password='".$db_password."' WHERE email='".$email."'");
	
	// send the password to the user
	$subject = "Login Information";
	$message = "Your password has been changed to $password ";
	$from = "From: myemail@yahoo.com";
	
	mail($email, $subject, $message, $from);
	echo "Your new password has emailed to you.";
	
   } else {
      echo "The email does not exist";
   }

}

?>

That’s a good step in de right direction, but you still need to [fphp]mysql_real_escape_string[/fphp] on $email before using it in a query.
PM me if you’re interested to know why not doing this is so bad :slight_smile:

Oh, and I assume you’ve removed the substr on the SHA1 from the login page as well?

Hey ScallioXTX,

Thanks again for your help. I’ve added the mysql_real_escape_string to my $email variable (code below). I’ve also gotten rid of the SHA1 on all pages. <- That made things a lot easier to understand. I would also like to point out in my sign up form my code checks to see if the email is already in my database. If it is, then a error is presented to the user. That syntax is below as well. I also sent you a PM. Thanks again!

forgot password code

<?php
// connect to database
include"connect_to_mysql3.php";

$email = $_POST['email'];
$submit = $_POST['submit'];

$email = mysql_real_escape_string($email);

if ($submit){

   // check is email exists
   // $email_check = mysql_query("SELECT * FROM practice WHERE email='$email'");
   $email_check = mysql_query("SELECT * FROM practice WHERE email='".$email."'");
   $count = mysql_num_rows($email_check);

   //

   if ($count != 0){
    // generate new password
    $password = rand();
    $db_password = sha1($password);

	$db_password = mysql_real_escape_string($db_password);

	// update database with new password
	// mysql_query("UPDATE practice SET password='$new_password' WHERE email='$email'");
	mysql_query("UPDATE practice SET password='".$db_password."' WHERE email='".$email."'");
	
	// send the password to the user
	$subject = "Login Information";
	$message = "Your password has been changed to $password ";
	$from = "From: myemail@yahoo.com";
	
	mail($email, $subject, $message, $from);
	echo "Your new password has emailed to you.";
	
   } else {
      echo "The email does not exist";
   }

}

?>

Part of my reg. code when a user signs up to make sure the email/name is not in the database

		  $name_check_ = mysql_query("SELECT id FROM practice WHERE name='$name' LIMIT 1 ");
		  $email_check_ = mysql_query("SELECT id FROM practice WHERE email='$email' LIMIT 1 ");
		
		  $name_check = mysql_num_rows($name_check_);
		  $email_check = mysql_num_rows($email_check_);
		
		  if ($name_check > 0){
		    $error_one = '<u>ERROR:</u><br />Your User Name is already in use inside our system. Please try another.';
		  } else if ($email_check > 0){
		    $error_two = '<u>ERROR:</u><br />Your User E-Mail is already in use inside our system. Please try another.';
		  } else