【问题标题】:Is the SQLAlchemy text function exposed to SQL Injection?SQLAlchemy 文本函数是否暴露给 SQL 注入?
【发布时间】:2021-11-15 11:00:12
【问题描述】:

我正在学习如何使用 SQL Alchemy,我正在尝试重新实现以前定义的 API,但现在使用的是 Python。

REST API 具有以下查询参数:

myService/v1/data?range=time:2015-08-01:2015-08-02

所以我想映射 field:FROM:TO 之类的东西来过滤一系列结果,例如日期范围。

这是我目前正在使用的:

 rangeStatement = range.split(':')
                if(len(rangeStatement)==3):
                    query = query.filter(text('{} BETWEEN "{}" AND "{}"'.format(*rangeStatement)))

因此,这将产生以下 WHERE 条件:

WHERE time BETWEEN "2015-08-01" AND "2015-08-02"

我知道 SQL Alchemy 是一个强大的工具,它允许创建像 Query.filter_by(MyClass.temp) 这样的查询,但我需要 API 请求尽可能开放。

所以,我担心有人会在range 参数中传递类似DROP TABLE 的内容并利用text 函数

【问题讨论】:

  • 如果您正在使用字符串格式构建查询,那么损坏已经造成。使用占位符和bindparams
  • 这是一个学习项目,我对数据访问层的 Java 和 Spring 框架太习惯了,我正在尝试找出如何在 Python 中做同样的事情(不依赖 Django 和Django 框架),所以,我可以更改查询。我不想改变的是 API Spec

标签: python python-3.x sqlalchemy


【解决方案1】:

如果查询是使用字符串格式构建的,那么sqlalchemy.text 将不会阻止 SQL 注入 - “注入”将已经存在于查询文本中。但是动态构建查询并不难,在这种情况下,通过使用getattr 来获取对列的引用。假设您正在使用带有模型类 Foo 和表 foos 的 ORM 层,您可以这样做

import sqlalchemy as sa
...
col, lower, upper = 'time:2015-08-01:2015-08-02'.split(':')

# Regardless of style, queries implement a fluent interface,
# so they can be built iteratively

# Classic/1.x style
q1 = session.query(Foo)
q1 = q1.filter(getattr(Foo, col).between(lower, upper))
print(q1)

# 2.0 style (available in v1.4+)
q2 = sa.select(Foo)
q2 = q2.where(getattr(Foo, col).between(lower, upper))
print(q2)

各自的输出是(参数会在执行时绑定):

SELECT foos.id AS foos_id, foos.time AS foos_time 
FROM foos 
WHERE foos.time BETWEEN ? AND ?

SELECT foos.id, foos.time 
FROM foos 
WHERE foos.time BETWEEN :time_1 AND :time_2

SQLAlchemy 会将值的引用委托给引擎正在使用的连接器包,因此您对注入的保护将与连接器包提供的保护一样好*


* 总的来说,我认为正确的引用应该可以很好地防御 SQL 注入,但是我不够专业,无法自信地说它是 100% 有效的。不过,这将比从字符串构建查询更有效。

【讨论】:

  • 假设time列`是Date类型,你可以在查询前将lowerupper转换为datetime.date实例。这样您就可以确信列名是正确的,并且日期不包括任何进样。
  • 太棒了,我会试一试。谢谢!
  • 有些连接器甚至可能不引用值,而是将它们与查询分开发送到 DBMS。
猜你喜欢
  • 2021-12-07
  • 2012-12-02
  • 2010-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-07
  • 1970-01-01
相关资源
最近更新 更多