1
0
mirror of https://github.com/django/django.git synced 2025-10-31 09:41:08 +00:00

Refs #33691 -- Deprecated insecure password hashers.

SHA1PasswordHasher, UnsaltedSHA1PasswordHasher, and UnsaltedMD5PasswordHasher
are now deprecated.
This commit is contained in:
Claude Paroz
2022-07-23 12:45:24 +02:00
committed by Mariusz Felisiak
parent a46dfa87d0
commit 3b79dab19a
5 changed files with 89 additions and 35 deletions

View File

@@ -11,7 +11,6 @@ from django.contrib.auth.hashers import (
PBKDF2PasswordHasher,
PBKDF2SHA1PasswordHasher,
ScryptPasswordHasher,
SHA1PasswordHasher,
check_password,
get_hasher,
identify_hasher,
@@ -20,7 +19,7 @@ from django.contrib.auth.hashers import (
)
from django.test import SimpleTestCase, ignore_warnings
from django.test.utils import override_settings
from django.utils.deprecation import RemovedInDjango50Warning
from django.utils.deprecation import RemovedInDjango50Warning, RemovedInDjango51Warning
# RemovedInDjango50Warning.
try:
@@ -96,6 +95,7 @@ class TestUtilsHashPass(SimpleTestCase):
self.assertIs(hasher.must_update(encoded_weak_salt), True)
self.assertIs(hasher.must_update(encoded_strong_salt), False)
@ignore_warnings(category=RemovedInDjango51Warning)
@override_settings(
PASSWORD_HASHERS=["django.contrib.auth.hashers.SHA1PasswordHasher"]
)
@@ -121,6 +121,14 @@ class TestUtilsHashPass(SimpleTestCase):
self.assertIs(hasher.must_update(encoded_weak_salt), True)
self.assertIs(hasher.must_update(encoded_strong_salt), False)
@override_settings(
PASSWORD_HASHERS=["django.contrib.auth.hashers.SHA1PasswordHasher"]
)
def test_sha1_deprecation_warning(self):
msg = "django.contrib.auth.hashers.SHA1PasswordHasher is deprecated."
with self.assertRaisesMessage(RemovedInDjango51Warning, msg):
get_hasher("sha1")
@override_settings(
PASSWORD_HASHERS=["django.contrib.auth.hashers.MD5PasswordHasher"]
)
@@ -144,6 +152,7 @@ class TestUtilsHashPass(SimpleTestCase):
self.assertIs(hasher.must_update(encoded_weak_salt), True)
self.assertIs(hasher.must_update(encoded_strong_salt), False)
@ignore_warnings(category=RemovedInDjango51Warning)
@override_settings(
PASSWORD_HASHERS=["django.contrib.auth.hashers.UnsaltedMD5PasswordHasher"]
)
@@ -165,6 +174,7 @@ class TestUtilsHashPass(SimpleTestCase):
self.assertTrue(check_password("", blank_encoded))
self.assertFalse(check_password(" ", blank_encoded))
@ignore_warnings(category=RemovedInDjango51Warning)
@override_settings(
PASSWORD_HASHERS=["django.contrib.auth.hashers.UnsaltedMD5PasswordHasher"]
)
@@ -174,6 +184,15 @@ class TestUtilsHashPass(SimpleTestCase):
with self.assertRaisesMessage(ValueError, msg):
hasher.encode("password", salt="salt")
@override_settings(
PASSWORD_HASHERS=["django.contrib.auth.hashers.UnsaltedMD5PasswordHasher"]
)
def test_unsalted_md5_deprecation_warning(self):
msg = "django.contrib.auth.hashers.UnsaltedMD5PasswordHasher is deprecated."
with self.assertRaisesMessage(RemovedInDjango51Warning, msg):
get_hasher("unsalted_md5")
@ignore_warnings(category=RemovedInDjango51Warning)
@override_settings(
PASSWORD_HASHERS=["django.contrib.auth.hashers.UnsaltedSHA1PasswordHasher"]
)
@@ -194,6 +213,7 @@ class TestUtilsHashPass(SimpleTestCase):
self.assertTrue(check_password("", blank_encoded))
self.assertFalse(check_password(" ", blank_encoded))
@ignore_warnings(category=RemovedInDjango51Warning)
@override_settings(
PASSWORD_HASHERS=["django.contrib.auth.hashers.UnsaltedSHA1PasswordHasher"]
)
@@ -203,6 +223,14 @@ class TestUtilsHashPass(SimpleTestCase):
with self.assertRaisesMessage(ValueError, msg):
hasher.encode("password", salt="salt")
@override_settings(
PASSWORD_HASHERS=["django.contrib.auth.hashers.UnsaltedSHA1PasswordHasher"]
)
def test_unsalted_sha1_deprecation_warning(self):
msg = "django.contrib.auth.hashers.UnsaltedSHA1PasswordHasher is deprecated."
with self.assertRaisesMessage(RemovedInDjango51Warning, msg):
get_hasher("unsalted_sha1")
@ignore_warnings(category=RemovedInDjango50Warning)
@skipUnless(crypt, "no crypt module to generate password.")
@override_settings(
@@ -432,13 +460,13 @@ class TestUtilsHashPass(SimpleTestCase):
@override_settings(
PASSWORD_HASHERS=[
"django.contrib.auth.hashers.PBKDF2PasswordHasher",
"django.contrib.auth.hashers.SHA1PasswordHasher",
"django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher",
"django.contrib.auth.hashers.MD5PasswordHasher",
],
)
def test_upgrade(self):
self.assertEqual("pbkdf2_sha256", get_hasher("default").algorithm)
for algo in ("sha1", "md5"):
for algo in ("pbkdf2_sha1", "md5"):
with self.subTest(algo=algo):
encoded = make_password("lètmein", hasher=algo)
state = {"upgraded": False}
@@ -462,13 +490,13 @@ class TestUtilsHashPass(SimpleTestCase):
@override_settings(
PASSWORD_HASHERS=[
"django.contrib.auth.hashers.PBKDF2PasswordHasher",
"django.contrib.auth.hashers.SHA1PasswordHasher",
"django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher",
"django.contrib.auth.hashers.MD5PasswordHasher",
],
)
def test_no_upgrade_on_incorrect_pass(self):
self.assertEqual("pbkdf2_sha256", get_hasher("default").algorithm)
for algo in ("sha1", "md5"):
for algo in ("pbkdf2_sha1", "md5"):
with self.subTest(algo=algo):
encoded = make_password("lètmein", hasher=algo)
state = {"upgraded": False}
@@ -583,7 +611,6 @@ class TestUtilsHashPass(SimpleTestCase):
PBKDF2PasswordHasher,
PBKDF2SHA1PasswordHasher,
ScryptPasswordHasher,
SHA1PasswordHasher,
]
msg = "salt must be provided and cannot contain $."
for hasher_class in hasher_classes:
@@ -599,7 +626,6 @@ class TestUtilsHashPass(SimpleTestCase):
PBKDF2PasswordHasher,
PBKDF2SHA1PasswordHasher,
ScryptPasswordHasher,
SHA1PasswordHasher,
]
msg = "password must be provided."
for hasher_class in hasher_classes: