1
0
mirror of https://github.com/django/django.git synced 2025-03-13 19:00:45 +00:00

[4.2.x] 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 18:19:13 +02:00 committed by Sarah Boyce
parent efea1ef7e2
commit f4af67b9b4
4 changed files with 31 additions and 2 deletions

View File

@ -2415,6 +2415,8 @@ class Query(BaseExpression):
self.has_select_fields = True
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

@ -106,3 +106,10 @@ class UUIDPK(models.Model):
class UUID(models.Model):
uuid = models.UUIDField(null=True)
uuid_fk = models.ForeignKey(UUIDPK, models.CASCADE, null=True)
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.