5

我很好地掌握了 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. 使用实体框架/LINQ to Entities(C#,也许是 F#?)

这些东西实际上是如何防止 SQL 注入发生的呢?为什么攻击者不能将相同的恶意值传递到他或她已经使用的任何输入中并获得相同的结果。

4

2 回答 2

10

您的第一个示例是参数化的,不易受到 SQL 注入的影响。

参数化查询不会简单地被服务器替换为值(就像您可能手动替换@var为一样value)。它们的发送和接收与您发送时完全相同.. 使用@valueFromApplication.

服务器将解析查询。当它到达一个变量时,它将查找提供的值。如果那个值是'' ; DROP DATABASE Foo --.. 那么它就变成了它使用的值。它不会解析它..它只是将它用作文本/数字/无论它是什么类型。

要添加关于实体框架的信息,它在内部使用参数化查询,因此它也是 SQL 注入安全的。

于 2014-04-23T22:27:45.497 回答
9

参数不是简单地直接替换到 SQL 中——它们与查询分开发送到 SQL Server。

因此,SQL Server 得到如下内容:

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

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

于 2014-04-23T22:27:23.333 回答