diff options
author | Florian Apolloner <florian@apolloner.eu> | 2021-12-27 14:53:18 +0100 |
---|---|---|
committer | Carlton Gibson <carlton.gibson@noumenal.es> | 2022-01-04 10:03:56 +0100 |
commit | 761f449e0daf3de06b0132bd4d6dfcdeef578e26 (patch) | |
tree | 3665faa206ffb627d944e50e047bc8689d6cacff /tests/template_tests | |
parent | 968a3d01fa79f055f93a1c3ed1535ecbcbdbb842 (diff) | |
download | django-761f449e0daf3de06b0132bd4d6dfcdeef578e26.tar.gz |
Fixed CVE-2021-45116 -- Fixed potential information disclosure in dictsort template filter.
Thanks to Dennis Brinkrolf for the report.
Co-authored-by: Adam Johnson <me@adamj.eu>
Diffstat (limited to 'tests/template_tests')
-rw-r--r-- | tests/template_tests/filter_tests/test_dictsort.py | 59 | ||||
-rw-r--r-- | tests/template_tests/filter_tests/test_dictsortreversed.py | 6 |
2 files changed, 63 insertions, 2 deletions
diff --git a/tests/template_tests/filter_tests/test_dictsort.py b/tests/template_tests/filter_tests/test_dictsort.py index 00c2bd42cb..3de247fd86 100644 --- a/tests/template_tests/filter_tests/test_dictsort.py +++ b/tests/template_tests/filter_tests/test_dictsort.py @@ -1,9 +1,58 @@ -from django.template.defaultfilters import dictsort +from django.template.defaultfilters import _property_resolver, dictsort from django.test import SimpleTestCase +class User: + password = 'abc' + + _private = 'private' + + @property + def test_property(self): + return 'cde' + + def test_method(self): + """This is just a test method.""" + + class FunctionTests(SimpleTestCase): + def test_property_resolver(self): + user = User() + dict_data = {'a': { + 'b1': {'c': 'result1'}, + 'b2': user, + 'b3': {'0': 'result2'}, + 'b4': [0, 1, 2], + }} + list_data = ['a', 'b', 'c'] + tests = [ + ('a.b1.c', dict_data, 'result1'), + ('a.b2.password', dict_data, 'abc'), + ('a.b2.test_property', dict_data, 'cde'), + # The method should not get called. + ('a.b2.test_method', dict_data, user.test_method), + ('a.b3.0', dict_data, 'result2'), + (0, list_data, 'a'), + ] + for arg, data, expected_value in tests: + with self.subTest(arg=arg): + self.assertEqual(_property_resolver(arg)(data), expected_value) + # Invalid lookups. + fail_tests = [ + ('a.b1.d', dict_data, AttributeError), + ('a.b2.password.0', dict_data, AttributeError), + ('a.b2._private', dict_data, AttributeError), + ('a.b4.0', dict_data, AttributeError), + ('a', list_data, AttributeError), + ('0', list_data, TypeError), + (4, list_data, IndexError), + ] + for arg, data, expected_exception in fail_tests: + with self.subTest(arg=arg): + with self.assertRaises(expected_exception): + _property_resolver(arg)(data) + def test_sort(self): sorted_dicts = dictsort( [{'age': 23, 'name': 'Barbara-Ann'}, @@ -21,7 +70,7 @@ class FunctionTests(SimpleTestCase): def test_dictsort_complex_sorting_key(self): """ - Since dictsort uses template.Variable under the hood, it can sort + Since dictsort uses dict.get()/getattr() under the hood, it can sort on keys like 'foo.bar'. """ data = [ @@ -60,3 +109,9 @@ class FunctionTests(SimpleTestCase): self.assertEqual(dictsort('Hello!', 'age'), '') self.assertEqual(dictsort({'a': 1}, 'age'), '') self.assertEqual(dictsort(1, 'age'), '') + + def test_invalid_args(self): + """Fail silently if invalid lookups are passed.""" + self.assertEqual(dictsort([{}], '._private'), '') + self.assertEqual(dictsort([{'_private': 'test'}], '_private'), '') + self.assertEqual(dictsort([{'nested': {'_private': 'test'}}], 'nested._private'), '') diff --git a/tests/template_tests/filter_tests/test_dictsortreversed.py b/tests/template_tests/filter_tests/test_dictsortreversed.py index ada199e127..e2e24e3128 100644 --- a/tests/template_tests/filter_tests/test_dictsortreversed.py +++ b/tests/template_tests/filter_tests/test_dictsortreversed.py @@ -46,3 +46,9 @@ class FunctionTests(SimpleTestCase): self.assertEqual(dictsortreversed('Hello!', 'age'), '') self.assertEqual(dictsortreversed({'a': 1}, 'age'), '') self.assertEqual(dictsortreversed(1, 'age'), '') + + def test_invalid_args(self): + """Fail silently if invalid lookups are passed.""" + self.assertEqual(dictsortreversed([{}], '._private'), '') + self.assertEqual(dictsortreversed([{'_private': 'test'}], '_private'), '') + self.assertEqual(dictsortreversed([{'nested': {'_private': 'test'}}], 'nested._private'), '') |