我正在使用sqlite3 for Python。为什么不能为表达式
的参数绑定工作?self.cursor.execute("PRAGMA table_info(?)", table_name)
像预期的那样吗?对于任何其他SELECT
查询,它将按预期替换我的参数。我现在使用
self.cursor.execute("PRAGMA table_info('%s')" % table_name)
,但这对SQL注入是不安全的。如何解决这个问题?
编辑:从SQLite版本3.16.0(2017-01-02)开始,所有PRAGMA现在都可以用作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"
然后将这些表名存储在数组/列表/集合中。既然db中有了所有可能的表的列表,就可以简单地检查用户输入,看看它是否与数组中的某个表匹配。如果是这样,那么直接插入字符串将是安全的,并且不会有SQL注入的机会。从本质上讲,它是根据白名单进行消毒的。
在Python中,它看起来像这样:if table_name in tables:
self.cursor.execute("PRAGMA table_info('%s')" % table_name)
else:
print("Bad table name: %s" % table_name)
对于遇到这个问题的人,最佳的方法是像这样使用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 );