summaryrefslogtreecommitdiffstats
path: root/meta-python/recipes-devtools/python/python3-django
diff options
context:
space:
mode:
authorSoumya Sambu <soumya.sambu@windriver.com>2025-01-10 13:18:00 +0000
committerArmin Kuster <akuster808@gmail.com>2025-01-22 19:23:02 -0500
commitb4feba446d7a8f8232528c4b2ee936e5b98ced3d (patch)
tree6c0bdb1b0ca864a54fdd5de45ddce37dcdfab2cd /meta-python/recipes-devtools/python/python3-django
parentaa9e8a5557adbd25b5ebaa090c0843dc6b042f1d (diff)
downloadmeta-openembedded-b4feba446d7a8f8232528c4b2ee936e5b98ced3d.tar.gz
python3-django: Fix CVE-2024-45230
An issue was discovered in Django 5.1 before 5.1.1, 5.0 before 5.0.9, and 4.2 before 4.2.16. The urlize() and urlizetrunc() template filters are subject to a potential denial-of-service attack via very large inputs with a specific sequence of characters. Reference: https://nvd.nist.gov/vuln/detail/CVE-2024-45230 Upstream-patch: https://github.com/django/django/commit/d147a8ebbdf28c17cafbbe2884f0bc57e2bf82e2 Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com> Signed-off-by: Armin Kuster <akuster808@gmail.com>
Diffstat (limited to 'meta-python/recipes-devtools/python/python3-django')
-rw-r--r--meta-python/recipes-devtools/python/python3-django/CVE-2024-45230.patch137
1 files changed, 137 insertions, 0 deletions
diff --git a/meta-python/recipes-devtools/python/python3-django/CVE-2024-45230.patch b/meta-python/recipes-devtools/python/python3-django/CVE-2024-45230.patch
new file mode 100644
index 0000000000..b3474dc496
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-django/CVE-2024-45230.patch
@@ -0,0 +1,137 @@
1From d147a8ebbdf28c17cafbbe2884f0bc57e2bf82e2 Mon Sep 17 00:00:00 2001
2From: Sarah Boyce <42296566+sarahboyce@users.noreply.github.com>
3Date: Mon, 12 Aug 2024 15:17:57 +0200
4Subject: [PATCH] [4.2.x] Fixed CVE-2024-45230 -- Mitigated potential DoS in
5 urlize and urlizetrunc template filters.
6
7Thanks MProgrammer (https://hackerone.com/mprogrammer) for the report.
8
9CVE: CVE-2024-45230
10
11Upstream-Status: Backport [https://github.com/django/django/commit/d147a8ebbdf28c17cafbbe2884f0bc57e2bf82e2]
12
13Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
14---
15 django/utils/html.py | 22 +++++++++++--------
16 docs/ref/templates/builtins.txt | 11 ++++++++++
17 .../filter_tests/test_urlize.py | 22 +++++++++++++++++++
18 tests/utils_tests/test_html.py | 1 +
19 4 files changed, 47 insertions(+), 9 deletions(-)
20
21diff --git a/django/utils/html.py b/django/utils/html.py
22index 79f06bd..d129334 100644
23--- a/django/utils/html.py
24+++ b/django/utils/html.py
25@@ -1,5 +1,6 @@
26 """HTML utilities suitable for global use."""
27
28+import html
29 import json
30 import re
31 from html.parser import HTMLParser
32@@ -327,16 +328,19 @@ def urlize(text, trim_url_limit=None, nofollow=False, autoescape=False):
33 if trailing_punctuation_chars_has_semicolon() and middle.endswith(";"):
34 # Only strip if not part of an HTML entity.
35 potential_entity = middle[amp:]
36- escaped = unescape(potential_entity)
37+ escaped = html.unescape(potential_entity)
38 if escaped == potential_entity or escaped.endswith(";"):
39- rstripped = middle.rstrip(";")
40- amount_stripped = len(middle) - len(rstripped)
41- if amp > -1 and amount_stripped > 1:
42- # Leave a trailing semicolon as might be an entity.
43- trail = middle[len(rstripped) + 1 :] + trail
44- middle = rstripped + ";"
45+ rstripped = middle.rstrip(TRAILING_PUNCTUATION_CHARS)
46+ trail_start = len(rstripped)
47+ amount_trailing_semicolons = len(middle) - len(middle.rstrip(";"))
48+ if amp > -1 and amount_trailing_semicolons > 1:
49+ # Leave up to most recent semicolon as might be an entity.
50+ recent_semicolon = middle[trail_start:].index(";")
51+ middle_semicolon_index = recent_semicolon + trail_start + 1
52+ trail = middle[middle_semicolon_index:] + trail
53+ middle = rstripped + middle[trail_start:middle_semicolon_index]
54 else:
55- trail = middle[len(rstripped) :] + trail
56+ trail = middle[trail_start:] + trail
57 middle = rstripped
58 trimmed_something = True
59
60@@ -373,7 +377,7 @@ def urlize(text, trim_url_limit=None, nofollow=False, autoescape=False):
61 url = None
62 nofollow_attr = ' rel="nofollow"' if nofollow else ''
63 if len(middle) <= MAX_URL_LENGTH and simple_url_re.match(middle):
64- url = smart_urlquote(unescape(middle))
65+ url = smart_urlquote(html.unescape(middle))
66 elif len(middle) <= MAX_URL_LENGTH and simple_url_2_re.match(middle):
67 url = smart_urlquote('http://%s' % unescape(middle))
68 elif ':' not in middle and is_email_simple(middle):
69diff --git a/docs/ref/templates/builtins.txt b/docs/ref/templates/builtins.txt
70index 4faab38..1990ed0 100644
71--- a/docs/ref/templates/builtins.txt
72+++ b/docs/ref/templates/builtins.txt
73@@ -2483,6 +2483,17 @@ Django's built-in :tfilter:`escape` filter. The default value for
74 email addresses that contain single quotes (``'``), things won't work as
75 expected. Apply this filter only to plain text.
76
77+.. warning::
78+
79+ Using ``urlize`` or ``urlizetrunc`` can incur a performance penalty, which
80+ can become severe when applied to user controlled values such as content
81+ stored in a :class:`~django.db.models.TextField`. You can use
82+ :tfilter:`truncatechars` to add a limit to such inputs:
83+
84+ .. code-block:: html+django
85+
86+ {{ value|truncatechars:500|urlize }}
87+
88 .. templatefilter:: urlizetrunc
89
90 ``urlizetrunc``
91diff --git a/tests/template_tests/filter_tests/test_urlize.py b/tests/template_tests/filter_tests/test_urlize.py
92index 649a965..1991301 100644
93--- a/tests/template_tests/filter_tests/test_urlize.py
94+++ b/tests/template_tests/filter_tests/test_urlize.py
95@@ -260,6 +260,28 @@ class FunctionTests(SimpleTestCase):
96 'A test <a href="http://testing.com/example" rel="nofollow">http://testing.com/example</a>.,:;)&quot;!'
97 )
98
99+ def test_trailing_semicolon(self):
100+ self.assertEqual(
101+ urlize("http://example.com?x=&amp;", autoescape=False),
102+ '<a href="http://example.com?x=" rel="nofollow">'
103+ "http://example.com?x=&amp;</a>",
104+ )
105+ self.assertEqual(
106+ urlize("http://example.com?x=&amp;;", autoescape=False),
107+ '<a href="http://example.com?x=" rel="nofollow">'
108+ "http://example.com?x=&amp;</a>;",
109+ )
110+ self.assertEqual(
111+ urlize("http://example.com?x=&amp;;;", autoescape=False),
112+ '<a href="http://example.com?x=" rel="nofollow">'
113+ "http://example.com?x=&amp;</a>;;",
114+ )
115+ self.assertEqual(
116+ urlize("http://example.com?x=&amp.;...;", autoescape=False),
117+ '<a href="http://example.com?x=" rel="nofollow">'
118+ "http://example.com?x=&amp</a>.;...;",
119+ )
120+
121 def test_brackets(self):
122 """
123 #19070 - Check urlize handles brackets properly
124diff --git a/tests/utils_tests/test_html.py b/tests/utils_tests/test_html.py
125index 1a5c963..b382843 100644
126--- a/tests/utils_tests/test_html.py
127+++ b/tests/utils_tests/test_html.py
128@@ -289,6 +289,7 @@ class TestUtilsHtml(SimpleTestCase):
129 "&:" + ";" * 100_000,
130 "&.;" * 100_000,
131 ".;" * 100_000,
132+ "&" + ";:" * 100_000,
133 )
134 for value in tests:
135 with self.subTest(value=value):
136--
1372.40.0