Version in base suite: 1.11.27-1~deb10u1 Base version: python-django_1.11.27-1~deb10u1 Target version: python-django_1.11.28-1~deb10u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/p/python-django/python-django_1.11.27-1~deb10u1.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/p/python-django/python-django_1.11.28-1~deb10u1.dsc Django.egg-info/PKG-INFO | 2 - Django.egg-info/SOURCES.txt | 1 PKG-INFO | 2 - debian/changelog | 16 ++++++++++++++ django/__init__.py | 2 - django/contrib/postgres/aggregates/general.py | 6 +++-- docs/releases/1.11.28.txt | 13 ++++++++++++ docs/releases/index.txt | 1 docs/releases/security.txt | 13 ++++++++++++ tests/postgres_tests/test_aggregates.py | 4 +++ tests/timezones/tests.py | 28 ++++++++++++++++++++------ 11 files changed, 77 insertions(+), 11 deletions(-) diff -Nru python-django-1.11.27/Django.egg-info/PKG-INFO python-django-1.11.28/Django.egg-info/PKG-INFO --- python-django-1.11.27/Django.egg-info/PKG-INFO 2019-12-18 08:33:12.000000000 +0000 +++ python-django-1.11.28/Django.egg-info/PKG-INFO 2020-02-03 08:17:38.000000000 +0000 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: Django -Version: 1.11.27 +Version: 1.11.28 Summary: A high-level Python Web framework that encourages rapid development and clean, pragmatic design. Home-page: https://www.djangoproject.com/ Author: Django Software Foundation diff -Nru python-django-1.11.27/Django.egg-info/SOURCES.txt python-django-1.11.28/Django.egg-info/SOURCES.txt --- python-django-1.11.27/Django.egg-info/SOURCES.txt 2019-12-18 08:33:13.000000000 +0000 +++ python-django-1.11.28/Django.egg-info/SOURCES.txt 2020-02-03 08:17:38.000000000 +0000 @@ -3555,6 +3555,7 @@ docs/releases/1.11.25.txt docs/releases/1.11.26.txt docs/releases/1.11.27.txt +docs/releases/1.11.28.txt docs/releases/1.11.3.txt docs/releases/1.11.4.txt docs/releases/1.11.5.txt diff -Nru python-django-1.11.27/PKG-INFO python-django-1.11.28/PKG-INFO --- python-django-1.11.27/PKG-INFO 2019-12-18 08:33:15.000000000 +0000 +++ python-django-1.11.28/PKG-INFO 2020-02-03 08:17:45.000000000 +0000 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: Django -Version: 1.11.27 +Version: 1.11.28 Summary: A high-level Python Web framework that encourages rapid development and clean, pragmatic design. Home-page: https://www.djangoproject.com/ Author: Django Software Foundation diff -Nru python-django-1.11.27/debian/changelog python-django-1.11.28/debian/changelog --- python-django-1.11.27/debian/changelog 2020-01-06 15:35:55.000000000 +0000 +++ python-django-1.11.28/debian/changelog 2020-02-14 10:00:33.000000000 +0000 @@ -1,3 +1,19 @@ +python-django (1:1.11.28-1~deb10u1) buster-security; urgency=high + + * New upstream security release. (Closes: #950581) + + + - CVE-2020-7471: Potential SQL injection via StringAgg(delimiter) + + 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. + + -- Chris Lamb Fri, 14 Feb 2020 10:00:33 +0000 + python-django (1:1.11.27-1~deb10u1) buster-security; urgency=high * New upstream security release. (Closes: #946937) diff -Nru python-django-1.11.27/django/__init__.py python-django-1.11.28/django/__init__.py --- python-django-1.11.27/django/__init__.py 2019-12-18 08:32:18.000000000 +0000 +++ python-django-1.11.28/django/__init__.py 2020-02-03 08:16:32.000000000 +0000 @@ -2,7 +2,7 @@ from django.utils.version import get_version -VERSION = (1, 11, 27, 'final', 0) +VERSION = (1, 11, 28, 'final', 0) __version__ = get_version(VERSION) diff -Nru python-django-1.11.27/django/contrib/postgres/aggregates/general.py python-django-1.11.28/django/contrib/postgres/aggregates/general.py --- python-django-1.11.27/django/contrib/postgres/aggregates/general.py 2019-12-18 08:31:54.000000000 +0000 +++ python-django-1.11.28/django/contrib/postgres/aggregates/general.py 2020-02-03 08:16:09.000000000 +0000 @@ -1,4 +1,5 @@ from django.contrib.postgres.fields import JSONField +from django.db.models import Value from django.db.models.aggregates import Aggregate __all__ = [ @@ -43,11 +44,12 @@ class StringAgg(Aggregate): function = 'STRING_AGG' - template = "%(function)s(%(distinct)s%(expressions)s, '%(delimiter)s')" + template = '%(function)s(%(distinct)s%(expressions)s)' def __init__(self, expression, delimiter, distinct=False, **extra): distinct = 'DISTINCT ' if distinct else '' - super(StringAgg, self).__init__(expression, delimiter=delimiter, distinct=distinct, **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 -Nru python-django-1.11.27/docs/releases/1.11.28.txt python-django-1.11.28/docs/releases/1.11.28.txt --- python-django-1.11.27/docs/releases/1.11.28.txt 1970-01-01 00:00:00.000000000 +0000 +++ python-django-1.11.28/docs/releases/1.11.28.txt 2020-02-03 07:49:13.000000000 +0000 @@ -0,0 +1,13 @@ +============================ +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``. diff -Nru python-django-1.11.27/docs/releases/index.txt python-django-1.11.28/docs/releases/index.txt --- python-django-1.11.27/docs/releases/index.txt 2019-12-18 08:31:54.000000000 +0000 +++ python-django-1.11.28/docs/releases/index.txt 2020-02-03 08:16:10.000000000 +0000 @@ -26,6 +26,7 @@ .. toctree:: :maxdepth: 1 + 1.11.28 1.11.27 1.11.26 1.11.25 diff -Nru python-django-1.11.27/docs/releases/security.txt python-django-1.11.28/docs/releases/security.txt --- python-django-1.11.27/docs/releases/security.txt 2019-12-18 08:31:54.000000000 +0000 +++ python-django-1.11.28/docs/releases/security.txt 2020-02-03 08:16:10.000000000 +0000 @@ -1029,3 +1029,16 @@ * Django 2.2 :commit:`(patch) ` * Django 2.1 :commit:`(patch) <5d50a2e5fa36ad23ab532fc54cf4073de84b3306>` * Django 1.11 :commit:`(patch) <869b34e9b3be3a4cfcb3a145f218ffd3f5e3fd79>` + +December 18, 2019 - :cve:`2019-19844` +------------------------------------- + +Potential account hijack via password reset form. `Full description +`__ + +Versions affected +~~~~~~~~~~~~~~~~~ + +* Django 3.0 :commit:`(patch) <302a4ff1e8b1c798aab97673909c7a3dfda42c26>` +* Django 2.2 :commit:`(patch) <4d334bea06cac63dc1272abcec545b85136cca0e>` +* Django 1.11 :commit:`(patch) ` diff -Nru python-django-1.11.27/tests/postgres_tests/test_aggregates.py python-django-1.11.28/tests/postgres_tests/test_aggregates.py --- python-django-1.11.27/tests/postgres_tests/test_aggregates.py 2019-12-18 08:31:54.000000000 +0000 +++ python-django-1.11.28/tests/postgres_tests/test_aggregates.py 2020-02-03 08:16:11.000000000 +0000 @@ -108,6 +108,10 @@ 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'}) diff -Nru python-django-1.11.27/tests/timezones/tests.py python-django-1.11.28/tests/timezones/tests.py --- python-django-1.11.27/tests/timezones/tests.py 2019-12-18 08:31:54.000000000 +0000 +++ python-django-1.11.28/tests/timezones/tests.py 2020-02-03 08:16:11.000000000 +0000 @@ -36,6 +36,12 @@ AllDayEvent, Event, MaybeEvent, Session, SessionEvent, Timestamp, ) +try: + import yaml + HAS_YAML = True +except ImportError: + HAS_YAML = False + # These tests use the EAT (Eastern Africa Time) and ICT (Indochina Time) # who don't have Daylight Saving Time, so we can represent them easily # with FixedOffset, and use them directly as tzinfo in the constructors. @@ -662,9 +668,10 @@ # Backend-specific notes: # - JSON supports only milliseconds, microseconds will be truncated. - # - PyYAML dumps the UTC offset correctly for timezone-aware datetimes, - # but when it loads this representation, it subtracts the offset and - # returns a naive datetime object in UTC. See ticket #18867. + # - PyYAML dumps the UTC offset correctly for timezone-aware datetimes. + # When PyYAML < 5.3 loads this representation, it subtracts the offset + # and returns a naive datetime object in UTC. PyYAML 5.3+ loads timezones + # correctly. # Tests are adapted to take these quirks into account. def assert_python_contains_datetime(self, objects, dt): @@ -751,7 +758,10 @@ data = serializers.serialize('yaml', [Event(dt=dt)], default_flow_style=None) self.assert_yaml_contains_datetime(data, "2011-09-01 17:20:30.405060+07:00") obj = next(serializers.deserialize('yaml', data)).object - self.assertEqual(obj.dt.replace(tzinfo=UTC), dt) + if HAS_YAML and yaml.__version__ < '5.3': + self.assertEqual(obj.dt.replace(tzinfo=UTC), dt) + else: + self.assertEqual(obj.dt, dt) def test_aware_datetime_in_utc(self): dt = datetime.datetime(2011, 9, 1, 10, 20, 30, tzinfo=UTC) @@ -799,7 +809,10 @@ data = serializers.serialize('yaml', [Event(dt=dt)], default_flow_style=None) self.assert_yaml_contains_datetime(data, "2011-09-01 13:20:30+03:00") obj = next(serializers.deserialize('yaml', data)).object - self.assertEqual(obj.dt.replace(tzinfo=UTC), dt) + if HAS_YAML and yaml.__version__ < '5.3': + self.assertEqual(obj.dt.replace(tzinfo=UTC), dt) + else: + self.assertEqual(obj.dt, dt) def test_aware_datetime_in_other_timezone(self): dt = datetime.datetime(2011, 9, 1, 17, 20, 30, tzinfo=ICT) @@ -823,7 +836,10 @@ data = serializers.serialize('yaml', [Event(dt=dt)], default_flow_style=None) self.assert_yaml_contains_datetime(data, "2011-09-01 17:20:30+07:00") obj = next(serializers.deserialize('yaml', data)).object - self.assertEqual(obj.dt.replace(tzinfo=UTC), dt) + if HAS_YAML and yaml.__version__ < '5.3': + self.assertEqual(obj.dt.replace(tzinfo=UTC), dt) + else: + self.assertEqual(obj.dt, dt) @override_settings(DATETIME_FORMAT='c', TIME_ZONE='Africa/Nairobi', USE_L10N=False, USE_TZ=True)