Forums

password invalid after server restart

Hi,

When I restart the server, when I try to login, it says invalid password. But when I create a new user and try to login, everythig seems fine untill I restart the server. Why do I see this ?

I have a secert key as

app.config['SECRET_KEY'] = 'x\x05\xe9A#\xf2D\xa4\x1f\xb9\xf7\xfd\xa9\xa2IOy\xc4\x1ad\xa9\xa6\x1d\x98'

I was trying to use os.urandom(24) but found that we should not be using that since it invalidates the sessions when server restarts...

and using salt and has as follows :

app.config['SECURITY_PASSWORD_HASH'] = 'pbkdf2_sha512'
app.config['SECURITY_PASSWORD_SALT'] = os.urandom(24)

You're quite right that the SECRET_KEY should be constant in your settings file (though you shouldn't post it in a public forum like this -- I recommend you change it now).

But it's certainly strange that sessions aren't persisting across a restart. Which database are you using?

Hi Giles, thanks for the message. of course I will change it :) . its just a dev key for now.

As I keeo restarting server on code changes on my localmachine. I am noticing this behavious. Strangly enough, this was not happening untill recently. So not sure what changed.

I am using sqlite on my localmachine and mysql in PA. Once I deploy to PA, I reload and then start from there. So I dont see this issue on PA as I dont reload that often on PA.

Try making SECURITY_PASSWORD_SALT a constant instead of a random number that will change every time the server restarts.

but is that safe ? or recommended?

No idea, but trying it would either eliminate it as a possibility or point to it as the cause. Also, if it should change, then don't put it in the app config, get a new one every time you create a password and store that.

Just to add a little bit to what Glenn was saying: it might be worth explaining a little bit about how password storage/authentication works, because once you know that it should be clear why changing the salt every time is not going to work (and sorry, I should have picked up on that earlier!). You probably know some of this, but I'm guessing not all (as otherwise you wouldn't be regenerating the salt).

When a user enters a password on a website when they're signing up, you want

  • When they log in, to be able to check the password that they entered for this login attempt against the one they originally entered, and
  • To be reasonably sure that if somehow someone bad was to get hold of your database, they won't be able to work out what your users' passwords were.

So, in a simple implementation (too simple for today's world), you would hash the passwords -- that is, put them through a one-way cryptographic function, where you can easily calculate that hash("apassword") is a number like "2132132343134", but it's incredibly computationally expensive to work out what passwords the number might be generated from.

When the user originally enters their password, you would calculate the hash of the password and store that in the database. And when the user tries to log in again later, you calculate the hash of the password they entered, and check if it matches the one you stored originally, and if they match then you know the password was right.

Nowadays, of course, doing things simply like that is not such a good idea. This is because hackers have prepared rainbow tables, which are basically just huge dictionaries mapping between well-known passwords and their hashes. So if they got hold of your database, they would still be able to work out the passwords from the hashes you have stored.

This is where salting comes in. Instead of hashing the password the user enters, you hash the concatenation of the password and the salt. So, a salt of "ABDE" and a password of "mypassword123" gets converted to "ABDEmypassword123", and it's that that goes through the hashing algorithm and the result is stored in the database when the user registers.

Later on, when someone tries to log in to the site, in order to re-do the hashing, you need to concatenate the same hash with the password that they enter when they log in. So they enter "mypassword123", you prepend "ABDE" once again, "ABDEmypassword123" gets hashed and compared to what's in the database, and you let them log in if it matches.

So, given all that, we can see the problem with changing the salt every time you restart the website:

  • Initially the salt is, let's say, "ABCD". Someone registers with password "mypassword123", and so "ABCDmypassword123" gets hashed and stored in the database.
  • Then, you restart your website. When it starts up, it has a new salt, let's say "DEFG".
  • The user comes along again, and tries to log in. They enter the correct password, "mypassword123", and the new salt is added before it's hashed: "DEFGmypassword123".
  • Because hash("ABCDmypassword123") != hash("DEFGmypassword123"), the website thinks they've entered the wrong password and won't let them in.

The solution? The salt value you use should be randomly-generated, and completely secret, but it should not change once you've deployed your site.

Hope that helps!

One more thing :-) Some frameworks make it possible to use a different salt for every user, which is nice because it makes hackers' life even harder. It's still stable over time, though -- the same user has the same salt even if the website is restarted.

hmm, interesting.. Thank for the detailed explanation. :)

Glad to help!