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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1766876 - (hide 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 neoclust 1766876 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