1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
|
From: Chris Lamb <lamby@debian.org>
Date: Sat, 15 Feb 2020 10:22:47 +0000
Subject: CVE-2020-7471 -- Properly escape StringAgg(delimiter) parameter
---
django/contrib/postgres/aggregates/general.py | 5 +++--
tests/postgres_tests/test_aggregates.py | 4 ++++
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/django/contrib/postgres/aggregates/general.py b/django/contrib/postgres/aggregates/general.py
index 1dda69c..71a7237 100644
--- a/django/contrib/postgres/aggregates/general.py
+++ b/django/contrib/postgres/aggregates/general.py
@@ -32,10 +32,11 @@ class BoolOr(Aggregate):
class StringAgg(Aggregate):
function = 'STRING_AGG'
- template = "%(function)s(%(expressions)s, '%(delimiter)s')"
+ template = "%(function)s(%(distinct)s%(expressions)s)"
def __init__(self, expression, delimiter, **extra):
- super(StringAgg, self).__init__(expression, delimiter=delimiter, **extra)
+ delimiter_expr = Value(str(delimiter))
+ super(StringAgg, self).__init__(expression, delimiter_expr, distinct=distinct, **extra)
def convert_value(self, value, expression, connection, context):
if not value:
diff --git a/tests/postgres_tests/test_aggregates.py b/tests/postgres_tests/test_aggregates.py
index 07e4ea0..b4b4e5b 100644
--- a/tests/postgres_tests/test_aggregates.py
+++ b/tests/postgres_tests/test_aggregates.py
@@ -101,6 +101,10 @@ class TestGeneralAggregate(PostgreSQLTestCase):
with self.assertRaises(TypeError):
AggregateTestModel.objects.aggregate(stringagg=StringAgg('char_field'))
+ def test_string_agg_delimiter_escaping(self):
+ values = AggregateTestModel.objects.aggregate(stringagg=StringAgg('char_field', delimiter="'"))
+ self.assertEqual(values, {'stringagg': "Foo1'Foo2'Foo3'Foo4"})
+
def test_string_agg_charfield(self):
values = AggregateTestModel.objects.aggregate(stringagg=StringAgg('char_field', delimiter=';'))
self.assertEqual(values, {'stringagg': 'Foo1;Foo2;Foo3;Foo4'})
|