A RetroSearch Logo

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

Search Query:

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

[2.2.x] Fixed CVE-2022-28346 -- Protected QuerySet.annotate(), aggreg… · django/django@2c09e68 · GitHub

File tree Expand file treeCollapse file tree 6 files changed

+83

-0

lines changed

Filter options

Expand file treeCollapse file tree 6 files changed

+83

-0

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

@@ -8,6 +8,7 @@

8 8

"""

9 9

import difflib

10 10

import functools

11 +

import re

11 12

from collections import Counter, OrderedDict, namedtuple

12 13

from collections.abc import Iterator, Mapping

13 14

from itertools import chain, count, product

@@ -40,6 +41,10 @@

40 41 41 42

__all__ = ['Query', 'RawQuery']

42 43 44 +

# Quotation marks ('"`[]), whitespace characters, semicolons, or inline

45 +

# SQL comments are forbidden in column aliases.

46 +

FORBIDDEN_ALIAS_PATTERN = re.compile(r"['`\"\]\[;\s]|--|/\*|\*/")

47 + 43 48 44 49

def get_field_names_from_opts(opts):

45 50

return set(chain.from_iterable(

@@ -994,8 +999,16 @@ def join_parent_model(self, opts, model, alias, seen):

994 999

alias = seen[int_model] = join_info.joins[-1]

995 1000

return alias or seen[None]

996 1001 1002 +

def check_alias(self, alias):

1003 +

if FORBIDDEN_ALIAS_PATTERN.search(alias):

1004 +

raise ValueError(

1005 +

"Column aliases cannot contain whitespace characters, quotation marks, "

1006 +

"semicolons, or SQL comments."

1007 +

)

1008 + 997 1009

def add_annotation(self, annotation, alias, is_summary=False):

998 1010

"""Add a single annotation expression to the Query."""

1011 +

self.check_alias(alias)

999 1012

annotation = annotation.resolve_expression(self, allow_joins=True, reuse=None,

1000 1013

summarize=is_summary)

1001 1014

self.append_annotation_mask([alias])

@@ -1873,6 +1886,7 @@ def add_extra(self, select, select_params, where, params, tables, order_by):

1873 1886

else:

1874 1887

param_iter = iter([])

1875 1888

for name, entry in select.items():

1889 +

self.check_alias(name)

1876 1890

entry = str(entry)

1877 1891

entry_params = []

1878 1892

pos = entry.find("%s")

Original file line number Diff line number Diff line change

@@ -5,3 +5,11 @@ Django 2.2.28 release notes

5 5

*April 11, 2022*

6 6 7 7

Django 2.2.28 fixes two security issues with severity "high" in 2.2.27.

8 + 9 +

CVE-2022-28346: Potential SQL injection in ``QuerySet.annotate()``, ``aggregate()``, and ``extra()``

10 +

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

11 + 12 +

:meth:`.QuerySet.annotate`, :meth:`~.QuerySet.aggregate`, and

13 +

:meth:`~.QuerySet.extra` methods were subject to SQL injection in column

14 +

aliases, using a suitably crafted dictionary, with dictionary expansion, as the

15 +

``**kwargs`` passed to these methods.

Original file line number Diff line number Diff line change

@@ -1114,3 +1114,12 @@ def test_arguments_must_be_expressions(self):

1114 1114

Book.objects.aggregate(is_book=True)

1115 1115

with self.assertRaisesMessage(TypeError, msg % ', '.join([str(FloatField()), 'True'])):

1116 1116

Book.objects.aggregate(FloatField(), Avg('price'), is_book=True)

1117 + 1118 +

def test_alias_sql_injection(self):

1119 +

crafted_alias = """injected_name" from "aggregation_author"; --"""

1120 +

msg = (

1121 +

"Column aliases cannot contain whitespace characters, quotation marks, "

1122 +

"semicolons, or SQL comments."

1123 +

)

1124 +

with self.assertRaisesMessage(ValueError, msg):

1125 +

Author.objects.aggregate(**{crafted_alias: Avg("age")})

Original file line number Diff line number Diff line change

@@ -598,3 +598,37 @@ def test_annotation_filter_with_subquery(self):

598 598

total_books=Subquery(long_books_qs, output_field=IntegerField()),

599 599

).values('name')

600 600

self.assertCountEqual(publisher_books_qs, [{'name': 'Sams'}, {'name': 'Morgan Kaufmann'}])

601 + 602 +

def test_alias_sql_injection(self):

603 +

crafted_alias = """injected_name" from "annotations_book"; --"""

604 +

msg = (

605 +

"Column aliases cannot contain whitespace characters, quotation marks, "

606 +

"semicolons, or SQL comments."

607 +

)

608 +

with self.assertRaisesMessage(ValueError, msg):

609 +

Book.objects.annotate(**{crafted_alias: Value(1)})

610 + 611 +

def test_alias_forbidden_chars(self):

612 +

tests = [

613 +

'al"ias',

614 +

"a'lias",

615 +

"ali`as",

616 +

"alia s",

617 +

"alias\t",

618 +

"ali\nas",

619 +

"alias--",

620 +

"ali/*as",

621 +

"alias*/",

622 +

"alias;",

623 +

# [] are used by MSSQL.

624 +

"alias[",

625 +

"alias]",

626 +

]

627 +

msg = (

628 +

"Column aliases cannot contain whitespace characters, quotation marks, "

629 +

"semicolons, or SQL comments."

630 +

)

631 +

for crafted_alias in tests:

632 +

with self.subTest(crafted_alias):

633 +

with self.assertRaisesMessage(ValueError, msg):

634 +

Book.objects.annotate(**{crafted_alias: Value(1)})

Original file line number Diff line number Diff line change

@@ -27,6 +27,15 @@ def test_values_expression(self):

27 27

[{'salary': 10}, {'salary': 20}, {'salary': 30}],

28 28

)

29 29 30 +

def test_values_expression_alias_sql_injection(self):

31 +

crafted_alias = """injected_name" from "expressions_company"; --"""

32 +

msg = (

33 +

"Column aliases cannot contain whitespace characters, quotation marks, "

34 +

"semicolons, or SQL comments."

35 +

)

36 +

with self.assertRaisesMessage(ValueError, msg):

37 +

Company.objects.values(**{crafted_alias: F("ceo__salary")})

38 + 30 39

def test_values_expression_group_by(self):

31 40

# values() applies annotate() first, so values selected are grouped by

32 41

# id, not firstname.

Original file line number Diff line number Diff line change

@@ -1737,6 +1737,15 @@ def test_extra_select_literal_percent_s(self):

1737 1737

'bar %s'

1738 1738

)

1739 1739 1740 +

def test_extra_select_alias_sql_injection(self):

1741 +

crafted_alias = """injected_name" from "queries_note"; --"""

1742 +

msg = (

1743 +

"Column aliases cannot contain whitespace characters, quotation marks, "

1744 +

"semicolons, or SQL comments."

1745 +

)

1746 +

with self.assertRaisesMessage(ValueError, msg):

1747 +

Note.objects.extra(select={crafted_alias: "1"})

1748 + 1740 1749 1741 1750

class SelectRelatedTests(TestCase):

1742 1751

def test_tickets_3045_3288(self):

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