简体   繁体   English

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

[英]Why does using parameterized queries or entity framework prevent sql injection?

I've got a good grasp on SQL injection. 我已经很好地掌握了SQL注入。 It's when a SQL query that is supposed to be something like 这是一个SQL查询应该是什么样的

SELECT FirstName, LastName 
FROM Customers 
WHERE CustomerId = @valueFromApplication

Gets turned into a query like 变成了像这样的查询

SELECT FirstName, LastName 
FROM Customers 
WHERE CustomerId = '' ; DROP DATABASE Foo --

When the user inserts a malicious value into your app, website, client, whatever.. I'm also aware that instead of just dropping the DB the attacker can try to discover the names of tables and get info out of them. 当用户将恶意值插入您的应用程序,网站,客户端等等时......我也知道,攻击者可以尝试发现表的名称并从中获取信息,而不仅仅是删除数据库。

I also know some things that help prevent this are: 我也知道一些有助于防止这种情况的事情:

  1. Using stored procedures which take parameters (SQL Server) 使用带参数的存储过程(SQL Server)
  2. Using parametrized SQL queries 使用参数化SQL查询
  3. Using Entity Framework / LINQ to Entities (C#, maybe F#?) 使用Entity Framework / LINQ to Entities(C#,也许是F#?)

How do these things actually prevent SQL injection from occurring? 这些事情实际上如何防止SQL注入发生? Why can't the attacker just pass the same malicious value into whatever input he or she is already using and have the same result. 为什么攻击者不能将相同的恶意值传递给他或她已经使用的任何输入并且具有相同的结果。

Your first example is parameterised and is not vulnerable to SQL injection. 您的第一个示例是参数化的,不易受SQL注入的影响。

Parameterised queries aren't simply replaced by the server with values (like you might do manually replacing @var with value ). 参数化查询不是简单地由具有值的服务器替换(就像您可以手动用value替换@var )。 They are sent and received exactly as you sent it.. with @valueFromApplication . 它们的发送和接收完全与您发送的一样..与@valueFromApplication

The server will parse the query.. and when it gets to a variable it will look up the value supplied. 服务器将解析查询..当它到达变量时,它将查找提供的值。 If that value is '' ; DROP DATABASE Foo -- 如果该值为'' ; DROP DATABASE Foo -- '' ; DROP DATABASE Foo -- .. then that becomes the value it uses. '' ; DROP DATABASE Foo -- ..然后它成为它使用的 It doesn't parse that.. it just uses it as text/number/whatever type it is. 它不会解析它...它只是将它用作文本/数字/它是什么类型。

To add about Entity Framework, it internally uses Parameterised query so it is also SQL injection safe. 要添加有关Entity Framework的内容,它在内部使用Parameterised查询,因此它也是SQL注入安全的。

Parameters are not simply replaced in-line into the SQL - they are sent separately from the query to the SQL Server. 参数不是简单地在线替换到SQL中 - 它们是从查询单独发送到SQL Server的。

So, SQL Server gets something like: 所以,SQL Server得到类似的东西:

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

And therefore it compiles a query that checks for a customer whose CustomerId is literally equal to '' ; DROP DATABASE Foo -- 因此,它编译一个查询,检查CustomerId字面上等于'' ; DROP DATABASE Foo --的客户'' ; DROP DATABASE Foo -- '' ; DROP DATABASE Foo -- . '' ; DROP DATABASE Foo -- The parameter value is never executed as SQL. 参数值永远不会作为SQL执行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM