Opened 70 minutes ago
Last modified 16 minutes ago
#37078 new Cleanup/optimization
salted_hmac() defaults to SHA-1 algorithm despite SHA-256 being preferred everywhere else
| Reported by: | Denny Biasiolli | Owned by: | |
|---|---|---|---|
| Component: | Utilities | Version: | |
| Severity: | Normal | Keywords: | security, crypto |
| Cc: | Denny Biasiolli | Triage Stage: | Unreviewed |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
The salted_hmac() function (crypto.py:19) defaults to algorithm="sha1". While HMAC-SHA1 is not cryptographically broken (HMAC construction is resistant to collision attacks), SHA-1 is deprecated by NIST and modern security standards recommend SHA-256 or stronger for all new applications.
All security-sensitive callers within Django already override this default — Signer uses sha256 (signing.py:193), PasswordResetTokenGenerator passes sha256 explicitly, and session auth hashes use SHA-256. However, any third-party code or custom application calling salted_hmac() without specifying an algorithm will silently use SHA-1.
## Steps to Reproduce
- In any Django project, call:
`python from django.utils.crypto import salted_hmac mac = salted_hmac("my_salt", "my_value") print(mac.digest_size) # 20 bytes = SHA-1` - Observe the HMAC uses SHA-1 without any explicit algorithm selection
## Expected Behavior
salted_hmac() should default to "sha256" to match modern cryptographic best practices and align with Django's own internal usage.
## Actual Behavior
salted_hmac() defaults to algorithm="sha1" (line 19 of crypto.py).
Change History (3)
comment:1 by , 65 minutes ago
| Has patch: | set |
|---|
comment:2 by , 25 minutes ago
comment:3 by , 16 minutes ago
A deprecation might make sense, but just to check my understanding -- Tim, does it make a difference that base64_hmac() isn't documented? (And that all uses in Django have already migrated?)
Previous work was done in #27468. We cannot just change default value of the parameter due to backward compatibility. The change would have to go through a deprecation.