Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
Cloud:OpenStack:Newton
python-Django
CVE-2019-14232-avoid-backtracking-issues.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File CVE-2019-14232-avoid-backtracking-issues.patch of Package python-Django
commit 067770b2c420277ad9bcdf075cdbcaf8a7c3d25c Author: Florian Apolloner <florian@apolloner.eu> Date: Mon, 15 Jul 2019 11:46:09 +0200 [1.8.X] Fixed CVE-2019-14232 -- Adjusted regex to avoid backtracking issues when truncating HTML. Thanks to Guido Vranken for initial report. diff --git a/django/utils/text.py b/django/utils/text.py index 49b6d91fb0..db7b5e00ad 100644 --- a/django/utils/text.py +++ b/django/utils/text.py @@ -25,8 +25,8 @@ capfirst = lambda x: x and force_text(x)[0].upper() + force_text(x)[1:] 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_words = re.compile(r'<[^>]+?>|([^<>\s]+)', re.S) +re_chars = re.compile(r'<[^>]+?>|(.)', 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 96410a331c..bd64941485 100644 --- a/docs/releases/1.8.19.txt +++ b/docs/releases/1.8.19.txt @@ -28,3 +28,17 @@ expression. The ``chars()`` and ``words()`` methods are used to implement the thus vulnerable. The backtracking problem in the regular expression is fixed. + +CVE-2019-14232: Denial-of-service possibility in ``django.utils.text.Truncator`` +================================================================================ + +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 +:tfilter:`truncatechars_html` and :tfilter:`truncatewords_html` template +filters, which were thus vulnerable. + +The regular expressions used by ``Truncator`` have been simplified in order to +avoid potential backtracking issues. As a consequence, trailing punctuation may +now at times be included in the truncated output. diff --git a/tests/template_tests/filter_tests/test_truncatewords_html.py b/tests/template_tests/filter_tests/test_truncatewords_html.py index aec2abf2d4..3c73442fbe 100644 --- a/tests/template_tests/filter_tests/test_truncatewords_html.py +++ b/tests/template_tests/filter_tests/test_truncatewords_html.py @@ -19,13 +19,13 @@ class FunctionTests(SimpleTestCase): def test_truncate2(self): self.assertEqual( truncatewords_html('<p>one <a href="#">two - three <br>four</a> five</p>', 4), - '<p>one <a href="#">two - three <br>four ...</a></p>', + '<p>one <a href="#">two - three ...</a></p>', ) def test_truncate3(self): self.assertEqual( truncatewords_html('<p>one <a href="#">two - three <br>four</a> five</p>', 5), - '<p>one <a href="#">two - three <br>four</a> five</p>', + '<p>one <a href="#">two - three <br>four ...</a></p>', ) def test_truncate4(self): diff --git a/tests/utils_tests/test_text.py b/tests/utils_tests/test_text.py index a66f9258c9..5fe66e7b90 100644 --- a/tests/utils_tests/test_text.py +++ b/tests/utils_tests/test_text.py @@ -98,6 +98,16 @@ class TestUtilsText(SimpleTestCase): # a length shorter than the ellipsis shouldn't break self.assertEqual('...', text.Truncator('asdf').chars(1)) + def test_truncate_chars_html(self): + perf_test_values = [ + (('</a' + '\t' * 50000) + '//>', None), + ('&' * 50000, '&' * 7 + '...'), + ('_X<<<<<<<<<<<>', None), + ] + for value, expected in perf_test_values: + truncator = text.Truncator(value) + self.assertEqual(expected if expected else value, truncator.chars(10, html=True)) + def test_truncate_words(self): truncator = text.Truncator('The quick brown fox jumped over the lazy ' 'dog.') @@ -141,12 +151,17 @@ class TestUtilsText(SimpleTestCase): self.assertEqual('<i>Buenos días! ¿Cómo...</i>', truncator.words(3, '...', html=True)) truncator = text.Truncator('<p>I <3 python, what about you?</p>') - self.assertEqual('<p>I <3 python...</p>', + self.assertEqual('<p>I <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)) + perf_test_values = [ + ('</a' + '\t' * 50000) + '//>', + '&' * 50000, + '_X<<<<<<<<<<<>', + ] + for value in perf_test_values: + truncator = text.Truncator(value) + self.assertEqual(value, truncator.words(50, html=True)) def test_wrap(self): digits = '1234 67 9'
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor