1
0
mirror of https://github.com/django/django.git synced 2025-10-31 09:41:08 +00:00

[5.0.x] Fixed CVE-2024-41991 -- Prevented potential ReDoS in django.utils.html.urlize() and AdminURLFieldWidget.

Thanks Seokchan Yoon for the report.

Co-authored-by: Sarah Boyce <42296566+sarahboyce@users.noreply.github.com>
This commit is contained in:
Mariusz Felisiak
2024-07-10 20:30:12 +02:00
committed by Sarah Boyce
parent 7b7b909579
commit 523da8771b
6 changed files with 42 additions and 4 deletions

View File

@@ -390,7 +390,7 @@ class AdminURLFieldWidget(forms.URLInput):
context["current_label"] = _("Currently:")
context["change_label"] = _("Change:")
context["widget"]["href"] = (
smart_urlquote(context["widget"]["value"]) if value else ""
smart_urlquote(context["widget"]["value"]) if url_valid else ""
)
context["url_valid"] = url_valid
return context

View File

@@ -36,6 +36,8 @@ VOID_ELEMENTS = {
"spacer",
}
MAX_URL_LENGTH = 2048
@keep_lazy(SafeString)
def escape(text):
@@ -330,9 +332,9 @@ class Urlizer:
# Make URL we want to point to.
url = None
nofollow_attr = ' rel="nofollow"' if nofollow else ""
if self.simple_url_re.match(middle):
if len(middle) <= MAX_URL_LENGTH and self.simple_url_re.match(middle):
url = smart_urlquote(html.unescape(middle))
elif self.simple_url_2_re.match(middle):
elif len(middle) <= MAX_URL_LENGTH and self.simple_url_2_re.match(middle):
url = smart_urlquote("http://%s" % html.unescape(middle))
elif ":" not in middle and self.is_email_simple(middle):
local, domain = middle.rsplit("@", 1)
@@ -447,6 +449,10 @@ class Urlizer:
except ValueError:
# value contains more than one @.
return False
# Max length for domain name labels is 63 characters per RFC 1034.
# Helps to avoid ReDoS vectors in the domain part.
if len(p2) > 63:
return False
# Dot must be in p2 (e.g. example.com)
if "." not in p2 or p2.startswith("."):
return False