4

我正在为 Python 使用 sqlite3。为什么表达式的参数绑定不起作用:

self.cursor.execute("PRAGMA table_info(?)", table_name)

正如预期的那样?对于任何其他SELECT查询,它会按预期替换我的参数。我现在用

self.cursor.execute("PRAGMA table_info('%s')" % table_name)

但这对 SQL 注入是不安全的。我该如何解决这个问题?

4

2 回答 2

2

编辑:从 SQLite 版本 3.16.0 (2017-01-02) 开始,所有 PRAGMAS 现在都可以用作 PRAGMA 函数,这应该允许参数化。

在 Python 中:

self.cursor.execute("SELECT * FROM pragma_table_info(?)", table_name)

(感谢 Rubinium 的回答指出了这一点)。但是,如果您使用的是早期版本的 SQLite,那么我的原始答案可能是您唯一的选择。


我想做同样的事情,但似乎无法将参数绑定到 Sqlite PRAGMA。

您可以做些什么来保持安全(以及我最终可能会做的事情)是在 SQL中查询当前 Sqlite 数据库中的所有表名,如下所示:

SELECT * FROM sqlite_master

或者,要获取表格并忽略视图,请执行以下操作:

SELECT * FROM sqlite_master where type="table"

然后将这些表名存储在数组/列表/集合中。现在您已经有了数据库中所有可能表的列表,您可以简单地检查用户输入以查看它是否与数组中的一个表匹配。如果是,那么直接插入到字符串中是安全的,不会有SQL注入的机会。从本质上讲,它正在根据白名单进行清理。

在 Python 中,它看起来像这样:

if table_name in tables:
    self.cursor.execute("PRAGMA table_info('%s')" % table_name)
else:
    print("Bad table name: %s" % table_name)
于 2017-06-01T02:11:51.720 回答
2

对于发生在这个问题上的任何人,最佳方法是使用 pragma 函数,如下所示:

self.cursor.execute("SELECT * FROM pragma_table_info(?)", table_name)

或者

sqlite3_prepare_v2( db, "SELECT * FROM pragma_table_info(?)", -1, &stmt, &tail );
sqlite3_bind_text( stmt, 1, table_name, -1, nullptr );
于 2019-10-01T14:49:22.613 回答