Python最佳实践和securest连接到MySQL并执行查询
在mysql上运行查询最安全的方法是什么?我知道mysql和SQL注入所涉及的危险 但是,我不知道应该如何运行查询,以防止注入其他用户(WebClient)可以操作的变量。我曾经写过我自己的转义函数,但显然这是“没有完成”Python最佳实践和securest连接到MySQL并执行查询,python,mysql,sql-injection,Python,Mysql,Sql Injection,在mysql上运行查询最安全的方法是什么?我知道mysql和SQL注入所涉及的危险 但是,我不知道应该如何运行查询,以防止注入其他用户(WebClient)可以操作的变量。我曾经写过我自己的转义函数,但显然这是“没有完成” 我应该使用什么以及如何使用它通过python在MySQL数据库上安全地查询和执行插入操作,而不冒MySQL注入的风险 为避免注入,使用execute和%s代替每个变量,然后通过列表或元组传递值作为execute的第二个参数。以下是一份: c=db.cursor() 最高价格=
我应该使用什么以及如何使用它通过python在MySQL数据库上安全地查询和执行插入操作,而不冒MySQL注入的风险 为避免注入,使用
execute
和%s
代替每个变量,然后通过列表或元组传递值作为execute
的第二个参数。以下是一份:
c=db.cursor()
最高价格=5
c、 执行(““”从早餐中选择垃圾邮件、鸡蛋、香肠
其中价格<%s”“,(最高价格,)
请注意,这是使用逗号,而不是%(这将是直接字符串替换,而不是转义)不要这样做:
c.execute("""SELECT spam, eggs, sausage FROM breakfast
WHERE price < %s""" % (max_price,))
c.execute(““”从早餐中选择垃圾邮件、鸡蛋、香肠
其中价格<%s”“”%(最高价格,)
此外,如果参数是字符串,则不需要在持仓人(
'%s'
)周围加引号。作为Bruno答案的扩展,您的MySQL客户端库可能支持指定命名参数的几种不同格式中的任意一种。从中,您可以编写如下查询:
“qmark”
“数字”
“命名”
“格式”
“pyformat”
通过查看paramstyle
module-level变量,可以查看您的客户端库支持哪些:
>>> clientlibrary.paramstyle
'pyformat'
对于处理可能不安全的数据,上述任何选项都应该是正确的。正如布鲁诺指出的,请不要试图自己插入参数。常用的客户端库在正确处理数据方面比我们凡人都要好得多。如果您使用的是mysqldb,您可以使用内置的escape_string函数。像这样
sql = "SELECT spam FROM eggs WHERE lumberjack = '" + MySQLdb.escape_string(str(lumberjack)) + "';"
cursor.execute(sql)
我总是更喜欢使用数据库连接器的转义功能-它按预期工作,手动编码转义功能本身存在安全风险。也使用
%s
(请参阅上面的max\u price
示例)。为什么max\u price后面有逗号?这是什么意思?很抱歉,如果我的问题看起来没有意义,但我对python还是很陌生:)max_price之后的coma是一个1元素元组的符号:@hussantamboli,是的,这正是我所说的:逗号是使用参数占位符的正确方法(它做了所有必要的转义),%
不转义参数。@lucidbrot表名不是参数。如果需要使用来自变量的表名动态生成查询,则需要在将这些变量放入查询字符串(而不是通过参数占位符)之前手动清理这些变量。例如,只允许表名与[a-z0-9.]+
匹配。哪些客户端库支持“已命名”?PyMySQL和MySQLdb支持“格式”,而oursql支持“qmark”。sqlite3至少支持“命名”。我没有安装任何MySQL适配器来检查其中的“命名”支持。我知道这是一个老问题,但我正在尝试正确地编写我的网页,在安全SQL方面没有太多经验。使用上述方法是否足以防止SQL注入,或者除此之外,我还需要做其他事情?谢谢,这就足够了。不过,我强烈建议您检查一下像SQLAlchemy这样的ORM,让它为您处理细节。因为,而且因为上面说“不要使用此函数”,所以使用它可能不是一个好主意。即使使用real\u escape\u string
,(大多数是PHP示例,但在这两种情况下都基于相同的C API)。
>>> 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})
>>> clientlibrary.paramstyle
'pyformat'
sql = "SELECT spam FROM eggs WHERE lumberjack = '" + MySQLdb.escape_string(str(lumberjack)) + "';"
cursor.execute(sql)