User authentication is something crucial for every system requiring to have user accounts.
Even (especially) for small websites and businesses, it is critical to always make sure to follow good practices for maximum security.
We’re not talking about some hardcore stuff, though, as the OWASP cheatsheet demonstrates.
Bad idea: plain-text storing and unfit mechanisms
Every technique below is a bad idea, resulting in very poor security.
- Storing passwords in plain text, is it really necessary to explain?
- Ciphering passwords, as a password should never be deciphered.
- Using hash mechanisms, as a plain hash algorithm is not made to protect passwords, only to generate a trace of a data (you can throw away md5/sha1).
- Changing the encoding of the password, like base 64. You’re not protecting anything, it’s basically plaintext here.
- Stacking hash algorithms together, you’ll only augment the collision risk and it’s still not made for this purpose.
As a developer, you musn’t re-develop security mechanisms like password protection. Home-made security gives you no guarantee that your system is to be trusted, unlike provided and well-audited mechanisms, which are “almost” guaranteed safe.
If you had the technical knowledge to do so in a proper and secure way, you would be working in security anyways!
Good idea: Using the provided mechanisms, or using dedicated libraries
As a golden rule, a secure password should never be seen by anyone.
So, how do you actually do that?
Well, you won’t store the password, but a derived value, commonly called a hash (note, as this can be confusing, that the value contains more than the plain hash, a lot more is done behind the scenes).
In PHP, the
password_hash function does the job for you.
You’ll store the value generated by the following code in database.
<?php // Example $hashed_value_to_store = password_hash($password, PASSWORD_DEFAULT);
But how do you actually verify that the password the user is providing during login is the one he entered during registering?
Before you answer, no, you won’t make another
password_hash and compare both results.
For that, every library provides a function, and PHP provides the nifty password_verify function.
You can simply use it like the following example.
<?php // Example, password comes from the login form, and hashed_value comes from the saved entry in database $will_be_true_if_matches = password_verify($password, $hashed_value);