我目前正在查看某人的代码,并且遇到了以下Python行:
db.query('''SELECT foo FROM bar WHERE id = %r''' % id)
这违背了我的常识,因为我通常会选择使用准备好的语句,或者至少使用数据库系统的本机字符串转义功能。
但是,鉴于以下情况,我仍然很好奇如何加以利用:
答案 0 :(得分:1)
MySQL的Python驱动程序不支持真正的预备语句。它们都执行某种形式的字符串插值。诀窍是让Python以适当的转义进行字符串插值。
观看不安全操作的演示:How do PyMySQL prevent user from sql injection attack?
模拟参数的常规方法如下:
{
cards:
[
{
reference: "",
response: {
text: "",
title: "",
},
timestamp: ""
},
{
reference: "",
response: {
text: "",
title: "",
},
timestamp: ""
},
.... and so on
请参见https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-execute.html
我知道克服转义的唯一方法(正确完成时)是:
sql = "SELECT foo FROM bar WHERE id = %s"
cursor.execute(sql, (id,))
,您应该可以避免此问题。set names utf8
以打破转义,例如启用sql_mode
或NO_BACKSLASH_ESCAPES
。您应该在会话开始时设置ANSI_QUOTES
,类似于设置名称的方式。这样可以确保它不会使用引起问题的全局更改的sql_mode。另请参阅Is "mysqli_real_escape_string" enough to avoid SQL injection or other SQL attacks?