[2.2.x] Fixed CVE-2022-22818 -- Fixed possible XSS via {% debug %} template tag.
Thanks Keryn Knight for the report. Backport of 394517f07886495efcf79f95c7ee402a9437bd68 from main. Co-authored-by: Adam Johnson <me@adamj.eu>
This commit is contained in:
parent
4cafd3aacb
commit
c27a7eb9f4
@ -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
|
||||||
|
|
||||||
@ -94,10 +94,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)
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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``.
|
||||||
|
46
tests/template_tests/syntax_tests/test_debug.py
Normal file
46
tests/template_tests/syntax_tests/test_debug.py
Normal 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(
|
||||||
|
''django': <module 'django' ',
|
||||||
|
output,
|
||||||
|
)
|
||||||
|
|
||||||
|
@setup({'plain': '{% debug %}'})
|
||||||
|
def test_plain(self):
|
||||||
|
output = self.engine.render_to_string('plain', {'a': 1})
|
||||||
|
self.assertTrue(output.startswith(
|
||||||
|
'{'a': 1}'
|
||||||
|
'{'False': False, 'None': None, '
|
||||||
|
''True': 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(
|
||||||
|
'{'group': <Group: 清風>}'
|
||||||
|
))
|
||||||
|
|
||||||
|
@setup({'script': '{% debug %}'})
|
||||||
|
def test_script(self):
|
||||||
|
output = self.engine.render_to_string('script', {'frag': '<script>'})
|
||||||
|
self.assertTrue(output.startswith(
|
||||||
|
'{'frag': '<script>'}'
|
||||||
|
))
|
@ -1,6 +1,5 @@
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
from django.contrib.auth.models import Group
|
|
||||||
from django.template import Context, Engine, TemplateSyntaxError
|
from django.template import Context, Engine, TemplateSyntaxError
|
||||||
from django.template.base import UNKNOWN_SOURCE
|
from django.template.base import UNKNOWN_SOURCE
|
||||||
from django.test import SimpleTestCase, override_settings
|
from django.test import SimpleTestCase, override_settings
|
||||||
@ -143,15 +142,6 @@ class TemplateTests(SimpleTestCase):
|
|||||||
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 = 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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user