5👍
The password hash is used to generate a password reset token. By reducing the complexity, it opens up the reset token to a brute-force attack. The attacker has to have the SECRET_KEY
for this to work.
To generate the password reset token, the ID of the user, the date in last_login
, the password hash and the SECRET_KEY
are used[1]. For superusers, it is reasonably likely that the ID is 1
and the last_login
date is within a few weeks of when the site came live, i.e. the superuser has never logged in and it’s the creation date of the account.
If the SECRET_KEY
is known, the ID is pretty much guessable and the password hash is known, an attacker only has to guess the datetime, which is within a few weeks timespan. A resolution of a second is used (the microsecond part of the last_login
is set to 0), which leaves around 600K possible values per week. With time and patience, this value can be brute-forced and the attacker can set a new, usable password for the superuser or admin account.
There are quite a few “if”s in this attack, but it is a possible attack vector. The random hash in the unusable password increases the entropy of the password reset token for unusable passwords, and eliminates this kind of attack.
[1] https://github.com/django/django/blob/master/django/contrib/auth/tokens.py#L66
1👍
The unusable password is used to generate a reset token for password reset.
Therefore knowing it’s value !
is less secure than a random string.