A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/django/django/commit/be9c27c4d18c2e6a5be8af4e53c0797440794473 below:

[4.2.x] Fixed CVE-2023-43665 -- Mitigated potential DoS in django.uti… · django/django@be9c27c · GitHub

File tree Expand file treeCollapse file tree 6 files changed

+113

-11

lines changed

Filter options

Expand file treeCollapse file tree 6 files changed

+113

-11

lines changed Original file line number Diff line number Diff line change

@@ -67,8 +67,14 @@ def _generator():

67 67

class Truncator(SimpleLazyObject):

68 68

"""

69 69

An object used to truncate text, either by characters or words.

70 + 71 +

When truncating HTML text (either chars or words), input will be limited to

72 +

at most `MAX_LENGTH_HTML` characters.

70 73

"""

71 74 75 +

# 5 million characters are approximately 4000 text pages or 3 web pages.

76 +

MAX_LENGTH_HTML = 5_000_000

77 + 72 78

def __init__(self, text):

73 79

super().__init__(lambda: str(text))

74 80

@@ -164,6 +170,11 @@ def _truncate_html(self, length, truncate, text, truncate_len, words):

164 170

if words and length <= 0:

165 171

return ""

166 172 173 +

size_limited = False

174 +

if len(text) > self.MAX_LENGTH_HTML:

175 +

text = text[: self.MAX_LENGTH_HTML]

176 +

size_limited = True

177 + 167 178

html4_singlets = (

168 179

"br",

169 180

"col",

@@ -220,10 +231,14 @@ def _truncate_html(self, length, truncate, text, truncate_len, words):

220 231

# Add it to the start of the open tags list

221 232

open_tags.insert(0, tagname)

222 233 234 +

truncate_text = self.add_truncation_text("", truncate)

235 + 223 236

if current_len <= length:

237 +

if size_limited and truncate_text:

238 +

text += truncate_text

224 239

return text

240 + 225 241

out = text[:end_text_pos]

226 -

truncate_text = self.add_truncation_text("", truncate)

227 242

if truncate_text:

228 243

out += truncate_text

229 244

# Close any tags still open

Original file line number Diff line number Diff line change

@@ -2652,6 +2652,16 @@ If ``value`` is ``"<p>Joel is a slug</p>"``, the output will be

2652 2652 2653 2653

Newlines in the HTML content will be preserved.

2654 2654 2655 +

.. admonition:: Size of input string

2656 + 2657 +

Processing large, potentially malformed HTML strings can be

2658 +

resource-intensive and impact service performance. ``truncatechars_html``

2659 +

limits input to the first five million characters.

2660 + 2661 +

.. versionchanged:: 3.2.22

2662 + 2663 +

In older versions, strings over five million characters were processed.

2664 + 2655 2665

.. templatefilter:: truncatewords

2656 2666 2657 2667

``truncatewords``

@@ -2694,6 +2704,16 @@ If ``value`` is ``"<p>Joel is a slug</p>"``, the output will be

2694 2704 2695 2705

Newlines in the HTML content will be preserved.

2696 2706 2707 +

.. admonition:: Size of input string

2708 + 2709 +

Processing large, potentially malformed HTML strings can be

2710 +

resource-intensive and impact service performance. ``truncatewords_html``

2711 +

limits input to the first five million characters.

2712 + 2713 +

.. versionchanged:: 3.2.22

2714 + 2715 +

In older versions, strings over five million characters were processed.

2716 + 2697 2717

.. templatefilter:: unordered_list

2698 2718 2699 2719

``unordered_list``

Original file line number Diff line number Diff line change

@@ -6,4 +6,20 @@ Django 3.2.22 release notes

6 6 7 7

Django 3.2.22 fixes a security issue with severity "moderate" in 3.2.21.

8 8 9 -

...

9 +

CVE-2023-43665: Denial-of-service possibility in ``django.utils.text.Truncator``

10 +

================================================================================

11 + 12 +

Following the fix for :cve:`2019-14232`, the regular expressions used in the

13 +

implementation of ``django.utils.text.Truncator``'s ``chars()`` and ``words()``

14 +

methods (with ``html=True``) were revised and improved. However, these regular

15 +

expressions still exhibited linear backtracking complexity, so when given a

16 +

very long, potentially malformed HTML input, the evaluation would still be

17 +

slow, leading to a potential denial of service vulnerability.

18 + 19 +

The ``chars()`` and ``words()`` methods are used to implement the

20 +

:tfilter:`truncatechars_html` and :tfilter:`truncatewords_html` template

21 +

filters, which were thus also vulnerable.

22 + 23 +

The input processed by ``Truncator``, when operating in HTML mode, has been

24 +

limited to the first five million characters in order to avoid potential

25 +

performance and memory issues.

Original file line number Diff line number Diff line change

@@ -6,4 +6,20 @@ Django 4.1.12 release notes

6 6 7 7

Django 4.1.12 fixes a security issue with severity "moderate" in 4.1.11.

8 8 9 -

...

9 +

CVE-2023-43665: Denial-of-service possibility in ``django.utils.text.Truncator``

10 +

================================================================================

11 + 12 +

Following the fix for :cve:`2019-14232`, the regular expressions used in the

13 +

implementation of ``django.utils.text.Truncator``'s ``chars()`` and ``words()``

14 +

methods (with ``html=True``) were revised and improved. However, these regular

15 +

expressions still exhibited linear backtracking complexity, so when given a

16 +

very long, potentially malformed HTML input, the evaluation would still be

17 +

slow, leading to a potential denial of service vulnerability.

18 + 19 +

The ``chars()`` and ``words()`` methods are used to implement the

20 +

:tfilter:`truncatechars_html` and :tfilter:`truncatewords_html` template

21 +

filters, which were thus also vulnerable.

22 + 23 +

The input processed by ``Truncator``, when operating in HTML mode, has been

24 +

limited to the first five million characters in order to avoid potential

25 +

performance and memory issues.

Original file line number Diff line number Diff line change

@@ -7,6 +7,24 @@ Django 4.2.6 release notes

7 7

Django 4.2.6 fixes a security issue with severity "moderate" and several bugs

8 8

in 4.2.5.

9 9 10 +

CVE-2023-43665: Denial-of-service possibility in ``django.utils.text.Truncator``

11 +

================================================================================

12 + 13 +

Following the fix for :cve:`2019-14232`, the regular expressions used in the

14 +

implementation of ``django.utils.text.Truncator``'s ``chars()`` and ``words()``

15 +

methods (with ``html=True``) were revised and improved. However, these regular

16 +

expressions still exhibited linear backtracking complexity, so when given a

17 +

very long, potentially malformed HTML input, the evaluation would still be

18 +

slow, leading to a potential denial of service vulnerability.

19 + 20 +

The ``chars()`` and ``words()`` methods are used to implement the

21 +

:tfilter:`truncatechars_html` and :tfilter:`truncatewords_html` template

22 +

filters, which were thus also vulnerable.

23 + 24 +

The input processed by ``Truncator``, when operating in HTML mode, has been

25 +

limited to the first five million characters in order to avoid potential

26 +

performance and memory issues.

27 + 10 28

Bugfixes

11 29

========

12 30 Original file line number Diff line number Diff line change

@@ -1,5 +1,6 @@

1 1

import json

2 2

import sys

3 +

from unittest.mock import patch

3 4 4 5

from django.core.exceptions import SuspiciousFileOperation

5 6

from django.test import SimpleTestCase

@@ -94,11 +95,17 @@ def test_truncate_chars(self):

94 95

text.Truncator(lazystr("The quick brown fox")).chars(10), "The quick…"

95 96

)

