为什么使用参数化查询或实体框架会阻止sql注入?

时间:2014-04-23 22:21:44

标签: c# sql entity-framework sql-injection sql-parametrized-query

我已经很好地掌握了SQL注入。这是一个SQL查询,应该是

SELECT FirstName, LastName 
FROM Customers 
WHERE CustomerId = @valueFromApplication

变成了像

这样的查询
SELECT FirstName, LastName 
FROM Customers 
WHERE CustomerId = '' ; DROP DATABASE Foo --

当用户将恶意值插入您的应用,网站,客户端等等时......我也知道,攻击者可以尝试发现表的名称并从中获取信息,而不仅仅是删除数据库。

我也知道一些有助于防止这种情况的事情:

  1. 使用带参数的存储过程(SQL Server)
  2. 使用参数化SQL查询
  3. 使用Entity Framework / LINQ to Entities(C#,也许是F#?)
  4. 这些事情实际上是如何防止SQL注入发生的?为什么攻击者不能将相同的恶意值传递给他或她已经使用的任何输入并且具有相同的结果。

2 个答案:

答案 0 :(得分:9)

您的第一个示例已参数化,不易受SQL注入攻击。

参数化查询不会简单地由具有值的服务器替换(就像您可以手动将@var替换为value)。它们的发送和接收完全与您发送的一样.. @valueFromApplication

服务器将解析查询..当它到达变量时,它将查找提供的值。如果该值为'' ; DROP DATABASE Foo -- ..那么它将成为它使用的。它没有解析它......它只是将它用作文本/数字/它是什么类型。

要添加有关Entity Framework的内容,它在内部使用Parameterised查询,因此它也是SQL注入安全的。

答案 1 :(得分:8)

参数不是简单地在线替换到SQL中 - 它们是从查询单独发送到SQL Server的。

因此,SQL Server得到类似的东西:

Query:
   SELECT FirstName, LastName FROM Customers WHERE CustomerId = ?
Parameter 1:
   '' ; DROP DATABASE Foo --

因此,它编译一个查询,检查CustomerId实际上等于'' ; DROP DATABASE Foo --的客户。参数值永远不会作为SQL执行。