#34661 closed New feature (duplicate)
Peppering user passwords
Reported by: | Fatih Erikli | Owned by: | nobody |
---|---|---|---|
Component: | contrib.auth | Version: | 4.2 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
Currently a user's password stored in database in this format:
<algorithm>$<iterations>$<salt>$<hash>
Hash (Last column) is the password hashed with the salt in previous column.
Example, these are two computed passwords, stored on database, for the same password of two users.
pbkdf2_sha256$600000$fb9cUsHWK4EMZ7VWGBAcGD$2uwiVefFwanIhxLrv+/t3sKvP4X6tDKEMw/ysHD5dIc=
pbkdf2_sha256$600000$HgWHWrF2qQD9Owj4XeEkjY$rh0qzfo+/ZCzWbL9ZJa8aKhiO5xoEMfT4EtP/+A+LzI=
The password is 123456.
Imagine I am an attacker, who got the database of different django project, I want to look up the users who have chosen the password 123456.
I have the salts of users stored in database.
make_password('123456', 'fb9cUsHWK4EMZ7VWGBAcGD')
pbkdf2_sha256$600000$fb9cUsHWK4EMZ7VWGBAcGD$2uwiVefFwanIhxLrv+/t3sKvP4X6tDKEMw/ysHD5dIc=
make_password('123456', 'HgWHWrF2qQD9Owj4XeEkjY')
pbkdf2_sha256$600000$HgWHWrF2qQD9Owj4XeEkjY$rh0qzfo+/ZCzWbL9ZJa8aKhiO5xoEMfT4EtP/+A+LzI=
These are correct password combinations. I am able to lookup the users who have their passwords exposed in public.
Password 123456 is not a possible case in Django, since the password fields have a complexity validation. However, the salt is available to the attacker when a database is stolen. Salt could be used
- to hash the raw password pair in a rainbow table.
- to hash the already exposed passwords.
There is one more element needed for hashing the password, pepper, should be project specific. When a database is exposed in public, the attacker will not be able to lookup the passwords, since they don't have the secret pepper key.
I am not sure about the vulnerability enumeration, but CWE-760 seems closer. Salt is not weak, but it is known. The salt is stored next to the hashed password.
This is a case of when a database is stolen, however I think Django, by default, should do everything that could be done at the framework level to keep the user information secured.
Change History (14)
comment:1 by , 18 months ago
Description: | modified (diff) |
---|
comment:2 by , 18 months ago
Description: | modified (diff) |
---|
comment:3 by , 18 months ago
Description: | modified (diff) |
---|
comment:4 by , 18 months ago
Description: | modified (diff) |
---|
comment:5 by , 18 months ago
Description: | modified (diff) |
---|
comment:6 by , 18 months ago
Description: | modified (diff) |
---|
comment:7 by , 18 months ago
Description: | modified (diff) |
---|
comment:9 by , 18 months ago
Description: | modified (diff) |
---|
comment:10 by , 18 months ago
Description: | modified (diff) |
---|
comment:11 by , 18 months ago
Description: | modified (diff) |
---|
comment:12 by , 18 months ago
Description: | modified (diff) |
---|
comment:14 by , 18 months ago
Type: | Uncategorized → New feature |
---|
Here is an example hasher:
The hash is base64 encoded on default PBKD hasher. I deleted. There is too much things going on a piece of data. It may confuse the developers at this context, lead to another security issue.
In settings:
Django updates the computed passwords when a new hashing algorithm is added. The passwords will break when a pepper is changed.