Browse Source

Fixed #31375 -- Made contrib.auth.hashers.make_password() accept only bytes or strings.

Hasan Ramezani 5 years ago
parent
commit
8aa71f4e87

+ 5 - 0
django/contrib/auth/hashers.py

@@ -72,6 +72,11 @@ def make_password(password, salt=None, hasher='default'):
     """
     if password is None:
         return UNUSABLE_PASSWORD_PREFIX + get_random_string(UNUSABLE_PASSWORD_SUFFIX_LENGTH)
+    if not isinstance(password, (bytes, str)):
+        raise TypeError(
+            'Password must be a string or bytes, got %s.'
+            % type(password).__qualname__
+        )
     hasher = get_hasher(hasher)
     salt = salt or hasher.salt()
     return hasher.encode(password, salt)

+ 4 - 0
docs/releases/3.1.txt

@@ -603,6 +603,10 @@ Miscellaneous
 * The admin CSS classes ``row1`` and ``row2`` are removed in favor of
   ``:nth-child(odd)`` and ``:nth-child(even)`` pseudo-classes.
 
+* The :func:`~django.contrib.auth.hashers.make_password` now requires its
+  argument to be a string or bytes. Other types should be explicitly cast to
+  one of these.
+
 .. _deprecated-features-3.1:
 
 Features deprecated in 3.1

+ 10 - 6
docs/topics/auth/passwords.txt

@@ -402,12 +402,16 @@ from the ``User`` model.
 .. function:: make_password(password, salt=None, hasher='default')
 
     Creates a hashed password in the format used by this application. It takes
-    one mandatory argument: the password in plain-text. Optionally, you can
-    provide a salt and a hashing algorithm to use, if you don't want to use the
-    defaults (first entry of ``PASSWORD_HASHERS`` setting). See
-    :ref:`auth-included-hashers` for the algorithm name of each hasher. If the
-    password argument is ``None``, an unusable password is returned (one that
-    will never be accepted by :func:`check_password`).
+    one mandatory argument: the password in plain-text (string or bytes).
+    Optionally, you can provide a salt and a hashing algorithm to use, if you
+    don't want to use the defaults (first entry of ``PASSWORD_HASHERS``
+    setting). See :ref:`auth-included-hashers` for the algorithm name of each
+    hasher. If the password argument is ``None``, an unusable password is
+    returned (one that will never be accepted by :func:`check_password`).
+
+    .. versionchanged:: 3.1
+
+        The ``password`` parameter must be a string or bytes if not ``None``.
 
 .. function:: is_password_usable(encoded_password)
 

+ 5 - 0
tests/auth_tests/test_hashers.py

@@ -56,6 +56,11 @@ class TestUtilsHashPass(SimpleTestCase):
         self.assertIs(is_password_usable(encoded), True)
         self.assertIs(check_password(b'bytes_password', encoded), True)
 
+    def test_invalid_password(self):
+        msg = 'Password must be a string or bytes, got int.'
+        with self.assertRaisesMessage(TypeError, msg):
+            make_password(1)
+
     def test_pbkdf2(self):
         encoded = make_password('lètmein', 'seasalt', 'pbkdf2_sha256')
         self.assertEqual(encoded, 'pbkdf2_sha256$216000$seasalt$youGZxOw6ZOcfrXv2i8/AhrnpZflJJ9EshS9XmUJTUg=')