如何进行SQL注入攻击?

4

我被告知以下内容存在不安全性:

cursor.execute("""SELECT currency FROM exchange_rates WHERE date='%s'"""%(self.date))

为什么'%s'是不好的?有人会如何进行SQL注入攻击?


1
这里不一定能够进行 SQL 注入攻击。这取决于 self.date 可能包含的内容。但最好的做法是正确传递查询参数 - 这并不需要额外的努力。 - John La Rooy
严肃点,把“SQL注入是如何工作”的问题输入Google搜索框,你会得到几个类似的例子。 - Karl Knechtel
2个回答

9
假设self.date的值为"'; DROP TABLE exchange_rates --"。那么你将会执行以下代码:SELECT currency FROM exchange_rates WHERE date=''; DROP TABLE exchange_rates -- ',结果会出现问题。你需要对'进行转义,这样self.date的值就会完整地包含在字符串中,而不是作为查询语句被执行。

-1 是不好的实践,尝试转义特殊字符;相反,你应该利用Python DBAPI将值与查询分开传递的能力。 - Andrew Gorcester
4
下投票有点过于武断,只是因为糟糕的解决方案而被否定了。原帖的问题是在询问“如何”。 - p.campbell
最初我在这里留下了一个不同意的评论,但是我改变了主意(不幸的是太晚了,无法撤销投票)。 - Andrew Gorcester

6
问题在于您正在使用字符串格式化,而应该从查询中单独传递值。
例如,对比以下两个示例:
cursor.execute("SELECT currency FROM exchange_rates WHERE date=?", self.date)

使用字符串格式化方法时,有人可以将一个 ; 放入值中(编辑:具体来说,用 ' 关闭引号,然后添加分号),然后尝试在其后注入其他查询,那么将直接执行。通过单独传递值,您确保数据只被视为数据,并且不作为查询执行。
在这种情况下的另一个好处是,如果 self.date 是 Python 的日期或时间对象,则在发送时将自动以适当的方式格式化为数据库所需的格式。如果您尝试直接将 self.date 添加到查询字符串中,则必须使用日期格式化来确保它按照数据库所期望的方式输出。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接