Django:SQL注入在原始查询中使用子查询

2024-09-26 18:14:02 发布

您现在位置:Python中文网/ 问答频道 /正文

当我试图将未执行的查询字符串传递到原始查询中时,遇到了一个错误,使用Django recommends参数将其用作子查询:

from apps.bikeshare.models import Station
qs = Station.objects.filter(...)

subquery_string = qs.values('id').order_by().query
raw = Station.objects.raw('SELECT * FROM bikeshare_station WHERE id IN (%s)', [subquery_string])

查询打印正确的SQL(WHERE子句省略):

^{pr2}$

但是,执行原始查询(raw[0])会出现错误:

Traceback (most recent call last):
  File "/home/gbrown/Envs/bikeshare-dev/lib/python3.5/site-packages/IPython/core/interactiveshell.py", line 2847, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-4-6eada3e31b4e>", line 1, in <module>
    raw[0]
  File "/home/gbrown/Envs/bikeshare-dev/lib/python3.5/site-packages/django/db/models/query.py", line 1329, in __getitem__
    return list(self)[k]
  File "/home/gbrown/Envs/bikeshare-dev/lib/python3.5/site-packages/django/db/models/query.py", line 1299, in __iter__
    query = iter(self.query)
  File "/home/gbrown/Envs/bikeshare-dev/lib/python3.5/site-packages/django/db/models/sql/query.py", line 93, in __iter__
    self._execute_query()
  File "/home/gbrown/Envs/bikeshare-dev/lib/python3.5/site-packages/django/db/models/sql/query.py", line 127, in _execute_query
    self.cursor.execute(self.sql, params)
  File "/home/gbrown/Envs/bikeshare-dev/lib/python3.5/site-packages/django/db/backends/utils.py", line 100, in execute
    return super().execute(sql, params)
  File "/home/gbrown/Envs/bikeshare-dev/lib/python3.5/site-packages/django/db/backends/utils.py", line 68, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "/home/gbrown/Envs/bikeshare-dev/lib/python3.5/site-packages/django/db/backends/utils.py", line 77, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "/home/gbrown/Envs/bikeshare-dev/lib/python3.5/site-packages/django/db/backends/utils.py", line 85, in _execute
    return self.cursor.execute(sql, params)
  File "/home/gbrown/Envs/bikeshare-dev/lib/python3.5/site-packages/django/db/utils.py", line 89, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/home/gbrown/Envs/bikeshare-dev/lib/python3.5/site-packages/django/db/backends/utils.py", line 85, in _execute
    return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: can't adapt type 'Query'

我知道这是很危险的,因为它是SQL注入。但是,我想支持这一点,创建一个QuerySet方法(碰巧需要raw query),它可以在QuerySet链的末尾使用,过滤后的QuerySet作为子查询传递到原始查询中。在

即使错误没有发生,params参数是否会降低任何风险?还是让我冒这个风险,使用基本的python字符串格式?在


Tags: djangoinpydevselfhomeexecutelib
1条回答
网友
1楼 · 发布于 2024-09-26 18:14:02

我刚刚发布了我的方法无论如何都不能正常工作,因为query方法没有返回有效的SQL,也就是说

qs = Station.objects.filter(name='Albert Gate, Hyde Park').values('id').order_by()
print(qs.query)

[out] SELECT "bikeshare_station"."id" FROM "bikeshare_station" WHERE "bikeshare_station"."name" = Albert Gate, Hyde Park

因为没有引用名称字符串而爆炸。在

正如Jon Clements在其评论中指出的那样,似乎唯一的方法就是执行查询并传入一个id列表,该列表可以实现:

^{pr2}$

然后可以将id列表传递给原始查询,而不是字符串。在

相关问题 更多 >

    热门问题