Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP2:GA
python-Django
CVE-2024-45231.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File CVE-2024-45231.patch of Package python-Django
From fe42da9cdacd9f43fb0d499244314c36f9a11a19 Mon Sep 17 00:00:00 2001 From: Natalia <124304+nessita@users.noreply.github.com> Date: Mon, 19 Aug 2024 14:47:38 -0300 Subject: [PATCH 2/2] [4.2.x] Fixed CVE-2024-45231 -- Avoided server error on password reset when email sending fails. On successful submission of a password reset request, an email is sent to the accounts known to the system. If sending this email fails (due to email backend misconfiguration, service provider outage, network issues, etc.), an attacker might exploit this by detecting which password reset requests succeed and which ones generate a 500 error response. Thanks to Thibaut Spriet for the report, and to Mariusz Felisiak and Sarah Boyce for the reviews. --- django/contrib/auth/forms.py | 9 ++++++++- docs/ref/logging.txt | 12 ++++++++++++ docs/releases/4.2.16.txt | 11 +++++++++++ docs/topics/auth/default.txt | 4 +++- tests/auth_tests/test_forms.py | 21 +++++++++++++++++++++ tests/mail/custombackend.py | 5 +++++ 6 files changed, 60 insertions(+), 2 deletions(-) Index: Django-2.0.7/django/contrib/auth/forms.py =================================================================== --- Django-2.0.7.orig/django/contrib/auth/forms.py +++ Django-2.0.7/django/contrib/auth/forms.py @@ -1,3 +1,4 @@ +import logging import unicodedata from django import forms @@ -18,6 +19,7 @@ from django.utils.text import capfirst from django.utils.translation import gettext, gettext_lazy as _ UserModel = get_user_model() +logger = logging.getLogger("django.contrib.auth") class ReadOnlyPasswordHashWidget(forms.Widget): @@ -248,7 +250,12 @@ class PasswordResetForm(forms.Form): html_email = loader.render_to_string(html_email_template_name, context) email_message.attach_alternative(html_email, 'text/html') - email_message.send() + try: + email_message.send() + except Exception: + logger.exception( + "Failed to send password reset email to %s:", context["user"].pk + ) def get_users(self, email): """Given an email, return matching user(s) who should receive a reset. Index: Django-2.0.7/docs/releases/4.2.16.txt =================================================================== --- Django-2.0.7.orig/docs/releases/4.2.16.txt +++ Django-2.0.7/docs/releases/4.2.16.txt @@ -13,3 +13,14 @@ CVE-2024-45230: Potential denial-of-serv :tfilter:`urlize` and :tfilter:`urlizetrunc` were subject to a potential denial-of-service attack via very large inputs with a specific sequence of characters. + +CVE-2024-45231: Potential user email enumeration via response status on password reset +====================================================================================== + +Due to unhandled email sending failures, the +:class:`~django.contrib.auth.forms.PasswordResetForm` class allowed remote +attackers to enumerate user emails by issuing password reset requests and +observing the outcomes. + +To mitigate this risk, exceptions occurring during password reset email sending +are now handled and logged using the :ref:`django-contrib-auth-logger` logger. Index: Django-2.0.7/docs/topics/auth/default.txt =================================================================== --- Django-2.0.7.orig/docs/topics/auth/default.txt +++ Django-2.0.7/docs/topics/auth/default.txt @@ -1581,7 +1581,9 @@ provides several built-in forms located .. method:: send_mail(subject_template_name, email_template_name, context, from_email, to_email, html_email_template_name=None) Uses the arguments to send an ``EmailMultiAlternatives``. - Can be overridden to customize how the email is sent to the user. + Can be overridden to customize how the email is sent to the user. If + you choose to override this method, be mindful of handling potential + exceptions raised due to email sending failures. :param subject_template_name: the template for the subject. :param email_template_name: the template for the email body. Index: Django-2.0.7/tests/auth_tests/test_forms.py =================================================================== --- Django-2.0.7.orig/tests/auth_tests/test_forms.py +++ Django-2.0.7/tests/auth_tests/test_forms.py @@ -846,6 +846,27 @@ class PasswordResetFormTest(TestDataMixi message.get_payload(1).get_payload() )) + @override_settings(EMAIL_BACKEND="mail.custombackend.FailingEmailBackend") + def test_save_send_email_exceptions_are_catched_and_logged(self): + (user, username, email) = self.create_dummy_user() + form = PasswordResetForm({"email": email}) + self.assertTrue(form.is_valid()) + + with self.assertLogs("django.contrib.auth", level=0) as cm: + form.save() + + self.assertEqual(len(mail.outbox), 0) + self.assertEqual(len(cm.output), 1) + errors = cm.output[0].split("\n") + pk = user.pk + self.assertEqual( + errors[0], + f"ERROR:django.contrib.auth:Failed to send password reset email to {pk}:", + ) + self.assertEqual( + errors[-1], "ValueError: FailingEmailBackend is doomed to fail." + ) + @override_settings(AUTH_USER_MODEL='auth_tests.CustomEmailField') def test_custom_email_field(self): email = 'test@mail.com' Index: Django-2.0.7/tests/mail/custombackend.py =================================================================== --- Django-2.0.7.orig/tests/mail/custombackend.py +++ Django-2.0.7/tests/mail/custombackend.py @@ -13,3 +13,8 @@ class EmailBackend(BaseEmailBackend): # Messages are stored in an instance variable for testing. self.test_outbox.extend(email_messages) return len(email_messages) + + +class FailingEmailBackend(BaseEmailBackend): + def send_messages(self, email_messages): + raise ValueError("FailingEmailBackend is doomed to fail.")
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor