【发布时间】:2022-01-16 16:58:54
【问题描述】:
我是 PyMySQL 的新手,只是尝试执行一个查询:
c.execute('''INSERT INTO mysql_test1 (
data,
duration,
audio,
comments
) VALUES (
?,
?,
?,
?
);
''', [
comments_var,
duration_var,
audio_var,
comments_var
]
);
但是,它抛出了以下错误:
TypeError: not all arguments converted during string formatting
我注意到我的变量一定有问题,并阅读了如何在 PyMySQL 中正确处理它们,期待参数替换的方法,但令我惊讶的是,我找不到任何东西。相反,我发现的每个线程都使用了字符串操作(例如here、here、here 和 here(有评论声称字符串操作将是 PyMySQL 的标准)。
这对我来说很有趣,因为我以前只处理过 SQLite,其中 DBAPI 文档 explicitly warns 使用带变量的字符串操作:
SQL 操作通常需要使用 Python 变量中的值。但是,请注意使用 Python 的字符串操作来组装查询,因为它们容易受到 SQL 注入攻击。
文档用以下代码 sn-p 举例说明了这一点:
Never do this -- insecure!
symbol = 'RHAT'
cur.execute("SELECT * FROM stocks WHERE symbol = '%s'" % symbol)
Instead, use the DB-API’s parameter substitution.
在阅读PyMySQL docs 时,我找不到任何关于此类危险的提及。它只是证实了我之前的发现:
如果 args 是一个列表或元组,%s 可以用作查询中的占位符。如果 args 是 dict,则 %(name)s 可以用作查询中的占位符。
为什么在sqlite3 中使用字符串操作被认为容易受到 SQL 注入攻击,同时在 pymysql 中不受质疑?
【问题讨论】:
标签: python mysql sql-injection pymysql string-operations