Python最佳实践,最安全,可连接MySQL并执行查询

时间:2011-10-28 12:38:48

标签: python mysql sql-injection

在mysql上运行查询的最安全的方法是什么,我知道MySQL和SQL注入所涉及的危险。

但是我不知道如何运行查询以防止注入其他用户(webclients)可以操作的变量。我曾经写过自己的转义函数,但显然这是“未完成”。

我应该使用什么以及如何使用它来查询并通过python安全地插入MySQL数据库而不会冒险注入mysql?

3 个答案:

答案 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)开始,您可以编写如下查询:

'QMARK'

>>> 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,))

'pyformat'

>>> 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)

我总是更喜欢使用数据库连接器的转义功能-它可以按预期工作,并且您自己手动编写转义功能会带来安全风险。