/[packages]/updates/8/python-django/current/SOURCES/c7fe895bca06daf12cc1670b56eaf72a1ef27a16.patch
ViewVC logotype

Contents of /updates/8/python-django/current/SOURCES/c7fe895bca06daf12cc1670b56eaf72a1ef27a16.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1766876 - (show annotations) (download)
Tue Jan 4 20:20:05 2022 UTC (2 years, 3 months ago) by neoclust
File size: 7333 byte(s)
Add P100->102: Fixes CVE-2021-4511[56] and CVE-2021-45452 (mga#29843)
1 From c7fe895bca06daf12cc1670b56eaf72a1ef27a16 Mon Sep 17 00:00:00 2001
2 From: Florian Apolloner <florian@apolloner.eu>
3 Date: Mon, 27 Dec 2021 14:53:18 +0100
4 Subject: [PATCH] [3.2.x] Fixed CVE-2021-45116 -- Fixed potential information
5 disclosure in dictsort template filter.
6
7 Thanks to Dennis Brinkrolf for the report.
8
9 Co-authored-by: Adam Johnson <me@adamj.eu>
10 ---
11 django/template/defaultfilters.py | 22 +++++--
12 docs/ref/templates/builtins.txt | 7 +++
13 docs/releases/2.2.26.txt | 16 +++++
14 docs/releases/3.2.11.txt | 16 +++++
15 .../filter_tests/test_dictsort.py | 59 ++++++++++++++++++-
16 .../filter_tests/test_dictsortreversed.py | 6 ++
17 6 files changed, 119 insertions(+), 7 deletions(-)
18
19 diff --git a/django/template/defaultfilters.py b/django/template/defaultfilters.py
20 index 1c844580c651..92050122abdf 100644
21 --- a/django/template/defaultfilters.py
22 +++ b/django/template/defaultfilters.py
23 @@ -22,7 +22,7 @@
24 from django.utils.timesince import timesince, timeuntil
25 from django.utils.translation import gettext, ngettext
26
27 -from .base import Variable, VariableDoesNotExist
28 +from .base import VARIABLE_ATTRIBUTE_SEPARATOR
29 from .library import Library
30
31 register = Library()
32 @@ -481,7 +481,7 @@ def striptags(value):
33 def _property_resolver(arg):
34 """
35 When arg is convertible to float, behave like operator.itemgetter(arg)
36 - Otherwise, behave like Variable(arg).resolve
37 + Otherwise, chain __getitem__() and getattr().
38
39 >>> _property_resolver(1)('abc')
40 'b'
41 @@ -499,7 +499,19 @@ def _property_resolver(arg):
42 try:
43 float(arg)
44 except ValueError:
45 - return Variable(arg).resolve
46 + if VARIABLE_ATTRIBUTE_SEPARATOR + '_' in arg or arg[0] == '_':
47 + raise AttributeError('Access to private variables is forbidden.')
48 + parts = arg.split(VARIABLE_ATTRIBUTE_SEPARATOR)
49 +
50 + def resolve(value):
51 + for part in parts:
52 + try:
53 + value = value[part]
54 + except (AttributeError, IndexError, KeyError, TypeError, ValueError):
55 + value = getattr(value, part)
56 + return value
57 +
58 + return resolve
59 else:
60 return itemgetter(arg)
61
62 @@ -512,7 +524,7 @@ def dictsort(value, arg):
63 """
64 try:
65 return sorted(value, key=_property_resolver(arg))
66 - except (TypeError, VariableDoesNotExist):
67 + except (AttributeError, TypeError):
68 return ''
69
70
71 @@ -524,7 +536,7 @@ def dictsortreversed(value, arg):
72 """
73 try:
74 return sorted(value, key=_property_resolver(arg), reverse=True)
75 - except (TypeError, VariableDoesNotExist):
76 + except (AttributeError, TypeError):
77 return ''
78
79
80 diff --git a/docs/ref/templates/builtins.txt b/docs/ref/templates/builtins.txt
81 index 709f23172930..ee7cc0eda3dd 100644
82 --- a/docs/ref/templates/builtins.txt
83 +++ b/docs/ref/templates/builtins.txt
84 @@ -1586,6 +1586,13 @@ produce empty output::
85
86 {{ values|dictsort:"0" }}
87
88 +Ordering by elements at specified index is not supported on dictionaries.
89 +
90 +.. versionchanged:: 2.2.26
91 +
92 + In older versions, ordering elements at specified index was supported on
93 + dictionaries.
94 +
95 .. templatefilter:: dictsortreversed
96
97 ``dictsortreversed``
98 diff --git a/tests/template_tests/filter_tests/test_dictsort.py b/tests/template_tests/filter_tests/test_dictsort.py
99 index 00c2bd42cbd8..3de247fd86fa 100644
100 --- a/tests/template_tests/filter_tests/test_dictsort.py
101 +++ b/tests/template_tests/filter_tests/test_dictsort.py
102 @@ -1,9 +1,58 @@
103 -from django.template.defaultfilters import dictsort
104 +from django.template.defaultfilters import _property_resolver, dictsort
105 from django.test import SimpleTestCase
106
107
108 +class User:
109 + password = 'abc'
110 +
111 + _private = 'private'
112 +
113 + @property
114 + def test_property(self):
115 + return 'cde'
116 +
117 + def test_method(self):
118 + """This is just a test method."""
119 +
120 +
121 class FunctionTests(SimpleTestCase):
122
123 + def test_property_resolver(self):
124 + user = User()
125 + dict_data = {'a': {
126 + 'b1': {'c': 'result1'},
127 + 'b2': user,
128 + 'b3': {'0': 'result2'},
129 + 'b4': [0, 1, 2],
130 + }}
131 + list_data = ['a', 'b', 'c']
132 + tests = [
133 + ('a.b1.c', dict_data, 'result1'),
134 + ('a.b2.password', dict_data, 'abc'),
135 + ('a.b2.test_property', dict_data, 'cde'),
136 + # The method should not get called.
137 + ('a.b2.test_method', dict_data, user.test_method),
138 + ('a.b3.0', dict_data, 'result2'),
139 + (0, list_data, 'a'),
140 + ]
141 + for arg, data, expected_value in tests:
142 + with self.subTest(arg=arg):
143 + self.assertEqual(_property_resolver(arg)(data), expected_value)
144 + # Invalid lookups.
145 + fail_tests = [
146 + ('a.b1.d', dict_data, AttributeError),
147 + ('a.b2.password.0', dict_data, AttributeError),
148 + ('a.b2._private', dict_data, AttributeError),
149 + ('a.b4.0', dict_data, AttributeError),
150 + ('a', list_data, AttributeError),
151 + ('0', list_data, TypeError),
152 + (4, list_data, IndexError),
153 + ]
154 + for arg, data, expected_exception in fail_tests:
155 + with self.subTest(arg=arg):
156 + with self.assertRaises(expected_exception):
157 + _property_resolver(arg)(data)
158 +
159 def test_sort(self):
160 sorted_dicts = dictsort(
161 [{'age': 23, 'name': 'Barbara-Ann'},
162 @@ -21,7 +70,7 @@ def test_sort(self):
163
164 def test_dictsort_complex_sorting_key(self):
165 """
166 - Since dictsort uses template.Variable under the hood, it can sort
167 + Since dictsort uses dict.get()/getattr() under the hood, it can sort
168 on keys like 'foo.bar'.
169 """
170 data = [
171 @@ -60,3 +109,9 @@ def test_invalid_values(self):
172 self.assertEqual(dictsort('Hello!', 'age'), '')
173 self.assertEqual(dictsort({'a': 1}, 'age'), '')
174 self.assertEqual(dictsort(1, 'age'), '')
175 +
176 + def test_invalid_args(self):
177 + """Fail silently if invalid lookups are passed."""
178 + self.assertEqual(dictsort([{}], '._private'), '')
179 + self.assertEqual(dictsort([{'_private': 'test'}], '_private'), '')
180 + self.assertEqual(dictsort([{'nested': {'_private': 'test'}}], 'nested._private'), '')
181 diff --git a/tests/template_tests/filter_tests/test_dictsortreversed.py b/tests/template_tests/filter_tests/test_dictsortreversed.py
182 index ada199e127d2..e2e24e312849 100644
183 --- a/tests/template_tests/filter_tests/test_dictsortreversed.py
184 +++ b/tests/template_tests/filter_tests/test_dictsortreversed.py
185 @@ -46,3 +46,9 @@ def test_invalid_values(self):
186 self.assertEqual(dictsortreversed('Hello!', 'age'), '')
187 self.assertEqual(dictsortreversed({'a': 1}, 'age'), '')
188 self.assertEqual(dictsortreversed(1, 'age'), '')
189 +
190 + def test_invalid_args(self):
191 + """Fail silently if invalid lookups are passed."""
192 + self.assertEqual(dictsortreversed([{}], '._private'), '')
193 + self.assertEqual(dictsortreversed([{'_private': 'test'}], '_private'), '')
194 + self.assertEqual(dictsortreversed([{'nested': {'_private': 'test'}}], 'nested._private'), '')

  ViewVC Help
Powered by ViewVC 1.1.30