在mysql上运行查询的最安全的方法是什么,我知道MySQL和SQL注入所涉及的危险。
但是我不知道如何运行查询以防止注入其他用户(webclients)可以操作的变量。我曾经写过自己的转义函数,但显然这是“未完成”。
我应该使用什么以及如何使用它来查询并通过python安全地插入MySQL数据库而不会冒险注入mysql?
答案 0 :(得分:77)
为避免注入,请使用execute
代替%s
代替每个变量,然后通过列表或元组作为execute
的第二个参数传递值。这是一个example from the documentation:
c=db.cursor()
max_price=5
c.execute("""SELECT spam, eggs, sausage FROM breakfast
WHERE price < %s""", (max_price,))
请注意,这是使用逗号,而不是%(这将是直接字符串替换,不会被转义)。 不要这样做:
c.execute("""SELECT spam, eggs, sausage FROM breakfast
WHERE price < %s""" % (max_price,))
此外,如果参数是字符串,则不需要位置持有者('%s'
)周围的引号。
答案 1 :(得分:70)
作为Bruno答案的扩展,您的MySQL客户端库可能支持几种不同格式中的任何一种来指定命名参数。从PEP 249 (DB-API)开始,您可以编写如下查询:
>>> cursor.execute("SELECT spam FROM eggs WHERE lumberjack = ?", (lumberjack,))
>>> cursor.execute("SELECT spam FROM eggs WHERE lumberjack = :1", (lumberjack,))
>>> cursor.execute("SELECT spam FROM eggs WHERE lumberjack = :jack", {'jack': lumberjack})
>>> cursor.execute("SELECT spam FROM eggs WHERE lumberjack = %s", (lumberjack,))
>>> cursor.execute("SELECT spam FROM eggs WHERE lumberjack = %(jack)s", {'jack': lumberjack})
您可以通过查看paramstyle
模块级变量来查看客户端库支持的内容:
>>> clientlibrary.paramstyle
'pyformat'
上述任何一个选项都应该就处理你可能不安全的数据做正确的事。正如布鲁诺指出的那样,请不要尝试自己插入参数。常用的客户端库在处理数据方面比我们凡人永远都要好得多。
答案 2 :(得分:-3)
如果使用的是mysqldb,则可以使用内置的escape_string函数。这样。
sql = "SELECT spam FROM eggs WHERE lumberjack = '" + MySQLdb.escape_string(str(lumberjack)) + "';"
cursor.execute(sql)
我总是更喜欢使用数据库连接器的转义功能-它可以按预期工作,并且您自己手动编写转义功能会带来安全风险。