浏览代码

Fixed CVE-2022-22818 -- Fixed possible XSS via {% debug %} template tag.

Thanks Keryn Knight for the report.

Co-authored-by: Adam Johnson <me@adamj.eu>
Markus Holtermann 3 年之前
父节点
当前提交
394517f078

+ 6 - 3
django/template/defaulttags.py

@@ -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)
 
 
 
 

+ 7 - 1
docs/ref/templates/builtins.txt

@@ -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
 
 

+ 9 - 1
docs/releases/2.2.27.txt

@@ -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``.

+ 9 - 1
docs/releases/3.2.12.txt

@@ -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``.

+ 10 - 0
docs/releases/4.0.2.txt

@@ -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
 ========
 ========
 
 

+ 46 - 0
tests/template_tests/syntax_tests/test_debug.py

@@ -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;}'
+        ))

+ 0 - 10
tests/template_tests/tests.py

@@ -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