96 97 97 -

def test_truncate_chars_html(self):

98 +

@patch("django.utils.text.Truncator.MAX_LENGTH_HTML", 10_000)

99 +

def test_truncate_chars_html_size_limit(self):

100 +

max_len = text.Truncator.MAX_LENGTH_HTML

101 +

bigger_len = text.Truncator.MAX_LENGTH_HTML + 1

102 +

valid_html = "<p>Joel is a slug</p>" # 14 chars

98 103

perf_test_values = [

99 -

(("</a" + "\t" * 50000) + "//>", None),

100 -

("&" * 50000, "&" * 9 + "…"),

104 +

("</a" + "\t" * (max_len - 6) + "//>", None),

105 +

("</p" + "\t" * bigger_len + "//>", "</p" + "\t" * 6 + "…"),

106 +

("&" * bigger_len, "&" * 9 + "…"),

101 107

("_X<<<<<<<<<<<>", None),

108 +

(valid_html * bigger_len, "<p>Joel is a…</p>"), # 10 chars

102 109

]

103 110

for value, expected in perf_test_values:

104 111

with self.subTest(value=value):

@@ -176,15 +183,25 @@ def test_truncate_html_words(self):

176 183

truncator = text.Truncator("<p>I &lt;3 python, what about you?</p>")

177 184

self.assertEqual("<p>I &lt;3 python,…</p>", truncator.words(3, html=True))

178 185 186 +

@patch("django.utils.text.Truncator.MAX_LENGTH_HTML", 10_000)

187 +

def test_truncate_words_html_size_limit(self):

188 +

max_len = text.Truncator.MAX_LENGTH_HTML

189 +

bigger_len = text.Truncator.MAX_LENGTH_HTML + 1

190 +

valid_html = "<p>Joel is a slug</p>" # 4 words

179 191

perf_test_values = [

180 -

("</a" + "\t" * 50000) + "//>",

181 -

"&" * 50000,

182 -

"_X<<<<<<<<<<<>",

192 +

("</a" + "\t" * (max_len - 6) + "//>", None),

193 +

("</p" + "\t" * bigger_len + "//>", "</p" + "\t" * (max_len - 3) + "…"),

194 +

("&" * max_len, None), # no change

195 +

("&" * bigger_len, "&" * max_len + "…"),

196 +

("_X<<<<<<<<<<<>", None),

197 +

(valid_html * bigger_len, valid_html * 12 + "<p>Joel is…</p>"), # 50 words

183 198

]

184 -

for value in perf_test_values:

199 +

for value, expected in perf_test_values:

185 200

with self.subTest(value=value):

186 201

truncator = text.Truncator(value)

187 -

self.assertEqual(value, truncator.words(50, html=True))

202 +

self.assertEqual(

203 +

expected if expected else value, truncator.words(50, html=True)

204 +

)

188 205 189 206

def test_wrap(self):

190 207

digits = "1234 67 9"

You can’t perform that action at this time.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4