diff -Nru python-django-1.8.7/debian/changelog python-django-1.8.7/debian/changelog --- python-django-1.8.7/debian/changelog 2017-03-29 11:34:09.000000000 +0000 +++ python-django-1.8.7/debian/changelog 2018-03-05 15:10:26.000000000 +0000 @@ -1,3 +1,17 @@ +python-django (1.8.7-1ubuntu5.6) xenial-security; urgency=medium + + * SECURITY UPDATE: DoS in urlize and urlizetrunc template filters + - debian/patches/CVE-2018-7536.patch: fix backtracking in + django/utils/html.py, add test to tests/utils_tests/test_html.py. + - CVE-2018-7536 + * SECURITY UPDATE: DoS in truncatechars_html and truncatewords_html + template filters + - debian/patches/CVE-2018-7537.patch: fix backtracking in + django/utils/text.py, add test to tests/utils_tests/test_text.py. + - CVE-2018-7537 + + -- Marc Deslauriers Mon, 05 Mar 2018 15:32:46 +0100 + python-django (1.8.7-1ubuntu5.5) xenial-security; urgency=medium * SECURITY UPDATE: Open redirect and possible XSS attack via diff -Nru python-django-1.8.7/debian/patches/CVE-2018-7536.patch python-django-1.8.7/debian/patches/CVE-2018-7536.patch --- python-django-1.8.7/debian/patches/CVE-2018-7536.patch 1970-01-01 00:00:00.000000000 +0000 +++ python-django-1.8.7/debian/patches/CVE-2018-7536.patch 2018-03-05 14:32:35.000000000 +0000 @@ -0,0 +1,86 @@ +commit 89b1fd64bd9da42d78502dc111554334cc5ca465 +Author: Tim Graham +Date: Sat Feb 24 11:30:11 2018 -0500 + + [1.8.x] Fixed CVE-2018-7536 -- Fixed catastrophic backtracking in urlize and urlizetrunc template filters. + + Thanks Florian Apolloner for assisting with the patch. + +diff --git a/django/utils/html.py b/django/utils/html.py +index a2672d4..0204fd4 100644 +--- a/django/utils/html.py ++++ b/django/utils/html.py +@@ -30,7 +30,6 @@ unencoded_ampersands_re = re.compile(r'&(?!(\w+|#\d+);)') + word_split_re = re.compile(r'(\s+)') + simple_url_re = re.compile(r'^https?://\[?\w', re.IGNORECASE) + simple_url_2_re = re.compile(r'^www\.|^(?!http)\w[^@]+\.(com|edu|gov|int|mil|net|org)($|/.*)$', re.IGNORECASE) +-simple_email_re = re.compile(r'^\S+@\S+\.\S+$') + link_target_attribute_re = re.compile(r'(]*?)target=[^\s>]+') + html_gunk_re = re.compile( + r'(?:
|<\/i>|<\/b>|<\/em>|<\/strong>|' +@@ -304,6 +303,21 @@ def urlize(text, trim_url_limit=None, nofollow=False, autoescape=False): + trail = '' + return text, unescaped, trail + ++ def is_email_simple(value): ++ """Return True if value looks like an email address.""" ++ # An @ must be in the middle of the value. ++ if '@' not in value or value.startswith('@') or value.endswith('@'): ++ return False ++ try: ++ p1, p2 = value.split('@') ++ except ValueError: ++ # value contains more than one @. ++ return False ++ # Dot must be in p2 (e.g. example.com) ++ if '.' not in p2 or p2.startswith('.'): ++ return False ++ return True ++ + words = word_split_re.split(force_text(text)) + for i, word in enumerate(words): + if '.' in word or '@' in word or ':' in word: +@@ -332,7 +346,7 @@ def urlize(text, trim_url_limit=None, nofollow=False, autoescape=False): + elif simple_url_2_re.match(middle): + middle, middle_unescaped, trail = unescape(middle, trail) + url = smart_urlquote('http://%s' % middle_unescaped) +- elif ':' not in middle and simple_email_re.match(middle): ++ elif ':' not in middle and is_email_simple(middle): + local, domain = middle.rsplit('@', 1) + try: + domain = domain.encode('idna').decode('ascii') +#diff --git a/docs/releases/1.8.19.txt b/docs/releases/1.8.19.txt +#index 9709f26..ae509f1 100644 +#--- a/docs/releases/1.8.19.txt +#+++ b/docs/releases/1.8.19.txt +#@@ -5,3 +5,14 @@ Django 1.8.19 release notes +# *March 6, 2018* +# +# Django 1.8.19 fixes two security issues in 1.18.18. +#+ +#+CVE-2018-7536: Denial-of-service possibility in ``urlize`` and ``urlizetrunc`` template filters +#+=============================================================================================== +#+ +#+The ``django.utils.html.urlize()`` function was extremely slow to evaluate +#+certain inputs due to a catastrophic backtracking vulnerability in a regular +#+expression. The ``urlize()`` function is used to implement the ``urlize`` and +#+``urlizetrunc`` template filters, which were thus vulnerable. +#+ +#+The problematic regular expression is replaced with parsing logic that behaves +#+similarly. +diff --git a/tests/utils_tests/test_html.py b/tests/utils_tests/test_html.py +index bc9874c..b108268 100644 +--- a/tests/utils_tests/test_html.py ++++ b/tests/utils_tests/test_html.py +@@ -248,3 +248,11 @@ class TestUtilsHtml(SimpleTestCase): + @html.html_safe + class HtmlClass(object): + pass ++ ++ def test_urlize_unchanged_inputs(self): ++ tests = ( ++ ('a' + '@a' * 50000) + 'a', # simple_email_re catastrophic test ++ ('a' + '.' * 1000000) + 'a', # trailing_punctuation catastrophic test ++ ) ++ for value in tests: ++ self.assertEqual(html.urlize(value), value) diff -Nru python-django-1.8.7/debian/patches/CVE-2018-7537.patch python-django-1.8.7/debian/patches/CVE-2018-7537.patch --- python-django-1.8.7/debian/patches/CVE-2018-7537.patch 1970-01-01 00:00:00.000000000 +0000 +++ python-django-1.8.7/debian/patches/CVE-2018-7537.patch 2018-03-05 14:32:40.000000000 +0000 @@ -0,0 +1,56 @@ +commit edc4f7a1c38f56527d26204df9d06cad2d9d5a34 +Author: Tim Graham +Date: Sat Feb 24 16:22:43 2018 -0500 + + [1.8.x] Fixed CVE-2018-7537 -- Fixed catastrophic backtracking in django.utils.text.Truncator. + + Thanks James Davis for suggesting the fix. + +diff --git a/django/utils/text.py b/django/utils/text.py +index eb66b77..49b6d91 100644 +--- a/django/utils/text.py ++++ b/django/utils/text.py +@@ -27,7 +27,7 @@ capfirst = allow_lazy(capfirst, six.text_type) + # 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.8.19.txt b/docs/releases/1.8.19.txt +#index ae509f1..96410a3 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 084645d..a66f925 100644 +--- a/tests/utils_tests/test_text.py ++++ b/tests/utils_tests/test_text.py +@@ -144,6 +144,10 @@ class TestUtilsText(SimpleTestCase): + self.assertEqual('

I <3 python...

', + truncator.words(3, '...', html=True)) + ++ re_tag_catastrophic_test = ('' ++ 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') diff -Nru python-django-1.8.7/debian/patches/series python-django-1.8.7/debian/patches/series --- python-django-1.8.7/debian/patches/series 2017-03-29 11:34:06.000000000 +0000 +++ python-django-1.8.7/debian/patches/series 2018-03-05 14:32:40.000000000 +0000 @@ -11,3 +11,5 @@ CVE-2016-9014.patch CVE-2017-7233.patch CVE-2017-7234.patch +CVE-2018-7536.patch +CVE-2018-7537.patch