SQLAlchemy 文本函数是否暴露于 SQL 注入?
Is the SQLAlchemy text function exposed to SQL Injection?
我正在学习如何使用 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
函数
如果查询是使用字符串格式构造的,那么 sqlalchemy.text
将不会阻止 SQL 注入 - “注入”已经存在于查询文本中。但是,动态构建查询并不困难,在本例中使用 getattr 来获取对列的引用。假设您使用模型 class Foo
和 table 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% 有效.不过,它比从字符串构建查询更有效。
我正在学习如何使用 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
函数
如果查询是使用字符串格式构造的,那么 sqlalchemy.text
将不会阻止 SQL 注入 - “注入”已经存在于查询文本中。但是,动态构建查询并不困难,在本例中使用 getattr 来获取对列的引用。假设您使用模型 class Foo
和 table 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% 有效.不过,它比从字符串构建查询更有效。