Skip to content

Commit 022ab0a

Browse files
sarahboycenessita
authored andcommitted
[5.1.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 6203965 commit 022ab0a

File tree

7 files changed

+46
-9
lines changed

7 files changed

+46
-9
lines changed

django/utils/html.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -428,14 +428,17 @@ def trim_punctuation(self, word):
428428
potential_entity = middle[amp:]
429429
escaped = html.unescape(potential_entity)
430430
if escaped == potential_entity or escaped.endswith(";"):
431-
rstripped = middle.rstrip(";")
432-
amount_stripped = len(middle) - len(rstripped)
433-
if amp > -1 and amount_stripped > 1:
434-
# Leave a trailing semicolon as might be an entity.
435-
trail = middle[len(rstripped) + 1 :] + trail
436-
middle = rstripped + ";"
431+
rstripped = middle.rstrip(self.trailing_punctuation_chars)
432+
trail_start = len(rstripped)
433+
amount_trailing_semicolons = len(middle) - len(middle.rstrip(";"))
434+
if amp > -1 and amount_trailing_semicolons > 1:
435+
# Leave up to most recent semicolon as might be an entity.
436+
recent_semicolon = middle[trail_start:].index(";")
437+
middle_semicolon_index = recent_semicolon + trail_start + 1
438+
trail = middle[middle_semicolon_index:] + trail
439+
middle = rstripped + middle[trail_start:middle_semicolon_index]
437440
else:
438-
trail = middle[len(rstripped) :] + trail
441+
trail = middle[trail_start:] + trail
439442
middle = rstripped
440443
trimmed_something = True
441444

docs/ref/templates/builtins.txt

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

2935+
.. warning::
2936+
2937+
Using ``urlize`` or ``urlizetrunc`` can incur a performance penalty, which
2938+
can become severe when applied to user controlled values such as content
2939+
stored in a :class:`~django.db.models.TextField`. You can use
2940+
:tfilter:`truncatechars` to add a limit to such inputs:
2941+
2942+
.. code-block:: html+django
2943+
2944+
{{ value|truncatechars:500|urlize }}
2945+
29352946
.. templatefilter:: urlizetrunc
29362947

29372948
``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.

docs/releases/5.0.9.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,9 @@ Django 5.0.9 release notes
77
Django 5.0.9 fixes one security issue with severity "moderate" and one security
88
issue with severity "low" in 5.0.8.
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.

docs/releases/5.1.1.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ Django 5.1.1 release notes
77
Django 5.1.1 fixes one security issue with severity "moderate", one security
88
issue with severity "low", and several bugs in 5.1.
99

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.
16+
1017
Bugfixes
1118
========
1219

tests/template_tests/filter_tests/test_urlize.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,11 @@ def test_trailing_semicolon(self):
321321
'<a href="http://example.com?x=" rel="nofollow">'
322322
"http://example.com?x=&amp;</a>;;",
323323
)
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+
)
324329

325330
def test_brackets(self):
326331
"""

tests/utils_tests/test_html.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,7 @@ def test_urlize_unchanged_inputs(self):
375375
"&:" + ";" * 100_000,
376376
"&.;" * 100_000,
377377
".;" * 100_000,
378+
"&" + ";:" * 100_000,
378379
)
379380
for value in tests:
380381
with self.subTest(value=value):

0 commit comments

Comments
 (0)