mirror of
https://github.com/django/django.git
synced 2025-10-31 09:41:08 +00:00
Fixed CVE-2024-53907 -- Mitigated potential DoS in strip_tags().
Thanks to jiangniao for the report, and Shai Berger and Natalia Bidart for the reviews.
This commit is contained in:
@@ -8,6 +8,7 @@ from collections.abc import Mapping
|
||||
from html.parser import HTMLParser
|
||||
from urllib.parse import parse_qsl, quote, unquote, urlencode, urlsplit, urlunsplit
|
||||
|
||||
from django.core.exceptions import SuspiciousOperation
|
||||
from django.utils.deprecation import RemovedInDjango60Warning
|
||||
from django.utils.encoding import punycode
|
||||
from django.utils.functional import Promise, cached_property, keep_lazy, keep_lazy_text
|
||||
@@ -40,6 +41,7 @@ VOID_ELEMENTS = frozenset(
|
||||
)
|
||||
|
||||
MAX_URL_LENGTH = 2048
|
||||
MAX_STRIP_TAGS_DEPTH = 50
|
||||
|
||||
|
||||
@keep_lazy(SafeString)
|
||||
@@ -211,15 +213,19 @@ def _strip_once(value):
|
||||
@keep_lazy_text
|
||||
def strip_tags(value):
|
||||
"""Return the given HTML with all tags stripped."""
|
||||
# Note: in typical case this loop executes _strip_once once. Loop condition
|
||||
# is redundant, but helps to reduce number of executions of _strip_once.
|
||||
value = str(value)
|
||||
# Note: in typical case this loop executes _strip_once twice (the second
|
||||
# execution does not remove any more tags).
|
||||
strip_tags_depth = 0
|
||||
while "<" in value and ">" in value:
|
||||
if strip_tags_depth >= MAX_STRIP_TAGS_DEPTH:
|
||||
raise SuspiciousOperation
|
||||
new_value = _strip_once(value)
|
||||
if value.count("<") == new_value.count("<"):
|
||||
# _strip_once wasn't able to detect more tags.
|
||||
break
|
||||
value = new_value
|
||||
strip_tags_depth += 1
|
||||
return value
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user