我正在进行一些网络安全研究,我的文章的修改者说:
“应该很清楚,为了避免SQL注入,应用程序应该使用预准备语句,存储过程和转义输入”
我的问题是:其中一种方法是不够的?好吧,准备好的语句或存储过程比简单的转义更好,但是如果我使用PDO,为什么我应该转义输入或者有一个存储过程?这有意义吗?
答案 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数据。