A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/django/django/commit/c7fe895bca06daf12cc1670b56eaf72a1ef27a16 below:

[3.2.x] Fixed CVE-2021-45116 -- Fixed potential information disclosur… · django/django@c7fe895 · GitHub

File tree Expand file treeCollapse file tree 6 files changed

+119

-7

lines changed

Filter options

Expand file treeCollapse file tree 6 files changed

+119

-7

lines changed Original file line number Diff line number Diff line change

@@ -22,7 +22,7 @@

22 22

from django.utils.timesince import timesince, timeuntil

23 23

from django.utils.translation import gettext, ngettext

24 24 25 -

from .base import Variable, VariableDoesNotExist

25 +

from .base import VARIABLE_ATTRIBUTE_SEPARATOR

26 26

from .library import Library

27 27 28 28

register = Library()

@@ -481,7 +481,7 @@ def striptags(value):

481 481

def _property_resolver(arg):

482 482

"""

483 483

When arg is convertible to float, behave like operator.itemgetter(arg)

484 -

Otherwise, behave like Variable(arg).resolve

484 +

Otherwise, chain __getitem__() and getattr().

485 485 486 486

>>> _property_resolver(1)('abc')

487 487

'b'

@@ -499,7 +499,19 @@ def _property_resolver(arg):

499 499

try:

500 500

float(arg)

501 501

except ValueError:

502 -

return Variable(arg).resolve

502 +

if VARIABLE_ATTRIBUTE_SEPARATOR + '_' in arg or arg[0] == '_':

503 +

raise AttributeError('Access to private variables is forbidden.')

504 +

parts = arg.split(VARIABLE_ATTRIBUTE_SEPARATOR)

505 + 506 +

def resolve(value):

507 +

for part in parts:

508 +

try:

509 +

value = value[part]

510 +

except (AttributeError, IndexError, KeyError, TypeError, ValueError):

511 +

value = getattr(value, part)

512 +

return value

513 + 514 +

return resolve

503 515

else:

504 516

return itemgetter(arg)

505 517

@@ -512,7 +524,7 @@ def dictsort(value, arg):

512 524

"""

513 525

try:

514 526

return sorted(value, key=_property_resolver(arg))

515 -

except (TypeError, VariableDoesNotExist):

527 +

except (AttributeError, TypeError):

516 528

return ''

517 529 518 530

@@ -524,7 +536,7 @@ def dictsortreversed(value, arg):

524 536

