[4.0.x] Fixed CVE-2022-22818 -- Fixed possible XSS via {% debug %} template tag.

Thanks Keryn Knight for the report.

Backport of 394517f078 from main.

Co-authored-by: Adam Johnson <me@adamj.eu>
This commit is contained in:
Markus Holtermann 2022-01-02 00:37:40 +01:00 committed by Mariusz Felisiak
parent 6928227dff
commit 0142204606
7 changed files with 87 additions and 16 deletions

View File

@ -8,7 +8,7 @@ from itertools import cycle as itertools_cycle, groupby
from django.conf import settings from django.conf import settings
from django.utils import timezone from django.utils import timezone
from django.utils.html import conditional_escape, format_html from django.utils.html import conditional_escape, escape, format_html
from django.utils.lorem_ipsum import paragraphs, words from django.utils.lorem_ipsum import paragraphs, words
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
@ -99,10 +99,13 @@ class CycleNode(Node):
class DebugNode(Node): class DebugNode(Node):
def render(self, context): def render(self, context):
if not settings.DEBUG:
return ''
from pprint import pformat from pprint import pformat
output = [pformat(val) for val in context] output = [escape(pformat(val)) for val in context]
output.append('\n\n') output.append('\n\n')
output.append(pformat(sys.modules)) output.append(escape(pformat(sys.modules)))
return ''.join(output) return ''.join(output)

View File

@ -194,7 +194,13 @@ from its first value when it's next encountered.
--------- ---------
Outputs a whole load of debugging information, including the current context Outputs a whole load of debugging information, including the current context
and imported modules. and imported modules. ``{% debug %}`` outputs nothing when the :setting:`DEBUG`
setting is ``False``.
.. versionchanged:: 2.2.27
In older versions, debugging information was displayed when the
:setting:`DEBUG` setting was ``False``.
.. templatetag:: extends .. templatetag:: extends

View File

@ -6,4 +6,12 @@ Django 2.2.27 release notes
Django 2.2.27 fixes two security issues with severity "medium" in 2.2.26. Django 2.2.27 fixes two security issues with severity "medium" in 2.2.26.
... CVE-2022-22818: Possible XSS via ``{% debug %}`` template tag
=============================================================
The ``{% debug %}`` template tag didn't properly encode the current context,
posing an XSS attack vector.
In order to avoid this vulnerability, ``{% debug %}`` no longer outputs an
information when the ``DEBUG`` setting is ``False``, and it ensures all context
variables are correctly escaped when the ``DEBUG`` setting is ``True``.

View File

@ -6,4 +6,12 @@ Django 3.2.12 release notes
Django 3.2.12 fixes two security issues with severity "medium" in 3.2.11. Django 3.2.12 fixes two security issues with severity "medium" in 3.2.11.
... CVE-2022-22818: Possible XSS via ``{% debug %}`` template tag
=============================================================
The ``{% debug %}`` template tag didn't properly encode the current context,
posing an XSS attack vector.
In order to avoid this vulnerability, ``{% debug %}`` no longer outputs an
information when the ``DEBUG`` setting is ``False``, and it ensures all context
variables are correctly escaped when the ``DEBUG`` setting is ``True``.

View File

@ -8,6 +8,16 @@ Django 4.0.2 fixes two security issues with severity "medium" and several bugs
in 4.0.1. Also, the latest string translations from Transifex are incorporated, in 4.0.1. Also, the latest string translations from Transifex are incorporated,
with a special mention for Bulgarian (fully translated). with a special mention for Bulgarian (fully translated).
CVE-2022-22818: Possible XSS via ``{% debug %}`` template tag
=============================================================
The ``{% debug %}`` template tag didn't properly encode the current context,
posing an XSS attack vector.
In order to avoid this vulnerability, ``{% debug %}`` no longer outputs an
information when the ``DEBUG`` setting is ``False``, and it ensures all context
variables are correctly escaped when the ``DEBUG`` setting is ``True``.
Bugfixes Bugfixes
======== ========

View File

@ -0,0 +1,46 @@
from django.contrib.auth.models import Group
from django.test import SimpleTestCase, override_settings
from ..utils import setup
@override_settings(DEBUG=True)
class DebugTests(SimpleTestCase):
@override_settings(DEBUG=False)
@setup({'non_debug': '{% debug %}'})
def test_non_debug(self):
output = self.engine.render_to_string('non_debug', {})
self.assertEqual(output, '')
@setup({'modules': '{% debug %}'})
def test_modules(self):
output = self.engine.render_to_string('modules', {})
self.assertIn(
'&#x27;django&#x27;: &lt;module &#x27;django&#x27; ',
output,
)
@setup({'plain': '{% debug %}'})
def test_plain(self):
output = self.engine.render_to_string('plain', {'a': 1})
self.assertTrue(output.startswith(
'{&#x27;a&#x27;: 1}'
'{&#x27;False&#x27;: False, &#x27;None&#x27;: None, '
'&#x27;True&#x27;: True}\n\n{'
))
@setup({'non_ascii': '{% debug %}'})
def test_non_ascii(self):
group = Group(name="清風")
output = self.engine.render_to_string('non_ascii', {'group': group})
self.assertTrue(output.startswith(
'{&#x27;group&#x27;: &lt;Group: 清風&gt;}'
))
@setup({'script': '{% debug %}'})
def test_script(self):
output = self.engine.render_to_string('script', {'frag': '<script>'})
self.assertTrue(output.startswith(
'{&#x27;frag&#x27;: &#x27;&lt;script&gt;&#x27;}'
))

View File

@ -1,6 +1,5 @@
import sys import sys
from django.contrib.auth.models import Group
from django.template import ( from django.template import (
Context, Engine, TemplateDoesNotExist, TemplateSyntaxError, Context, Engine, TemplateDoesNotExist, TemplateSyntaxError,
) )
@ -163,15 +162,6 @@ class TemplateTestMixin:
with self.assertRaises(NoReverseMatch): with self.assertRaises(NoReverseMatch):
t.render(Context()) t.render(Context())
def test_debug_tag_non_ascii(self):
"""
#23060 -- Test non-ASCII model representation in debug output.
"""
group = Group(name="清風")
c1 = Context({"objs": [group]})
t1 = self._engine().from_string('{% debug %}')
self.assertIn("清風", t1.render(c1))
def test_extends_generic_template(self): def test_extends_generic_template(self):
""" """
#24338 -- Allow extending django.template.backends.django.Template #24338 -- Allow extending django.template.backends.django.Template