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()周围的引号.
Kir*_*ser 72
作为Bruno答案的扩展,您的MySQL客户端库可以支持几种不同格式中的任何一种来指定命名参数.从PEP 249(DB-API),您可以编写如下查询:
>>> 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)
>>> 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)
关于处理可能不安全的数据,上述任何选项都应该做正确的事.正如布鲁诺指出的那样,请不要尝试自己插入参数.常用的客户端库在处理数据方面比我们凡人永远都要好得多.