为啥使用参数化查询或实体框架会阻止 sql 注入?
Posted
技术标签:
【中文标题】为啥使用参数化查询或实体框架会阻止 sql 注入?【英文标题】:Why does using parameterized queries or entity framework prevent sql injection?为什么使用参数化查询或实体框架会阻止 sql 注入? 【发布时间】:2014-06-08 23:52:08 【问题描述】:我已经很好地掌握了 SQL 注入。当一个 SQL 查询应该类似于
SELECT FirstName, LastName
FROM Customers
WHERE CustomerId = @valueFromApplication
变成类似的查询
SELECT FirstName, LastName
FROM Customers
WHERE CustomerId = '' ; DROP DATABASE Foo --
当用户向您的应用程序、网站、客户端等中插入恶意值时。我还知道,攻击者不仅可以删除数据库,还可以尝试发现表的名称并从中获取信息。
我还知道一些有助于防止这种情况发生的事情是:
-
使用带参数的存储过程 (SQL Server)
使用参数化 SQL 查询
使用实体框架/LINQ to Entities(C#,也许是 F#?)
这些东西实际上是如何防止 SQL 注入发生的?为什么攻击者不能将相同的恶意值传递到他或她已经使用的任何输入中并获得相同的结果。
【问题讨论】:
因为如果将某些东西作为参数发送,那么 SQL Server 会将其视为参数,并且不会尝试将其视为 SQL 代码执行。所以参数的内容不会被执行 你的第一个 SQL 语句是参数化的,不容易受到 SQL 注入的攻击。 C# 代码string sql = "SELECT FirstName, LastName FROM Customers WHERE CustomerId = " + valueFromApplication;
易受攻击。
当你传递给参数一些代码破坏语法,如'--'或';'被视为普通字符,只需将它们插入或更新到您的列字段或执行其他工作,例如 LIKE 运算符将搜索参数值“;Drop Database..”作为字符串本身而不是执行。
为了速度和安全性,将准备好的语句准确地预编译为存储过程。
另外,大多数用于执行参数化语句的 API 一次只会执行一条语句。
【参考方案1】:
您的第一个示例是参数化的,不易受到 SQL 注入的影响。
参数化查询不会简单地被服务器替换为值(就像您可能手动将 @var
替换为 value
一样)。它们的发送和接收与您发送的完全相同。使用@valueFromApplication
。
服务器将解析查询......当它到达一个变量时,它会查找提供的值。如果那个值是'' ; DROP DATABASE Foo --
.. 那么它就变成了它使用的值。它不会解析它.. 它只是将它用作文本/数字/无论它是什么类型。
要添加关于实体框架,它在内部使用参数化查询,因此它也是 SQL 注入安全的。
【讨论】:
【参考方案2】:参数不是简单地内嵌到 SQL 中的 - 它们是从查询中单独发送到 SQL Server 的。
所以,SQL Server 得到类似:
Query:
SELECT FirstName, LastName FROM Customers WHERE CustomerId = ?
Parameter 1:
'' ; DROP DATABASE Foo --
因此它会编译一个查询来检查 CustomerId 字面上等于'' ; DROP DATABASE Foo --
的客户。参数值永远不会作为 SQL 执行。
【讨论】:
以上是关于为啥使用参数化查询或实体框架会阻止 sql 注入?的主要内容,如果未能解决你的问题,请参考以下文章