password storage in database hash
ez |
|
---|---|
Hi, I have donated my improved security project to Trustmaster.
It involves salting the stored passwords. Now the passwords are stored as an md5 hash... which can be bruteforced very easily.
I have made improvements to the user authentication and added features to auto-salt. This means that passwords are salted on the moment people login. I hope he will add it to 0.6.24... ==- I say: Keep it EZ -==
|
Trustmaster |
|
---|---|
Thanks, ez! Here is your patch for the others if they want to test it. May the Source be with you!
|
ez |
|
---|---|
Please remember : Always make backups of code and DB, because this is in testing fase. user_salted tinyint default value 0 And after that there is a var that needs to be added to your config.php (datas) $cfg['psalt'] = ''; The saltvalue can be anything you want e.g. '12AB#'
==- I say: Keep it EZ -==
|
GHengeveld |
|
---|---|
Your code seems acceptable for Genoa. I'm not a big fan of the user_salted column, since you wouldn't want to let a hacker know that the password is salted or not (even though a hacker could find out by reading the open-source code). Why you'd assign the value of this column to a tpl tag doesn't seem like a useful/secure addition either. Anyway, it's more or less what we had in mind. For readability I think some variable names should be changed (e.g. $newspass, 'psalt'). It's consistent with the terrible variable naming practices of Genoa though. I'm assuming your //2basix comments are meant to indicate where your changes are. Don't expect them to be in the final code. Cotonti is a team effort, we don't claim individual 'ownership' of any pieces of code. Modules and plugins are a different story. Added 2 minutes later: #34738 ez: I suggest a salt of at least 20 random characters. |
ez |
|
---|---|
I made this very quick.. and it is a first draft that I made.
About the comments: "Don't expect them to be in the final code". I donated the code (like I wrote earlier).. so I have no problems leaving them out. ==- I say: Keep it EZ -==
|
GHengeveld |
|
---|---|
Sorry about that, it wasn't necessary to make a comment about that. I really do appreciate your efforts. I was thinking perhaps it's an idea to add a prefix to the hashed password instead of an extra column. The downside is that the password field has to be longer than 32 chars. Alternatively, it may be a good idea to switch from md5 to sha1/sha256, which results in a 40-char hash. Then it's possible to check the passhash string length to determine whether the user's password is already migrated to the new scheme (with salt). E.g. user_salted = (strlen(user_password) == 40) |
ez |
|
---|---|
Forget about my old version.... I have read more articles, and I was doing it wrong. The salt should be random on every user, so no fixed salts ! ==- I say: Keep it EZ -==
|
|
This post was edited by ez (2012-06-22 20:31, 12 years ago) |
Trustmaster |
|
---|---|
Sorry for sarcasm, but letting your entire database leak in first place is a lot more unsafe. May the Source be with you!
|
ez |
|
---|---|
you know what, forget about the whole thing... ==- I say: Keep it EZ -==
|
GHengeveld |
|
---|---|
Trust wasn't being serious. Of course the db shouldn't be hacked in the first place, but we've seen in the past that there is always a risk of SQL injection, especially in extensions. I think you're really on the right path to make this thing more secure. I like your idea about changing salts. I haven't looked at your new code yet but I suggest using the user ID and secret key hashed together as salt. Whatever you do, some part of the salt must be stored in a file rather than the db.
|
Trustmaster |
|
---|---|
ez, I apologize and I'm very sorry that you took my note as a personal offense. I appreciate your effort and I agree that these measures are necessary. They will be definitely applied to both Genoa 0.6.24 and Siena 0.9.11. My note was only about the fact that salting passwords is a special measure that mitigates consequences of a database being hacked, it must not be considered as a panacea: a hacked database is not safe still. May the Source be with you!
|
ez |
|
---|---|
Gert, Vladimir, ==- I say: Keep it EZ -==
|
|
This post was edited by ez (2012-06-23 14:47, 12 years ago) |
GHengeveld |
|
---|---|
Thanks for the article link. Now that I've read it, it makes more sense to me. This is exactly the reason why we like to take this thing slowly. It's better to think this thing over before we start implementing something that's insecure by design. The idea behind storing the salt in a disk file is that it's not stored as plaintext in the database, otherwise it's still useless because a hacker with access to the database would still be able to run a lookup table attack by simply adding the salt before precalculating the lookup table hashes. I understand from the article that a fixed salt like this isn't necessary, since the goal of a salt it to prevent an attacker from pre-calculating hashes from a dictionary. By using a different salt for each password, it becomes impossible to pre-calculate the hashes. An attacker can still use a dictionary, but he'd have to calculate all dictionary hashes individually for each password/salt combination, which would take considerably longer (the lookup table would be multiplied in size by the total number of users). A big advantage of storing the salt in the database instead of in config.php is the reduced risk of losing the salt (and losing all passwords in the process). It's not uncommon to accidently overwrite config.php and lose the configuration variables stored within. Perhaps we can make the 'fixed salt' optional for extremely security-minded administrators. PS. As an experiment I've ran a lookup table attack with only ~100k dictionary words on a major Cotonti website and succesfully found the plaintext passwords of almost 15% of users. |
ez |
|
---|---|
I did what the article recommended :D, and I checked other articles too. ==- I say: Keep it EZ -==
|
GHengeveld |
|
---|---|
The mainurl isn't secret or random, so I don't think it's a useful addition. The current idea is to use hash('sha256', $cfg['salt'].$user_salt.$user_password) with $cfg['salt'] being optional and $user_salt being randomly generated by cot_unique() when the password is changed. |