Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit7376bcb

Browse files
charettessarahboyce
authored andcommitted
[4.2.x] FixedCVE-2024-53908 -- Prevented SQL injections in direct HasKeyLookup usage on Oracle.
Thanks Seokchan Yoon for the report, and Mariusz Felisiak and SarahBoyce for the reviews.
1 parent790eb05 commit7376bcb

File tree

3 files changed

+53
-18
lines changed

3 files changed

+53
-18
lines changed

‎django/db/models/fields/json.py‎

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -216,20 +216,18 @@ def compile_json_path_final_key(self, key_transform):
216216
# Compile the final key without interpreting ints as array elements.
217217
return".%s"%json.dumps(key_transform)
218218

219-
defas_sql(self,compiler,connection,template=None):
219+
def_as_sql_parts(self,compiler,connection):
220220
# Process JSON path from the left-hand side.
221221
ifisinstance(self.lhs,KeyTransform):
222-
lhs,lhs_params,lhs_key_transforms=self.lhs.preprocess_lhs(
222+
lhs_sql,lhs_params,lhs_key_transforms=self.lhs.preprocess_lhs(
223223
compiler,connection
224224
)
225225
lhs_json_path=compile_json_path(lhs_key_transforms)
226226
else:
227-
lhs,lhs_params=self.process_lhs(compiler,connection)
227+
lhs_sql,lhs_params=self.process_lhs(compiler,connection)
228228
lhs_json_path="$"
229-
sql=template%lhs
230229
# Process JSON path from the right-hand side.
231230
rhs=self.rhs
232-
rhs_params= []
233231
ifnotisinstance(rhs, (list,tuple)):
234232
rhs= [rhs]
235233
forkeyinrhs:
@@ -240,24 +238,43 @@ def as_sql(self, compiler, connection, template=None):
240238
*rhs_key_transforms,final_key=rhs_key_transforms
241239
rhs_json_path=compile_json_path(rhs_key_transforms,include_root=False)
242240
rhs_json_path+=self.compile_json_path_final_key(final_key)
243-
rhs_params.append(lhs_json_path+rhs_json_path)
241+
yieldlhs_sql,lhs_params,lhs_json_path+rhs_json_path
242+
243+
def_combine_sql_parts(self,parts):
244244
# Add condition for each key.
245245
ifself.logical_operator:
246-
sql="(%s)"%self.logical_operator.join([sql]*len(rhs_params))
247-
returnsql,tuple(lhs_params)+tuple(rhs_params)
246+
return"(%s)"%self.logical_operator.join(parts)
247+
return"".join(parts)
248+
249+
defas_sql(self,compiler,connection,template=None):
250+
sql_parts= []
251+
params= []
252+
forlhs_sql,lhs_params,rhs_json_pathinself._as_sql_parts(
253+
compiler,connection
254+
):
255+
sql_parts.append(template% (lhs_sql,"%s"))
256+
params.extend(lhs_params+ [rhs_json_path])
257+
returnself._combine_sql_parts(sql_parts),tuple(params)
248258

249259
defas_mysql(self,compiler,connection):
250260
returnself.as_sql(
251-
compiler,connection,template="JSON_CONTAINS_PATH(%s, 'one', %%s)"
261+
compiler,connection,template="JSON_CONTAINS_PATH(%s, 'one', %s)"
252262
)
253263

254264
defas_oracle(self,compiler,connection):
255-
sql,params=self.as_sql(
256-
compiler,connection,template="JSON_EXISTS(%s, '%%s')"
257-
)
258-
# Add paths directly into SQL because path expressions cannot be passed
259-
# as bind variables on Oracle.
260-
returnsql%tuple(params), []
265+
template="JSON_EXISTS(%s, '%s')"
266+
sql_parts= []
267+
params= []
268+
forlhs_sql,lhs_params,rhs_json_pathinself._as_sql_parts(
269+
compiler,connection
270+
):
271+
# Add right-hand-side directly into SQL because it cannot be passed
272+
# as bind variables to JSON_EXISTS. It might result in invalid
273+
# queries but it is assumed that it cannot be evaded because the
274+
# path is JSON serialized.
275+
sql_parts.append(template% (lhs_sql,rhs_json_path))
276+
params.extend(lhs_params)
277+
returnself._combine_sql_parts(sql_parts),tuple(params)
261278

262279
defas_postgresql(self,compiler,connection):
263280
ifisinstance(self.rhs,KeyTransform):
@@ -269,7 +286,7 @@ def as_postgresql(self, compiler, connection):
269286

270287
defas_sqlite(self,compiler,connection):
271288
returnself.as_sql(
272-
compiler,connection,template="JSON_TYPE(%s, %%s) IS NOT NULL"
289+
compiler,connection,template="JSON_TYPE(%s, %s) IS NOT NULL"
273290
)
274291

275292

@@ -467,9 +484,9 @@ def as_oracle(self, compiler, connection):
467484
return"(NOT %s OR %s IS NULL)"% (sql,lhs),tuple(params)+tuple(lhs_params)
468485

469486
defas_sqlite(self,compiler,connection):
470-
template="JSON_TYPE(%s, %%s) IS NULL"
487+
template="JSON_TYPE(%s, %s) IS NULL"
471488
ifnotself.rhs:
472-
template="JSON_TYPE(%s, %%s) IS NOT NULL"
489+
template="JSON_TYPE(%s, %s) IS NOT NULL"
473490
returnHasKeyOrArrayIndex(self.lhs.lhs,self.lhs.key_name).as_sql(
474491
compiler,
475492
connection,

‎docs/releases/4.2.17.txt‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,12 @@ Remember that absolutely NO guarantee is provided about the results of
2222
``strip_tags()`` being HTML safe. So NEVER mark safe the result of a
2323
``strip_tags()`` call without escaping it first, for example with
2424
:func:`django.utils.html.escape`.
25+
26+
CVE-2024-53908: Potential SQL injection via ``HasKey(lhs, rhs)`` on Oracle
27+
==========================================================================
28+
29+
Direct usage of the ``django.db.models.fields.json.HasKey`` lookup on Oracle
30+
was subject to SQL injection if untrusted data was used as a ``lhs`` value.
31+
32+
Applications that use the :lookup:`has_key <jsonfield.has_key>` lookup through
33+
the ``__`` syntax are unaffected.

‎tests/model_fields/test_jsonfield.py‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
fromdjango.db.models.expressionsimportRawSQL
3030
fromdjango.db.models.fields.jsonimport (
3131
KT,
32+
HasKey,
3233
KeyTextTransform,
3334
KeyTransform,
3435
KeyTransformFactory,
@@ -607,6 +608,14 @@ def test_has_key_deep(self):
607608
[expected],
608609
)
609610

611+
deftest_has_key_literal_lookup(self):
612+
self.assertSequenceEqual(
613+
NullableJSONModel.objects.filter(
614+
HasKey(Value({"foo":"bar"},JSONField()),"foo")
615+
).order_by("id"),
616+
self.objs,
617+
)
618+
610619
deftest_has_key_list(self):
611620
obj=NullableJSONModel.objects.create(value=[{"a":1}, {"b":"x"}])
612621
tests= [

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp