在使用python时,净化SQL以防止注入的最佳方法是什么?我在用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上向我介绍任何东西,即使它不适合我。有有用的图书馆吗?
发布于 2022-03-24 15:00:07
当不受信任的输入被内插到SQL查询中,并且输入包含更改查询语法的字符时,SQL注入工作。
查询参数与SQL查询保持分离,从不插入其中。参数的值在被解析后与SQL查询相结合,因此不再有任何改变语法的机会。该参数保证被视为单个标量值(也就是说,它只是SQL表达式中的字符串文本)。
如果您使用MySQLCursorPrepared游标子类,这就是Python连接器的工作方式。请参阅https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursorprepared.html
否则,Python连接器将“模拟”准备好的查询。实际上,它在解析SQL查询之前会将参数插入到SQL查询中,但通过转义会导致SQL注入的特殊字符,这样做是安全的。它经过很好的测试,所以它是可靠的。
这两种游标类型的使用方式相同,传递带有%s占位符的SQL查询字符串,以及带有参数值元组的另一个参数。你正确地使用了它。
关于@Learningfrommasters的评论:
是的,存储在数据库中的字符串可能在另一个SQL查询中不安全地使用,并导致SQL注入。有些人认为只有用户输入必须被安全对待,但这不是真的。任何变量都应视为查询参数,无论该变量的值来自用户输入,还是从文件中读取,或者甚至从您自己的数据库中提取。
假设我的名字是比尔·奥卡文。它中有一个撇号,您知道它是SQL的一个特殊字符,因为它终止了字符串文字。
如果我的名字存储在数据库中,然后被取到一个应用程序中,放入一个变量userlastname中,那么我可以搜索具有相同姓氏的其他人:
sql = f"SELECT * FROM Users WHERE lastname = '{userlastname}'",这是不安全的,因为撇号会导致注入。尽管值不是直接来自用户输入,但它来自我自己的数据库。
因此,请为所有变量使用参数。那么您就不必考虑源是否安全。
sql = "SELECT * FROM Users WHERE lastname = %s"
cur.execute(sql, (userlastname,))https://stackoverflow.com/questions/71604741
复制相似问题