Authentication Security Explanation

Hi All,

Absolutely loving what I see if Yii 2.0 so far and can’t wait to see it become production ready. In the mean time, I continue to play with the current build to learn more. The simple fact is, if I don’t understand what something is doing, I can’t use it in a product for someone.

With that in mind, I am hoping someone can walk me through (at a fairly detailed level) what is happening to data as someone creates an account or logs in. Here is what I understand so far:

  • New user visits the signup page which is actionSignup of the SiteController

  • This creates a new instance of the User model

  • The User model creates a password_hash via generatePasswordHash

[list]

  • A salt is generated by generateSalt as part of this process but doesn’t seem to be stored anywhere. If this salt is used in the hashing of the password but isn’t stored, how can it be used during the hashing of an entered password for authentication?

[*]The User model creates auth_key via generateRandomKey

  • What is this auth_key used for?

[*]During login, validatePassword in the User model passes the entered password and the users hashed password to validatePassword in BaseSecurity for comparison.

[/list]

I’m sure this all makes sense to someone that understands what is going on but to me, I’m lost. I expected to see that the creation of a new User generate a salt, appended it to the entered password, then store the salt and hashed password/salt combination in the database. For logging in, the user would be found, the salt returned from the database and appended to the entered password for hashing and comparison.

Can someone explain the few items above (the generation of a salt but not storing it and the usage of auth_key)? Also, if the above is not functioning as I expect, how might one go about creating and storing a salt in the database for the purpose I mentioned in the previous paragraph?

Thanks for the hard work that has gone into Yii and the helpfulness of the answer I’m sure I’ll receive.

I think I answered my own (main) question here by learning more about encrypting password with crypt/bcrypt. Rather than store a salt and a salt/password hash as two separate fields, this stores them as one. A salt is generated, it is prepended to the password, the combination is then hashed, and that hash is stored in the database with the salt prepended to it. So, in one column you have the actual salt along with the hashed salt/password. Makes it much easier than creating a separate field.

If anyone wants to add to or clarify the above please do so as I am still learning and would love to know more. Also, my other question about auth_key still stands.

You are correct about bcrypt salt.

auth_key is used for "remember me".

Its value is random and nearly impossible to guess. It is stored in the auth cookie along with identity ID:




$cookie->value = json_encode([

	$identity->getId(),

	$identity->getAuthKey(),

	$duration,

]);



The purpose is to prevent user modifying ID in the cookie and logging in as another user.

Perfect, thanks samdark! One last quick question if anyone wants to take it.

Is there a reason that the password_reset_token is not cleared after the user resets their password? In my eyes, that opens a little security hole. If I request a password reset, the token is set. Until a new token is set the password reset link in the email is still valid. If someone gets their hands on my email a year from now, they can still reset my password with the same link.

I would any change to a users password (or at the very least a password reset) that the token should be set back to NULL.

The issue is solved in a pull request that isn’t merged yet.