diff options
| author | Luke Plant <L.Plant.98@cantab.net> | 2015-06-15 11:17:09 +0100 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2015-06-29 08:16:19 -0400 |
| commit | aef2a0ec59301022354c043744a6a2fa13583aa1 (patch) | |
| tree | ad562a7c7c5379594b499e14574e181188a51f10 /tests | |
| parent | 9ed82154bd0bd01c6195942db84302e791ad366f (diff) | |
Fixed #25018 -- Changed simple_tag to apply conditional_escape() to its output.
This is a security hardening fix to help prevent XSS (and incorrect HTML)
for the common use case of simple_tag.
Thanks to Tim Graham for the review.
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/admin_views/tests.py | 2 | ||||
| -rw-r--r-- | tests/template_tests/templatetags/custom.py | 19 | ||||
| -rw-r--r-- | tests/template_tests/test_custom.py | 22 |
3 files changed, 42 insertions, 1 deletions
diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py index b0c74b31fa..43dd92e7f9 100644 --- a/tests/admin_views/tests.py +++ b/tests/admin_views/tests.py @@ -2434,7 +2434,7 @@ class AdminViewStringPrimaryKeyTest(TestCase): expected_link = reverse('admin:%s_modelwithstringprimarykey_history' % ModelWithStringPrimaryKey._meta.app_label, args=(quote(self.pk),)) - self.assertContains(response, '<a href="%s" class="historylink"' % expected_link) + self.assertContains(response, '<a href="%s" class="historylink"' % escape(expected_link)) def test_redirect_on_add_view_continue_button(self): """As soon as an object is added using "Save and continue editing" diff --git a/tests/template_tests/templatetags/custom.py b/tests/template_tests/templatetags/custom.py index 50ebd353ec..9d47ca4201 100644 --- a/tests/template_tests/templatetags/custom.py +++ b/tests/template_tests/templatetags/custom.py @@ -4,6 +4,7 @@ import warnings from django import template from django.template.defaultfilters import stringfilter from django.utils import six +from django.utils.html import escape, format_html register = template.Library() @@ -110,6 +111,24 @@ simple_tag_without_context_parameter.anything = "Expected simple_tag_without_con @register.simple_tag(takes_context=True) +def escape_naive(context): + """A tag that doesn't even think about escaping issues""" + return "Hello {0}!".format(context['name']) + + +@register.simple_tag(takes_context=True) +def escape_explicit(context): + """A tag that uses escape explicitly""" + return escape("Hello {0}!".format(context['name'])) + + +@register.simple_tag(takes_context=True) +def escape_format_html(context): + """A tag that uses format_html""" + return format_html("Hello {0}!", context['name']) + + +@register.simple_tag(takes_context=True) def current_app(context): return "%s" % context.current_app diff --git a/tests/template_tests/test_custom.py b/tests/template_tests/test_custom.py index 5d2907074d..dec97589d6 100644 --- a/tests/template_tests/test_custom.py +++ b/tests/template_tests/test_custom.py @@ -104,6 +104,28 @@ class SimpleTagTests(TagTestCase): with self.assertRaisesMessage(TemplateSyntaxError, entry[0]): self.engine.from_string("%s as var %%}" % entry[1][0:-2]) + def test_simple_tag_escaping_autoescape_off(self): + c = Context({'name': "Jack & Jill"}, autoescape=False) + t = self.engine.from_string("{% load custom %}{% escape_naive %}") + self.assertEqual(t.render(c), "Hello Jack & Jill!") + + def test_simple_tag_naive_escaping(self): + c = Context({'name': "Jack & Jill"}) + t = self.engine.from_string("{% load custom %}{% escape_naive %}") + self.assertEqual(t.render(c), "Hello Jack & Jill!") + + def test_simple_tag_explicit_escaping(self): + # Check we don't double escape + c = Context({'name': "Jack & Jill"}) + t = self.engine.from_string("{% load custom %}{% escape_explicit %}") + self.assertEqual(t.render(c), "Hello Jack & Jill!") + + def test_simple_tag_format_html_escaping(self): + # Check we don't double escape + c = Context({'name': "Jack & Jill"}) + t = self.engine.from_string("{% load custom %}{% escape_format_html %}") + self.assertEqual(t.render(c), "Hello Jack & Jill!") + def test_simple_tag_registration(self): # Test that the decorators preserve the decorated function's docstring, name and attributes. self.verify_tag(custom.no_params, 'no_params') |
