#34661: Peppering user passwords
-------------------------------+--------------------------------------
     Reporter:  Fatih Erikli   |                    Owner:  nobody
         Type:  Uncategorized  |                   Status:  new
    Component:  contrib.auth   |                  Version:  4.2
     Severity:  Normal         |               Resolution:
     Keywords:                 |             Triage Stage:  Unreviewed
    Has patch:  0              |      Needs documentation:  0
  Needs tests:  0              |  Patch needs improvement:  0
Easy pickings:  0              |                    UI/UX:  0
-------------------------------+--------------------------------------
Description changed by Fatih Erikli:

Old description:

> Currently a user's password stored in database in this format:
>
> > <algorithm>$<iterations>$<salt>$<hash>
>
> The salt is a random generated string per user. Hash (Last column) is the
> password hashed with the stored value 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.

New description:

 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.

--

-- 
Ticket URL: <https://code.djangoproject.com/ticket/34661#comment:12>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/01070188d11c357d-a896a75d-3328-4f4c-85ef-7d83f6fb4c9a-000000%40eu-central-1.amazonses.com.

Reply via email to