1
0
mirror of https://github.com/django/django.git synced 2024-12-22 17:16:24 +00:00

Fixed CVE-2024-42005 -- Mitigated QuerySet.values() SQL injection attacks against JSON fields.

Thanks Eyal (eyalgabay) for the report.
This commit is contained in:
Simon Charette 2024-07-25 12:19:13 -04:00 committed by Sarah Boyce
parent 5f1757142f
commit c87bfaacf8
5 changed files with 38 additions and 2 deletions

View File

@ -2461,6 +2461,8 @@ class Query(BaseExpression):
selected = {}
if fields:
for field in fields:
self.check_alias(field)
field_names = []
extra_names = []
annotation_names = []

View File

@ -30,6 +30,13 @@ CVE-2024-41991: Potential denial-of-service vulnerability in ``django.utils.html
subject to a potential denial-of-service attack via certain inputs with a very
large number of Unicode characters.
CVE-2024-42005: Potential SQL injection in ``QuerySet.values()`` and ``values_list()``
======================================================================================
:meth:`.QuerySet.values` and :meth:`~.QuerySet.values_list` methods on models
with a ``JSONField`` were subject to SQL injection in column aliases, via a
crafted JSON object key as a passed ``*arg``.
Bugfixes
========

View File

@ -30,6 +30,13 @@ CVE-2024-41991: Potential denial-of-service vulnerability in ``django.utils.html
subject to a potential denial-of-service attack via certain inputs with a very
large number of Unicode characters.
CVE-2024-42005: Potential SQL injection in ``QuerySet.values()`` and ``values_list()``
======================================================================================
:meth:`.QuerySet.values` and :meth:`~.QuerySet.values_list` methods on models
with a ``JSONField`` were subject to SQL injection in column aliases, via a
crafted JSON object key as a passed ``*arg``.
Bugfixes
========

View File

@ -115,3 +115,10 @@ class UUID(models.Model):
class Text(models.Model):
name = models.TextField()
class JSONFieldModel(models.Model):
data = models.JSONField(null=True)
class Meta:
required_db_features = {"supports_json_field"}

View File

@ -1,7 +1,7 @@
from django.db.models import F, Sum
from django.test import TestCase
from django.test import TestCase, skipUnlessDBFeature
from .models import Company, Employee
from .models import Company, Employee, JSONFieldModel
class ValuesExpressionsTests(TestCase):
@ -43,6 +43,19 @@ class ValuesExpressionsTests(TestCase):
with self.assertRaisesMessage(ValueError, msg):
Company.objects.values(**{crafted_alias: F("ceo__salary")})
@skipUnlessDBFeature("supports_json_field")
def test_values_expression_alias_sql_injection_json_field(self):
crafted_alias = """injected_name" from "expressions_company"; --"""
msg = (
"Column aliases cannot contain whitespace characters, quotation marks, "
"semicolons, or SQL comments."
)
with self.assertRaisesMessage(ValueError, msg):
JSONFieldModel.objects.values(f"data__{crafted_alias}")
with self.assertRaisesMessage(ValueError, msg):
JSONFieldModel.objects.values_list(f"data__{crafted_alias}")
def test_values_expression_group_by(self):
# values() applies annotate() first, so values selected are grouped by
# id, not firstname.