Security

Let me start by saying I love CodeIgniter, it’s a developers dream.

Today I plan to talk about some of the security features that are used within my library : Redux Authentication.

Hash Once and Only Once!

Over at TalkPHP someone provided a code snippet which had this code :

$psd = sha1(md5(md5(sha1(md5(sha1(sha1(md5($_POST['password']))))))));

I’ve made a similar mistake myself in the past.  Someone on the CodeIgniter forums pointed out that a solution like the above will actually increase the probability of a collision. Here’s what inparo had to say :

“It’s safer if you only hash it once.  The initial string is random in both length and characters.  The first sha1 gives you a fixed length and reduced character set.  By hashing this again you’re actually increasing the probability of collisions.”

So there you go folks, hash once. This also leads nicely to my next topic “salts”

Salts

A lot of people when hashing passwords will do something like this :

$password = md5($password);

You may think this is secure, but actually it’s very insecure. Websites exist which store hashes of dictionary words, so if your database was ever stolen, the passwords could be looked up and revealed. This is where the power of the password salt comes in.  Salts come in two varieties : A dynamic salt and a static salt. A dynamic salt is automatically generated and is usually very hard to guess. A good example of a dynamic salt would be :

$salt = microtime();

It’s not totally random, but you get the idea.

You would then concatenate the salt along with the password to provide a new hash. This new hash can’t be looked up because of it’s “randomness”. You would then store it with other user info and select it when you need to log them in.

I know what you’re thinking. If the database is stolen they’ve got the password and the dynamic salt “What good is that?!” This is where a static salt comes in.

A static salt is just that, a variable that is random in both length and characters. This is best stored in a configuration file somewhere. You then combine this with the dynamic salt to provide a very secure solution. Reasons being: (a) If the database is stolen, they are missing the static salt; (b) Two passwords the same will result in a different hash. Here’s an example:

$dynamic_salt = microtime();
$static_salt = 'qGPBA8iCM3cUuCbBAQx3E0uOkKTrSeEUiSrAkykEk4sEniyP67Q2BTp8vtDqoqw'; // Grabbed from file.
$password = 'password'; // Password from input form.

$hashed_password = sha1($dynamic_salt.$password.$static_salt); // Super Secure!

Forgotten Password

Ooops, the user has forgotten their password. What are we going to do? Michael Wales made a well informed post about this topic a while ago, but it was recently lost.

The best method is to use a secret question and answer system coupled with email verification.

The logic would be something like this:

User requests new password -> Sends email verification code -> Verification code is looked up in the database -> Show secret question -> Check Answers

I prefer this system because a hacker could of got into your email account and requested a new password, but would then struggle to get your secret question right. Keeping the users account secure.

DB Sessions

This will be a quick talk. At the moment Redux stores a “users_id” in the session cookie and uses this to figure out if the user is logged in or not. A hacker could use the algorithm in CodeIgniter’s session library and craft his own cookie with a fake “user_id”.

Database sessions move this data from the clients cookie to the database providing a scenario where the client can’t edit it. Redux doesn’t currently use this, but it is in the works.

Thanks for listening to me babble on, hope you enjoyed it.