技术开发 频道

在C#3.0中使用LINQ轻松防御SQL注入攻击

五、通过LINQ使数据访问更安全

    我们用LINQ to SQL进行数据访问时,它可以很容易地消除在我们的应用程序中由于SQL注入而带来的安全隐患,这主要是由于在LINQ中每一个执行的SQL查询都是参数化的。当使用LINQ建立SQL查询时,任何提供给查询的输入都被看做是参数字符串,无论这个输入是从哪里来的。开发人员可以在Visual Studio2008中使用集成的LINQ,并通过智能编辑器和编译时语法检查来书写正确的代码。编译器可以捕捉很多可能引起功能性错误或其他类似的安全隐患的查询错误。与之对比,我们写的SQL表达式只能在运行时通过数据库系统对其进行分析和解释。这样我们就很难在运行之前知道它们是否正确。曾经有很多攻击者试着通过对LINQ采取欺骗的手段使其运行非法或具有恶意的SQL语句。但幸运的是,最新的语言和编译器阻止了这一切的发生。

    心动不如行动,在这里我们来使用LINQ实现一个customer搜索的例子,并使用LINQ来阻止SQL注入的攻击。第一步是在数据库中建立和关系数据对应的对象模型。Visual Studio2008包括了一个新的对象关系设计器(也就是O/R设计器),它可以通过拖拽的方式为我们产生全部的对象模型,其中包括对象的设计和它们之间的关系。为了对我们的Northwind中的Customers表建立对象模型,我们需要通过选择“Add New Item...”,并选择“LINQ to SQL File”模板(这个模板将打开O/R设计器)在应用程序中建立一个LINQ to SQL文件。为了自动建立完整的Customers表的对象模型,在Server Explorer中选择这个表,并将它拖到O/R设计器的界面上,如图2所示。在这个例子中,O/R设计器在应用程序中加入一个Customers.designer.cs文件来定义我们在代码中使用的类。而不是直接写代码和数据库交互。


               
                                              图2 使用O/R设计器映射Customers表

在定义完Customers表的对象模型类后,我们可以通过customer数据查询而在代码中直接查询数据。在LINQtoSQL.aspx.cs的Page_Load方法中,实例化了被O/R设计器建立的CustomersDataContext类,它重用了在上面例子中SQLInjection.aspx而使用的连接字符串。下面是LINQ查询获得的一个Customer对象的集合的代码:
protected void Page_Load(object sender, EventArgs e) { string connectionString = ConfigurationManager.ConnectionStrings ["northwndConnectionString1"].ConnectionString; CustomersDataContext db = new CustomersDataContext(connectionString); GridView1.DataSource = from customer in db.Customers where customer.CompanyName == txtCompanyName.Text orderby customer.CompanyName select customer; GridView1.DataBind(); }
使用LINQ to SQL,如果我们提供"Oracle"作为Search的值,那么在运行时和在服务器执行的通过LINQ产生的SQL表达式的代码如下:

SELECT [t0].[CustomerID], [t0].[CompanyName], [t0].[ContactName], [t0].[ContactTitle], [t0].[Address], [t0].[City], [t0].[Region], [t0].[PostalCode], [t0].[Country], [t0].[Phone], [t0].[Fax] FROM [dbo].[Customers] AS [t0] WHERE [t0].[CompanyName] = @p0 ORDER BY [t0].[CompanyName]}
我们从上面的代码可以看出,WHERE子句被自动参数化了。因此,使用方便的SQL注入攻击是无法得逞的。不管用户在查询页的输入字段中输入什么值,查询总是类型安全的,而且在服务端不允许将输入字符串作为命令执行。如果我们使用上述的SQL注入攻击方法来浏览敏感数据,那么将什么也不会显示出来。

六、小结

    从上面的例子可以看出,使用LINQ是非常容易在Web程序中预防SQL注入攻击的,当然,也非常容易检查出这种错误。微软的LINQ to SQL技术使用户通过对象模型和数据库进行交互而不是直接使用SQL和数据库进行交互,从而有效地避免了SQL注入攻击。这个LINQ结架被C#和Visual Basic建立来格式化字符串和SQL表达式,并阻止SQL注入攻击的发生,以使开发人员可以将更多的经理集中到程序本身的特性上来。无论我们选择使用LINQ或是SQL作为.NET应用程序访问数据的接口,或是设计自己的数据访问接口,我们都将会做出一个选择来建立更安全的应用程序。

 

1
相关文章