From 954acdcf1b7306654dc4aba36a2c423d64ee5a80 Mon Sep 17 00:00:00 2001 From: Soumya Sambu Date: Fri, 10 Jan 2025 13:18:02 +0000 Subject: python3-django: Fix CVE-2024-53907 An issue was discovered in Django 5.1 before 5.1.4, 5.0 before 5.0.10, and 4.2 before 4.2.17. The strip_tags() method and striptags template filter are subject to a potential denial-of-service attack via certain inputs containing large sequences of nested incomplete HTML entities. Reference: https://nvd.nist.gov/vuln/detail/CVE-2024-53907 Upstream-patch: https://github.com/django/django/commit/790eb058b0716c536a2f2e8d1c6d5079d776c22b Signed-off-by: Soumya Sambu Signed-off-by: Armin Kuster --- .../python/python3-django/CVE-2024-53907.patch | 92 ++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 meta-python/recipes-devtools/python/python3-django/CVE-2024-53907.patch (limited to 'meta-python/recipes-devtools/python/python3-django/CVE-2024-53907.patch') diff --git a/meta-python/recipes-devtools/python/python3-django/CVE-2024-53907.patch b/meta-python/recipes-devtools/python/python3-django/CVE-2024-53907.patch new file mode 100644 index 0000000000..5a6af70611 --- /dev/null +++ b/meta-python/recipes-devtools/python/python3-django/CVE-2024-53907.patch @@ -0,0 +1,92 @@ +From 790eb058b0716c536a2f2e8d1c6d5079d776c22b Mon Sep 17 00:00:00 2001 +From: Sarah Boyce <42296566+sarahboyce@users.noreply.github.com> +Date: Wed, 13 Nov 2024 15:06:23 +0100 +Subject: [PATCH] [4.2.x] Fixed CVE-2024-53907 -- Mitigated potential DoS in + strip_tags(). + +Thanks to jiangniao for the report, and Shai Berger and Natalia Bidart +for the reviews. + +CVE: CVE-2024-53907 + +Upstream-Status: Backport [https://github.com/django/django/commit/790eb058b0716c536a2f2e8d1c6d5079d776c22b] + +Signed-off-by: Soumya Sambu + +--- + django/utils/html.py | 10 ++++++++-- + tests/utils_tests/test_html.py | 7 +++++++ + 2 files changed, 15 insertions(+), 2 deletions(-) + +diff --git a/django/utils/html.py b/django/utils/html.py +index 3cf1bfc..0d5ffd2 100644 +--- a/django/utils/html.py ++++ b/django/utils/html.py +@@ -8,12 +8,14 @@ from urllib.parse import ( + parse_qsl, quote, unquote, urlencode, urlsplit, urlunsplit, + ) + ++from django.core.exceptions import SuspiciousOperation + from django.utils.functional import Promise, keep_lazy, keep_lazy_text + from django.utils.http import RFC3986_GENDELIMS, RFC3986_SUBDELIMS + from django.utils.safestring import SafeData, SafeText, mark_safe + from django.utils.text import normalize_newlines + + MAX_URL_LENGTH = 2048 ++MAX_STRIP_TAGS_DEPTH = 50 + + # Configuration for urlize() function. + TRAILING_PUNCTUATION_CHARS = '.,:;!' +@@ -185,15 +187,19 @@ def _strip_once(value): + @keep_lazy_text + def strip_tags(value): + """Return the given HTML with all tags stripped.""" +- # Note: in typical case this loop executes _strip_once once. Loop condition +- # is redundant, but helps to reduce number of executions of _strip_once. + value = str(value) ++ # Note: in typical case this loop executes _strip_once twice (the second ++ # execution does not remove any more tags). ++ strip_tags_depth = 0 + while '<' in value and '>' in value: ++ if strip_tags_depth >= MAX_STRIP_TAGS_DEPTH: ++ raise SuspiciousOperation + new_value = _strip_once(value) + if value.count('<') == new_value.count('<'): + # _strip_once wasn't able to detect more tags. + break + value = new_value ++ strip_tags_depth += 1 + return value + + +diff --git a/tests/utils_tests/test_html.py b/tests/utils_tests/test_html.py +index 8fe2f24..2f412e1 100644 +--- a/tests/utils_tests/test_html.py ++++ b/tests/utils_tests/test_html.py +@@ -1,6 +1,7 @@ + import os + from datetime import datetime + ++from django.core.exceptions import SuspiciousOperation + from django.test import SimpleTestCase + from django.utils.functional import lazystr + from django.utils.html import ( +@@ -90,12 +91,18 @@ class TestUtilsHtml(SimpleTestCase): + ('&h', 'alert()h'), + ('>br>br>br>X', 'XX'), ++ ("<" * 50 + "a>" * 50, ""), + ) + for value, output in items: + with self.subTest(value=value, output=output): + self.check_output(strip_tags, value, output) + self.check_output(strip_tags, lazystr(value), output) + ++ def test_strip_tags_suspicious_operation(self): ++ value = "<" * 51 + "a>" * 51, "" ++ with self.assertRaises(SuspiciousOperation): ++ strip_tags(value) ++ + def test_strip_tags_files(self): + # Test with more lengthy content (also catching performance regressions) + for filename in ('strip_tags1.html', 'strip_tags2.txt'): -- cgit v1.2.3-54-g00ecf