Click to See Complete Forum and Search --> : Forgot password script


bo0
04-10-2005, 11:03 AM
I have created the following forgot password script, it works, but I really think it needs making more secure and generally stronger. Any ideas?

<?

// TouringNet - Forgot password

if (isset($_POST['request'])) {

@extract($_POST);

$query="SELECT * FROM users WHERE email='$Email' LIMIT 1";
$result=mysql_query($query);
$num=mysql_num_rows($result);

$pass = generate_password();
$md5pw = md5($pass);

if(mysql_num_rows($result) == 0)
{
echo "<strong>There is no user registered with that email address, please go back and try again!</strong></span>";
} else {

$id=mysql_result($result,"id");

$query = "UPDATE users SET password='$md5pw' WHERE id='$id' LIMIT 1";
mysql_query($query) or die("Could not insert data because ".mysql_error());

$subject=("TouringNet Password");
$text=("Your new TouringNet password is $pass\n To login please goto http://touringnet.co.uk/chris\n\n\n If you did not request a password change please ignore this email.");
$name=("TouringNet");
mail($Email,$subject,$text,"From: $name <$Email>");

echo("<body onLoad=\"MM_popupMsg('Your new password has been sent to the email you signed upto TouringNet with. Press Ok to return to our homepage.')\">");
echo("<meta http-equiv=\"refresh\" content=\"0;URL=./?q=news\">");

}

} else {

echo("<table width=\"700\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" >");
echo(" <tr>");
echo(" <td height=\"19\" colspan=\"2\" valign=\"top\" class=\"unnamed1\"><span class=\"style3\">Forgot password form</span></td>");
echo(" </tr>");
echo(" <tr>");
echo(" <td width=\"6\" height=\"4\"></td>");
echo(" <td width=\"518\"></td>");
echo(" </tr>");
echo(" <tr>");
echo(" <td height=\"57\"></td>");
echo(" <td valign=\"top\"><span class=\"style7\">");
echo("To have your password emailed to your registered TouringNet email address please use the following form:<br>");
echo("<br>");
echo("<form name=\"forgotpass\" method=\"post\" action=\"\">");
echo(" <p>");
echo(" E-Mail address: ");
echo(" <input name=\"Email\" class=\"forms\" type=\"text\" id=\"Email\">");
echo(" <input type=\"submit\" class=\"forms\" name=\"request\" value=\"Submit\">");
echo(" </p>");
echo(" </form></span></td>");
echo(" </tr>");
echo(" </table>");

}

?>

TheDefender
04-10-2005, 11:11 AM
Set a flag to inactivate their account (You'll need to make adjustments to the login script itself), and then create a temporary encrypted password, and send that as part of a link to the user. When they click the link, it sends them to a page where they enter their email address and submit it. When they do that, it verifies that email address along with that variable (encrypted password) you sent in the link, and prompts the user to set their own password. Once they do that, then you can activate their account by resetting that flag you set from the start.

This accomplishes several things.
1) Verifies the right user's email got the email.
2) Ensures the user sets their own password to hopefully have a better chance to remember it.
3) Ensures you have no liability to their password or account by forcing them to set their own password. (That way, if something happens in their account, they can't claim that it's your fault, assuming you take the necessary precautions against compromising their password)
4) Ensures their account is inactive and can't be loged into until their account was properly verified, and the password was set.

bo0
04-10-2005, 11:13 AM
Originally posted by TheDefender
Create a temporary encrypted password, and send that as part of a link to the user. When they click the link, it sends them to a page where they enter their email address and submit it. When they do that, it verifies that email address along with that variable (encrypted password) you sent in the link, and prompts the user to set their own password.

This accomplishes several things.
1) Verifies the right user's email got the email.
2) Ensures the user sets their own password to hopefully have a better chance to remember it.
3) Ensures you have no liability to their password or account by forcing them to set their own password. (That way, if something happens in their account, they can't claim that it's your fault, assuming you take the necessary precautions against compromising their password)

Sounds like a very good idea, but how would I go about doing it?

TheDefender
04-10-2005, 11:16 AM
I will be heading to church shortly, and then I have baseball practice with my boy, so I won't be around for a bit, but I will work something up later today if I can find some time...

Also, I write a lot of databases for clinical research trials and studies, so I have to be very aware of HIPAA compliance, and one of the basics with that (and with general account security) is to never send a password exposed via email (even if temporary)... Just keep that in mind too.

bo0
04-10-2005, 11:19 AM
Originally posted by TheDefender
I will be heading to church shortly, and then I have baseball practice with my boy, so I won't be around for a bit, but I will work something up later today if I can find some time...

Also, I write a lot of databases for clinical research trials and studies, so I have to be very aware of HIPAA compliance, and one of the basics with that (and with general account security) is to never send a password exposed via email (even if temporary)... Just keep that in mind too.

Ok sounds good mate, if you have MSN please do add me@bo0.co.uk

I've just got back from church :)
Thanks again.

gfoot
04-11-2005, 12:05 AM
Hmm, fair enough regarding legal concerns about emailing passwords to people, but remember, there's no greater security in sending an unlocking link by email than there is in sending a temporary password. The consequences are equally severe if either were to get intercepted.

Generally I'd be inclined not to disable the account while you wait for the user to set a new password - it's open to abuse by third parties requesting new passwords for other people, effectively locking them out of the service until they do set a new one. I'd keep any temporary passwords or unlocking keys in parallel to the normal password system, and clear them if the user successfully logs in with the existing password.

TheDefender
04-11-2005, 01:07 AM
bo0, sorry, the time got away from me today... I will put something together as soon as I can.

gfoot, I get what you are saying, but that's the point of verifying the email address and the temporary password that was sent. You can even go so far as to incorporate in a secret question/answer thing. If the password is sent in the URL encrypted, then unless the user has some sort of decryption scheme, then they wouldn't know the password anyhow.

bo0
04-11-2005, 12:37 PM
Originally posted by TheDefender
bo0, sorry, the time got away from me today... I will put something together as soon as I can.

gfoot, I get what you are saying, but that's the point of verifying the email address and the temporary password that was sent. You can even go so far as to incorporate in a secret question/answer thing. If the password is sent in the URL encrypted, then unless the user has some sort of decryption scheme, then they wouldn't know the password anyhow.

Ok, when ever you can mate :)
Thanks.

Shrike
04-11-2005, 02:14 PM
@extract($_POST);

Alarm bells are ringing...

mrhappiness
04-12-2005, 03:23 AM
in addition to the things already mentioned:
I don't see any mysql_real_escape_string :confused:

Weedpacket
04-12-2005, 09:04 AM
SELECT *?

mysql_num_rows() is being used twice; probably just forgot to replace the second call with $num when the other one was written.

Might as well put the creation of $pass and $md5pw inside the second branch of the if() statement; otherwise a password is generated and md5's even if it's never going to be used.