>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 <[email protected]>
> ---
>  .../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 <[email protected]>
> +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 <[email protected]>
> +Co-Authored-By: Mariusz Felisiak <[email protected]>
> +Signed-off-by: Saravanan <[email protected]>
> +---
> + 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 &lt;3 python, what about you?</p>')
> +         self.assertEqual('<p>I &lt;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 <[email protected]>
> +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 <[email protected]>
> +Co-Authored-By: Mariusz Felisiak <[email protected]>
> +Signed-off-by: Saravanan <[email protected]>
> +---
> + 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 &lt;3 python, what about you?</p>')
> +         self.assertEqual('<p>I &lt;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 (#121776): 
https://lists.openembedded.org/g/openembedded-devel/message/121776
Mute This Topic: https://lists.openembedded.org/mt/116290447/21656
Group Owner: [email protected]
Unsubscribe: https://lists.openembedded.org/g/openembedded-devel/unsub 
[[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-

  • [oe][meta-o... Kadambathur Subramaniyam, Saravanan via lists.openembedded.org
    • Re: [o... Gyorgy Sarvari via lists.openembedded.org
      • Re... Kadambathur Subramaniyam, Saravanan via lists.openembedded.org
    • [oe][m... Kadambathur Subramaniyam, Saravanan via lists.openembedded.org

Reply via email to