티스토리 수익 글 보기

티스토리 수익 글 보기

[4.2.x] Fixed CVE-2024-45230 — Mitigated potential DoS in urlize and… · django/django@d147a8e · GitHub
Skip to content

Commit d147a8e

Browse files
sarahboycenessita
authored andcommitted
[4.2.x] Fixed CVE-2024-45230 — Mitigated potential DoS in urlize and urlizetrunc template filters.
Thanks MProgrammer (https://hackerone.com/mprogrammer) for the report.
1 parent 705066d commit d147a8e

File tree

5 files changed

+50
8
lines changed

5 files changed

+50
8
lines changed

django/utils/html.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -395,14 +395,17 @@ def trim_punctuation(self, word):
395395
potential_entity = middle[amp:]
396396
escaped = html.unescape(potential_entity)
397397
if escaped == potential_entity or escaped.endswith(";"):
398-
rstripped = middle.rstrip(";")
399-
amount_stripped = len(middle) - len(rstripped)
400-
if amp > -1 and amount_stripped > 1:
401-
# Leave a trailing semicolon as might be an entity.
402-
trail = middle[len(rstripped) + 1 :] + trail
403-
middle = rstripped + ";"
398+
rstripped = middle.rstrip(self.trailing_punctuation_chars)
399+
trail_start = len(rstripped)
400+
amount_trailing_semicolons = len(middle) - len(middle.rstrip(";"))
401+
if amp > -1 and amount_trailing_semicolons > 1:
402+
# Leave up to most recent semicolon as might be an entity.
403+
recent_semicolon = middle[trail_start:].index(";")
404+
middle_semicolon_index = recent_semicolon + trail_start + 1
405+
trail = middle[middle_semicolon_index:] + trail
406+
middle = rstripped + middle[trail_start:middle_semicolon_index]
404407
else:
405-
trail = middle[len(rstripped) :] + trail
408+
trail = middle[trail_start:] + trail
406409
middle = rstripped
407410
trimmed_something = True
408411

docs/ref/templates/builtins.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2831,6 +2831,17 @@ Django's built-in :tfilter:`escape` filter. The default value for
28312831
email addresses that contain single quotes (``'``), things won't work as
28322832
expected. Apply this filter only to plain text.
28332833

2834+
.. warning::
2835+
2836+
Using ``urlize`` or ``urlizetrunc`` can incur a performance penalty, which
2837+
can become severe when applied to user controlled values such as content
2838+
stored in a :class:`~django.db.models.TextField`. You can use
2839+
:tfilter:`truncatechars` to add a limit to such inputs:
2840+
2841+
.. code-block:: html+django
2842+
2843+
{{ value|truncatechars:500|urlize }}
2844+
28342845
.. templatefilter:: urlizetrunc
28352846

28362847
``urlizetrunc``

docs/releases/4.2.16.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,9 @@ Django 4.2.16 release notes
77
Django 4.2.16 fixes one security issue with severity "moderate" and one
88
security issue with severity "low" in 4.2.15.
99

10-
...
10+
CVE-2024-45230: Potential denial-of-service vulnerability in ``django.utils.html.urlize()``
11+
===========================================================================================
12+
13+
:tfilter:`urlize` and :tfilter:`urlizetrunc` were subject to a potential
14+
denial-of-service attack via very large inputs with a specific sequence of
15+
characters.

tests/template_tests/filter_tests/test_urlize.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,28 @@ def test_trailing_multiple_punctuation(self):
305305
"http://testing.com/example</a>.,:;)&quot;!",
306306
)
307307

308+
def test_trailing_semicolon(self):
309+
self.assertEqual(
310+
urlize("http://example.com?x=&amp;", autoescape=False),
311+
'<a href="http://example.com?x=" rel="nofollow">'
312+
"http://example.com?x=&amp;</a>",
313+
)
314+
self.assertEqual(
315+
urlize("http://example.com?x=&amp;;", autoescape=False),
316+
'<a href="http://example.com?x=" rel="nofollow">'
317+
"http://example.com?x=&amp;</a>;",
318+
)
319+
self.assertEqual(
320+
urlize("http://example.com?x=&amp;;;", autoescape=False),
321+
'<a href="http://example.com?x=" rel="nofollow">'
322+
"http://example.com?x=&amp;</a>;;",
323+
)
324+
self.assertEqual(
325+
urlize("http://example.com?x=&amp.;...;", autoescape=False),
326+
'<a href="http://example.com?x=" rel="nofollow">'
327+
"http://example.com?x=&amp</a>.;...;",
328+
)
329+
308330
def test_brackets(self):
309331
"""
310332
#19070 - Check urlize handles brackets properly

tests/utils_tests/test_html.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,7 @@ def test_urlize_unchanged_inputs(self):
364364
"&:" + ";" * 100_000,
365365
"&.;" * 100_000,
366366
".;" * 100_000,
367+
"&" + ";:" * 100_000,
367368
)
368369
for value in tests:
369370
with self.subTest(value=value):

0 commit comments

Comments
 (0)