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