diff options
| author | Sarah Boyce <42296566+sarahboyce@users.noreply.github.com> | 2025-08-26 13:37:34 +0200 |
|---|---|---|
| committer | Sarah Boyce <42296566+sarahboyce@users.noreply.github.com> | 2025-08-27 10:50:50 +0200 |
| commit | d0e4dd5cdd743a5c43c4ccc2c8fa29d3982eaa71 (patch) | |
| tree | ed64921a0f27e8df1b5ce69b729d34dfbfc9d815 /django/contrib | |
| parent | c594574175e379fff356e274893d797f6e6a95fa (diff) | |
Fixed #36572 -- Revert "Fixed #36546 -- Deprecated django.utils.crypto.constant_time_compare() in favor of hmac.compare_digest()."
This reverts commit 0246f478882c26bc1fe293224653074cd46a90d0.
Diffstat (limited to 'django/contrib')
| -rw-r--r-- | django/contrib/auth/__init__.py | 14 | ||||
| -rw-r--r-- | django/contrib/auth/hashers.py | 16 | ||||
| -rw-r--r-- | django/contrib/auth/tokens.py | 5 |
3 files changed, 19 insertions, 16 deletions
diff --git a/django/contrib/auth/__init__.py b/django/contrib/auth/__init__.py index f83007ac94..d752e3172b 100644 --- a/django/contrib/auth/__init__.py +++ b/django/contrib/auth/__init__.py @@ -1,4 +1,3 @@ -import hmac import inspect import re import warnings @@ -7,6 +6,7 @@ from django.apps import apps as django_apps from django.conf import settings from django.core.exceptions import ImproperlyConfigured, PermissionDenied from django.middleware.csrf import rotate_token +from django.utils.crypto import constant_time_compare from django.utils.deprecation import RemovedInDjango61Warning from django.utils.module_loading import import_string from django.views.decorators.debug import sensitive_variables @@ -175,7 +175,7 @@ def login(request, user, backend=None): if SESSION_KEY in request.session: if _get_user_session_key(request) != user.pk or ( session_auth_hash - and not hmac.compare_digest( + and not constant_time_compare( request.session.get(HASH_SESSION_KEY, ""), session_auth_hash ) ): @@ -217,7 +217,7 @@ async def alogin(request, user, backend=None): if await request.session.ahas_key(SESSION_KEY): if await _aget_user_session_key(request) != user.pk or ( session_auth_hash - and not hmac.compare_digest( + and not constant_time_compare( await request.session.aget(HASH_SESSION_KEY, ""), session_auth_hash, ) @@ -323,7 +323,7 @@ def get_user(request): session_hash_verified = False else: session_auth_hash = user.get_session_auth_hash() - session_hash_verified = hmac.compare_digest( + session_hash_verified = constant_time_compare( session_hash, session_auth_hash ) if not session_hash_verified: @@ -331,7 +331,7 @@ def get_user(request): # with the fallback secrets and stop when a matching one is # found. if session_hash and any( - hmac.compare_digest(session_hash, fallback_auth_hash) + constant_time_compare(session_hash, fallback_auth_hash) for fallback_auth_hash in user.get_session_auth_fallback_hash() ): request.session.cycle_key() @@ -364,7 +364,7 @@ async def aget_user(request): session_hash_verified = False else: session_auth_hash = user.get_session_auth_hash() - session_hash_verified = hmac.compare_digest( + session_hash_verified = constant_time_compare( session_hash, session_auth_hash ) if not session_hash_verified: @@ -372,7 +372,7 @@ async def aget_user(request): # with the fallback secrets and stop when a matching one is # found. if session_hash and any( - hmac.compare_digest(session_hash, fallback_auth_hash) + constant_time_compare(session_hash, fallback_auth_hash) for fallback_auth_hash in user.get_session_auth_fallback_hash() ): await request.session.acycle_key() diff --git a/django/contrib/auth/hashers.py b/django/contrib/auth/hashers.py index 4767ad560b..4bb518cb89 100644 --- a/django/contrib/auth/hashers.py +++ b/django/contrib/auth/hashers.py @@ -2,7 +2,6 @@ import base64 import binascii import functools import hashlib -import hmac import importlib import math import warnings @@ -13,7 +12,12 @@ from django.conf import settings from django.core.exceptions import ImproperlyConfigured from django.core.signals import setting_changed from django.dispatch import receiver -from django.utils.crypto import RANDOM_STRING_CHARS, get_random_string, pbkdf2 +from django.utils.crypto import ( + RANDOM_STRING_CHARS, + constant_time_compare, + get_random_string, + pbkdf2, +) from django.utils.encoding import force_bytes, force_str from django.utils.module_loading import import_string from django.utils.translation import gettext_noop as _ @@ -345,7 +349,7 @@ class PBKDF2PasswordHasher(BasePasswordHasher): def verify(self, password, encoded): decoded = self.decode(encoded) encoded_2 = self.encode(password, decoded["salt"], decoded["iterations"]) - return hmac.compare_digest(encoded, encoded_2) + return constant_time_compare(encoded, encoded_2) def safe_summary(self, encoded): decoded = self.decode(encoded) @@ -529,7 +533,7 @@ class BCryptSHA256PasswordHasher(BasePasswordHasher): algorithm, data = encoded.split("$", 1) assert algorithm == self.algorithm encoded_2 = self.encode(password, data.encode("ascii")) - return hmac.compare_digest(encoded, encoded_2) + return constant_time_compare(encoded, encoded_2) def safe_summary(self, encoded): decoded = self.decode(encoded) @@ -624,7 +628,7 @@ class ScryptPasswordHasher(BasePasswordHasher): decoded["block_size"], decoded["parallelism"], ) - return hmac.compare_digest(encoded, encoded_2) + return constant_time_compare(encoded, encoded_2) def safe_summary(self, encoded): decoded = self.decode(encoded) @@ -677,7 +681,7 @@ class MD5PasswordHasher(BasePasswordHasher): def verify(self, password, encoded): decoded = self.decode(encoded) encoded_2 = self.encode(password, decoded["salt"]) - return hmac.compare_digest(encoded, encoded_2) + return constant_time_compare(encoded, encoded_2) def safe_summary(self, encoded): decoded = self.decode(encoded) diff --git a/django/contrib/auth/tokens.py b/django/contrib/auth/tokens.py index 8e5d95cefd..09cc2b5195 100644 --- a/django/contrib/auth/tokens.py +++ b/django/contrib/auth/tokens.py @@ -1,8 +1,7 @@ -import hmac from datetime import datetime from django.conf import settings -from django.utils.crypto import salted_hmac +from django.utils.crypto import constant_time_compare, salted_hmac from django.utils.http import base36_to_int, int_to_base36 @@ -68,7 +67,7 @@ class PasswordResetTokenGenerator: # Check that the timestamp/uid has not been tampered with for secret in [self.secret, *self.secret_fallbacks]: - if hmac.compare_digest( + if constant_time_compare( self._make_token_with_timestamp(user, ts, secret), token, ): |
