summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHarsh Jain <131331439+Hj-codes@users.noreply.github.com>2025-11-06 03:26:15 +0530
committerGitHub <noreply@github.com>2025-11-05 16:56:15 -0500
commitdfcc662cf8fd7f897ddcdfeaf5cb4ae6c963ebf8 (patch)
treea707fecd5c6d5c47bd1076a946e37391682d5899
parentc5a107e8248813f07325ae65232b5e53e9ac4238 (diff)
Fixed #36709 -- Included static methods in system check for UserModel.is_anonymous/is_authenticated methods.
-rw-r--r--django/contrib/auth/checks.py5
-rw-r--r--tests/auth_tests/test_checks.py39
2 files changed, 41 insertions, 3 deletions
diff --git a/django/contrib/auth/checks.py b/django/contrib/auth/checks.py
index cf23c51746..0de4cf49f1 100644
--- a/django/contrib/auth/checks.py
+++ b/django/contrib/auth/checks.py
@@ -1,5 +1,4 @@
from itertools import chain
-from types import MethodType
from django.apps import apps
from django.conf import settings
@@ -98,7 +97,7 @@ def check_user_model(app_configs, **kwargs):
)
)
- if isinstance(cls().is_anonymous, MethodType):
+ if callable(cls().is_anonymous):
errors.append(
checks.Critical(
"%s.is_anonymous must be an attribute or property rather than "
@@ -108,7 +107,7 @@ def check_user_model(app_configs, **kwargs):
id="auth.C009",
)
)
- if isinstance(cls().is_authenticated, MethodType):
+ if callable(cls().is_authenticated):
errors.append(
checks.Critical(
"%s.is_authenticated must be an attribute or property rather "
diff --git a/tests/auth_tests/test_checks.py b/tests/auth_tests/test_checks.py
index 3d70451e9d..19e9fadded 100644
--- a/tests/auth_tests/test_checks.py
+++ b/tests/auth_tests/test_checks.py
@@ -206,6 +206,45 @@ class UserModelChecksTests(SimpleTestCase):
],
)
+ @override_settings(AUTH_USER_MODEL="auth_tests.VulnerableStaticUser")
+ def test_is_anonymous_authenticated_static_methods(self):
+ """
+ <User Model>.is_anonymous/is_authenticated must not be static methods.
+ """
+
+ class VulnerableStaticUser(AbstractBaseUser):
+ username = models.CharField(max_length=30, unique=True)
+ USERNAME_FIELD = "username"
+
+ @staticmethod
+ def is_anonymous():
+ return False
+
+ @staticmethod
+ def is_authenticated():
+ return False
+
+ errors = checks.run_checks(app_configs=self.apps.get_app_configs())
+ self.assertEqual(
+ errors,
+ [
+ checks.Critical(
+ "%s.is_anonymous must be an attribute or property rather than "
+ "a method. Ignoring this is a security issue as anonymous "
+ "users will be treated as authenticated!" % VulnerableStaticUser,
+ obj=VulnerableStaticUser,
+ id="auth.C009",
+ ),
+ checks.Critical(
+ "%s.is_authenticated must be an attribute or property rather "
+ "than a method. Ignoring this is a security issue as anonymous "
+ "users will be treated as authenticated!" % VulnerableStaticUser,
+ obj=VulnerableStaticUser,
+ id="auth.C010",
+ ),
+ ],
+ )
+
@isolate_apps("auth_tests", attr_name="apps")
@override_system_checks([check_models_permissions])