防止SQL注入 - 如果使用预准备语句,为什么要逃避输入?

时间:2012-01-03 16:13:12

标签: sql stored-procedures sql-injection prepared-statement

我正在进行一些网络安全研究,我的文章的修改者说:

“应该很清楚,为了避免SQL注入,应用程序应该使用预准备语句,存储过程和转义输入”

我的问题是:其中一种方法是不够的?好吧,准备好的语句或存储过程比简单的转义更好,但是如果我使用PDO,为什么我应该转义输入或者有一个存储过程?这有意义吗?

3 个答案:

答案 0 :(得分:8)

我会将修改者的措辞改为:

  

应该清楚的是,为了避免SQL注入,应用程序应该在插入SQL字符串之前使用预准备语句,转义输入或过滤应用程序数据。

如果您要作为参数传递,则无需转义值。实际上,您不应该这样做,因为您将在文档中插入文字反斜杠。

当您不能使用查询参数时,需要将字符串插入到SQL语句中。例子包括:

  • 表名称和列名称,其own syntax for delimited identifiers。这些必须是准备时SQL查询的一部分,因此RDBMS可以解析和验证它们。

  • SQL关键字,应该进行清理,但由于没有分隔,因此无法转义。

  • 其他语法或表达。

  • 在准备时必须提供字面值的某些情况,例如: MySQL的全文功能不支持搜索模式的参数。

存储过程不能防止SQL注入。您可以在存储过程中准备和执行不安全的动态SQL语句。有关这方面的精彩故事,请参阅http://thedailywtf.com/Articles/For-the-Ease-of-Maintenance.aspx

我在演讲SQL Injection Myths and Fallacies中涵盖了所有这些案例。这可能对你有用。

我还在本书的一章SQL Antipatterns: Avoiding the Pitfalls of Database Programming中介绍了SQL注入防御。

答案 1 :(得分:4)

  

如果我使用PDO,为什么我应该选择输入或存储过程?

只要你总是使用PDO,我就没有理由去理解输入转义或SP。

答案 2 :(得分:2)

如果有疑问,请问问自己:这条简单的输入数据是否会被一些API下线?大多数情况下,除非您从输入数据手动构建SQL语句。

如果使用PDO,则不应该逃避。如果使用带有参数的JDBC准备语句,则不应该转义。同样,大多数其他API也会处理这个问题。存储过程甚至不涉及转义数据,如果输入数据未在运行该过程的SQL中转义,则使用它们不会神奇地避免SQL注入安全问题。

始终在SQL语句中放入SQL-Escape数据。永远不要在SQL语句之外使用SQL-Escape数据。