summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSoumya Sambu <soumya.sambu@windriver.com>2025-01-10 13:18:01 +0000
committerArmin Kuster <akuster808@gmail.com>2025-01-22 19:23:05 -0500
commitbe168328f84eef8007cc8e3f9c2e08c59b036b9d (patch)
treecea2269af70b9df62b92638e69530599210d65eb
parentb4feba446d7a8f8232528c4b2ee936e5b98ced3d (diff)
downloadmeta-openembedded-be168328f84eef8007cc8e3f9c2e08c59b036b9d.tar.gz
python3-django: Fix CVE-2024-45231
An issue was discovered in Django v5.1.1, v5.0.9, and v4.2.16. The django.contrib.auth.forms.PasswordResetForm class, when used in a view implementing password reset flows, allows remote attackers to enumerate user e-mail addresses by sending password reset requests and observing the outcome (only when e-mail sending is consistently failing). Reference: https://nvd.nist.gov/vuln/detail/CVE-2024-45231 Upstream-patch: https://github.com/django/django/commit/bf4888d317ba4506d091eeac6e8b4f1fcc731199 Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com> Signed-off-by: Armin Kuster <akuster808@gmail.com>
-rw-r--r--meta-python/recipes-devtools/python/python3-django/CVE-2024-45231.patch120
-rw-r--r--meta-python/recipes-devtools/python/python3-django_2.2.28.bb1
2 files changed, 121 insertions, 0 deletions
diff --git a/meta-python/recipes-devtools/python/python3-django/CVE-2024-45231.patch b/meta-python/recipes-devtools/python/python3-django/CVE-2024-45231.patch
new file mode 100644
index 0000000000..2a0925ea9f
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-django/CVE-2024-45231.patch
@@ -0,0 +1,120 @@
1From bf4888d317ba4506d091eeac6e8b4f1fcc731199 Mon Sep 17 00:00:00 2001
2From: Natalia <124304+nessita@users.noreply.github.com>
3Date: Mon, 19 Aug 2024 14:47:38 -0300
4Subject: [PATCH] [4.2.x] Fixed CVE-2024-45231 -- Avoided server error on
5 password reset when email sending fails.
6
7On successful submission of a password reset request, an email is sent
8to the accounts known to the system. If sending this email fails (due to
9email backend misconfiguration, service provider outage, network issues,
10etc.), an attacker might exploit this by detecting which password reset
11requests succeed and which ones generate a 500 error response.
12
13Thanks to Thibaut Spriet for the report, and to Mariusz Felisiak, Adam
14Johnson, and Sarah Boyce for the reviews.
15
16CVE: CVE-2024-45231
17
18Upstream-Status: Backport [https://github.com/django/django/commit/bf4888d317ba4506d091eeac6e8b4f1fcc731199]
19
20Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
21---
22 django/contrib/auth/forms.py | 9 ++++++++-
23 docs/topics/auth/default.txt | 4 +++-
24 tests/auth_tests/test_forms.py | 21 +++++++++++++++++++++
25 tests/mail/custombackend.py | 5 +++++
26 4 files changed, 37 insertions(+), 2 deletions(-)
27
28diff --git a/django/contrib/auth/forms.py b/django/contrib/auth/forms.py
29index 26d3ca7..dc640a5 100644
30--- a/django/contrib/auth/forms.py
31+++ b/django/contrib/auth/forms.py
32@@ -1,3 +1,4 @@
33+import logging
34 import unicodedata
35
36 from django import forms
37@@ -18,6 +19,7 @@ from django.utils.text import capfirst
38 from django.utils.translation import gettext, gettext_lazy as _
39
40 UserModel = get_user_model()
41+logger = logging.getLogger("django.contrib.auth")
42
43
44 def _unicode_ci_compare(s1, s2):
45@@ -264,7 +266,12 @@ class PasswordResetForm(forms.Form):
46 html_email = loader.render_to_string(html_email_template_name, context)
47 email_message.attach_alternative(html_email, 'text/html')
48
49- email_message.send()
50+ try:
51+ email_message.send()
52+ except Exception:
53+ logger.exception(
54+ "Failed to send password reset email to %s", context["user"].pk
55+ )
56
57 def get_users(self, email):
58 """Given an email, return matching user(s) who should receive a reset.
59diff --git a/docs/topics/auth/default.txt b/docs/topics/auth/default.txt
60index 1af4951..6fdf700 100644
61--- a/docs/topics/auth/default.txt
62+++ b/docs/topics/auth/default.txt
63@@ -1530,7 +1530,9 @@ provides several built-in forms located in :mod:`django.contrib.auth.forms`:
64 .. method:: send_mail(subject_template_name, email_template_name, context, from_email, to_email, html_email_template_name=None)
65
66 Uses the arguments to send an ``EmailMultiAlternatives``.
67- Can be overridden to customize how the email is sent to the user.
68+ Can be overridden to customize how the email is sent to the user. If
69+ you choose to override this method, be mindful of handling potential
70+ exceptions raised due to email sending failures.
71
72 :param subject_template_name: the template for the subject.
73 :param email_template_name: the template for the email body.
74diff --git a/tests/auth_tests/test_forms.py b/tests/auth_tests/test_forms.py
75index e73d4b8..a45fd70 100644
76--- a/tests/auth_tests/test_forms.py
77+++ b/tests/auth_tests/test_forms.py
78@@ -935,6 +935,27 @@ class PasswordResetFormTest(TestDataMixin, TestCase):
79 message.get_payload(1).get_payload()
80 ))
81
82+ @override_settings(EMAIL_BACKEND="mail.custombackend.FailingEmailBackend")
83+ def test_save_send_email_exceptions_are_catched_and_logged(self):
84+ (user, username, email) = self.create_dummy_user()
85+ form = PasswordResetForm({"email": email})
86+ self.assertTrue(form.is_valid())
87+
88+ with self.assertLogs("django.contrib.auth", level=0) as cm:
89+ form.save()
90+
91+ self.assertEqual(len(mail.outbox), 0)
92+ self.assertEqual(len(cm.output), 1)
93+ errors = cm.output[0].split("\n")
94+ pk = user.pk
95+ self.assertEqual(
96+ errors[0],
97+ f"ERROR:django.contrib.auth:Failed to send password reset email to {pk}",
98+ )
99+ self.assertEqual(
100+ errors[-1], "ValueError: FailingEmailBackend is doomed to fail."
101+ )
102+
103 @override_settings(AUTH_USER_MODEL='auth_tests.CustomEmailField')
104 def test_custom_email_field(self):
105 email = 'test@mail.com'
106diff --git a/tests/mail/custombackend.py b/tests/mail/custombackend.py
107index fd57777..3e161d1 100644
108--- a/tests/mail/custombackend.py
109+++ b/tests/mail/custombackend.py
110@@ -13,3 +13,8 @@ class EmailBackend(BaseEmailBackend):
111 # Messages are stored in an instance variable for testing.
112 self.test_outbox.extend(email_messages)
113 return len(email_messages)
114+
115+
116+class FailingEmailBackend(BaseEmailBackend):
117+ def send_messages(self, email_messages):
118+ raise ValueError("FailingEmailBackend is doomed to fail.")
119--
1202.40.0
diff --git a/meta-python/recipes-devtools/python/python3-django_2.2.28.bb b/meta-python/recipes-devtools/python/python3-django_2.2.28.bb
index 275a61622d..4444d943cf 100644
--- a/meta-python/recipes-devtools/python/python3-django_2.2.28.bb
+++ b/meta-python/recipes-devtools/python/python3-django_2.2.28.bb
@@ -22,6 +22,7 @@ SRC_URI += "file://CVE-2023-31047.patch \
22 file://CVE-2024-41990.patch \ 22 file://CVE-2024-41990.patch \
23 file://CVE-2024-41991.patch \ 23 file://CVE-2024-41991.patch \
24 file://CVE-2024-45230.patch \ 24 file://CVE-2024-45230.patch \
25 file://CVE-2024-45231.patch \
25 " 26 "
26 27
27SRC_URI[sha256sum] = "0200b657afbf1bc08003845ddda053c7641b9b24951e52acd51f6abda33a7413" 28SRC_URI[sha256sum] = "0200b657afbf1bc08003845ddda053c7641b9b24951e52acd51f6abda33a7413"