Opened 49 minutes ago
#37184 new Bug
PBKDF2PasswordHasher no longer accepts password of type bytes
| Reported by: | Johannes Leuschner | Owned by: | |
|---|---|---|---|
| Component: | contrib.auth | Version: | 6.0 |
| Severity: | Normal | Keywords: | PBKDF2 hasher password bytes UTF-8 |
| Cc: | Johannes Leuschner | Triage Stage: | Unreviewed |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
Before 78fac1b0473ed8960ecd2a30aca4fa8420d150b8, PBKDF2PasswordHasher (which is the default hasher) used to accept a password of type bytes in make_password and check_password. After that commit, force_str is called on the password, raising a decoding error if the bytes are not valid UTF-8. The pbkdf2 implementation then actually converts back to bytes.
Minimal example:
from django.contrib.auth.hashers import make_password make_password(b"\xc0", hasher="pbkdf2_sha256") # fails with DjangoUnicodeDecodeError
and also
from django.contrib.auth.hashers import make_password, check_password encoded = make_password(b"", hasher="pbkdf2_sha256") check_password(b"\xc0", encoded) # fails with DjangoUnicodeDecodeError
A use-case for passing a password of type bytes is generated passwords/keys, which can be exposed to the user e.g. via base64 encoding. This maximizes password strength compared to only allowing valid UTF-8 characters, and generating random passwords with a restricted character set is not as straight-forward. Existing applications using passwords of type bytes now fail both at making and checking passwords.
Note that in the same commit force_str is also introduced to MD5PasswordHasher, but there it makes sense because .encode() has been called anyways, i.e. bytes was not supported before.