Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 505826b

Browse files
charettescarltongibson
authored andcommitted
[3.0.x] Fixed CVE-2020-7471 -- Properly escaped StringAgg(delimiter) parameter.
1 parent 673444d commit 505826b

File tree

7 files changed

+45
-5
lines changed

7 files changed

+45
-5
lines changed

django/contrib/postgres/aggregates/general.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from django.contrib.postgres.fields import ArrayField, JSONField
2+
from django.db.models import Value
23
from django.db.models.aggregates import Aggregate
34

45
from .mixins import OrderableAggMixin
@@ -51,11 +52,12 @@ def convert_value(self, value, expression, connection):
5152

5253
class StringAgg(OrderableAggMixin, Aggregate):
5354
function = 'STRING_AGG'
54-
template = "%(function)s(%(distinct)s%(expressions)s, '%(delimiter)s'%(ordering)s)"
55+
template = '%(function)s(%(distinct)s%(expressions)s %(ordering)s)'
5556
allow_distinct = True
5657

5758
def __init__(self, expression, delimiter, **extra):
58-
super().__init__(expression, delimiter=delimiter, **extra)
59+
delimiter_expr = Value(str(delimiter))
60+
super().__init__(expression, delimiter_expr, **extra)
5961

6062
def convert_value(self, value, expression, connection):
6163
if not value:

django/contrib/postgres/aggregates/mixins.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
class OrderableAggMixin:
55

6-
def __init__(self, expression, ordering=(), **extra):
6+
def __init__(self, *expressions, ordering=(), **extra):
77
if not isinstance(ordering, (list, tuple)):
88
ordering = [ordering]
99
ordering = ordering or []
@@ -12,7 +12,7 @@ def __init__(self, expression, ordering=(), **extra):
1212
(OrderBy(F(o[1:]), descending=True) if isinstance(o, str) and o[0] == '-' else o)
1313
for o in ordering
1414
)
15-
super().__init__(expression, **extra)
15+
super().__init__(*expressions, **extra)
1616
self.ordering = self._parse_expressions(*ordering)
1717

1818
def resolve_expression(self, *args, **kwargs):

docs/releases/1.11.28.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
============================
2+
Django 1.11.28 release notes
3+
============================
4+
5+
*February 3, 2020*
6+
7+
Django 1.11.28 fixes a security issue in 1.11.27.
8+
9+
CVE-2020-7471: Potential SQL injection via ``StringAgg(delimiter)``
10+
===================================================================
11+
12+
:class:`~django.contrib.postgres.aggregates.StringAgg` aggregation function was
13+
subject to SQL injection, using a suitably crafted ``delimiter``.

docs/releases/2.2.10.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
===========================
2+
Django 2.2.10 release notes
3+
===========================
4+
5+
*February 3, 2020*
6+
7+
Django 2.2.10 fixes a security issue in 2.2.9.
8+
9+
CVE-2020-7471: Potential SQL injection via ``StringAgg(delimiter)``
10+
===================================================================
11+
12+
:class:`~django.contrib.postgres.aggregates.StringAgg` aggregation function was
13+
subject to SQL injection, using a suitably crafted ``delimiter``.

docs/releases/3.0.3.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,13 @@ Django 3.0.3 release notes
44

55
*Expected February 3, 2020*
66

7-
Django 3.0.3 fixes several bugs in 3.0.2.
7+
Django 3.0.3 fixes a security issue and several bugs in 3.0.2.
8+
9+
CVE-2020-7471: Potential SQL injection via ``StringAgg(delimiter)``
10+
===================================================================
11+
12+
:class:`~django.contrib.postgres.aggregates.StringAgg` aggregation function was
13+
subject to SQL injection, using a suitably crafted ``delimiter``.
814

915
Bugfixes
1016
========

docs/releases/index.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ versions of the documentation contain the release notes for any later releases.
3535
.. toctree::
3636
:maxdepth: 1
3737

38+
2.2.10
3839
2.2.9
3940
2.2.8
4041
2.2.7
@@ -93,6 +94,7 @@ versions of the documentation contain the release notes for any later releases.
9394
.. toctree::
9495
:maxdepth: 1
9596

97+
1.11.28
9698
1.11.27
9799
1.11.26
98100
1.11.25

tests/postgres_tests/test_aggregates.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,10 @@ def test_string_agg_requires_delimiter(self):
163163
with self.assertRaises(TypeError):
164164
AggregateTestModel.objects.aggregate(stringagg=StringAgg('char_field'))
165165

166+
def test_string_agg_delimiter_escaping(self):
167+
values = AggregateTestModel.objects.aggregate(stringagg=StringAgg('char_field', delimiter="'"))
168+
self.assertEqual(values, {'stringagg': "Foo1'Foo2'Foo4'Foo3"})
169+
166170
def test_string_agg_charfield(self):
167171
values = AggregateTestModel.objects.aggregate(stringagg=StringAgg('char_field', delimiter=';'))
168172
self.assertEqual(values, {'stringagg': 'Foo1;Foo2;Foo4;Foo3'})

0 commit comments

Comments
 (0)