From 58e08e80e362db79eb0fd775dc81faad90dca47a Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Wed, 2 Aug 2017 16:22:35 -0400 Subject: [PATCH] [1.10.x] Fixed CVE-2017-12794 -- Fixed XSS possibility in traceback section of technical 500 debug page. This is a security fix. --- django/views/debug.py | 20 +++++++++----------- docs/releases/1.10.8.txt | 9 +++++++++ tests/view_tests/tests/py3_test_debug.py | 13 +++++++------ 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/django/views/debug.py b/django/views/debug.py index 0ed55fdfe4d..327ff433c52 100644 --- a/django/views/debug.py +++ b/django/views/debug.py @@ -775,38 +775,37 @@ TECHNICAL_500_TEMPLATE = ("""

Traceback {% if not is_email %} Switch to copy-and-paste view{% endif %}

- {% autoescape off %}
- {% endautoescape %}
{% if not is_email %}
@@ -888,9 +886,9 @@ In template {{ template_info.name }}, error at line {{ template_info.line }} Traceback:{% for frame in frames %} {% ifchanged frame.exc_cause %}{% if frame.exc_cause %}{% if frame.exc_cause_explicit %} -The above exception ({{ frame.exc_cause }}) was the direct cause of the following exception: +The above exception ({{ frame.exc_cause|force_escape }}) was the direct cause of the following exception: {% else %} -During handling of the above exception ({{ frame.exc_cause }}), another exception occurred: +During handling of the above exception ({{ frame.exc_cause|force_escape }}), another exception occurred: {% endif %}{% endif %}{% endifchanged %} File "{{ frame.filename|escape }}" in {{ frame.function|escape }} {% if frame.context_line %} {{ frame.lineno }}. {{ frame.context_line|escape }}{% endif %}{% endfor %} diff --git a/docs/releases/1.10.8.txt b/docs/releases/1.10.8.txt index 160e555fefd..3785e6535aa 100644 --- a/docs/releases/1.10.8.txt +++ b/docs/releases/1.10.8.txt @@ -5,3 +5,12 @@ Django 1.10.8 release notes *September 5, 2017* Django 1.10.8 fixes a security issue in 1.10.7. + +CVE-2017-12794: Possible XSS in traceback section of technical 500 debug page +============================================================================= + +In older versions, HTML autoescaping was disabled in a portion of the template +for the technical 500 debug page. Given the right circumstances, this allowed +a cross-site scripting attack. This vulnerability shouldn't affect most +production sites since you shouldn't run with ``DEBUG = True`` (which makes +this page accessible) in your production settings. diff --git a/tests/view_tests/tests/py3_test_debug.py b/tests/view_tests/tests/py3_test_debug.py index 30201bae53f..316179ae3e5 100644 --- a/tests/view_tests/tests/py3_test_debug.py +++ b/tests/view_tests/tests/py3_test_debug.py @@ -9,6 +9,7 @@ error (raise ... from ...) can't be silenced using NOQA. import sys from django.test import RequestFactory, TestCase +from django.utils.safestring import mark_safe from django.views.debug import ExceptionReporter @@ -20,10 +21,10 @@ class Py3ExceptionReporterTests(TestCase): request = self.rf.get('/test_view/') try: try: - raise AttributeError('Top level') + raise AttributeError(mark_safe('

Top level

')) except AttributeError as explicit: try: - raise ValueError('Second exception') from explicit + raise ValueError('

Second exception

') from explicit except ValueError: raise IndexError('Final exception') except Exception: @@ -37,9 +38,9 @@ class Py3ExceptionReporterTests(TestCase): html = reporter.get_traceback_html() # Both messages are twice on page -- one rendered as html, # one as plain text (for pastebin) - self.assertEqual(2, html.count(explicit_exc.format("Top level"))) - self.assertEqual(2, html.count(implicit_exc.format("Second exception"))) + self.assertEqual(2, html.count(explicit_exc.format('<p>Top level</p>'))) + self.assertEqual(2, html.count(implicit_exc.format('<p>Second exception</p>'))) text = reporter.get_traceback_text() - self.assertIn(explicit_exc.format("Top level"), text) - self.assertIn(implicit_exc.format("Second exception"), text) + self.assertIn(explicit_exc.format('

Top level

'), text) + self.assertIn(implicit_exc.format('

Second exception

'), text)