pallets-eco / flask-security-3.0

Quick and simple security for Flask applications
MIT License
1.63k stars 513 forks source link

Support the creation of a unique salt for each user #135

Closed shea256 closed 11 years ago

shea256 commented 11 years ago

From http://crackstation.net/hashing-security.htm:

The most common salt implementation errors are reusing the same salt in multiple hashes, or using a salt that is too short.

Salt Reuse

A common mistake is to use the same salt in each hash. Either the salt is hard-coded into the program, or is generated randomly once. This is ineffective because if two users have the same password, they'll still have the same hash. An attacker can still use a reverse lookup table attack to run a dictionary attack on every hash at the same time. They just have to apply the salt to each password guess before they hash it. If the salt is hard-coded into a popular product, lookup tables and rainbow tables can be built for that salt, to make it easier to crack hashes generated by the product.

A new random salt must be generated each time a user creates an account or changes their password."

Upon user signup, a new salt should be created and stored in the newly created User object.

If the application uses bcrypt, the best way to generate a salt would be as follows:

import bcrypt
salt = bcrypt.gensalt()
mattupstate commented 11 years ago

The passlib library takes care of this for us. It generates a random salt when hashing the password with your specified hashing algorithm. Given the encrypted password, Flask-Security also creates an HMAC+SHA1 hash salted with the the SECURITY_PASSWORD_SALT configuration option.

shea256 commented 11 years ago

Ok thanks Matt. I currently use SECURITY_PASSWORD_SALT.

Let me see if I understand this correctly...

  1. user enters a password
  2. passlib generates a salt, hashes the salt + password, and returns both the password and the salt
  3. the salt is appended to the beginning of the hashed password and goes into the user's "password" field

However, I'm confused as to where SECURITY_PASSWORD_SALT comes into play. Is it before step 3? Is it an application-wide salt on top of the user-specific salt?

Thanks for all your help and patience.

mattupstate commented 11 years ago

Ah, I just realized that I totally explained it all incorrectly. I explained it in reverse. The password is hashed with HMAC and the SECURITY_PASSWORD_SALT and then salted+encrypted by the passlib library. If you're curious about the implementation, you can find it here.

patrickyan commented 10 years ago

Could this be added to the documentation? It took me a while to decide whether or not to use Flask-Security, because I thought the documentation implied that only one salt was used for all users.

tedmiston commented 10 years ago

I've had the same confusion as @patrickyan.

evanhammer commented 10 years ago

I too had the same confusion as @patrickyan

corydolphin commented 10 years ago

@evanhammer I too had the same confusion, and found my way here to solve it.

mickey06 commented 10 years ago

The documentation should probably mention that for bcrypt the salt must be 22 characters long, drawn from the regexp range [./0-9A-Za-z]

mattupstate commented 10 years ago

The "salt" as required in the app configuration by Flask-Security for encrypted passwords does not have any requirements. As far as the individual password salting goes, passlib takes care of that.

rlam3 commented 9 years ago

Can the SECRET_KEY and SECURITY_PASSWORD_SALT be the same? or should they be different?

cybertoast commented 9 years ago

They can be the same. They're used in different places, and ideally would be different, but in this context that level of security is not really relevant.

On Thu, Apr 9, 2015 at 10:03 AM, rlam3 notifications@github.com wrote:

Can the SECRET_KEY and SECURITY_PASSWORD_SALT be the same? or should they be different?

— Reply to this email directly or view it on GitHub https://github.com/mattupstate/flask-security/issues/135#issuecomment-91241744 .

teloon commented 8 years ago

I would say the name of SECURITY_PASSWORD_SALT is very misleading and confusing. It's actually used as the "KEY" to generate HAMC.

ksdmitrieva commented 7 years ago

Agree with teloon. The name is missleading, because if the passlib is already generating the salt per user, why do we even need a static salt for the whole application? If it is a key to HMAC for the whole application, then it serves a different purpose. If the database is stolen (with the salts), then an attacker won't be able to crack a specific password (targeted attack), because there's the application HMAC key that is not stored in the database. This is a legitimate use. If that's the purpose of that variable specified during the configuration time, then it should be noted so in the documentation.