[Django] #36503: NFKC normalization DoS vulnerability in Django 4.2 LTS - needs backport protection

9 views
Skip to first unread message

Django

unread,
Jul 10, 2025, 12:41:58 PM7/10/25
to django-...@googlegroups.com
#36503: NFKC normalization DoS vulnerability in Django 4.2 LTS - needs backport
protection
-------------------------------------+-------------------------------------
Reporter: Nauman Tariq | Type: Bug
Status: new | Component:
| contrib.auth
Version: 4.2 | Severity: Normal
Keywords: security, | Triage Stage:
normalization, dos, | Unreviewed
authentication, LTS, backport |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Django 4.2 LTS is vulnerable to denial-of-service attacks via slow NFKC
normalization on Windows systems. This vulnerability has been fixed in
Django 5.0.14+ and 5.1.8+ but needs to be backported to Django 4.2 LTS for
comprehensive protection.

## Problem

Python's `unicodedata.normalize("NFKC", ...)` is slow on Windows with long
Unicode strings. Django 4.2 uses NFKC normalization in several functions
without length validation:

1. `django.contrib.auth.forms._unicode_ci_compare`
2. `django.contrib.auth.base_user.AbstractBaseUser.normalize_username`
3. `django.utils.text.slugify` (when `allow_unicode=True`)

## Impact

- **Views affected:** LoginView, LogoutView, set_language
- **Attack vector:** Malicious Unicode input (10,000+ characters)
- **Result:** Server threads hang for seconds/minutes on Windows
- **Scope:** All Django 4.2 LTS applications on Windows

## Proposed Solution

Backport the same length checks used in Django 5.x:

- `_unicode_ci_compare`: 320 character limit (RFC 5321 email standard)
- `normalize_username`: 150 character limit (common username limits)
- `slugify`: 200 character truncation (reasonable slug length)

## Why Django 4.2 LTS Needs This

Django 4.2 is LTS (supported until April 2026). Production applications
using LTS releases should receive the same security protections available
in newer versions.

## Implementation

I have prepared a complete backport with:
- ✅ Length validation before NFKC normalization
- ✅ Full backward compatibility maintained
- ✅ Comprehensive test suite
- ✅ Consistent with Django 5.x approach

Repository: https://github.com/nauman3128/django/tree/27556
Commit: 01873a0847

## Testing

Comprehensive test coverage in
`tests/auth_tests/test_nfkc_vulnerability.py` verifies:
- Normal inputs work correctly
- Length limits enforced properly
- No performance degradation
- Backward compatibility preserved

This backport ensures Django 4.2 LTS users get the same protection as
Django 5.x users.
--
Ticket URL: <https://code.djangoproject.com/ticket/36503>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Jul 10, 2025, 12:52:33 PM7/10/25
to django-...@googlegroups.com
#36503: NFKC normalization DoS vulnerability in Django 4.2 LTS - needs backport
protection
-------------------------------------+-------------------------------------
Reporter: Nauman Tariq | Owner: (none)
Type: Bug | Status: new
Component: contrib.auth | Version: 4.2
Severity: Normal | Resolution:
Keywords: security, | Triage Stage:
normalization, dos, | Unreviewed
authentication, LTS, backport |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by Nauman Tariq):

Pull request submitted: https://github.com/django/django/pull/19633
--
Ticket URL: <https://code.djangoproject.com/ticket/36503#comment:1>

Django

unread,
Jul 10, 2025, 2:04:45 PM7/10/25
to django-...@googlegroups.com
#36503: NFKC normalization DoS vulnerability in Django 4.2 LTS - needs backport
protection
-------------------------------------+-------------------------------------
Reporter: Nauman Tariq | Owner: (none)
Type: Bug | Status: new
Component: contrib.auth | Version: 4.2
Severity: Normal | Resolution:
Keywords: security, | Triage Stage:
normalization, dos, | Unreviewed
authentication, LTS, backport |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by Mariusz Felisiak):

Security patches [https://docs.djangoproject.com/en/5.2/internals/security
/#reporting-security-issues should never be processed publicly].🔥
--
Ticket URL: <https://code.djangoproject.com/ticket/36503#comment:2>
Reply all
Reply to author
Forward
0 new messages