* [oe][meta-oe][kirkstone][PATCH 1/1] python3-django: fix CVE-2024-27351
@ 2025-11-14 12:03 Saravanan
2025-11-17 8:16 ` Gyorgy Sarvari
0 siblings, 1 reply; 4+ messages in thread
From: Saravanan @ 2025-11-14 12:03 UTC (permalink / raw)
To: openembedded-devel
Reference:
https://nvd.nist.gov/vuln/detail/CVE-2024-27351
Upstream-patch:
https://github.com/django/django/commit/072963e4c4d0b3a7a8c5412bc0c7d27d1a9c3521
Signed-off-by: Saravanan <saravanan.kadambathursubramaniyam@windriver.com>
---
.../CVE-2024-27351.patch | 149 ++++++++++++++++++
.../CVE-2024-27351.patch | 145 +++++++++++++++++
.../python/python3-django_2.2.28.bb | 1 +
.../python/python3-django_3.2.23.bb | 1 +
4 files changed, 296 insertions(+)
create mode 100644 meta-python/recipes-devtools/python/python3-django-2.2.28/CVE-2024-27351.patch
create mode 100644 meta-python/recipes-devtools/python/python3-django-3.2.23/CVE-2024-27351.patch
diff --git a/meta-python/recipes-devtools/python/python3-django-2.2.28/CVE-2024-27351.patch b/meta-python/recipes-devtools/python/python3-django-2.2.28/CVE-2024-27351.patch
new file mode 100644
index 0000000000..f240b0852e
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-django-2.2.28/CVE-2024-27351.patch
@@ -0,0 +1,149 @@
+From 072963e4c4d0b3a7a8c5412bc0c7d27d1a9c3521 Mon Sep 17 00:00:00 2001
+From: Shai Berger <shai@platonix.com>
+Date: Mon, 19 Feb 2024 13:56:37 +0100
+Subject: [PATCH] Fixed CVE-2024-27351 -- Prevented potential ReDoS in
+ Truncator.words().
+
+Thanks Seokchan Yoon for the report.
+
+CVE: CVE-2024-27351
+
+Upstream-Status: Backport
+https://github.com/django/django/commit/072963e4c4d0b3a7a8c5412bc0c7d27d1a9c3521
+
+Signed-off-by: Shai Berger <shai@platonix.com>
+Co-Authored-By: Mariusz Felisiak <felisiak.mariusz@gmail.com>
+Signed-off-by: Saravanan <saravanan.kadambathursubramaniyam@windriver.com>
+---
+ django/utils/text.py | 57 ++++++++++++++++++++++++++++++++--
+ docs/releases/2.2.28.txt | 8 +++++
+ tests/utils_tests/test_text.py | 26 ++++++++++++++++
+ 3 files changed, 89 insertions(+), 2 deletions(-)
+
+diff --git a/django/utils/text.py b/django/utils/text.py
+index 06a377b..2c4040e 100644
+--- a/django/utils/text.py
++++ b/django/utils/text.py
+@@ -15,8 +15,61 @@ def capfirst(x):
+ return x and str(x)[0].upper() + str(x)[1:]
+
+
+-# Set up regular expressions
+-re_words = re.compile(r'<[^>]+?>|([^<>\s]+)', re.S)
++# ----- Begin security-related performance workaround -----
++
++# We used to have, below
++#
++# re_words = _lazy_re_compile(r"<[^>]+?>|([^<>\s]+)", re.S)
++#
++# But it was shown that this regex, in the way we use it here, has some
++# catastrophic edge-case performance features. Namely, when it is applied to
++# text with only open brackets "<<<...". The class below provides the services
++# and correct answers for the use cases, but in these edge cases does it much
++# faster.
++re_notag = _lazy_re_compile(r"([^<>\s]+)", re.S)
++re_prt = _lazy_re_compile(r"<|([^<>\s]+)", re.S)
++
++
++class WordsRegex:
++ @staticmethod
++ def search(text, pos):
++ # Look for "<" or a non-tag word.
++ partial = re_prt.search(text, pos)
++ if partial is None or partial[1] is not None:
++ return partial
++
++ # "<" was found, look for a closing ">".
++ end = text.find(">", partial.end(0))
++ if end < 0:
++ # ">" cannot be found, look for a word.
++ return re_notag.search(text, pos + 1)
++ else:
++ # "<" followed by a ">" was found -- fake a match.
++ end += 1
++ return FakeMatch(text[partial.start(0): end], end)
++
++
++class FakeMatch:
++ __slots__ = ["_text", "_end"]
++
++ def end(self, group=0):
++ assert group == 0, "This specific object takes only group=0"
++ return self._end
++
++ def __getitem__(self, group):
++ if group == 1:
++ return None
++ assert group == 0, "This specific object takes only group in {0,1}"
++ return self._text
++
++ def __init__(self, text, end):
++ self._text, self._end = text, end
++
++
++# ----- End security-related performance workaround -----
++
++# Set up regular expressions.
++re_words = WordsRegex
+ re_chars = re.compile(r'<[^>]+?>|(.)', re.S)
+ re_tag = re.compile(r'<(/)?(\S+?)(?:(\s*/)|\s.*?)?>', re.S)
+ re_newlines = re.compile(r'\r\n|\r') # Used in normalize_newlines
+diff --git a/docs/releases/2.2.28.txt b/docs/releases/2.2.28.txt
+index c653cb6..8f79fd0 100644
+--- a/docs/releases/2.2.28.txt
++++ b/docs/releases/2.2.28.txt
+@@ -6,6 +6,14 @@ Django 2.2.28 release notes
+
+ Django 2.2.28 fixes two security issues with severity "high" in 2.2.27.
+
++CVE-2024-27351: Potential regular expression denial-of-service in ``django.utils.text.Truncator.words()``
++=========================================================================================================
++
++``django.utils.text.Truncator.words()`` method (with ``html=True``) and
++:tfilter:`truncatewords_html` template filter were subject to a potential
++regular expression denial-of-service attack using a suitably crafted string
++(follow up to :cve:`2019-14232` and :cve:`2023-43665`).
++
+ CVE-2022-28346: Potential SQL injection in ``QuerySet.annotate()``, ``aggregate()``, and ``extra()``
+ ====================================================================================================
+
+diff --git a/tests/utils_tests/test_text.py b/tests/utils_tests/test_text.py
+index cb3063d..7e9f2b3 100644
+--- a/tests/utils_tests/test_text.py
++++ b/tests/utils_tests/test_text.py
+@@ -156,6 +156,32 @@ class TestUtilsText(SimpleTestCase):
+ truncator = text.Truncator('<p>I <3 python, what about you?</p>')
+ self.assertEqual('<p>I <3 python,…</p>', truncator.words(3, html=True))
+
++ # Only open brackets.
++ test = "<" * 60_000
++ truncator = text.Truncator(test)
++ self.assertEqual(truncator.words(1, html=True), test)
++
++ # Tags with special chars in attrs.
++ truncator = text.Truncator(
++ """<i style="margin: 5%; font: *;">Hello, my dear lady!</i>"""
++ )
++ self.assertEqual(
++ """<i style="margin: 5%; font: *;">Hello, my dear…</i>""",
++ truncator.words(3, html=True),
++ )
++
++ # Tags with special non-latin chars in attrs.
++ truncator = text.Truncator("""<p data-x="א">Hello, my dear lady!</p>""")
++ self.assertEqual(
++ """<p data-x="א">Hello, my dear…</p>""",
++ truncator.words(3, html=True),
++ )
++
++ # Misplaced brackets.
++ truncator = text.Truncator("hello >< world")
++ self.assertEqual(truncator.words(1, html=True), "hello…")
++ self.assertEqual(truncator.words(2, html=True), "hello >< world")
++
+ @patch("django.utils.text.Truncator.MAX_LENGTH_HTML", 10_000)
+ def test_truncate_words_html_size_limit(self):
+ max_len = text.Truncator.MAX_LENGTH_HTML
+--
+2.35.5
+
diff --git a/meta-python/recipes-devtools/python/python3-django-3.2.23/CVE-2024-27351.patch b/meta-python/recipes-devtools/python/python3-django-3.2.23/CVE-2024-27351.patch
new file mode 100644
index 0000000000..1251a41bb5
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-django-3.2.23/CVE-2024-27351.patch
@@ -0,0 +1,145 @@
+From 072963e4c4d0b3a7a8c5412bc0c7d27d1a9c3521 Mon Sep 17 00:00:00 2001
+From: Shai Berger <shai@platonix.com>
+Date: Mon, 19 Feb 2024 13:56:37 +0100
+Subject: [PATCH] Fixed CVE-2024-27351 -- Prevented potential ReDoS in
+ Truncator.words().
+
+Thanks Seokchan Yoon for the report.
+
+CVE: CVE-2024-27351
+
+Upstream-Status: Backport
+https://github.com/django/django/commit/072963e4c4d0b3a7a8c5412bc0c7d27d1a9c3521
+
+Signed-off-by: Shai Berger <shai@platonix.com>
+Co-Authored-By: Mariusz Felisiak <felisiak.mariusz@gmail.com>
+Signed-off-by: Saravanan <saravanan.kadambathursubramaniyam@windriver.com>
+---
+ django/utils/text.py | 57 ++++++++++++++++++++++++++++++++--
+ docs/releases/3.2.23.txt | 8 +++++
+ tests/utils_tests/test_text.py | 26 ++++++++++++++++
+ 3 files changed, 89 insertions(+), 2 deletions(-)
+
+diff --git a/django/utils/text.py b/django/utils/text.py
+index 83e258f..88da9a2 100644
+--- a/django/utils/text.py
++++ b/django/utils/text.py
+@@ -18,8 +18,61 @@ def capfirst(x):
+ return x and str(x)[0].upper() + str(x)[1:]
+
+
+-# Set up regular expressions
+-re_words = _lazy_re_compile(r'<[^>]+?>|([^<>\s]+)', re.S)
++# ----- Begin security-related performance workaround -----
++
++# We used to have, below
++#
++# re_words = _lazy_re_compile(r"<[^>]+?>|([^<>\s]+)", re.S)
++#
++# But it was shown that this regex, in the way we use it here, has some
++# catastrophic edge-case performance features. Namely, when it is applied to
++# text with only open brackets "<<<...". The class below provides the services
++# and correct answers for the use cases, but in these edge cases does it much
++# faster.
++re_notag = _lazy_re_compile(r"([^<>\s]+)", re.S)
++re_prt = _lazy_re_compile(r"<|([^<>\s]+)", re.S)
++
++
++class WordsRegex:
++ @staticmethod
++ def search(text, pos):
++ # Look for "<" or a non-tag word.
++ partial = re_prt.search(text, pos)
++ if partial is None or partial[1] is not None:
++ return partial
++
++ # "<" was found, look for a closing ">".
++ end = text.find(">", partial.end(0))
++ if end < 0:
++ # ">" cannot be found, look for a word.
++ return re_notag.search(text, pos + 1)
++ else:
++ # "<" followed by a ">" was found -- fake a match.
++ end += 1
++ return FakeMatch(text[partial.start(0): end], end)
++
++
++class FakeMatch:
++ __slots__ = ["_text", "_end"]
++
++ def end(self, group=0):
++ assert group == 0, "This specific object takes only group=0"
++ return self._end
++
++ def __getitem__(self, group):
++ if group == 1:
++ return None
++ assert group == 0, "This specific object takes only group in {0,1}"
++ return self._text
++
++ def __init__(self, text, end):
++ self._text, self._end = text, end
++
++
++# ----- End security-related performance workaround -----
++
++# Set up regular expressions.
++re_words = WordsRegex
+ re_chars = _lazy_re_compile(r'<[^>]+?>|(.)', re.S)
+ re_tag = _lazy_re_compile(r'<(/)?(\S+?)(?:(\s*/)|\s.*?)?>', re.S)
+ re_newlines = _lazy_re_compile(r'\r\n|\r') # Used in normalize_newlines
+diff --git a/docs/releases/3.2.23.txt b/docs/releases/3.2.23.txt
+index ba23d11..dd9d68a 100644
+--- a/docs/releases/3.2.23.txt
++++ b/docs/releases/3.2.23.txt
+@@ -17,3 +17,11 @@ 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.
++
++CVE-2024-27351: Potential regular expression denial-of-service in ``django.utils.text.Truncator.words()``
++=========================================================================================================
++
++``django.utils.text.Truncator.words()`` method (with ``html=True``) and
++:tfilter:`truncatewords_html` template filter were subject to a potential
++regular expression denial-of-service attack using a suitably crafted string
++(follow up to :cve:`2019-14232` and :cve:`2023-43665`).
+diff --git a/tests/utils_tests/test_text.py b/tests/utils_tests/test_text.py
+index 0a6f0bc..758919c 100644
+--- a/tests/utils_tests/test_text.py
++++ b/tests/utils_tests/test_text.py
+@@ -159,6 +159,32 @@ class TestUtilsText(SimpleTestCase):
+ truncator = text.Truncator('<p>I <3 python, what about you?</p>')
+ self.assertEqual('<p>I <3 python,…</p>', truncator.words(3, html=True))
+
++ # Only open brackets.
++ test = "<" * 60_000
++ truncator = text.Truncator(test)
++ self.assertEqual(truncator.words(1, html=True), test)
++
++ # Tags with special chars in attrs.
++ truncator = text.Truncator(
++ """<i style="margin: 5%; font: *;">Hello, my dear lady!</i>"""
++ )
++ self.assertEqual(
++ """<i style="margin: 5%; font: *;">Hello, my dear…</i>""",
++ truncator.words(3, html=True),
++ )
++
++ # Tags with special non-latin chars in attrs.
++ truncator = text.Truncator("""<p data-x="א">Hello, my dear lady!</p>""")
++ self.assertEqual(
++ """<p data-x="א">Hello, my dear…</p>""",
++ truncator.words(3, html=True),
++ )
++
++ # Misplaced brackets.
++ truncator = text.Truncator("hello >< world")
++ self.assertEqual(truncator.words(1, html=True), "hello…")
++ self.assertEqual(truncator.words(2, html=True), "hello >< world")
++
+ @patch("django.utils.text.Truncator.MAX_LENGTH_HTML", 10_000)
+ def test_truncate_words_html_size_limit(self):
+ max_len = text.Truncator.MAX_LENGTH_HTML
+--
+2.35.5
diff --git a/meta-python/recipes-devtools/python/python3-django_2.2.28.bb b/meta-python/recipes-devtools/python/python3-django_2.2.28.bb
index 0478fd3883..f394397453 100644
--- a/meta-python/recipes-devtools/python/python3-django_2.2.28.bb
+++ b/meta-python/recipes-devtools/python/python3-django_2.2.28.bb
@@ -24,6 +24,7 @@ SRC_URI += "file://CVE-2023-31047.patch \
file://CVE-2024-45230.patch \
file://CVE-2024-45231.patch \
file://CVE-2024-53907.patch \
+ file://CVE-2024-27351.patch \
"
SRC_URI[sha256sum] = "0200b657afbf1bc08003845ddda053c7641b9b24951e52acd51f6abda33a7413"
diff --git a/meta-python/recipes-devtools/python/python3-django_3.2.23.bb b/meta-python/recipes-devtools/python/python3-django_3.2.23.bb
index beecaa607c..e049b6552c 100644
--- a/meta-python/recipes-devtools/python/python3-django_3.2.23.bb
+++ b/meta-python/recipes-devtools/python/python3-django_3.2.23.bb
@@ -6,6 +6,7 @@ SRC_URI[sha256sum] = "82968f3640e29ef4a773af2c28448f5f7a08d001c6ac05b32d02aeee65
RDEPENDS:${PN} += "\
${PYTHON_PN}-sqlparse \
"
+SRC_URI += "file://CVE-2024-27351.patch"
# Set DEFAULT_PREFERENCE so that the LTS version of django is built by
# default. To build the 3.x branch,
--
2.40.0
^ permalink raw reply related [flat|nested] 4+ messages in thread* Re: [oe][meta-oe][kirkstone][PATCH 1/1] python3-django: fix CVE-2024-27351
2025-11-14 12:03 [oe][meta-oe][kirkstone][PATCH 1/1] python3-django: fix CVE-2024-27351 Saravanan
@ 2025-11-17 8:16 ` Gyorgy Sarvari
2025-11-17 10:09 ` Kadambathur Subramaniyam, Saravanan
0 siblings, 1 reply; 4+ messages in thread
From: Gyorgy Sarvari @ 2025-11-17 8:16 UTC (permalink / raw)
To: saravanan.kadambathursubramaniyam, openembedded-devel
I think for the 3.2.x recipe it could be just updated to 3.2.25, which
contains this patch (and has some other fixes too).
On 11/14/25 13:03, Kadambathur Subramaniyam, Saravanan via
lists.openembedded.org wrote:
> Reference:
> https://nvd.nist.gov/vuln/detail/CVE-2024-27351
>
> Upstream-patch:
> https://github.com/django/django/commit/072963e4c4d0b3a7a8c5412bc0c7d27d1a9c3521
>
> Signed-off-by: Saravanan <saravanan.kadambathursubramaniyam@windriver.com>
> ---
> .../CVE-2024-27351.patch | 149 ++++++++++++++++++
> .../CVE-2024-27351.patch | 145 +++++++++++++++++
> .../python/python3-django_2.2.28.bb | 1 +
> .../python/python3-django_3.2.23.bb | 1 +
> 4 files changed, 296 insertions(+)
> create mode 100644 meta-python/recipes-devtools/python/python3-django-2.2.28/CVE-2024-27351.patch
> create mode 100644 meta-python/recipes-devtools/python/python3-django-3.2.23/CVE-2024-27351.patch
>
> diff --git a/meta-python/recipes-devtools/python/python3-django-2.2.28/CVE-2024-27351.patch b/meta-python/recipes-devtools/python/python3-django-2.2.28/CVE-2024-27351.patch
> new file mode 100644
> index 0000000000..f240b0852e
> --- /dev/null
> +++ b/meta-python/recipes-devtools/python/python3-django-2.2.28/CVE-2024-27351.patch
> @@ -0,0 +1,149 @@
> +From 072963e4c4d0b3a7a8c5412bc0c7d27d1a9c3521 Mon Sep 17 00:00:00 2001
> +From: Shai Berger <shai@platonix.com>
> +Date: Mon, 19 Feb 2024 13:56:37 +0100
> +Subject: [PATCH] Fixed CVE-2024-27351 -- Prevented potential ReDoS in
> + Truncator.words().
> +
> +Thanks Seokchan Yoon for the report.
> +
> +CVE: CVE-2024-27351
> +
> +Upstream-Status: Backport
> +https://github.com/django/django/commit/072963e4c4d0b3a7a8c5412bc0c7d27d1a9c3521
> +
> +Signed-off-by: Shai Berger <shai@platonix.com>
> +Co-Authored-By: Mariusz Felisiak <felisiak.mariusz@gmail.com>
> +Signed-off-by: Saravanan <saravanan.kadambathursubramaniyam@windriver.com>
> +---
> + django/utils/text.py | 57 ++++++++++++++++++++++++++++++++--
> + docs/releases/2.2.28.txt | 8 +++++
> + tests/utils_tests/test_text.py | 26 ++++++++++++++++
> + 3 files changed, 89 insertions(+), 2 deletions(-)
> +
> +diff --git a/django/utils/text.py b/django/utils/text.py
> +index 06a377b..2c4040e 100644
> +--- a/django/utils/text.py
> ++++ b/django/utils/text.py
> +@@ -15,8 +15,61 @@ def capfirst(x):
> + return x and str(x)[0].upper() + str(x)[1:]
> +
> +
> +-# Set up regular expressions
> +-re_words = re.compile(r'<[^>]+?>|([^<>\s]+)', re.S)
> ++# ----- Begin security-related performance workaround -----
> ++
> ++# We used to have, below
> ++#
> ++# re_words = _lazy_re_compile(r"<[^>]+?>|([^<>\s]+)", re.S)
> ++#
> ++# But it was shown that this regex, in the way we use it here, has some
> ++# catastrophic edge-case performance features. Namely, when it is applied to
> ++# text with only open brackets "<<<...". The class below provides the services
> ++# and correct answers for the use cases, but in these edge cases does it much
> ++# faster.
> ++re_notag = _lazy_re_compile(r"([^<>\s]+)", re.S)
> ++re_prt = _lazy_re_compile(r"<|([^<>\s]+)", re.S)
> ++
> ++
> ++class WordsRegex:
> ++ @staticmethod
> ++ def search(text, pos):
> ++ # Look for "<" or a non-tag word.
> ++ partial = re_prt.search(text, pos)
> ++ if partial is None or partial[1] is not None:
> ++ return partial
> ++
> ++ # "<" was found, look for a closing ">".
> ++ end = text.find(">", partial.end(0))
> ++ if end < 0:
> ++ # ">" cannot be found, look for a word.
> ++ return re_notag.search(text, pos + 1)
> ++ else:
> ++ # "<" followed by a ">" was found -- fake a match.
> ++ end += 1
> ++ return FakeMatch(text[partial.start(0): end], end)
> ++
> ++
> ++class FakeMatch:
> ++ __slots__ = ["_text", "_end"]
> ++
> ++ def end(self, group=0):
> ++ assert group == 0, "This specific object takes only group=0"
> ++ return self._end
> ++
> ++ def __getitem__(self, group):
> ++ if group == 1:
> ++ return None
> ++ assert group == 0, "This specific object takes only group in {0,1}"
> ++ return self._text
> ++
> ++ def __init__(self, text, end):
> ++ self._text, self._end = text, end
> ++
> ++
> ++# ----- End security-related performance workaround -----
> ++
> ++# Set up regular expressions.
> ++re_words = WordsRegex
> + re_chars = re.compile(r'<[^>]+?>|(.)', re.S)
> + re_tag = re.compile(r'<(/)?(\S+?)(?:(\s*/)|\s.*?)?>', re.S)
> + re_newlines = re.compile(r'\r\n|\r') # Used in normalize_newlines
> +diff --git a/docs/releases/2.2.28.txt b/docs/releases/2.2.28.txt
> +index c653cb6..8f79fd0 100644
> +--- a/docs/releases/2.2.28.txt
> ++++ b/docs/releases/2.2.28.txt
> +@@ -6,6 +6,14 @@ Django 2.2.28 release notes
> +
> + Django 2.2.28 fixes two security issues with severity "high" in 2.2.27.
> +
> ++CVE-2024-27351: Potential regular expression denial-of-service in ``django.utils.text.Truncator.words()``
> ++=========================================================================================================
> ++
> ++``django.utils.text.Truncator.words()`` method (with ``html=True``) and
> ++:tfilter:`truncatewords_html` template filter were subject to a potential
> ++regular expression denial-of-service attack using a suitably crafted string
> ++(follow up to :cve:`2019-14232` and :cve:`2023-43665`).
> ++
> + CVE-2022-28346: Potential SQL injection in ``QuerySet.annotate()``, ``aggregate()``, and ``extra()``
> + ====================================================================================================
> +
> +diff --git a/tests/utils_tests/test_text.py b/tests/utils_tests/test_text.py
> +index cb3063d..7e9f2b3 100644
> +--- a/tests/utils_tests/test_text.py
> ++++ b/tests/utils_tests/test_text.py
> +@@ -156,6 +156,32 @@ class TestUtilsText(SimpleTestCase):
> + truncator = text.Truncator('<p>I <3 python, what about you?</p>')
> + self.assertEqual('<p>I <3 python,…</p>', truncator.words(3, html=True))
> +
> ++ # Only open brackets.
> ++ test = "<" * 60_000
> ++ truncator = text.Truncator(test)
> ++ self.assertEqual(truncator.words(1, html=True), test)
> ++
> ++ # Tags with special chars in attrs.
> ++ truncator = text.Truncator(
> ++ """<i style="margin: 5%; font: *;">Hello, my dear lady!</i>"""
> ++ )
> ++ self.assertEqual(
> ++ """<i style="margin: 5%; font: *;">Hello, my dear…</i>""",
> ++ truncator.words(3, html=True),
> ++ )
> ++
> ++ # Tags with special non-latin chars in attrs.
> ++ truncator = text.Truncator("""<p data-x="א">Hello, my dear lady!</p>""")
> ++ self.assertEqual(
> ++ """<p data-x="א">Hello, my dear…</p>""",
> ++ truncator.words(3, html=True),
> ++ )
> ++
> ++ # Misplaced brackets.
> ++ truncator = text.Truncator("hello >< world")
> ++ self.assertEqual(truncator.words(1, html=True), "hello…")
> ++ self.assertEqual(truncator.words(2, html=True), "hello >< world")
> ++
> + @patch("django.utils.text.Truncator.MAX_LENGTH_HTML", 10_000)
> + def test_truncate_words_html_size_limit(self):
> + max_len = text.Truncator.MAX_LENGTH_HTML
> +--
> +2.35.5
> +
> diff --git a/meta-python/recipes-devtools/python/python3-django-3.2.23/CVE-2024-27351.patch b/meta-python/recipes-devtools/python/python3-django-3.2.23/CVE-2024-27351.patch
> new file mode 100644
> index 0000000000..1251a41bb5
> --- /dev/null
> +++ b/meta-python/recipes-devtools/python/python3-django-3.2.23/CVE-2024-27351.patch
> @@ -0,0 +1,145 @@
> +From 072963e4c4d0b3a7a8c5412bc0c7d27d1a9c3521 Mon Sep 17 00:00:00 2001
> +From: Shai Berger <shai@platonix.com>
> +Date: Mon, 19 Feb 2024 13:56:37 +0100
> +Subject: [PATCH] Fixed CVE-2024-27351 -- Prevented potential ReDoS in
> + Truncator.words().
> +
> +Thanks Seokchan Yoon for the report.
> +
> +CVE: CVE-2024-27351
> +
> +Upstream-Status: Backport
> +https://github.com/django/django/commit/072963e4c4d0b3a7a8c5412bc0c7d27d1a9c3521
> +
> +Signed-off-by: Shai Berger <shai@platonix.com>
> +Co-Authored-By: Mariusz Felisiak <felisiak.mariusz@gmail.com>
> +Signed-off-by: Saravanan <saravanan.kadambathursubramaniyam@windriver.com>
> +---
> + django/utils/text.py | 57 ++++++++++++++++++++++++++++++++--
> + docs/releases/3.2.23.txt | 8 +++++
> + tests/utils_tests/test_text.py | 26 ++++++++++++++++
> + 3 files changed, 89 insertions(+), 2 deletions(-)
> +
> +diff --git a/django/utils/text.py b/django/utils/text.py
> +index 83e258f..88da9a2 100644
> +--- a/django/utils/text.py
> ++++ b/django/utils/text.py
> +@@ -18,8 +18,61 @@ def capfirst(x):
> + return x and str(x)[0].upper() + str(x)[1:]
> +
> +
> +-# Set up regular expressions
> +-re_words = _lazy_re_compile(r'<[^>]+?>|([^<>\s]+)', re.S)
> ++# ----- Begin security-related performance workaround -----
> ++
> ++# We used to have, below
> ++#
> ++# re_words = _lazy_re_compile(r"<[^>]+?>|([^<>\s]+)", re.S)
> ++#
> ++# But it was shown that this regex, in the way we use it here, has some
> ++# catastrophic edge-case performance features. Namely, when it is applied to
> ++# text with only open brackets "<<<...". The class below provides the services
> ++# and correct answers for the use cases, but in these edge cases does it much
> ++# faster.
> ++re_notag = _lazy_re_compile(r"([^<>\s]+)", re.S)
> ++re_prt = _lazy_re_compile(r"<|([^<>\s]+)", re.S)
> ++
> ++
> ++class WordsRegex:
> ++ @staticmethod
> ++ def search(text, pos):
> ++ # Look for "<" or a non-tag word.
> ++ partial = re_prt.search(text, pos)
> ++ if partial is None or partial[1] is not None:
> ++ return partial
> ++
> ++ # "<" was found, look for a closing ">".
> ++ end = text.find(">", partial.end(0))
> ++ if end < 0:
> ++ # ">" cannot be found, look for a word.
> ++ return re_notag.search(text, pos + 1)
> ++ else:
> ++ # "<" followed by a ">" was found -- fake a match.
> ++ end += 1
> ++ return FakeMatch(text[partial.start(0): end], end)
> ++
> ++
> ++class FakeMatch:
> ++ __slots__ = ["_text", "_end"]
> ++
> ++ def end(self, group=0):
> ++ assert group == 0, "This specific object takes only group=0"
> ++ return self._end
> ++
> ++ def __getitem__(self, group):
> ++ if group == 1:
> ++ return None
> ++ assert group == 0, "This specific object takes only group in {0,1}"
> ++ return self._text
> ++
> ++ def __init__(self, text, end):
> ++ self._text, self._end = text, end
> ++
> ++
> ++# ----- End security-related performance workaround -----
> ++
> ++# Set up regular expressions.
> ++re_words = WordsRegex
> + re_chars = _lazy_re_compile(r'<[^>]+?>|(.)', re.S)
> + re_tag = _lazy_re_compile(r'<(/)?(\S+?)(?:(\s*/)|\s.*?)?>', re.S)
> + re_newlines = _lazy_re_compile(r'\r\n|\r') # Used in normalize_newlines
> +diff --git a/docs/releases/3.2.23.txt b/docs/releases/3.2.23.txt
> +index ba23d11..dd9d68a 100644
> +--- a/docs/releases/3.2.23.txt
> ++++ b/docs/releases/3.2.23.txt
> +@@ -17,3 +17,11 @@ 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.
> ++
> ++CVE-2024-27351: Potential regular expression denial-of-service in ``django.utils.text.Truncator.words()``
> ++=========================================================================================================
> ++
> ++``django.utils.text.Truncator.words()`` method (with ``html=True``) and
> ++:tfilter:`truncatewords_html` template filter were subject to a potential
> ++regular expression denial-of-service attack using a suitably crafted string
> ++(follow up to :cve:`2019-14232` and :cve:`2023-43665`).
> +diff --git a/tests/utils_tests/test_text.py b/tests/utils_tests/test_text.py
> +index 0a6f0bc..758919c 100644
> +--- a/tests/utils_tests/test_text.py
> ++++ b/tests/utils_tests/test_text.py
> +@@ -159,6 +159,32 @@ class TestUtilsText(SimpleTestCase):
> + truncator = text.Truncator('<p>I <3 python, what about you?</p>')
> + self.assertEqual('<p>I <3 python,…</p>', truncator.words(3, html=True))
> +
> ++ # Only open brackets.
> ++ test = "<" * 60_000
> ++ truncator = text.Truncator(test)
> ++ self.assertEqual(truncator.words(1, html=True), test)
> ++
> ++ # Tags with special chars in attrs.
> ++ truncator = text.Truncator(
> ++ """<i style="margin: 5%; font: *;">Hello, my dear lady!</i>"""
> ++ )
> ++ self.assertEqual(
> ++ """<i style="margin: 5%; font: *;">Hello, my dear…</i>""",
> ++ truncator.words(3, html=True),
> ++ )
> ++
> ++ # Tags with special non-latin chars in attrs.
> ++ truncator = text.Truncator("""<p data-x="א">Hello, my dear lady!</p>""")
> ++ self.assertEqual(
> ++ """<p data-x="א">Hello, my dear…</p>""",
> ++ truncator.words(3, html=True),
> ++ )
> ++
> ++ # Misplaced brackets.
> ++ truncator = text.Truncator("hello >< world")
> ++ self.assertEqual(truncator.words(1, html=True), "hello…")
> ++ self.assertEqual(truncator.words(2, html=True), "hello >< world")
> ++
> + @patch("django.utils.text.Truncator.MAX_LENGTH_HTML", 10_000)
> + def test_truncate_words_html_size_limit(self):
> + max_len = text.Truncator.MAX_LENGTH_HTML
> +--
> +2.35.5
> diff --git a/meta-python/recipes-devtools/python/python3-django_2.2.28.bb b/meta-python/recipes-devtools/python/python3-django_2.2.28.bb
> index 0478fd3883..f394397453 100644
> --- a/meta-python/recipes-devtools/python/python3-django_2.2.28.bb
> +++ b/meta-python/recipes-devtools/python/python3-django_2.2.28.bb
> @@ -24,6 +24,7 @@ SRC_URI += "file://CVE-2023-31047.patch \
> file://CVE-2024-45230.patch \
> file://CVE-2024-45231.patch \
> file://CVE-2024-53907.patch \
> + file://CVE-2024-27351.patch \
> "
>
> SRC_URI[sha256sum] = "0200b657afbf1bc08003845ddda053c7641b9b24951e52acd51f6abda33a7413"
> diff --git a/meta-python/recipes-devtools/python/python3-django_3.2.23.bb b/meta-python/recipes-devtools/python/python3-django_3.2.23.bb
> index beecaa607c..e049b6552c 100644
> --- a/meta-python/recipes-devtools/python/python3-django_3.2.23.bb
> +++ b/meta-python/recipes-devtools/python/python3-django_3.2.23.bb
> @@ -6,6 +6,7 @@ SRC_URI[sha256sum] = "82968f3640e29ef4a773af2c28448f5f7a08d001c6ac05b32d02aeee65
> RDEPENDS:${PN} += "\
> ${PYTHON_PN}-sqlparse \
> "
> +SRC_URI += "file://CVE-2024-27351.patch"
>
> # Set DEFAULT_PREFERENCE so that the LTS version of django is built by
> # default. To build the 3.x branch,
>
> -=-=-=-=-=-=-=-=-=-=-=-
> Links: You receive all messages sent to this group.
> View/Reply Online (#121707): https://lists.openembedded.org/g/openembedded-devel/message/121707
> Mute This Topic: https://lists.openembedded.org/mt/116290447/6084445
> Group Owner: openembedded-devel+owner@lists.openembedded.org
> Unsubscribe: https://lists.openembedded.org/g/openembedded-devel/unsub [skandigraun@gmail.com]
> -=-=-=-=-=-=-=-=-=-=-=-
>
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [oe][meta-oe][kirkstone][PATCH 1/1] python3-django: fix CVE-2024-27351
2025-11-17 8:16 ` Gyorgy Sarvari
@ 2025-11-17 10:09 ` Kadambathur Subramaniyam, Saravanan
0 siblings, 0 replies; 4+ messages in thread
From: Kadambathur Subramaniyam, Saravanan @ 2025-11-17 10:09 UTC (permalink / raw)
To: Gyorgy Sarvari, openembedded-devel@lists.openembedded.org
>I think for the 3.2.x recipe it could be just updated to 3.2.25, which
>contains this patch (and has some other fixes too).
Sure, will upgrade to 3.2.25.
On 11/14/25 13:03, Kadambathur Subramaniyam, Saravanan via
lists.openembedded.org wrote:
> Reference:
> https://nvd.nist.gov/vuln/detail/CVE-2024-27351
>
> Upstream-patch:
> https://github.com/django/django/commit/072963e4c4d0b3a7a8c5412bc0c7d27d1a9c3521
>
> Signed-off-by: Saravanan <saravanan.kadambathursubramaniyam@windriver.com>
> ---
> .../CVE-2024-27351.patch | 149 ++++++++++++++++++
> .../CVE-2024-27351.patch | 145 +++++++++++++++++
> .../python/python3-django_2.2.28.bb | 1 +
> .../python/python3-django_3.2.23.bb | 1 +
> 4 files changed, 296 insertions(+)
> create mode 100644 meta-python/recipes-devtools/python/python3-django-2.2.28/CVE-2024-27351.patch
> create mode 100644 meta-python/recipes-devtools/python/python3-django-3.2.23/CVE-2024-27351.patch
>
> diff --git a/meta-python/recipes-devtools/python/python3-django-2.2.28/CVE-2024-27351.patch b/meta-python/recipes-devtools/python/python3-django-2.2.28/CVE-2024-27351.patch
> new file mode 100644
> index 0000000000..f240b0852e
> --- /dev/null
> +++ b/meta-python/recipes-devtools/python/python3-django-2.2.28/CVE-2024-27351.patch
> @@ -0,0 +1,149 @@
> +From 072963e4c4d0b3a7a8c5412bc0c7d27d1a9c3521 Mon Sep 17 00:00:00 2001
> +From: Shai Berger <shai@platonix.com>
> +Date: Mon, 19 Feb 2024 13:56:37 +0100
> +Subject: [PATCH] Fixed CVE-2024-27351 -- Prevented potential ReDoS in
> + Truncator.words().
> +
> +Thanks Seokchan Yoon for the report.
> +
> +CVE: CVE-2024-27351
> +
> +Upstream-Status: Backport
> +https://github.com/django/django/commit/072963e4c4d0b3a7a8c5412bc0c7d27d1a9c3521
> +
> +Signed-off-by: Shai Berger <shai@platonix.com>
> +Co-Authored-By: Mariusz Felisiak <felisiak.mariusz@gmail.com>
> +Signed-off-by: Saravanan <saravanan.kadambathursubramaniyam@windriver.com>
> +---
> + django/utils/text.py | 57 ++++++++++++++++++++++++++++++++--
> + docs/releases/2.2.28.txt | 8 +++++
> + tests/utils_tests/test_text.py | 26 ++++++++++++++++
> + 3 files changed, 89 insertions(+), 2 deletions(-)
> +
> +diff --git a/django/utils/text.py b/django/utils/text.py
> +index 06a377b..2c4040e 100644
> +--- a/django/utils/text.py
> ++++ b/django/utils/text.py
> +@@ -15,8 +15,61 @@ def capfirst(x):
> + return x and str(x)[0].upper() + str(x)[1:]
> +
> +
> +-# Set up regular expressions
> +-re_words = re.compile(r'<[^>]+?>|([^<>\s]+)', re.S)
> ++# ----- Begin security-related performance workaround -----
> ++
> ++# We used to have, below
> ++#
> ++# re_words = _lazy_re_compile(r"<[^>]+?>|([^<>\s]+)", re.S)
> ++#
> ++# But it was shown that this regex, in the way we use it here, has some
> ++# catastrophic edge-case performance features. Namely, when it is applied to
> ++# text with only open brackets "<<<...". The class below provides the services
> ++# and correct answers for the use cases, but in these edge cases does it much
> ++# faster.
> ++re_notag = _lazy_re_compile(r"([^<>\s]+)", re.S)
> ++re_prt = _lazy_re_compile(r"<|([^<>\s]+)", re.S)
> ++
> ++
> ++class WordsRegex:
> ++ @staticmethod
> ++ def search(text, pos):
> ++ # Look for "<" or a non-tag word.
> ++ partial = re_prt.search(text, pos)
> ++ if partial is None or partial[1] is not None:
> ++ return partial
> ++
> ++ # "<" was found, look for a closing ">".
> ++ end = text.find(">", partial.end(0))
> ++ if end < 0:
> ++ # ">" cannot be found, look for a word.
> ++ return re_notag.search(text, pos + 1)
> ++ else:
> ++ # "<" followed by a ">" was found -- fake a match.
> ++ end += 1
> ++ return FakeMatch(text[partial.start(0): end], end)
> ++
> ++
> ++class FakeMatch:
> ++ __slots__ = ["_text", "_end"]
> ++
> ++ def end(self, group=0):
> ++ assert group == 0, "This specific object takes only group=0"
> ++ return self._end
> ++
> ++ def __getitem__(self, group):
> ++ if group == 1:
> ++ return None
> ++ assert group == 0, "This specific object takes only group in {0,1}"
> ++ return self._text
> ++
> ++ def __init__(self, text, end):
> ++ self._text, self._end = text, end
> ++
> ++
> ++# ----- End security-related performance workaround -----
> ++
> ++# Set up regular expressions.
> ++re_words = WordsRegex
> + re_chars = re.compile(r'<[^>]+?>|(.)', re.S)
> + re_tag = re.compile(r'<(/)?(\S+?)(?:(\s*/)|\s.*?)?>', re.S)
> + re_newlines = re.compile(r'\r\n|\r') # Used in normalize_newlines
> +diff --git a/docs/releases/2.2.28.txt b/docs/releases/2.2.28.txt
> +index c653cb6..8f79fd0 100644
> +--- a/docs/releases/2.2.28.txt
> ++++ b/docs/releases/2.2.28.txt
> +@@ -6,6 +6,14 @@ Django 2.2.28 release notes
> +
> + Django 2.2.28 fixes two security issues with severity "high" in 2.2.27.
> +
> ++CVE-2024-27351: Potential regular expression denial-of-service in ``django.utils.text.Truncator.words()``
> ++=========================================================================================================
> ++
> ++``django.utils.text.Truncator.words()`` method (with ``html=True``) and
> ++:tfilter:`truncatewords_html` template filter were subject to a potential
> ++regular expression denial-of-service attack using a suitably crafted string
> ++(follow up to :cve:`2019-14232` and :cve:`2023-43665`).
> ++
> + CVE-2022-28346: Potential SQL injection in ``QuerySet.annotate()``, ``aggregate()``, and ``extra()``
> + ====================================================================================================
> +
> +diff --git a/tests/utils_tests/test_text.py b/tests/utils_tests/test_text.py
> +index cb3063d..7e9f2b3 100644
> +--- a/tests/utils_tests/test_text.py
> ++++ b/tests/utils_tests/test_text.py
> +@@ -156,6 +156,32 @@ class TestUtilsText(SimpleTestCase):
> + truncator = text.Truncator('<p>I <3 python, what about you?</p>')
> + self.assertEqual('<p>I <3 python,…</p>', truncator.words(3, html=True))
> +
> ++ # Only open brackets.
> ++ test = "<" * 60_000
> ++ truncator = text.Truncator(test)
> ++ self.assertEqual(truncator.words(1, html=True), test)
> ++
> ++ # Tags with special chars in attrs.
> ++ truncator = text.Truncator(
> ++ """<i style="margin: 5%; font: *;">Hello, my dear lady!</i>"""
> ++ )
> ++ self.assertEqual(
> ++ """<i style="margin: 5%; font: *;">Hello, my dear…</i>""",
> ++ truncator.words(3, html=True),
> ++ )
> ++
> ++ # Tags with special non-latin chars in attrs.
> ++ truncator = text.Truncator("""<p data-x="א">Hello, my dear lady!</p>""")
> ++ self.assertEqual(
> ++ """<p data-x="א">Hello, my dear…</p>""",
> ++ truncator.words(3, html=True),
> ++ )
> ++
> ++ # Misplaced brackets.
> ++ truncator = text.Truncator("hello >< world")
> ++ self.assertEqual(truncator.words(1, html=True), "hello…")
> ++ self.assertEqual(truncator.words(2, html=True), "hello >< world")
> ++
> + @patch("django.utils.text.Truncator.MAX_LENGTH_HTML", 10_000)
> + def test_truncate_words_html_size_limit(self):
> + max_len = text.Truncator.MAX_LENGTH_HTML
> +--
> +2.35.5
> +
> diff --git a/meta-python/recipes-devtools/python/python3-django-3.2.23/CVE-2024-27351.patch b/meta-python/recipes-devtools/python/python3-django-3.2.23/CVE-2024-27351.patch
> new file mode 100644
> index 0000000000..1251a41bb5
> --- /dev/null
> +++ b/meta-python/recipes-devtools/python/python3-django-3.2.23/CVE-2024-27351.patch
> @@ -0,0 +1,145 @@
> +From 072963e4c4d0b3a7a8c5412bc0c7d27d1a9c3521 Mon Sep 17 00:00:00 2001
> +From: Shai Berger <shai@platonix.com>
> +Date: Mon, 19 Feb 2024 13:56:37 +0100
> +Subject: [PATCH] Fixed CVE-2024-27351 -- Prevented potential ReDoS in
> + Truncator.words().
> +
> +Thanks Seokchan Yoon for the report.
> +
> +CVE: CVE-2024-27351
> +
> +Upstream-Status: Backport
> +https://github.com/django/django/commit/072963e4c4d0b3a7a8c5412bc0c7d27d1a9c3521
> +
> +Signed-off-by: Shai Berger <shai@platonix.com>
> +Co-Authored-By: Mariusz Felisiak <felisiak.mariusz@gmail.com>
> +Signed-off-by: Saravanan <saravanan.kadambathursubramaniyam@windriver.com>
> +---
> + django/utils/text.py | 57 ++++++++++++++++++++++++++++++++--
> + docs/releases/3.2.23.txt | 8 +++++
> + tests/utils_tests/test_text.py | 26 ++++++++++++++++
> + 3 files changed, 89 insertions(+), 2 deletions(-)
> +
> +diff --git a/django/utils/text.py b/django/utils/text.py
> +index 83e258f..88da9a2 100644
> +--- a/django/utils/text.py
> ++++ b/django/utils/text.py
> +@@ -18,8 +18,61 @@ def capfirst(x):
> + return x and str(x)[0].upper() + str(x)[1:]
> +
> +
> +-# Set up regular expressions
> +-re_words = _lazy_re_compile(r'<[^>]+?>|([^<>\s]+)', re.S)
> ++# ----- Begin security-related performance workaround -----
> ++
> ++# We used to have, below
> ++#
> ++# re_words = _lazy_re_compile(r"<[^>]+?>|([^<>\s]+)", re.S)
> ++#
> ++# But it was shown that this regex, in the way we use it here, has some
> ++# catastrophic edge-case performance features. Namely, when it is applied to
> ++# text with only open brackets "<<<...". The class below provides the services
> ++# and correct answers for the use cases, but in these edge cases does it much
> ++# faster.
> ++re_notag = _lazy_re_compile(r"([^<>\s]+)", re.S)
> ++re_prt = _lazy_re_compile(r"<|([^<>\s]+)", re.S)
> ++
> ++
> ++class WordsRegex:
> ++ @staticmethod
> ++ def search(text, pos):
> ++ # Look for "<" or a non-tag word.
> ++ partial = re_prt.search(text, pos)
> ++ if partial is None or partial[1] is not None:
> ++ return partial
> ++
> ++ # "<" was found, look for a closing ">".
> ++ end = text.find(">", partial.end(0))
> ++ if end < 0:
> ++ # ">" cannot be found, look for a word.
> ++ return re_notag.search(text, pos + 1)
> ++ else:
> ++ # "<" followed by a ">" was found -- fake a match.
> ++ end += 1
> ++ return FakeMatch(text[partial.start(0): end], end)
> ++
> ++
> ++class FakeMatch:
> ++ __slots__ = ["_text", "_end"]
> ++
> ++ def end(self, group=0):
> ++ assert group == 0, "This specific object takes only group=0"
> ++ return self._end
> ++
> ++ def __getitem__(self, group):
> ++ if group == 1:
> ++ return None
> ++ assert group == 0, "This specific object takes only group in {0,1}"
> ++ return self._text
> ++
> ++ def __init__(self, text, end):
> ++ self._text, self._end = text, end
> ++
> ++
> ++# ----- End security-related performance workaround -----
> ++
> ++# Set up regular expressions.
> ++re_words = WordsRegex
> + re_chars = _lazy_re_compile(r'<[^>]+?>|(.)', re.S)
> + re_tag = _lazy_re_compile(r'<(/)?(\S+?)(?:(\s*/)|\s.*?)?>', re.S)
> + re_newlines = _lazy_re_compile(r'\r\n|\r') # Used in normalize_newlines
> +diff --git a/docs/releases/3.2.23.txt b/docs/releases/3.2.23.txt
> +index ba23d11..dd9d68a 100644
> +--- a/docs/releases/3.2.23.txt
> ++++ b/docs/releases/3.2.23.txt
> +@@ -17,3 +17,11 @@ 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.
> ++
> ++CVE-2024-27351: Potential regular expression denial-of-service in ``django.utils.text.Truncator.words()``
> ++=========================================================================================================
> ++
> ++``django.utils.text.Truncator.words()`` method (with ``html=True``) and
> ++:tfilter:`truncatewords_html` template filter were subject to a potential
> ++regular expression denial-of-service attack using a suitably crafted string
> ++(follow up to :cve:`2019-14232` and :cve:`2023-43665`).
> +diff --git a/tests/utils_tests/test_text.py b/tests/utils_tests/test_text.py
> +index 0a6f0bc..758919c 100644
> +--- a/tests/utils_tests/test_text.py
> ++++ b/tests/utils_tests/test_text.py
> +@@ -159,6 +159,32 @@ class TestUtilsText(SimpleTestCase):
> + truncator = text.Truncator('<p>I <3 python, what about you?</p>')
> + self.assertEqual('<p>I <3 python,…</p>', truncator.words(3, html=True))
> +
> ++ # Only open brackets.
> ++ test = "<" * 60_000
> ++ truncator = text.Truncator(test)
> ++ self.assertEqual(truncator.words(1, html=True), test)
> ++
> ++ # Tags with special chars in attrs.
> ++ truncator = text.Truncator(
> ++ """<i style="margin: 5%; font: *;">Hello, my dear lady!</i>"""
> ++ )
> ++ self.assertEqual(
> ++ """<i style="margin: 5%; font: *;">Hello, my dear…</i>""",
> ++ truncator.words(3, html=True),
> ++ )
> ++
> ++ # Tags with special non-latin chars in attrs.
> ++ truncator = text.Truncator("""<p data-x="א">Hello, my dear lady!</p>""")
> ++ self.assertEqual(
> ++ """<p data-x="א">Hello, my dear…</p>""",
> ++ truncator.words(3, html=True),
> ++ )
> ++
> ++ # Misplaced brackets.
> ++ truncator = text.Truncator("hello >< world")
> ++ self.assertEqual(truncator.words(1, html=True), "hello…")
> ++ self.assertEqual(truncator.words(2, html=True), "hello >< world")
> ++
> + @patch("django.utils.text.Truncator.MAX_LENGTH_HTML", 10_000)
> + def test_truncate_words_html_size_limit(self):
> + max_len = text.Truncator.MAX_LENGTH_HTML
> +--
> +2.35.5
> diff --git a/meta-python/recipes-devtools/python/python3-django_2.2.28.bb b/meta-python/recipes-devtools/python/python3-django_2.2.28.bb
> index 0478fd3883..f394397453 100644
> --- a/meta-python/recipes-devtools/python/python3-django_2.2.28.bb
> +++ b/meta-python/recipes-devtools/python/python3-django_2.2.28.bb
> @@ -24,6 +24,7 @@ SRC_URI += "file://CVE-2023-31047.patch \
> file://CVE-2024-45230.patch \
> file://CVE-2024-45231.patch \
> file://CVE-2024-53907.patch \
> + file://CVE-2024-27351.patch \
> "
>
> SRC_URI[sha256sum] = "0200b657afbf1bc08003845ddda053c7641b9b24951e52acd51f6abda33a7413"
> diff --git a/meta-python/recipes-devtools/python/python3-django_3.2.23.bb b/meta-python/recipes-devtools/python/python3-django_3.2.23.bb
> index beecaa607c..e049b6552c 100644
> --- a/meta-python/recipes-devtools/python/python3-django_3.2.23.bb
> +++ b/meta-python/recipes-devtools/python/python3-django_3.2.23.bb
> @@ -6,6 +6,7 @@ SRC_URI[sha256sum] = "82968f3640e29ef4a773af2c28448f5f7a08d001c6ac05b32d02aeee65
> RDEPENDS:${PN} += "\
> ${PYTHON_PN}-sqlparse \
> "
> +SRC_URI += "file://CVE-2024-27351.patch"
>
> # Set DEFAULT_PREFERENCE so that the LTS version of django is built by
> # default. To build the 3.x branch,
>
> -=-=-=-=-=-=-=-=-=-=-=-
> Links: You receive all messages sent to this group.
> View/Reply Online (#121707): https://lists.openembedded.org/g/openembedded-devel/message/121707
> Mute This Topic: https://lists.openembedded.org/mt/116290447/6084445
> Group Owner: openembedded-devel+owner@lists.openembedded.org
> Unsubscribe: https://lists.openembedded.org/g/openembedded-devel/unsub [skandigraun@gmail.com]
> -=-=-=-=-=-=-=-=-=-=-=-
>
^ permalink raw reply [flat|nested] 4+ messages in thread
* [oe][meta-oe][kirkstone][PATCH 1/1] python3-django: fix CVE-2024-27351
@ 2025-11-30 11:25 Saravanan
0 siblings, 0 replies; 4+ messages in thread
From: Saravanan @ 2025-11-30 11:25 UTC (permalink / raw)
To: openembedded-devel
Reference:
https://nvd.nist.gov/vuln/detail/CVE-2024-27351
Upstream-patch:
https://github.com/django/django/commit/072963e4c4d0b3a7a8c5412bc0c7d27d1a9c3521
Signed-off-by: Saravanan <saravanan.kadambathursubramaniyam@windriver.com>
---
.../python3-django/CVE-2024-27351.patch | 149 ++++++++++++++++++
.../python/python3-django_2.2.28.bb | 1 +
2 files changed, 150 insertions(+)
create mode 100644 meta-python/recipes-devtools/python/python3-django/CVE-2024-27351.patch
diff --git a/meta-python/recipes-devtools/python/python3-django/CVE-2024-27351.patch b/meta-python/recipes-devtools/python/python3-django/CVE-2024-27351.patch
new file mode 100644
index 0000000000..a341897ebe
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-django/CVE-2024-27351.patch
@@ -0,0 +1,149 @@
+From 072963e4c4d0b3a7a8c5412bc0c7d27d1a9c3521 Mon Sep 17 00:00:00 2001
+From: Shai Berger <shai@platonix.com>
+Date: Mon, 19 Feb 2024 13:56:37 +0100
+Subject: [PATCH] Fixed CVE-2024-27351 -- Prevented potential ReDoS in
+ Truncator.words().
+
+Thanks Seokchan Yoon for the report.
+
+CVE: CVE-2024-27351
+
+Upstream-Status: Backport
+https://github.com/django/django/commit/072963e4c4d0b3a7a8c5412bc0c7d27d1a9c3521
+
+Signed-off-by: Shai Berger <shai@platonix.com>
+Co-Authored-By: Mariusz Felisiak <felisiak.mariusz@gmail.com>
+Signed-off-by: Saravanan <saravanan.kadambathursubramaniyam@windriver.com>
+
+%% original patch: CVE-2024-27351.patch
+---
+ django/utils/text.py | 57 ++++++++++++++++++++++++++++++++--
+ docs/releases/2.2.28.txt | 9 ++++++
+ tests/utils_tests/test_text.py | 26 ++++++++++++++++
+ 3 files changed, 90 insertions(+), 2 deletions(-)
+
+diff --git a/django/utils/text.py b/django/utils/text.py
+index 06a377b..2c4040e 100644
+--- a/django/utils/text.py
++++ b/django/utils/text.py
+@@ -15,8 +15,61 @@ def capfirst(x):
+ return x and str(x)[0].upper() + str(x)[1:]
+
+
+-# Set up regular expressions
+-re_words = re.compile(r'<[^>]+?>|([^<>\s]+)', re.S)
++# ----- Begin security-related performance workaround -----
++
++# We used to have, below
++#
++# re_words = _lazy_re_compile(r"<[^>]+?>|([^<>\s]+)", re.S)
++#
++# But it was shown that this regex, in the way we use it here, has some
++# catastrophic edge-case performance features. Namely, when it is applied to
++# text with only open brackets "<<<...". The class below provides the services
++# and correct answers for the use cases, but in these edge cases does it much
++# faster.
++re_notag = _lazy_re_compile(r"([^<>\s]+)", re.S)
++re_prt = _lazy_re_compile(r"<|([^<>\s]+)", re.S)
++
++
++class WordsRegex:
++ @staticmethod
++ def search(text, pos):
++ # Look for "<" or a non-tag word.
++ partial = re_prt.search(text, pos)
++ if partial is None or partial[1] is not None:
++ return partial
++
++ # "<" was found, look for a closing ">".
++ end = text.find(">", partial.end(0))
++ if end < 0:
++ # ">" cannot be found, look for a word.
++ return re_notag.search(text, pos + 1)
++ else:
++ # "<" followed by a ">" was found -- fake a match.
++ end += 1
++ return FakeMatch(text[partial.start(0): end], end)
++
++
++class FakeMatch:
++ __slots__ = ["_text", "_end"]
++
++ def end(self, group=0):
++ assert group == 0, "This specific object takes only group=0"
++ return self._end
++
++ def __getitem__(self, group):
++ if group == 1:
++ return None
++ assert group == 0, "This specific object takes only group in {0,1}"
++ return self._text
++
++ def __init__(self, text, end):
++ self._text, self._end = text, end
++
++
++# ----- End security-related performance workaround -----
++
++# Set up regular expressions.
++re_words = WordsRegex
+ re_chars = re.compile(r'<[^>]+?>|(.)', re.S)
+ re_tag = re.compile(r'<(/)?(\S+?)(?:(\s*/)|\s.*?)?>', re.S)
+ re_newlines = re.compile(r'\r\n|\r') # Used in normalize_newlines
+diff --git a/docs/releases/2.2.28.txt b/docs/releases/2.2.28.txt
+index c653cb6..7227452 100644
+--- a/docs/releases/2.2.28.txt
++++ b/docs/releases/2.2.28.txt
+@@ -90,3 +90,12 @@ 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.
++
++CVE-2024-27351: Potential regular expression denial-of-service in ``django.utils.text.Truncator.words()``
++=========================================================================================================
++
++``django.utils.text.Truncator.words()`` method (with ``html=True``) and
++:tfilter:`truncatewords_html` template filter were subject to a potential
++regular expression denial-of-service attack using a suitably crafted string
++(follow up to :cve:`2019-14232` and :cve:`2023-43665`).
++
+diff --git a/tests/utils_tests/test_text.py b/tests/utils_tests/test_text.py
+index cb3063d..7e9f2b3 100644
+--- a/tests/utils_tests/test_text.py
++++ b/tests/utils_tests/test_text.py
+@@ -156,6 +156,32 @@ class TestUtilsText(SimpleTestCase):
+ truncator = text.Truncator('<p>I <3 python, what about you?</p>')
+ self.assertEqual('<p>I <3 python,…</p>', truncator.words(3, html=True))
+
++ # Only open brackets.
++ test = "<" * 60_000
++ truncator = text.Truncator(test)
++ self.assertEqual(truncator.words(1, html=True), test)
++
++ # Tags with special chars in attrs.
++ truncator = text.Truncator(
++ """<i style="margin: 5%; font: *;">Hello, my dear lady!</i>"""
++ )
++ self.assertEqual(
++ """<i style="margin: 5%; font: *;">Hello, my dear…</i>""",
++ truncator.words(3, html=True),
++ )
++
++ # Tags with special non-latin chars in attrs.
++ truncator = text.Truncator("""<p data-x="א">Hello, my dear lady!</p>""")
++ self.assertEqual(
++ """<p data-x="א">Hello, my dear…</p>""",
++ truncator.words(3, html=True),
++ )
++
++ # Misplaced brackets.
++ truncator = text.Truncator("hello >< world")
++ self.assertEqual(truncator.words(1, html=True), "hello…")
++ self.assertEqual(truncator.words(2, html=True), "hello >< world")
++
+ @patch("django.utils.text.Truncator.MAX_LENGTH_HTML", 10_000)
+ def test_truncate_words_html_size_limit(self):
+ max_len = text.Truncator.MAX_LENGTH_HTML
+--
+2.40.0
+
diff --git a/meta-python/recipes-devtools/python/python3-django_2.2.28.bb b/meta-python/recipes-devtools/python/python3-django_2.2.28.bb
index 0478fd3883..f394397453 100644
--- a/meta-python/recipes-devtools/python/python3-django_2.2.28.bb
+++ b/meta-python/recipes-devtools/python/python3-django_2.2.28.bb
@@ -24,6 +24,7 @@ SRC_URI += "file://CVE-2023-31047.patch \
file://CVE-2024-45230.patch \
file://CVE-2024-45231.patch \
file://CVE-2024-53907.patch \
+ file://CVE-2024-27351.patch \
"
SRC_URI[sha256sum] = "0200b657afbf1bc08003845ddda053c7641b9b24951e52acd51f6abda33a7413"
--
2.35.5
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2025-11-30 11:25 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-14 12:03 [oe][meta-oe][kirkstone][PATCH 1/1] python3-django: fix CVE-2024-27351 Saravanan
2025-11-17 8:16 ` Gyorgy Sarvari
2025-11-17 10:09 ` Kadambathur Subramaniyam, Saravanan
-- strict thread matches above, loose matches on Subject: below --
2025-11-30 11:25 Saravanan
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.