On 11/17/25 04:14, Kadambathur Subramaniyam, Saravanan via
lists.openembedded.org wrote:
> Reference:
> https://nvd.nist.gov/vuln/detail/CVE-2025-26699
>
> Upstream-patch:
> https://github.com/django/django/commit/e88f7376fe68dbf4ebaf11fad1513ce700b45860
>
> Signed-off-by: Saravanan <[email protected]>
> ---
>  .../CVE-2025-26699.patch                      | 107 ++++++++++++++++++
>  .../CVE-2025-26699.patch                      | 105 +++++++++++++++++
>  .../CVE-2025-26699.patch                      | 107 ++++++++++++++++++
>  .../python/python3-django_2.2.28.bb           |   1 +
>  .../python/python3-django_3.2.23.bb           |   5 +-
>  .../python/python3-django_4.2.17.bb           |   2 +
>  6 files changed, 326 insertions(+), 1 deletion(-)
>  create mode 100644 
> meta-python/recipes-devtools/python/python3-django-2.2.28/CVE-2025-26699.patch
>  create mode 100644 
> meta-python/recipes-devtools/python/python3-django-3.2.23/CVE-2025-26699.patch
>  create mode 100644 
> meta-python/recipes-devtools/python/python3-django-4.2.17/CVE-2025-26699.patch
>
> diff --git 
> a/meta-python/recipes-devtools/python/python3-django-2.2.28/CVE-2025-26699.patch
>  
> b/meta-python/recipes-devtools/python/python3-django-2.2.28/CVE-2025-26699.patch
> new file mode 100644
> index 0000000000..d1c3767069
> --- /dev/null
> +++ 
> b/meta-python/recipes-devtools/python/python3-django-2.2.28/CVE-2025-26699.patch
> @@ -0,0 +1,107 @@
> +From e88f7376fe68dbf4ebaf11fad1513ce700b45860 Mon Sep 17 00:00:00 2001
> +From: Sarah Boyce <[email protected]>
> +Date: Tue, 25 Feb 2025 09:40:54 +0100
> +Subject: [PATCH] Fixed CVE-2025-26699 -- Mitigated potential DoS in wordwrap
> + template filter.
> +
> +Thanks sw0rd1ight for the report.
> +
> +Backport of 55d89e25f4115c5674cdd9b9bcba2bb2bb6d820b from main.
> +
> +CVE: CVE-2025-26699
> +
> +Upstream-Status: Backport
> +https://github.com/django/django/commit/e88f7376fe68dbf4ebaf11fad1513ce700b45860
> +
> +Signed-off-by: Sarah Boyce <[email protected]>

Please do not add other people's sign off without their explicit
permission. If the author didn't include it in the original patch, then
it should go without it. Your sign off is enough.

