summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Graham <timograham@gmail.com>2018-02-24 16:22:43 -0500
committerTim Graham <timograham@gmail.com>2018-02-27 13:56:26 -0500
commita91436360b79a6ff995c3e5018bcc666dfaf1539 (patch)
tree2581958aedc8649eb5b1f91fde6cc9c651ed2c23
parentabf89d729f210c692a50e0ad3f75fb6bec6fae16 (diff)
[1.11.x] Fixed CVE-2018-7537 -- Fixed catastrophic backtracking in django.utils.text.Truncator.
Thanks James Davis for suggesting the fix.
-rw-r--r--django/utils/text.py2
-rw-r--r--docs/releases/1.11.11.txt12
-rw-r--r--docs/releases/1.8.19.txt12
-rw-r--r--tests/utils_tests/test_text.py4
4 files changed, 29 insertions, 1 deletions
diff --git a/django/utils/text.py b/django/utils/text.py
index b0f139e034..a6172c41b0 100644
--- a/django/utils/text.py
+++ b/django/utils/text.py
@@ -29,7 +29,7 @@ def capfirst(x):
# Set up regular expressions
re_words = re.compile(r'<.*?>|((?:\w[-\w]*|&.*?;)+)', re.U | re.S)
re_chars = re.compile(r'<.*?>|(.)', re.U | re.S)
-re_tag = re.compile(r'<(/)?([^ ]+?)(?:(\s*/)| .*?)?>', re.S)
+re_tag = re.compile(r'<(/)?(\S+?)(?:(\s*/)|\s.*?)?>', re.S)
re_newlines = re.compile(r'\r\n|\r') # Used in normalize_newlines
re_camel_case = re.compile(r'(((?<=[a-z])[A-Z])|([A-Z](?![A-Z]|$)))')
diff --git a/docs/releases/1.11.11.txt b/docs/releases/1.11.11.txt
index 696465fd47..314338a541 100644
--- a/docs/releases/1.11.11.txt
+++ b/docs/releases/1.11.11.txt
@@ -16,3 +16,15 @@ expressions. The ``urlize()`` function is used to implement the ``urlize`` and
The problematic regular expressions are replaced with parsing logic that
behaves similarly.
+
+CVE-2018-7537: Denial-of-service possibility in ``truncatechars_html`` and ``truncatewords_html`` template filters
+==================================================================================================================
+
+If ``django.utils.text.Truncator``'s ``chars()`` and ``words()`` methods were
+passed the ``html=True`` argument, they were extremely slow to evaluate certain
+inputs due to a catastrophic backtracking vulnerability in a regular
+expression. The ``chars()`` and ``words()`` methods are used to implement the
+``truncatechars_html`` and ``truncatewords_html`` template filters, which were
+thus vulnerable.
+
+The backtracking problem in the regular expression is fixed.
diff --git a/docs/releases/1.8.19.txt b/docs/releases/1.8.19.txt
index ae509f11c4..96410a331c 100644
--- a/docs/releases/1.8.19.txt
+++ b/docs/releases/1.8.19.txt
@@ -16,3 +16,15 @@ expression. The ``urlize()`` function is used to implement the ``urlize`` and
The problematic regular expression is replaced with parsing logic that behaves
similarly.
+
+CVE-2018-7537: Denial-of-service possibility in ``truncatechars_html`` and ``truncatewords_html`` template filters
+==================================================================================================================
+
+If ``django.utils.text.Truncator``'s ``chars()`` and ``words()`` methods were
+passed the ``html=True`` argument, they were extremely slow to evaluate certain
+inputs due to a catastrophic backtracking vulnerability in a regular
+expression. The ``chars()`` and ``words()`` methods are used to implement the
+``truncatechars_html`` and ``truncatewords_html`` template filters, which were
+thus vulnerable.
+
+The backtracking problem in the regular expression is fixed.
diff --git a/tests/utils_tests/test_text.py b/tests/utils_tests/test_text.py
index d190d85232..50d1805e86 100644
--- a/tests/utils_tests/test_text.py
+++ b/tests/utils_tests/test_text.py
@@ -139,6 +139,10 @@ class TestUtilsText(SimpleTestCase):
truncator = text.Truncator('<p>I &lt;3 python, what about you?</p>')
self.assertEqual('<p>I &lt;3 python...</p>', truncator.words(3, '...', html=True))
+ re_tag_catastrophic_test = ('</a' + '\t' * 50000) + '//>'
+ truncator = text.Truncator(re_tag_catastrophic_test)
+ self.assertEqual(re_tag_catastrophic_test, truncator.words(500, html=True))
+
def test_wrap(self):
digits = '1234 67 9'
self.assertEqual(text.wrap(digits, 100), '1234 67 9')