I think you both (Jeff and Jon) misunderstood what I meant...  Of course, I
probably didn't explain very well either :-)

I will describe the process again and then address each of your concerns...

- Create a form named lostpass.php or something similar.  This form should
take the user's email address as input.  You could additionally decide (for
added security) to require both the username AND email address in order to
work, however an email address is typically enough...

- Once the form has been submitted, you look up the record that corresponds
to the email the user input.  If user doesn't exist, you give back an error
to the script and handle it there.  If the user DOES exist, you then take
some "useful but meaningless" information and make it into an MD5 hash.  For
instance, a real simple way would be to take a timestamp and run the md5
function on it.  You then insert this hash into the user's database record
under a column named "pass_verify" or something like that.

- Your script then sends a mail() to the email address of the user's account
(the same one they entered) that has a URL like:


You could also just give them the "verification code" and tell them to go to
newpass.php and have a form there that requests the code.  You might also
send some sort of username variable with the email.  It's not required, but
it would probably make it more secure...

- The newpass.php script queries the database for a pass_verify value equal
to the value you sent in the email (and in return, they sent to your
script).  Once it's found, you know the owner of the account is currently
accessing your web page.  This is where sending a username value would make
it more secure.  You would then select based on username and THEN compare
the hash...  Otherwise, you potentially (although EXTREMELY unlikely) could
return more than one record.

- You can now allow them to set an entirely new password and then remove the
pass_verify value from their db record.

Hopefully that makes a little more sense...  Now to address your concerns:

Q: How do I make sure it's them who's creating a new password so that
someone else doesn't maliciously change their password?

A: Because they have to verify that it's them with a 32byte MD5 hash that is
randomly generated and emailed to the account owner.  If other people have
access to the owners email account this will obviously not work, but neither
would any other email verification method.  Likewise, if the email is
intercepted it's useless, although this isn't likely either.  You know it's
them, because you created a completely random string of text and sent it to
ONLY them...  It's next to impossible to guess a MD5 hash...  There is one
security hole however, but is fixed by doing one of two things (or both if
you want the most secure):

1) Be SURE to delete the verify_pass value from the database when they've
successfully changed their password.  Otherwise, you'd leave their account
open to potentially hacking.  Of course, it's the same level of protection
their password is stored as, but leaving two values for potential
authentication is twice as dangerous as one...

2) Insert a verify_date column as well and only allow a certain amount of
time until the person must request a new hash...  When they attempt to
verify, you'd just compare the current date with the date they requested the
password change...  Typically someone will check their email immediately,
not wait a week....  This just prevents people from using an old hash that
the user never verified with...

Q: If someone knew someone's username and e-mail address I would think they
could change it.

A: This would be true if the emailing step was removed.  However, since you
typically assume the user's email account is a secure place to communicate,
you can safely email the verification to them and assume if the same
verification is returned, it MUST be the user...  If all you do is ask for a
username and email and then allow them to change the password without the
email verification... yeah, anyone who knew that information would be able
to gain access to someone's account...

Q/Comment:  Don't let them change it to whatever they want - have your
program/system create a new, random password and e-mail it to the user's

A/Comment:  I believe one of his original desires was to allow the user to
choose their own password.  Which is possible, while remaining secure, under
the method described above, while meeting the same level of expectations as
the system you suggest.  I'm not saying either is 'better', however I think
the above example better suit's Jeff's needs.

Hopefully this clarifies the idea a little more.  I am taking my lunch now
and then must get back to writing, however I will try and address any
additional concerns...

NOTE:  I've only structured this in my head, I haven't physically done it
yet (although I might now just to do it ;-)).  I have seen this done
however, many sites use it I believe...  I'm providing this information
as-is, with no warranty of its' security level or anything of the sort...
Just don't wanna get crap if it isn't executed correctly :-)  Cheers!

John Pickett

PHP Database Mailing List (http://www.php.net/)
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
To contact the list administrators, e-mail: [EMAIL PROTECTED]

Reply via email to