SQLAlchemy 文本函数是否暴露于 SQL 注入?

raf*_*uru 5 python sqlalchemy python-3.x

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

REST API 具有以下查询参数:

myService/v1/data?range=time:2015-08-01:2015-08-02
Run Code Online (Sandbox Code Playgroud)

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

这就是我现在正在使用的:

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

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

WHERE time BETWEEN "2015-08-01" AND "2015-08-02"
Run Code Online (Sandbox Code Playgroud)

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

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

sna*_*erb 9

如果使用字符串格式构造查询,则sqlalchemy.text不会阻止 SQL 注入 - “注入”将已经存在于查询文本中。然而,动态构建查询并不困难,在本例中通过使用getattr来获取对该列的引用。假设您正在使用带有模型类Foo和表的ORM 层foos,您可以执行以下操作

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)
Run Code Online (Sandbox Code Playgroud)

或者

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

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

SELECT foos.id AS foos_id, foos.time AS foos_time 
FROM foos 
WHERE foos.time BETWEEN ? AND ?
Run Code Online (Sandbox Code Playgroud)

SELECT foos.id, foos.time 
FROM foos 
WHERE foos.time BETWEEN :time_1 AND :time_2
Run Code Online (Sandbox Code Playgroud)

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


*一般来说,我相信正确的引用应该可以很好地防御 SQL 注入,但是我还没有足够的专业知识来自信地说它是 100% 有效的。不过,它比从字符串构建查询更有效。