"""

525 537

try:

526 538

return sorted(value, key=_property_resolver(arg), reverse=True)

527 -

except (TypeError, VariableDoesNotExist):

539 +

except (AttributeError, TypeError):

528 540

return ''

529 541 530 542 Original file line number Diff line number Diff line change

@@ -1586,6 +1586,13 @@ produce empty output::

1586 1586 1587 1587

{{ values|dictsort:"0" }}

1588 1588 1589 +

Ordering by elements at specified index is not supported on dictionaries.

1590 + 1591 +

.. versionchanged:: 2.2.26

1592 + 1593 +

In older versions, ordering elements at specified index was supported on

1594 +

dictionaries.

1595 + 1589 1596

.. templatefilter:: dictsortreversed

1590 1597 1591 1598

``dictsortreversed``

Original file line number Diff line number Diff line change

@@ -20,3 +20,19 @@ In order to mitigate this issue, relatively long values are now ignored by

20 20 21 21

This issue has severity "medium" according to the :ref:`Django security policy

22 22

<security-disclosure>`.

23 + 24 +

CVE-2021-45116: Potential information disclosure in ``dictsort`` template filter

25 +

================================================================================

26 + 27 +

Due to leveraging the Django Template Language's variable resolution logic, the

28 +

:tfilter:`dictsort` template filter was potentially vulnerable to information

29 +

disclosure or unintended method calls, if passed a suitably crafted key.

30 + 31 +

In order to avoid this possibility, ``dictsort`` now works with a restricted

32 +

resolution logic, that will not call methods, nor allow indexing on

33 +

dictionaries.

34 + 35 +

As a reminder, all untrusted user input should be validated before use.

36 + 37 +

This issue has severity "low" according to the :ref:`Django security policy

38 +

<security-disclosure>`.

Original file line number Diff line number Diff line change

@@ -20,3 +20,19 @@ In order to mitigate this issue, relatively long values are now ignored by

20 20 21 21

This issue has severity "medium" according to the :ref:`Django security policy

22 22

<security-disclosure>`.

23 + 24 +

CVE-2021-45116: Potential information disclosure in ``dictsort`` template filter

25 +

================================================================================

26 + 27 +

Due to leveraging the Django Template Language's variable resolution logic, the

28 +

:tfilter:`dictsort` template filter was potentially vulnerable to information

29 +

disclosure or unintended method calls, if passed a suitably crafted key.

30 + 31 +

In order to avoid this possibility, ``dictsort`` now works with a restricted

32 +

resolution logic, that will not call methods, nor allow indexing on

33 +

dictionaries.

34 + 35 +

As a reminder, all untrusted user input should be validated before use.

36 + 37 +

This issue has severity "low" according to the :ref:`Django security policy

38 +

<security-disclosure>`.

Original file line number Diff line number Diff line change

@@ -1,9 +1,58 @@

1 -

from django.template.defaultfilters import dictsort

1 +

from django.template.defaultfilters import _property_resolver, dictsort

2 2

from django.test import SimpleTestCase

3 3 4 4 5 +

class User:

6 +

password = 'abc'

7 + 8 +

_private = 'private'

9 + 10 +

@property

11 +

def test_property(self):

12 +

return 'cde'

13 + 14 +

def test_method(self):

15 +

"""This is just a test method."""

16 + 17 + 5 18

class FunctionTests(SimpleTestCase):

6 19 20 +

def test_property_resolver(self):

21 +

user = User()

22 +

dict_data = {'a': {

23 +

'b1': {'c': 'result1'},

24 +

'b2': user,

25 +

'b3': {'0': 'result2'},

26 +

'b4': [0, 1, 2],

27 +

}}

28 +

list_data = ['a', 'b', 'c']

29 +

tests = [

30 +

('a.b1.c', dict_data, 'result1'),

31 +

('a.b2.password', dict_data, 'abc'),

32 +

('a.b2.test_property', dict_data, 'cde'),

33 +

# The method should not get called.

34 +

('a.b2.test_method', dict_data, user.test_method),

35 +

('a.b3.0', dict_data, 'result2'),

36 +

(0, list_data, 'a'),

37 +

]

38 +

for arg, data, expected_value in tests:

39 +

with self.subTest(arg=arg):

40 +

self.assertEqual(_property_resolver(arg)(data), expected_value)

41 +

# Invalid lookups.

42 +

fail_tests = [

43 +

('a.b1.d', dict_data, AttributeError),

44 +

('a.b2.password.0', dict_data, AttributeError),

45 +

('a.b2._private', dict_data, AttributeError),

46 +

('a.b4.0', dict_data, AttributeError),

47 +

('a', list_data, AttributeError),

48 +

('0', list_data, TypeError),

49 +

(4, list_data, IndexError),

50 +

]

51 +

for arg, data, expected_exception in fail_tests:

52 +

with self.subTest(arg=arg):

53 +

with self.assertRaises(expected_exception):

54 +

_property_resolver(arg)(data)

55 + 7 56

def test_sort(self):

8 57

sorted_dicts = dictsort(

9 58

[{'age': 23, 'name': 'Barbara-Ann'},

@@ -21,7 +70,7 @@ def test_sort(self):

21 70 22 71

def test_dictsort_complex_sorting_key(self):

23 72

"""

24 -

Since dictsort uses template.Variable under the hood, it can sort

73 +

Since dictsort uses dict.get()/getattr() under the hood, it can sort

25 74

on keys like 'foo.bar'.

26 75

"""

27 76

data = [

@@ -60,3 +109,9 @@ def test_invalid_values(self):

60 109

self.assertEqual(dictsort('Hello!', 'age'), '')

61 110

self.assertEqual(dictsort({'a': 1}, 'age'), '')

62 111

self.assertEqual(dictsort(1, 'age'), '')

112 + 113 +

def test_invalid_args(self):

114 +

"""Fail silently if invalid lookups are passed."""

115 +

self.assertEqual(dictsort([{}], '._private'), '')

116 +

self.assertEqual(dictsort([{'_private': 'test'}], '_private'), '')

117 +

self.assertEqual(dictsort([{'nested': {'_private': 'test'}}], 'nested._private'), '')

Original file line number Diff line number Diff line change

@@ -46,3 +46,9 @@ def test_invalid_values(self):

46 46

self.assertEqual(dictsortreversed('Hello!', 'age'), '')

47 47

self.assertEqual(dictsortreversed({'a': 1}, 'age'), '')

48 48

self.assertEqual(dictsortreversed(1, 'age'), '')

49 + 50 +

def test_invalid_args(self):

51 +

"""Fail silently if invalid lookups are passed."""

52 +

self.assertEqual(dictsortreversed([{}], '._private'), '')

53 +

self.assertEqual(dictsortreversed([{'_private': 'test'}], '_private'), '')

54 +

self.assertEqual(dictsortreversed([{'nested': {'_private': 'test'}}], 'nested._private'), '')

You can’t perform that action at this time.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4