CVE-2020-7471 (Other, published 2020-02-03T12:15Z)
Description: value: Django 1.11 before 1.11.28, 2.2 before 2.2.10, and 3.0 before 3.0.3 allows SQL Injection if untrusted data is used as a StringAgg delimiter (e.g., in Django applications that offer downloads of data as a series of rows with a user-specified column delimiter). By passing a suitably crafted delimiter to a contrib.postgres.aggregates.StringAgg instance, it was possible to break escaping and inject malicious SQL.
Severity: HIGH (CVSS v3 base score: 9.8)
Weakness: CWE-89 \u2014 Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')
The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component. Without sufficient removal or quoting of SQL syntax in user-controllable inputs, the generated SQL query can cause those inputs to be interpreted as SQL instead of ordinary user data.
Repository: https://github.com/django/django
Files changed:
django/contrib/postgres/aggregates/general.py
django/contrib/postgres/aggregates/mixins.py
docs/releases/1.11.28.txt
docs/releases/2.2.10.txt
docs/releases/3.0.3.txt
docs/releases/index.txt
tests/postgres_tests/test_aggregates.py
Commit message: Fixed CVE-2020-7471 -- Properly escaped StringAgg(delimiter) parameter.


Vulnerable code:
    template = "%(function)s(%(distinct)s%(expressions)s, '%(delimiter)s'%(ordering)s)"
        super().__init__(expression, delimiter=delimiter, **extra)
    def __init__(self, expression, ordering=(), **extra):
        super().__init__(expression, **extra)
Django 3.0.3 fixes several bugs in 3.0.2.

Fixed code:
from django.db.models import Value
    template = '%(function)s(%(distinct)s%(expressions)s %(ordering)s)'
        delimiter_expr = Value(str(delimiter))
        super().__init__(expression, delimiter_expr, **extra)
    def __init__(self, *expressions, ordering=(), **extra):
        super().__init__(*expressions, **extra)
============================
Django 1.11.28 release notes
============================

*February 3, 2020*

Django 1.11.28 fixes a security issue in 1.11.27.

CVE-2020-7471: Potential SQL injection via ``StringAgg(delimiter)``
===================================================================

:class:`~django.contrib.postgres.aggregates.StringAgg` aggregation function was
subject to SQL injection, using a suitably crafted ``delimiter``.
===========================
Django 2.2.10 release notes
===========================

*February 3, 2020*

Django 2.2.10 fixes a security issue in 2.2.9.

CVE-2020-7471: Potential SQL injection via ``StringAgg(delimiter)``
===================================================================

:class:`~django.contrib.postgres.aggregates.StringAgg` aggregation function was
subject to SQL injection, using a suitably crafted ``delimiter``.
Django 3.0.3 fixes a security issue and several bugs in 3.0.2.

CVE-2020-7471: Potential SQL injection via ``StringAgg(delimiter)``
===================================================================

:class:`~django.contrib.postgres.aggregates.StringAgg` aggregation function was
subject to SQL injection, using a suitably crafted ``delimiter``.
   2.2.10
   1.11.28
    def test_string_agg_delimiter_escaping(self):
        values = AggregateTestModel.objects.aggregate(stringagg=StringAgg('char_field', delimiter="'"))
        self.assertEqual(values, {'stringagg': "Foo1'Foo2'Foo4'Foo3"})