From 572ea07e84b38ea8de0551f4b4eda685d91d09d2 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Mon, 22 Jan 2024 13:21:13 +0000 Subject: [PATCH] [4.2.x] Fixed CVE-2024-24680 -- Mitigated potential DoS in intcomma template filter. Thanks Seokchan Yoon for the report. Co-authored-by: Mariusz Felisiak Co-authored-by: Natalia <124304+nessita@users.noreply.github.com> Co-authored-by: Shai Berger --- .../contrib/humanize/templatetags/humanize.py | 13 ++-- docs/releases/3.2.24.txt | 6 +- docs/releases/4.2.10.txt | 6 +- tests/humanize_tests/tests.py | 64 +++++++++++++++++++ 4 files changed, 81 insertions(+), 8 deletions(-) diff --git a/django/contrib/humanize/templatetags/humanize.py b/django/contrib/humanize/templatetags/humanize.py index 23224779c55..2c26f8944a7 100644 --- a/django/contrib/humanize/templatetags/humanize.py +++ b/django/contrib/humanize/templatetags/humanize.py @@ -75,12 +75,13 @@ def intcomma(value, use_l10n=True): return intcomma(value, False) else: return number_format(value, use_l10n=True, force_grouping=True) - orig = str(value) - new = re.sub(r"^(-?\d+)(\d{3})", r"\g<1>,\g<2>", orig) - if orig == new: - return new - else: - return intcomma(new, use_l10n) + result = str(value) + match = re.match(r"-?\d+", result) + if match: + prefix = match[0] + prefix_with_commas = re.sub(r"\d{3}", r"\g<0>,", prefix[::-1])[::-1] + result = prefix_with_commas + result[len(prefix) :] + return result # A tuple of standard large number to their converters diff --git a/docs/releases/3.2.24.txt b/docs/releases/3.2.24.txt index 1ab7024f73c..67be0f65d18 100644 --- a/docs/releases/3.2.24.txt +++ b/docs/releases/3.2.24.txt @@ -6,4 +6,8 @@ Django 3.2.24 release notes Django 3.2.24 fixes a security issue with severity "moderate" in 3.2.23. -... +CVE-2024-24680: Potential denial-of-service in ``intcomma`` template filter +=========================================================================== + +The ``intcomma`` template filter was subject to a potential denial-of-service +attack when used with very long strings. diff --git a/docs/releases/4.2.10.txt b/docs/releases/4.2.10.txt index c039f6840f7..7cdfa698144 100644 --- a/docs/releases/4.2.10.txt +++ b/docs/releases/4.2.10.txt @@ -6,4 +6,8 @@ Django 4.2.10 release notes Django 4.2.10 fixes a security issue with severity "moderate" in 4.2.9. -... +CVE-2024-24680: Potential denial-of-service in ``intcomma`` template filter +=========================================================================== + +The ``intcomma`` template filter was subject to a potential denial-of-service +attack when used with very long strings. diff --git a/tests/humanize_tests/tests.py b/tests/humanize_tests/tests.py index cf29f582329..a78bbadafd8 100644 --- a/tests/humanize_tests/tests.py +++ b/tests/humanize_tests/tests.py @@ -116,39 +116,71 @@ class HumanizeTests(SimpleTestCase): def test_intcomma(self): test_list = ( 100, + -100, 1000, + -1000, 10123, + -10123, 10311, + -10311, 1000000, + -1000000, 1234567.25, + -1234567.25, "100", + "-100", "1000", + "-1000", "10123", + "-10123", "10311", + "-10311", "1000000", + "-1000000", "1234567.1234567", + "-1234567.1234567", Decimal("1234567.1234567"), + Decimal("-1234567.1234567"), None, "1234567", + "-1234567", "1234567.12", + "-1234567.12", + "the quick brown fox jumped over the lazy dog", ) result_list = ( "100", + "-100", "1,000", + "-1,000", "10,123", + "-10,123", "10,311", + "-10,311", "1,000,000", + "-1,000,000", "1,234,567.25", + "-1,234,567.25", "100", + "-100", "1,000", + "-1,000", "10,123", + "-10,123", "10,311", + "-10,311", "1,000,000", + "-1,000,000", "1,234,567.1234567", + "-1,234,567.1234567", "1,234,567.1234567", + "-1,234,567.1234567", None, "1,234,567", + "-1,234,567", "1,234,567.12", + "-1,234,567.12", + "the quick brown fox jumped over the lazy dog", ) with translation.override("en"): self.humanize_tester(test_list, result_list, "intcomma") @@ -156,39 +188,71 @@ class HumanizeTests(SimpleTestCase): def test_l10n_intcomma(self): test_list = ( 100, + -100, 1000, + -1000, 10123, + -10123, 10311, + -10311, 1000000, + -1000000, 1234567.25, + -1234567.25, "100", + "-100", "1000", + "-1000", "10123", + "-10123", "10311", + "-10311", "1000000", + "-1000000", "1234567.1234567", + "-1234567.1234567", Decimal("1234567.1234567"), + -Decimal("1234567.1234567"), None, "1234567", + "-1234567", "1234567.12", + "-1234567.12", + "the quick brown fox jumped over the lazy dog", ) result_list = ( "100", + "-100", "1,000", + "-1,000", "10,123", + "-10,123", "10,311", + "-10,311", "1,000,000", + "-1,000,000", "1,234,567.25", + "-1,234,567.25", "100", + "-100", "1,000", + "-1,000", "10,123", + "-10,123", "10,311", + "-10,311", "1,000,000", + "-1,000,000", "1,234,567.1234567", + "-1,234,567.1234567", "1,234,567.1234567", + "-1,234,567.1234567", None, "1,234,567", + "-1,234,567", "1,234,567.12", + "-1,234,567.12", + "the quick brown fox jumped over the lazy dog", ) with self.settings(USE_THOUSAND_SEPARATOR=False): with translation.override("en"):