Flask-security: Support the creation of a unique salt for each user

Created on 12 Jul 2013  Â·  13Comments  Â·  Source: mattupstate/flask-security

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()

Most helpful comment

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.

All 13 comments

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.

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.

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.

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.

I've had the same confusion as @patrickyan.

I too had the same confusion as @patrickyan

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

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

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.

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

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 [email protected] 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
.

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

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Ben095 picture Ben095  Â·  6Comments

lashex picture lashex  Â·  3Comments

DerekDomino picture DerekDomino  Â·  5Comments

adamlwgriffiths picture adamlwgriffiths  Â·  5Comments

Galstat picture Galstat  Â·  3Comments