1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
|
From: Chris Lamb <lamby@debian.org>
Date: Fri, 3 Aug 2018 11:48:27 +0800
Subject: CVE-2017-12794
Fix a cross-site scripting attack in the technical HTTP 500
page. This vulnerability did not affect production sites as they
typically do not run with "DEBUG = True".
---
django/views/debug.py | 20 +++++++++-----------
tests/view_tests/tests/py3_test_debug.py | 13 +++++++------
2 files changed, 16 insertions(+), 17 deletions(-)
diff --git a/django/views/debug.py b/django/views/debug.py
index 0ed55fd..327ff43 100644
--- a/django/views/debug.py
+++ b/django/views/debug.py
@@ -775,38 +775,37 @@ TECHNICAL_500_TEMPLATE = ("""
<h2>Traceback <span class="commands">{% if not is_email %}<a href="#" onclick="return switchPastebinFriendly(this);">
Switch to copy-and-paste view</a></span>{% endif %}
</h2>
- {% autoescape off %}
<div id="browserTraceback">
<ul class="traceback">
{% for frame in frames %}
{% ifchanged frame.exc_cause %}{% if frame.exc_cause %}
<li><h3>
{% 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 %}
</h3></li>
{% endif %}{% endifchanged %}
<li class="frame {{ frame.type }}">
- <code>{{ frame.filename|escape }}</code> in <code>{{ frame.function|escape }}</code>
+ <code>{{ frame.filename }}</code> in <code>{{ frame.function }}</code>
{% if frame.context_line %}
<div class="context" id="c{{ frame.id }}">
{% if frame.pre_context and not is_email %}
<ol start="{{ frame.pre_context_lineno }}" class="pre-context" id="pre{{ frame.id }}">
{% for line in frame.pre_context %}
- <li onclick="toggle('pre{{ frame.id }}', 'post{{ frame.id }}')"><pre>{{ line|escape }}</pre></li>
+ <li onclick="toggle('pre{{ frame.id }}', 'post{{ frame.id }}')"><pre>{{ line }}</pre></li>
{% endfor %}
</ol>
{% endif %}
<ol start="{{ frame.lineno }}" class="context-line">
<li onclick="toggle('pre{{ frame.id }}', 'post{{ frame.id }}')"><pre>
-""" """{{ frame.context_line|escape }}</pre>{% if not is_email %} <span>...</span>{% endif %}</li></ol>
+""" """{{ frame.context_line }}</pre>{% if not is_email %} <span>...</span>{% endif %}</li></ol>
{% if frame.post_context and not is_email %}
<ol start='{{ frame.lineno|add:"1" }}' class="post-context" id="post{{ frame.id }}">
{% for line in frame.post_context %}
- <li onclick="toggle('pre{{ frame.id }}', 'post{{ frame.id }}')"><pre>{{ line|escape }}</pre></li>
+ <li onclick="toggle('pre{{ frame.id }}', 'post{{ frame.id }}')"><pre>{{ line }}</pre></li>
{% endfor %}
</ol>
{% endif %}
@@ -831,7 +830,7 @@ TECHNICAL_500_TEMPLATE = ("""
<tbody>
{% for var in frame.vars|dictsort:0 %}
<tr>
- <td>{{ var.0|force_escape }}</td>
+ <td>{{ var.0 }}</td>
<td class="code"><pre>{{ var.1 }}</pre></td>
</tr>
{% endfor %}
@@ -842,7 +841,6 @@ TECHNICAL_500_TEMPLATE = ("""
{% endfor %}
</ul>
</div>
- {% endautoescape %}
<form action="http://dpaste.com/" name="pasteform" id="pasteform" method="post">
{% if not is_email %}
<div id="pastebinTraceback" class="pastebin">
@@ -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/tests/view_tests/tests/py3_test_debug.py b/tests/view_tests/tests/py3_test_debug.py
index 30201ba..316179a 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('<p>Top level</p>'))
except AttributeError as explicit:
try:
- raise ValueError('Second exception') from explicit
+ raise ValueError('<p>Second exception</p>') 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('<p>Top level</p>'), text)
+ self.assertIn(implicit_exc.format('<p>Second exception</p>'), text)
|