diff options
| author | Saravanan <saravanan.kadambathursubramaniyam@windriver.com> | 2025-11-30 16:55:22 +0530 |
|---|---|---|
| committer | Gyorgy Sarvari <skandigraun@gmail.com> | 2025-11-30 15:16:29 +0100 |
| commit | 666ec505b4a90a1c02d1d9205a9c6840b9adf528 (patch) | |
| tree | fbf36a8188e06ba7b712b1b3d1c092a5794092c1 /meta-python/recipes-devtools/python | |
| parent | d4a5c4cf6ca9e91770f840006398573b45f50d05 (diff) | |
| download | meta-openembedded-666ec505b4a90a1c02d1d9205a9c6840b9adf528.tar.gz | |
python3-django: fix CVE-2024-27351
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>
Signed-off-by: Gyorgy Sarvari <skandigraun@gmail.com>
Diffstat (limited to 'meta-python/recipes-devtools/python')
| -rw-r--r-- | meta-python/recipes-devtools/python/python3-django/CVE-2024-27351.patch | 149 | ||||
| -rw-r--r-- | meta-python/recipes-devtools/python/python3-django_2.2.28.bb | 1 |
2 files changed, 150 insertions, 0 deletions
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 @@ | |||
| 1 | From 072963e4c4d0b3a7a8c5412bc0c7d27d1a9c3521 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Shai Berger <shai@platonix.com> | ||
| 3 | Date: Mon, 19 Feb 2024 13:56:37 +0100 | ||
| 4 | Subject: [PATCH] Fixed CVE-2024-27351 -- Prevented potential ReDoS in | ||
| 5 | Truncator.words(). | ||
| 6 | |||
| 7 | Thanks Seokchan Yoon for the report. | ||
| 8 | |||
| 9 | CVE: CVE-2024-27351 | ||
| 10 | |||
| 11 | Upstream-Status: Backport | ||
| 12 | https://github.com/django/django/commit/072963e4c4d0b3a7a8c5412bc0c7d27d1a9c3521 | ||
| 13 | |||
| 14 | Signed-off-by: Shai Berger <shai@platonix.com> | ||
| 15 | Co-Authored-By: Mariusz Felisiak <felisiak.mariusz@gmail.com> | ||
| 16 | Signed-off-by: Saravanan <saravanan.kadambathursubramaniyam@windriver.com> | ||
| 17 | |||
| 18 | %% original patch: CVE-2024-27351.patch | ||
| 19 | --- | ||
| 20 | django/utils/text.py | 57 ++++++++++++++++++++++++++++++++-- | ||
| 21 | docs/releases/2.2.28.txt | 9 ++++++ | ||
| 22 | tests/utils_tests/test_text.py | 26 ++++++++++++++++ | ||
| 23 | 3 files changed, 90 insertions(+), 2 deletions(-) | ||
| 24 | |||
| 25 | diff --git a/django/utils/text.py b/django/utils/text.py | ||
| 26 | index 06a377b..2c4040e 100644 | ||
| 27 | --- a/django/utils/text.py | ||
| 28 | +++ b/django/utils/text.py | ||
| 29 | @@ -15,8 +15,61 @@ def capfirst(x): | ||
| 30 | return x and str(x)[0].upper() + str(x)[1:] | ||
| 31 | |||
| 32 | |||
| 33 | -# Set up regular expressions | ||
| 34 | -re_words = re.compile(r'<[^>]+?>|([^<>\s]+)', re.S) | ||
| 35 | +# ----- Begin security-related performance workaround ----- | ||
| 36 | + | ||
| 37 | +# We used to have, below | ||
| 38 | +# | ||
| 39 | +# re_words = _lazy_re_compile(r"<[^>]+?>|([^<>\s]+)", re.S) | ||
| 40 | +# | ||
| 41 | +# But it was shown that this regex, in the way we use it here, has some | ||
| 42 | +# catastrophic edge-case performance features. Namely, when it is applied to | ||
| 43 | +# text with only open brackets "<<<...". The class below provides the services | ||
| 44 | +# and correct answers for the use cases, but in these edge cases does it much | ||
| 45 | +# faster. | ||
| 46 | +re_notag = _lazy_re_compile(r"([^<>\s]+)", re.S) | ||
| 47 | +re_prt = _lazy_re_compile(r"<|([^<>\s]+)", re.S) | ||
| 48 | + | ||
| 49 | + | ||
| 50 | +class WordsRegex: | ||
| 51 | + @staticmethod | ||
| 52 | + def search(text, pos): | ||
| 53 | + # Look for "<" or a non-tag word. | ||
| 54 | + partial = re_prt.search(text, pos) | ||
| 55 | + if partial is None or partial[1] is not None: | ||
| 56 | + return partial | ||
| 57 | + | ||
| 58 | + # "<" was found, look for a closing ">". | ||
| 59 | + end = text.find(">", partial.end(0)) | ||
| 60 | + if end < 0: | ||
| 61 | + # ">" cannot be found, look for a word. | ||
| 62 | + return re_notag.search(text, pos + 1) | ||
| 63 | + else: | ||
| 64 | + # "<" followed by a ">" was found -- fake a match. | ||
| 65 | + end += 1 | ||
| 66 | + return FakeMatch(text[partial.start(0): end], end) | ||
| 67 | + | ||
| 68 | + | ||
| 69 | +class FakeMatch: | ||
| 70 | + __slots__ = ["_text", "_end"] | ||
| 71 | + | ||
| 72 | + def end(self, group=0): | ||
| 73 | + assert group == 0, "This specific object takes only group=0" | ||
| 74 | + return self._end | ||
| 75 | + | ||
| 76 | + def __getitem__(self, group): | ||
| 77 | + if group == 1: | ||
| 78 | + return None | ||
| 79 | + assert group == 0, "This specific object takes only group in {0,1}" | ||
| 80 | + return self._text | ||
| 81 | + | ||
| 82 | + def __init__(self, text, end): | ||
| 83 | + self._text, self._end = text, end | ||
| 84 | + | ||
| 85 | + | ||
| 86 | +# ----- End security-related performance workaround ----- | ||
| 87 | + | ||
| 88 | +# Set up regular expressions. | ||
| 89 | +re_words = WordsRegex | ||
| 90 | re_chars = re.compile(r'<[^>]+?>|(.)', re.S) | ||
| 91 | re_tag = re.compile(r'<(/)?(\S+?)(?:(\s*/)|\s.*?)?>', re.S) | ||
| 92 | re_newlines = re.compile(r'\r\n|\r') # Used in normalize_newlines | ||
| 93 | diff --git a/docs/releases/2.2.28.txt b/docs/releases/2.2.28.txt | ||
| 94 | index c653cb6..7227452 100644 | ||
| 95 | --- a/docs/releases/2.2.28.txt | ||
| 96 | +++ b/docs/releases/2.2.28.txt | ||
| 97 | @@ -90,3 +90,12 @@ large number of Unicode characters. | ||
| 98 | In order to avoid the vulnerability, invalid values longer than | ||
| 99 | ``UsernameField.max_length`` are no longer normalized, since they cannot pass | ||
| 100 | validation anyway. | ||
| 101 | + | ||
| 102 | +CVE-2024-27351: Potential regular expression denial-of-service in ``django.utils.text.Truncator.words()`` | ||
| 103 | +========================================================================================================= | ||
| 104 | + | ||
| 105 | +``django.utils.text.Truncator.words()`` method (with ``html=True``) and | ||
| 106 | +:tfilter:`truncatewords_html` template filter were subject to a potential | ||
| 107 | +regular expression denial-of-service attack using a suitably crafted string | ||
| 108 | +(follow up to :cve:`2019-14232` and :cve:`2023-43665`). | ||
| 109 | + | ||
| 110 | diff --git a/tests/utils_tests/test_text.py b/tests/utils_tests/test_text.py | ||
| 111 | index cb3063d..7e9f2b3 100644 | ||
| 112 | --- a/tests/utils_tests/test_text.py | ||
| 113 | +++ b/tests/utils_tests/test_text.py | ||
| 114 | @@ -156,6 +156,32 @@ class TestUtilsText(SimpleTestCase): | ||
| 115 | truncator = text.Truncator('<p>I <3 python, what about you?</p>') | ||
| 116 | self.assertEqual('<p>I <3 python,…</p>', truncator.words(3, html=True)) | ||
| 117 | |||
| 118 | + # Only open brackets. | ||
| 119 | + test = "<" * 60_000 | ||
| 120 | + truncator = text.Truncator(test) | ||
| 121 | + self.assertEqual(truncator.words(1, html=True), test) | ||
| 122 | + | ||
| 123 | + # Tags with special chars in attrs. | ||
| 124 | + truncator = text.Truncator( | ||
| 125 | + """<i style="margin: 5%; font: *;">Hello, my dear lady!</i>""" | ||
| 126 | + ) | ||
| 127 | + self.assertEqual( | ||
| 128 | + """<i style="margin: 5%; font: *;">Hello, my dear…</i>""", | ||
| 129 | + truncator.words(3, html=True), | ||
| 130 | + ) | ||
| 131 | + | ||
| 132 | + # Tags with special non-latin chars in attrs. | ||
| 133 | + truncator = text.Truncator("""<p data-x="א">Hello, my dear lady!</p>""") | ||
| 134 | + self.assertEqual( | ||
| 135 | + """<p data-x="א">Hello, my dear…</p>""", | ||
| 136 | + truncator.words(3, html=True), | ||
| 137 | + ) | ||
| 138 | + | ||
| 139 | + # Misplaced brackets. | ||
| 140 | + truncator = text.Truncator("hello >< world") | ||
| 141 | + self.assertEqual(truncator.words(1, html=True), "hello…") | ||
| 142 | + self.assertEqual(truncator.words(2, html=True), "hello >< world") | ||
| 143 | + | ||
| 144 | @patch("django.utils.text.Truncator.MAX_LENGTH_HTML", 10_000) | ||
| 145 | def test_truncate_words_html_size_limit(self): | ||
| 146 | max_len = text.Truncator.MAX_LENGTH_HTML | ||
| 147 | -- | ||
| 148 | 2.40.0 | ||
| 149 | |||
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 \ | |||
| 24 | file://CVE-2024-45230.patch \ | 24 | file://CVE-2024-45230.patch \ |
| 25 | file://CVE-2024-45231.patch \ | 25 | file://CVE-2024-45231.patch \ |
| 26 | file://CVE-2024-53907.patch \ | 26 | file://CVE-2024-53907.patch \ |
| 27 | file://CVE-2024-27351.patch \ | ||
| 27 | " | 28 | " |
| 28 | 29 | ||
| 29 | SRC_URI[sha256sum] = "0200b657afbf1bc08003845ddda053c7641b9b24951e52acd51f6abda33a7413" | 30 | SRC_URI[sha256sum] = "0200b657afbf1bc08003845ddda053c7641b9b24951e52acd51f6abda33a7413" |
