Skip to content

Commit

Permalink
[4.1.x] Fixed CVE-2023-46695 -- Fixed potential DoS in UsernameField …
Browse files Browse the repository at this point in the history
…on Windows.

Thanks MProgrammer (https://hackerone.com/mprogrammer) for the report.
  • Loading branch information
felixxm committed Nov 1, 2023
1 parent 8581d91 commit 4965bfd
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 3 deletions.
10 changes: 9 additions & 1 deletion django/contrib/auth/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,15 @@ def __init__(self, *args, **kwargs):

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", "½" -> "1⁄2") 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 {
Expand Down
12 changes: 11 additions & 1 deletion docs/releases/3.2.23.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,14 @@ Django 3.2.23 release notes

Django 3.2.23 fixes a security issue with severity "moderate" in 3.2.22.

...
CVE-2023-46695: Potential denial of service vulnerability in ``UsernameField`` on Windows
=========================================================================================

The :func:`NFKC normalization <python:unicodedata.normalize>` is slow on
Windows. As a consequence, ``django.contrib.auth.forms.UsernameField`` was
subject to a potential denial of service attack via certain inputs with a very
large number of Unicode characters.

In order to avoid the vulnerability, invalid values longer than
``UsernameField.max_length`` are no longer normalized, since they cannot pass
validation anyway.
12 changes: 11 additions & 1 deletion docs/releases/4.1.13.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,14 @@ Django 4.1.13 release notes

Django 4.1.13 fixes a security issue with severity "moderate" in 4.1.12.

...
CVE-2023-46695: Potential denial of service vulnerability in ``UsernameField`` on Windows
=========================================================================================

The :func:`NFKC normalization <python:unicodedata.normalize>` is slow on
Windows. As a consequence, ``django.contrib.auth.forms.UsernameField`` was
subject to a potential denial of service attack via certain inputs with a very
large number of Unicode characters.

In order to avoid the vulnerability, invalid values longer than
``UsernameField.max_length`` are no longer normalized, since they cannot pass
validation anyway.
7 changes: 7 additions & 0 deletions tests/auth_tests/test_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
SetPasswordForm,
UserChangeForm,
UserCreationForm,
UsernameField,
)
from django.contrib.auth.models import User
from django.contrib.auth.signals import user_login_failed
Expand Down Expand Up @@ -150,6 +151,12 @@ def test_normalize_username(self):
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
Expand Down

0 comments on commit 4965bfd

Please sign in to comment.