> +Signed-off-by: Saravanan <[email protected]>
> +---
> + django/utils/text.py                          | 28 ++++++++-----------
> + docs/releases/2.2.28.txt                      |  6 ++++
> + .../filter_tests/test_wordwrap.py             | 12 ++++++++
> + 3 files changed, 29 insertions(+), 17 deletions(-)
> +
> +diff --git a/django/utils/text.py b/django/utils/text.py
> +index 2c4040e..c474d56 100644
> +--- a/django/utils/text.py
> ++++ b/django/utils/text.py
> +@@ -1,5 +1,6 @@
> + import html.entities
> + import re
> ++import textwrap
> + import unicodedata
> + from gzip import GzipFile
> + from io import BytesIO
> +@@ -88,23 +89,16 @@ def wrap(text, width):
> +     Don't wrap long words, thus the output text may have lines longer than
> +     ``width``.
> +     """
> +-    def _generator():
> +-        for line in text.splitlines(True):  # True keeps trailing linebreaks
> +-            max_width = min((line.endswith('\n') and width + 1 or width), 
> width)
> +-            while len(line) > max_width:
> +-                space = line[:max_width + 1].rfind(' ') + 1
> +-                if space == 0:
> +-                    space = line.find(' ') + 1
> +-                    if space == 0:
> +-                        yield line
> +-                        line = ''
> +-                        break
> +-                yield '%s\n' % line[:space - 1]
> +-                line = line[space:]
> +-                max_width = min((line.endswith('\n') and width + 1 or 
> width), width)
> +-            if line:
> +-                yield line
> +-    return ''.join(_generator())
> ++
> ++    wrapper = textwrap.TextWrapper(
> ++        width=width,
> ++        break_long_words=False,
> ++        break_on_hyphens=False,
> ++    )
> ++    result = []
> ++    for line in text.splitlines(True):
> ++        result.extend(wrapper.wrap(line))
> ++    return "\n".join(result)
> +
> +
> + class Truncator(SimpleLazyObject):
> +diff --git a/docs/releases/2.2.28.txt b/docs/releases/2.2.28.txt
> +index 8f79fd0..63877eb 100644
> +--- a/docs/releases/2.2.28.txt
> ++++ b/docs/releases/2.2.28.txt
> +@@ -6,6 +6,12 @@ Django 2.2.28 release notes
> +
> + Django 2.2.28 fixes two security issues with severity "high" in 2.2.27.
> +
> ++CVE-2025-26699: Potential denial-of-service vulnerability in 
> ``django.utils.text.wrap()``
> ++=========================================================================================
> ++
> ++The ``wrap()`` and :tfilter:`wordwrap` template filter were subject to a
> ++potential denial-of-service attack when used with very long strings.
> ++
> + CVE-2024-27351: Potential regular expression denial-of-service in 
> ``django.utils.text.Truncator.words()``
> + 
> =========================================================================================================
> +
> +diff --git a/tests/template_tests/filter_tests/test_wordwrap.py 
> b/tests/template_tests/filter_tests/test_wordwrap.py
> +index 02f8605..c1c1fe9 100644
> +--- a/tests/template_tests/filter_tests/test_wordwrap.py
> ++++ b/tests/template_tests/filter_tests/test_wordwrap.py
> +@@ -51,3 +51,15 @@ class FunctionTests(SimpleTestCase):
> +             ), 14),
> +             'this is a long\nparagraph of\ntext that\nreally needs\nto be 
> wrapped\nI\'m afraid',
> +         )
> ++
> ++    def test_wrap_long_text(self):
> ++        long_text = (
> ++            "this is a long paragraph of text that really needs"
> ++            " to be wrapped I'm afraid " * 20_000
> ++        )
> ++        self.assertIn(
> ++            "this is a\nlong\nparagraph\nof text\nthat\nreally\nneeds 
> to\nbe wrapped\n"
> ++            "I'm afraid",
> ++            wordwrap(long_text, 10),
> ++        )
> ++
> +--
> +2.35.5
> diff --git 
> a/meta-python/recipes-devtools/python/python3-django-3.2.23/CVE-2025-26699.patch
>  
> b/meta-python/recipes-devtools/python/python3-django-3.2.23/CVE-2025-26699.patch
> new file mode 100644
> index 0000000000..e9552bbfbc
> --- /dev/null
> +++ 
> b/meta-python/recipes-devtools/python/python3-django-3.2.23/CVE-2025-26699.patch
> @@ -0,0 +1,105 @@
> +From e88f7376fe68dbf4ebaf11fad1513ce700b45860 Mon Sep 17 00:00:00 2001
> +From: Sarah Boyce <[email protected]>
> +Date: Tue, 25 Feb 2025 09:40:54 +0100
> +Subject: [PATCH] Fixed CVE-2025-26699 -- Mitigated potential DoS in wordwrap
> + template filter.
> +
> +Thanks sw0rd1ight for the report.
> +
> +Backport of 55d89e25f4115c5674cdd9b9bcba2bb2bb6d820b from main.
> +
> +CVE: CVE-2025-26699
> +
> +Upstream-Status: Backport
> +https://github.com/django/django/commit/e88f7376fe68dbf4ebaf11fad1513ce700b45860
> +
> +Signed-off-by: Sarah Boyce <[email protected]>
> +Signed-off-by: Saravanan <[email protected]>
> +---
> + django/utils/text.py                          | 27 +++++++------------
> + docs/releases/3.2.23.txt                      |  7 +++++
> + .../filter_tests/test_wordwrap.py             | 12 +++++++++
> + 3 files changed, 29 insertions(+), 17 deletions(-)
> +
> +diff --git a/django/utils/text.py b/django/utils/text.py
> +index 88da9a2..cabd76f 100644
> +--- a/django/utils/text.py
> ++++ b/django/utils/text.py
> +@@ -1,5 +1,6 @@
> + import html.entities
> + import re
> ++import textwrap
> + import unicodedata
> + import warnings
> + from gzip import GzipFile
> +@@ -91,23 +92,15 @@ def wrap(text, width):
> +     Don't wrap long words, thus the output text may have lines longer than
> +     ``width``.
> +     """
> +-    def _generator():
> +-        for line in text.splitlines(True):  # True keeps trailing linebreaks
> +-            max_width = min((line.endswith('\n') and width + 1 or width), 
> width)
> +-            while len(line) > max_width:
> +-                space = line[:max_width + 1].rfind(' ') + 1
> +-                if space == 0:
> +-                    space = line.find(' ') + 1
> +-                    if space == 0:
> +-                        yield line
> +-                        line = ''
> +-                        break
> +-                yield '%s\n' % line[:space - 1]
> +-                line = line[space:]
> +-                max_width = min((line.endswith('\n') and width + 1 or 
> width), width)
> +-            if line:
> +-                yield line
> +-    return ''.join(_generator())
> ++    wrapper = textwrap.TextWrapper(
> ++        width=width,
> ++        break_long_words=False,
> ++        break_on_hyphens=False,
> ++    )
> ++    result = []
> ++    for line in text.splitlines(True):
> ++        result.extend(wrapper.wrap(line))
> ++    return "\n".join(result)
> + 
> + 
> + class Truncator(SimpleLazyObject):
> +diff --git a/docs/releases/3.2.23.txt b/docs/releases/3.2.23.txt
> +index dd9d68a..da75eca 100644
> +--- a/docs/releases/3.2.23.txt
> ++++ b/docs/releases/3.2.23.txt
> +@@ -25,3 +25,10 @@ CVE-2024-27351: Potential regular expression 
> denial-of-service in ``django.utils
> + :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-2025-26699: Potential denial-of-service vulnerability in 
> ``django.utils.text.wrap()``
> ++=========================================================================================
> ++
> ++The ``wrap()`` and :tfilter:`wordwrap` template filter were subject to a
> ++potential denial-of-service attack when used with very long strings.
> ++
> +diff --git a/tests/template_tests/filter_tests/test_wordwrap.py 
> b/tests/template_tests/filter_tests/test_wordwrap.py
> +index 02f8605..e6f2afb 100644
> +--- a/tests/template_tests/filter_tests/test_wordwrap.py
> ++++ b/tests/template_tests/filter_tests/test_wordwrap.py
> +@@ -51,3 +51,15 @@ class FunctionTests(SimpleTestCase):
> +             ), 14),
> +             'this is a long\nparagraph of\ntext that\nreally needs\nto be 
> wrapped\nI\'m afraid',
> +         )
> ++
> ++    def test_wrap_long_text(self):
> ++        long_text = (
> ++            "this is a long paragraph of text that really needs"
> ++            " to be wrapped I'm afraid " * 20_000
> ++        )
> ++        self.assertIn(
> ++            "this is a\nlong\nparagraph\nof text\nthat\nreally\nneeds 
> to\nbe wrapped\n"
> ++            "I'm afraid",
> ++            wordwrap(long_text, 10),
> ++        )
> ++
> +-- 
> +2.35.5
> +
> diff --git 
> a/meta-python/recipes-devtools/python/python3-django-4.2.17/CVE-2025-26699.patch
>  
> b/meta-python/recipes-devtools/python/python3-django-4.2.17/CVE-2025-26699.patch
> new file mode 100644
> index 0000000000..6a4e32bd27
> --- /dev/null
> +++ 
> b/meta-python/recipes-devtools/python/python3-django-4.2.17/CVE-2025-26699.patch
> @@ -0,0 +1,107 @@
> +From e88f7376fe68dbf4ebaf11fad1513ce700b45860 Mon Sep 17 00:00:00 2001
> +From: Sarah Boyce <[email protected]>
> +Date: Tue, 25 Feb 2025 09:40:54 +0100
> +Subject: [PATCH] Fixed CVE-2025-26699 -- Mitigated potential DoS in wordwrap
> + template filter.
> +
> +Thanks sw0rd1ight for the report.
> +
> +Backport of 55d89e25f4115c5674cdd9b9bcba2bb2bb6d820b from main.
> +
> +CVE: CVE-2025-26699
> +
> +Upstream-Status: Backport
> +https://github.com/django/django/commit/e88f7376fe68dbf4ebaf11fad1513ce700b45860
> +
> +Signed-off-by: Sarah Boyce <[email protected]>
> +Signed-off-by: Saravanan <[email protected]>
> +---
> + django/utils/text.py                          | 28 +++++++------------
> + docs/releases/4.2.17.txt                      |  8 ++++++
> + .../filter_tests/test_wordwrap.py             | 11 ++++++++
> + 3 files changed, 29 insertions(+), 18 deletions(-)
> +
> +diff --git a/django/utils/text.py b/django/utils/text.py
> +index e1b835e..81ae88d 100644
> +--- a/django/utils/text.py
> ++++ b/django/utils/text.py
> +@@ -1,6 +1,7 @@
> + import gzip
> + import re
> + import secrets
> ++import textwrap
> + import unicodedata
> + from gzip import GzipFile
> + from gzip import compress as gzip_compress
> +@@ -97,24 +98,15 @@ def wrap(text, width):
> +     ``width``.
> +     """
> + 
> +-    def _generator():
> +-        for line in text.splitlines(True):  # True keeps trailing linebreaks
> +-            max_width = min((line.endswith("\n") and width + 1 or width), 
> width)
> +-            while len(line) > max_width:
> +-                space = line[: max_width + 1].rfind(" ") + 1
> +-                if space == 0:
> +-                    space = line.find(" ") + 1
> +-                    if space == 0:
> +-                        yield line
> +-                        line = ""
> +-                        break
> +-                yield "%s\n" % line[: space - 1]
> +-                line = line[space:]
> +-                max_width = min((line.endswith("\n") and width + 1 or 
> width), width)
> +-            if line:
> +-                yield line
> +-
> +-    return "".join(_generator())
> ++    wrapper = textwrap.TextWrapper(
> ++        width=width,
> ++        break_long_words=False,
> ++        break_on_hyphens=False,
> ++    )
> ++    result = []
> ++    for line in text.splitlines(True):
> ++        result.extend(wrapper.wrap(line))
> ++    return "\n".join(result)
> + 
> + 
> + class Truncator(SimpleLazyObject):
> +diff --git a/docs/releases/4.2.17.txt b/docs/releases/4.2.17.txt
> +index 9a6aee3..0475a96 100644
> +--- a/docs/releases/4.2.17.txt
> ++++ b/docs/releases/4.2.17.txt
> +@@ -31,3 +31,11 @@ was subject to SQL injection if untrusted data was used 
> as a ``lhs`` value.
> + 
> + Applications that use the :lookup:`has_key <jsonfield.has_key>` lookup 
> through
> + the ``__`` syntax are unaffected.
> ++
> ++
> ++CVE-2025-26699: Potential denial-of-service vulnerability in 
> ``django.utils.text.wrap()``
> ++=========================================================================================
> ++
> ++The ``wrap()`` and :tfilter:`wordwrap` template filter were subject to a
> ++potential denial-of-service attack when used with very long strings.
> ++
> +diff --git a/tests/template_tests/filter_tests/test_wordwrap.py 
> b/tests/template_tests/filter_tests/test_wordwrap.py
> +index 88fbd27..4afa1dd 100644
> +--- a/tests/template_tests/filter_tests/test_wordwrap.py
> ++++ b/tests/template_tests/filter_tests/test_wordwrap.py
> +@@ -78,3 +78,14 @@ class FunctionTests(SimpleTestCase):
> +             "this is a long\nparagraph of\ntext that\nreally needs\nto be 
> wrapped\n"
> +             "I'm afraid",
> +         )
> ++
> ++    def test_wrap_long_text(self):
> ++        long_text = (
> ++            "this is a long paragraph of text that really needs"
> ++            " to be wrapped I'm afraid " * 20_000
> ++        )
> ++        self.assertIn(
> ++            "this is a\nlong\nparagraph\nof text\nthat\nreally\nneeds 
> to\nbe wrapped\n"
> ++            "I'm afraid",
> ++            wordwrap(long_text, 10),
> ++        )
> +-- 
> +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 f394397453..24eee95f03 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
> @@ -25,6 +25,7 @@ SRC_URI += "file://CVE-2023-31047.patch \
>              file://CVE-2024-45231.patch \
>              file://CVE-2024-53907.patch \
>              file://CVE-2024-27351.patch \
> +            file://CVE-2025-26699.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 e049b6552c..92a3886cbc 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,7 +6,10 @@ SRC_URI[sha256sum] = 
> "82968f3640e29ef4a773af2c28448f5f7a08d001c6ac05b32d02aeee65
>  RDEPENDS:${PN} += "\
>      ${PYTHON_PN}-sqlparse \
>  "
> -SRC_URI += "file://CVE-2024-27351.patch"
> +SRC_URI += "\
> +     file://CVE-2024-27351.patch \
> +     file://CVE-2025-26699.patch \
> +"
>  
>  # Set DEFAULT_PREFERENCE so that the LTS version of django is built by
>  # default. To build the 3.x branch, 
> diff --git a/meta-python/recipes-devtools/python/python3-django_4.2.17.bb 
> b/meta-python/recipes-devtools/python/python3-django_4.2.17.bb
> index dfce4b85c2..c2b517a441 100644
> --- a/meta-python/recipes-devtools/python/python3-django_4.2.17.bb
> +++ b/meta-python/recipes-devtools/python/python3-django_4.2.17.bb
> @@ -7,6 +7,8 @@ RDEPENDS:${PN} += "\
>      ${PYTHON_PN}-sqlparse \
>  "
>  
> +SRC_URI += "file://CVE-2025-26699.patch"
> +
>  # Set DEFAULT_PREFERENCE so that the LTS version of django is built by
>  # default. To build the 4.x branch, 
>  # PREFERRED_VERSION_python3-django = "4.2.17" can be added to local.conf
>
> 
>

-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#121756): 
https://lists.openembedded.org/g/openembedded-devel/message/121756
Mute This Topic: https://lists.openembedded.org/mt/116332353/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
    • [oe][m... Kadambathur Subramaniyam, Saravanan via lists.openembedded.org

Reply via email to