Secure Password Reset PHP & MySQL
Posted 16 January 2014 - 05:15 AM
Can someone perhaps direct me to, or help me with a secure password reset script for PHP & MySQL.
I have a really nice login script tha I found here:
I now need something that I can use for users to reset their password in the event that they forget their passwords.
Posted 16 January 2014 - 01:46 PM
There is no magic "reset password script" you can just download from the intertubes and drop into your site.
Posted 16 January 2014 - 03:55 PM
Passwords are stored using sha512, so I would not be able to resend the password, instead the user would have to change their password. But to keep this secure I would imagine the best practice would to sent them an e-mail with a change password link. When opening the link the will need to be asked for their username, and then the new password, with a new password confirmation.
When they complete the form, I would assume that it would work the same as my registration form, except, I would be updating the table with the new password, instead of inserting a new row.
I tried using the script linked in my second post in this thread, but I could not get it to work. Also it seems to be using md5 as apposed to sha512.
Posted 16 January 2014 - 04:13 PM
At a minimum:
1. Generate a reset code and store that somewhere
2. Send the user an email with the code
3. Email has a link to an SSLed page where they (manually) enter their email address and the code
4. If correct, let them change their password
There are plenty of things out there that have one or more of those pieces: a reset code is basically just a password salt (except typeable), emails are covered to death, and changing the password is an UPDATE query.
Posted 17 January 2014 - 01:09 AM Best Answer
Thanks, let me get to work with this and I will let you know what i come up with and if I may need any additional help.
Posted 24 March 2014 - 07:54 PM
Just wondering if you got this to work for you and, if so, would you share the script?
Posted 07 April 2014 - 06:15 AM
Got it all working, I just have to clean out the confidential items then I will share the script here.
Posted 08 April 2014 - 02:23 PM
I hope you haven't used the scripts from your first two posts? Both are awful and not secure at all. Unfortunately, too many people run around writing “security tutorials” right after their very first “Hello world”.
Writing a full review is too much, so I'll focus on the worst failures:
SHA-512? Seriously? It's the 21st century. An average gamer PC easily calculates hundreds of millions of SHA-512 hashes per second. If you spend a few dollars on a cloud service, you can have many billions of hashes per second. It's easy to see that even strong passwords aren't gonna survive such an attack, no matter how often they've been salted.
The only effective way of protecting passwords against brute-force attacks is to hash them with a specialized algorithm like bcrypt. PHP 5.5 supports it natively. Otherwise, there's a compatibility library with the same functions.
In the script, there's a function which is supposed to stop people from doing more than 5 login attempts. Unfortunately, this is completely ineffective due to a naive implementation: They first check the current value, then they do all kids of stuff, and finally they increment the counter. Well, what if make 100 attempts before the counter is incremented? Then they will all be accepted, because the script still sees the old counter value.
The same mistake is made in the registration script. They check if the name is already registered, and if it's not, they accept it. That means if two people request the same name at the same time, they may both be allowed to use it.
Then they hash the password together with the user agent and store the result in the session to somehow check the login status. WTF? The password doesn't go anywhere except into the user table. You certainly don't store it in dozens of unencrypted session files loitering on the server!
There are plenty of other brainfarts. For example, they run the user ID and the username through some homegrown filter before storing them in the session, because they “might print this value”. What? Have they never heard of escaping?
Mistakes like this show a deep misunderstanding of programming and security fundamentals. That code is really the last thing you want to run on your server.
You should generally be much more careful with your sources. Don't just copypaste code from some crappy amateur site. Make sure the people you're learning from actually know their stuff. You'll find them in big projects on Github, not so much on “wikiHow”.
Posted 08 April 2014 - 06:06 PM
All my linux machines use by default SHA-512 and one of them I set manualy to blowfish encryption method. Just out of curiosity (I'm not expert) what's wrong in this algorithm Jacques? More than an year ago all redhat/centos/debian distros used to use MD5
Posted 09 April 2014 - 02:22 AM
Neither MD5 nor SHA-512 were ever intended to be password hash algorithms. They're primarily designed for digital signatures, which means they're very fast and take up very little resources so that they can be implemented on weak hardware like smartcards.
Speed and low hardware requirements are pretty much the last thing you want when you're trying to protect passwords. Thanks to those properties, a stock PC can calculate billions(!) of MD5 hashes per second and millions of SHA-512 hashes. See this chart for concrete figures:
It's easy to see what that means: Let's say a typical password has 8 characters from the alphabet a-zA-Z0-9. That's 64^8 = 281,474,976,710,656 possible passwords. According to the chart above, an HD 7970 calculates 8,089,000,000 MD5 hashes per second and 74,000,000 SHA-512 hashes. So trying out every single password in this range takes ~10 hours for MD5 and ~44 days for SHA-512.
And that's just a naive brute-force attack with an average gamer PC. Actual attackers use sophisticated patterns and cloud computing services to gain much higher performance. Instead of hours and days, we're now talking about seconds and minutes. I hear people babbling about “rainbow tables” all the time. Who needs a rainbow table if they can simply calculate all hashes ad hoc?
Long story short: SHA-512 and MD5 are dead (for password hashing). It doesn't matter which one you use. It doesn't matter if you salt those hashes. None of this makes a difference, because an attacker can simply grab some more dollars and make up for it. The only workaround would be to use extremely strong passwords (something like 16 bytes read from /dev/urandom). But that's obviously not a solution for the general public.
If you want to protect passwords, you must use a specialized algorithm with three features:
- It must be computationally expensive
- The cost factor must be adjustable so that it can be increased as hardware becomes better
- It must generate a random salt per hash so that an attacker has to break each hash individually
Anything other than bcrypt or a similar algorithm is unacceptable.
Edited by Jacques1, 09 April 2014 - 02:24 AM.
- jazzman1 likes this
0 user(s) are reading this topic
0 members, 0 guests, 0 anonymous users