Fixed #33461 -- Escaped template errors in the technical 500 debug page.
This commit is contained in:
parent
3a9b8b25d4
commit
c5c7a15b09
|
@ -190,7 +190,7 @@
|
||||||
<div id="template">
|
<div id="template">
|
||||||
<h2>Error during template rendering</h2>
|
<h2>Error during template rendering</h2>
|
||||||
<p>In template <code>{{ template_info.name }}</code>, error at line <strong>{{ template_info.line }}</strong></p>
|
<p>In template <code>{{ template_info.name }}</code>, error at line <strong>{{ template_info.line }}</strong></p>
|
||||||
<h3>{{ template_info.message }}</h3>
|
<h3>{{ template_info.message|force_escape }}</h3>
|
||||||
<table class="source{% if template_info.top %} cut-top{% endif %}
|
<table class="source{% if template_info.top %} cut-top{% endif %}
|
||||||
{% if template_info.bottom != template_info.total %} cut-bottom{% endif %}">
|
{% if template_info.bottom != template_info.total %} cut-bottom{% endif %}">
|
||||||
{% for source_line in template_info.source_lines %}
|
{% for source_line in template_info.source_lines %}
|
||||||
|
@ -316,7 +316,7 @@ Using engine {{ entry.backend.name }}:
|
||||||
{% endif %}{% endif %}{% if template_info %}
|
{% endif %}{% endif %}{% if template_info %}
|
||||||
Template error:
|
Template error:
|
||||||
In template {{ template_info.name }}, error at line {{ template_info.line }}
|
In template {{ template_info.name }}, error at line {{ template_info.line }}
|
||||||
{{ template_info.message }}
|
{{ template_info.message|force_escape }}
|
||||||
{% for source_line in template_info.source_lines %}{% if source_line.0 == template_info.line %} {{ source_line.0 }} : {{ template_info.before }} {{ template_info.during }} {{ template_info.after }}{% else %} {{ source_line.0 }} : {{ source_line.1 }}{% endif %}{% endfor %}{% endif %}
|
{% for source_line in template_info.source_lines %}{% if source_line.0 == template_info.line %} {{ source_line.0 }} : {{ template_info.before }} {{ template_info.during }} {{ template_info.after }}{% else %} {{ source_line.0 }} : {{ source_line.1 }}{% endif %}{% endfor %}{% endif %}
|
||||||
|
|
||||||
Traceback (most recent call last):{% for frame in frames %}
|
Traceback (most recent call last):{% for frame in frames %}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import tempfile
|
||||||
import threading
|
import threading
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from unittest import mock
|
from unittest import mock, skipIf
|
||||||
|
|
||||||
from django.core import mail
|
from django.core import mail
|
||||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
from django.core.files.uploadedfile import SimpleUploadedFile
|
||||||
|
@ -263,6 +263,27 @@ class DebugViewTests(SimpleTestCase):
|
||||||
"traceback, instead found: %s" % raising_loc
|
"traceback, instead found: %s" % raising_loc
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@skipIf(
|
||||||
|
sys.platform == 'win32',
|
||||||
|
'Raises OSError instead of TemplateDoesNotExist on Windows.',
|
||||||
|
)
|
||||||
|
def test_safestring_in_exception(self):
|
||||||
|
with self.assertLogs('django.request', 'ERROR'):
|
||||||
|
response = self.client.get('/safestring_exception/')
|
||||||
|
self.assertNotContains(
|
||||||
|
response,
|
||||||
|
'<script>alert(1);</script>',
|
||||||
|
status_code=500,
|
||||||
|
html=True,
|
||||||
|
)
|
||||||
|
self.assertContains(
|
||||||
|
response,
|
||||||
|
'<script>alert(1);</script>',
|
||||||
|
count=3,
|
||||||
|
status_code=500,
|
||||||
|
html=True,
|
||||||
|
)
|
||||||
|
|
||||||
def test_template_loader_postmortem(self):
|
def test_template_loader_postmortem(self):
|
||||||
"""Tests for not existing file"""
|
"""Tests for not existing file"""
|
||||||
template_name = "notfound.html"
|
template_name = "notfound.html"
|
||||||
|
|
|
@ -59,6 +59,11 @@ urlpatterns += i18n_patterns(
|
||||||
)
|
)
|
||||||
|
|
||||||
urlpatterns += [
|
urlpatterns += [
|
||||||
|
path(
|
||||||
|
'safestring_exception/',
|
||||||
|
views.safestring_in_template_exception,
|
||||||
|
name='safestring_exception',
|
||||||
|
),
|
||||||
path('template_exception/', views.template_exception, name='template_exception'),
|
path('template_exception/', views.template_exception, name='template_exception'),
|
||||||
path(
|
path(
|
||||||
'raises_template_does_not_exist/<path:path>',
|
'raises_template_does_not_exist/<path:path>',
|
||||||
|
|
|
@ -9,7 +9,7 @@ from django.core.exceptions import (
|
||||||
)
|
)
|
||||||
from django.http import Http404, HttpResponse, JsonResponse
|
from django.http import Http404, HttpResponse, JsonResponse
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from django.template import TemplateDoesNotExist
|
from django.template import Context, Template, TemplateDoesNotExist
|
||||||
from django.urls import get_resolver
|
from django.urls import get_resolver
|
||||||
from django.views import View
|
from django.views import View
|
||||||
from django.views.debug import (
|
from django.views.debug import (
|
||||||
|
@ -89,6 +89,18 @@ def template_exception(request):
|
||||||
return render(request, 'debug/template_exception.html')
|
return render(request, 'debug/template_exception.html')
|
||||||
|
|
||||||
|
|
||||||
|
def safestring_in_template_exception(request):
|
||||||
|
"""
|
||||||
|
Trigger an exception in the template machinery which causes a SafeString
|
||||||
|
to be inserted as args[0] of the Exception.
|
||||||
|
"""
|
||||||
|
template = Template('{% extends "<script>alert(1);</script>" %}')
|
||||||
|
try:
|
||||||
|
template.render(Context())
|
||||||
|
except Exception:
|
||||||
|
return technical_500_response(request, *sys.exc_info())
|
||||||
|
|
||||||
|
|
||||||
def jsi18n(request):
|
def jsi18n(request):
|
||||||
return render(request, 'jsi18n.html')
|
return render(request, 'jsi18n.html')
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue