Fixed CVE-2024-45230 -- Mitigated potential DoS in urlize and urlizetrunc template filters.

Thanks MProgrammer (https://hackerone.com/mprogrammer) for the report.
This commit is contained in:
Sarah Boyce 2024-08-12 15:17:57 +02:00 committed by Natalia
parent f5ddd54986
commit 320dd27412
7 changed files with 46 additions and 9 deletions

View File

@ -434,14 +434,17 @@ class Urlizer:
potential_entity = middle[amp:] potential_entity = middle[amp:]
escaped = html.unescape(potential_entity) escaped = html.unescape(potential_entity)
if escaped == potential_entity or escaped.endswith(";"): if escaped == potential_entity or escaped.endswith(";"):
rstripped = middle.rstrip(";") rstripped = middle.rstrip(self.trailing_punctuation_chars)
amount_stripped = len(middle) - len(rstripped) trail_start = len(rstripped)
if amp > -1 and amount_stripped > 1: amount_trailing_semicolons = len(middle) - len(middle.rstrip(";"))
# Leave a trailing semicolon as might be an entity. if amp > -1 and amount_trailing_semicolons > 1:
trail = middle[len(rstripped) + 1 :] + trail # Leave up to most recent semicolon as might be an entity.
middle = rstripped + ";" recent_semicolon = middle[trail_start:].index(";")
middle_semicolon_index = recent_semicolon + trail_start + 1
trail = middle[middle_semicolon_index:] + trail
middle = rstripped + middle[trail_start:middle_semicolon_index]
else: else:
trail = middle[len(rstripped) :] + trail trail = middle[trail_start:] + trail
middle = rstripped middle = rstripped
trimmed_something = True trimmed_something = True

View File

@ -2922,6 +2922,17 @@ Django's built-in :tfilter:`escape` filter. The default value for
email addresses that contain single quotes (``'``), things won't work as email addresses that contain single quotes (``'``), things won't work as
expected. Apply this filter only to plain text. expected. Apply this filter only to plain text.
.. warning::
Using ``urlize`` or ``urlizetrunc`` can incur a performance penalty, which
can become severe when applied to user controlled values such as content
stored in a :class:`~django.db.models.TextField`. You can use
:tfilter:`truncatechars` to add a limit to such inputs:
.. code-block:: html+django
{{ value|truncatechars:500|urlize }}
.. templatefilter:: urlizetrunc .. templatefilter:: urlizetrunc
``urlizetrunc`` ``urlizetrunc``

View File

@ -7,4 +7,9 @@ Django 4.2.16 release notes
Django 4.2.16 fixes one security issue with severity "moderate" and one Django 4.2.16 fixes one security issue with severity "moderate" and one
security issue with severity "low" in 4.2.15. security issue with severity "low" in 4.2.15.
... CVE-2024-45230: Potential denial-of-service vulnerability in ``django.utils.html.urlize()``
===========================================================================================
:tfilter:`urlize` and :tfilter:`urlizetrunc` were subject to a potential
denial-of-service attack via very large inputs with a specific sequence of
characters.

View File

@ -7,4 +7,9 @@ Django 5.0.9 release notes
Django 5.0.9 fixes one security issue with severity "moderate" and one security Django 5.0.9 fixes one security issue with severity "moderate" and one security
issue with severity "low" in 5.0.8. issue with severity "low" in 5.0.8.
... CVE-2024-45230: Potential denial-of-service vulnerability in ``django.utils.html.urlize()``
===========================================================================================
:tfilter:`urlize` and :tfilter:`urlizetrunc` were subject to a potential
denial-of-service attack via very large inputs with a specific sequence of
characters.

View File

@ -7,6 +7,13 @@ Django 5.1.1 release notes
Django 5.1.1 fixes one security issue with severity "moderate", one security Django 5.1.1 fixes one security issue with severity "moderate", one security
issue with severity "low", and several bugs in 5.1. issue with severity "low", and several bugs in 5.1.
CVE-2024-45230: Potential denial-of-service vulnerability in ``django.utils.html.urlize()``
===========================================================================================
:tfilter:`urlize` and :tfilter:`urlizetrunc` were subject to a potential
denial-of-service attack via very large inputs with a specific sequence of
characters.
Bugfixes Bugfixes
======== ========

View File

@ -321,6 +321,11 @@ class FunctionTests(SimpleTestCase):
'<a href="http://example.com?x=" rel="nofollow">' '<a href="http://example.com?x=" rel="nofollow">'
"http://example.com?x=&amp;</a>;;", "http://example.com?x=&amp;</a>;;",
) )
self.assertEqual(
urlize("http://example.com?x=&amp.;...;", autoescape=False),
'<a href="http://example.com?x=" rel="nofollow">'
"http://example.com?x=&amp</a>.;...;",
)
def test_brackets(self): def test_brackets(self):
""" """

View File

@ -396,6 +396,7 @@ class TestUtilsHtml(SimpleTestCase):
"&:" + ";" * 100_000, "&:" + ";" * 100_000,
"&.;" * 100_000, "&.;" * 100_000,
".;" * 100_000, ".;" * 100_000,
"&" + ";:" * 100_000,
) )
for value in tests: for value in tests:
with self.subTest(value=value): with self.subTest(value=value):