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

Luc*_*man 56 python mysql sql-injection

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

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

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

Bru*_*uno 82

为了避免注射,使用execute%s代替每个可变的,然后通过列表或元组作为第二参数传递值execute.以下是文档中示例:

c=db.cursor()
max_price=5
c.execute("""SELECT spam, eggs, sausage FROM breakfast
          WHERE price < %s""", (max_price,))
Run Code Online (Sandbox Code Playgroud)

请注意,这是使用逗号而不是%(这将是直接字符串替换,而不是转义).不要这样做:

c.execute("""SELECT spam, eggs, sausage FROM breakfast
          WHERE price < %s""" % (max_price,))
Run Code Online (Sandbox Code Playgroud)

此外,'%s'如果参数是字符串,则不需要位置holder()周围的引号.

  • 而当它是整数? (3认同)
  • 也要使用“%s”(请参见上面的“ max_price”示例)。 (3认同)
  • 为什么max_price后面有逗号?这是什么意思 ?抱歉,如果我的问题看起来不太好,但是我对python还是很陌生的:) (2认同)
  • “ max_price”后的逗号是1元素元组的符号:http://docs.python.org/tutorial/datastructures.html#tuples-and-sequences (2认同)

Kir*_*ser 72

作为Bruno答案的扩展,您的MySQL客户端库可以支持几种不同格式中的任何一种来指定命名参数.从PEP 249(DB-API),您可以编写如下查询:

'QMARK'

>>> cursor.execute("SELECT spam FROM eggs WHERE lumberjack = ?", (lumberjack,))
Run Code Online (Sandbox Code Playgroud)

'数字'

>>> cursor.execute("SELECT spam FROM eggs WHERE lumberjack = :1", (lumberjack,))
Run Code Online (Sandbox Code Playgroud)

"名为"

>>> cursor.execute("SELECT spam FROM eggs WHERE lumberjack = :jack", {'jack': lumberjack})
Run Code Online (Sandbox Code Playgroud)

'格式'

>>> cursor.execute("SELECT spam FROM eggs WHERE lumberjack = %s", (lumberjack,))
Run Code Online (Sandbox Code Playgroud)

'pyformat'

>>> cursor.execute("SELECT spam FROM eggs WHERE lumberjack = %(jack)s", {'jack': lumberjack})
Run Code Online (Sandbox Code Playgroud)

您可以通过查看paramstyle模块级变量来查看客户端库支持的内容:

>>> clientlibrary.paramstyle
'pyformat'
Run Code Online (Sandbox Code Playgroud)

关于处理可能不安全的数据,上述任何选项都应该做正确的事.正如布鲁诺指出的那样,请不要尝试自己插入参数.常用的客户端库在处理数据方面比我们凡人永远都要好得多.

  • 哪些客户端库支持'命名'?PyMySQL和MySQLdb支持'format',而ourql支持'qmark'. (3认同)