我正在使用Python的sqlite3。为什么无法对表达式进行参数绑定:
self.cursor.execute("PRAGMA table_info(?)", table_name)
是否如预期?对于任何其他的SELECT
查询,它都会按照预期替换我的参数。我现在使用了
self.cursor.execute("PRAGMA table_info('%s')" % table_name)
但是这种方法不能有效预防SQL注入攻击。我该如何解决这个问题?
我正在使用Python的sqlite3。为什么无法对表达式进行参数绑定:
self.cursor.execute("PRAGMA table_info(?)", table_name)
是否如预期?对于任何其他的SELECT
查询,它都会按照预期替换我的参数。我现在使用了
self.cursor.execute("PRAGMA table_info('%s')" % table_name)
编辑:从 SQLite 版本 3.16.0 (2017-01-02) 开始,所有 PRAGMA 现在都可以用作 PRAGMA 函数,这应该允许进行参数化。
在 Python 中:
self.cursor.execute("SELECT * FROM pragma_table_info(?)", table_name)
感谢Rubinium的回答指出这一点。但是,如果您使用的是早期版本的SQLite,则我的原始答案可能是您唯一的选择。
我想做同样的事情,但似乎不可能将参数绑定到Sqlite PRAGMAs。
为了保持安全(我自己也可能会这样做),您可以像以下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)
对于任何遇到这个问题的人,最佳方法是使用像这样的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 );