我被告知以下是不安全的:
cursor.execute("""SELECT currency FROM exchange_rates WHERE date='%s'"""%(self.date))
为什么是'%s'
坏的?有人会如何在这里实际进行 SQL 注入?
想象一下,如果self.date
是"'; DROP TABLE exchange_rates --"
。然后你将执行:
SELECT currency FROM exchange_rates WHERE date=''; DROP TABLE exchange_rates -- '
和繁荣,你被冲洗了。您必须转义,'
因此 的值self.date
将完全包含在字符串中,而不是作为查询执行。
问题是当您应该与查询分开传递值时,您使用的是字符串格式。
例如,比较:
cursor.execute("SELECT currency FROM exchange_rates WHERE date=?", self.date)
使用字符串格式化方法,有人可以将 a;
放入值中(编辑:具体来说,用 a 关闭引号,'
然后添加分号),然后尝试在此之后注入额外的查询,它将像那样执行。通过单独传递值,您可以确保数据仅被视为数据,而不是作为查询执行。
在这种情况下,一个额外的好处是,如果 self.date 是 python 日期或日期时间对象,则在发送时将自动以适合您的数据库的方式对其进行格式化。如果您尝试将 self.date 直接添加到查询字符串中,则必须使用日期格式来确保其输出完全符合数据库的预期。