python-django/CVE-2023-46695.patch
starlet-dx bab57e3872 Fix CVE-2023-46695
(cherry picked from commit ccee4996a1b6ce668da45275749e310a24023533)
2024-02-07 10:40:05 +08:00

63 lines
2.7 KiB
Diff
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

From f9a7fb8466a7ba4857eaf930099b5258f3eafb2b Mon Sep 17 00:00:00 2001
From: Mariusz Felisiak <felisiak.mariusz@gmail.com>
Date: Tue, 17 Oct 2023 11:48:32 +0200
Subject: [PATCH] [3.2.x] Fixed CVE-2023-46695 -- Fixed potential DoS in
UsernameField on Windows.
Thanks MProgrammer (https://hackerone.com/mprogrammer) for the report.
---
django/contrib/auth/forms.py | 10 +++++++++-
tests/auth_tests/test_forms.py | 8 +++++++-
2 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/django/contrib/auth/forms.py b/django/contrib/auth/forms.py
index 20d8922..fb7cfda 100644
--- a/django/contrib/auth/forms.py
+++ b/django/contrib/auth/forms.py
@@ -62,7 +62,15 @@ class ReadOnlyPasswordHashField(forms.Field):
class UsernameField(forms.CharField):
def to_python(self, value):
- return unicodedata.normalize('NFKC', super().to_python(value))
+ value = super().to_python(value)
+ if self.max_length is not None and len(value) > self.max_length:
+ # Normalization can increase the string length (e.g.
+ # "ff" -> "ff", "½" -> "12") but cannot reduce it, so there is no
+ # point in normalizing invalid data. Moreover, Unicode
+ # normalization is very slow on Windows and can be a DoS attack
+ # vector.
+ return value
+ return unicodedata.normalize("NFKC", value)
def widget_attrs(self, widget):
return {
diff --git a/tests/auth_tests/test_forms.py b/tests/auth_tests/test_forms.py
index 7a731be..c0e1975 100644
--- a/tests/auth_tests/test_forms.py
+++ b/tests/auth_tests/test_forms.py
@@ -5,7 +5,7 @@ from unittest import mock
from django.contrib.auth.forms import (
AdminPasswordChangeForm, AuthenticationForm, PasswordChangeForm,
PasswordResetForm, ReadOnlyPasswordHashField, ReadOnlyPasswordHashWidget,
- SetPasswordForm, UserChangeForm, UserCreationForm,
+ SetPasswordForm, UserChangeForm, UserCreationForm, UsernameField,
)
from django.contrib.auth.models import User
from django.contrib.auth.signals import user_login_failed
@@ -132,6 +132,12 @@ class UserCreationFormTest(TestDataMixin, TestCase):
self.assertNotEqual(user.username, ohm_username)
self.assertEqual(user.username, 'testΩ') # U+03A9 GREEK CAPITAL LETTER OMEGA
+ def test_invalid_username_no_normalize(self):
+ field = UsernameField(max_length=254)
+ # Usernames are not normalized if they are too long.
+ self.assertEqual(field.to_python("½" * 255), "½" * 255)
+ self.assertEqual(field.to_python("ff" * 254), "ff" * 254)
+
def test_duplicate_normalized_unicode(self):
"""
To prevent almost identical usernames, visually identical but differing
--
2.30.0