SQL 消毒 python

SQL sanitize python

消毒 SQL 以防止在使用 python 时注入的最佳方法是什么?我正在使用 mysql-连接器。我读过我应该使用类似于以下的结构:

import mysql.connector

connection = mysql.connector.connect(host="", port="", user="", password="", database="")
cursor = connection.cursor( buffered = True )

sql = "INSERT INTO mytable (column1, column2) VALUES (%s, %s)"
val = (myvalue1, myvalue2)

cursor.execute(sql, val)
connection.commit()

但是,我不明白为什么这样可以防止注射。这够了吗?用户可以在 myvalue1 或 myvalue2 上向我介绍任何内容,即使不应该这样做。有什么有用的库吗?

SQL 当不受信任的输入被插入到 SQL 查询中并且输入包含更改查询语法的字符时,

SQL 注入起作用。

查询参数与 SQL 查询分开,从不插入其中。参数值与 SQL 查询 解析后结合,因此不再有任何更改语法的机会。该参数保证被视为单个标量值(即,就好像它只是 SQL 表达式中的字符串文字一样)。

如果您使用 MySQLCursorPrepared 游标子类,这就是 Python 连接器的工作方式。参见 https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursorprepared.html

否则,Python 连接器“模拟”准备好的查询。它实际上在 SQL 查询被解析之前将参数插入到查询中,但它这样做是安全的,通过转义会导致 SQL 注入的特殊字符。 well-tested 值得信赖

两种游标类型的使用方式相同,传递带有 %s 占位符的 SQL 查询字符串,以及带有参数值元组的另一个参数。你用对了。


来自@Learningfrommasters 的回复:

是的,存储在您数据库中的字符串可以在另一个 SQL 查询中不安全地使用,并导致 SQL 注入。有些人认为只有用户输入必须被安全对待,但事实并非如此。 任何变量都应被视为查询参数,无论该变量的值是来自用户输入,还是从文件中读取,甚至是从您自己的数据库中提取。

示例:假设我的名字是 Bill O'Karwin。它有一个撇号,你知道它是 SQL 的一个特殊字符,因为它终止了一个字符串文字。

如果我的名字存储在数据库中,然后在应用程序中提取到一个变量中 userlastname,那么我可以搜索具有相同姓氏的其他人:

sql = f"SELECT * FROM Users WHERE lastname = '{userlastname}'"

那是不安全的 因为撇号会导致 SQL 注入。尽管该值不是直接来自用户输入,但它来自我自己的数据库。

所以对所有变量使用参数。那就不用考虑源码是否安全了

sql = "SELECT * FROM Users WHERE lastname = %s"
cur.execute(sql, (userlastname,))