使用LINQ解除SQL注入安全问题

在开发人员承受越来越多的安全责任之时,许多开发人员了解到的第一个Web应用安全漏洞,是一个被称为“SQL注入”的极危险的命令注入形式。命令注入的原始的形式本是指这样一种漏洞:***者通过提供一个正常使用者意料之外的输入,改变你的Web应用程序的运行方式,从而允许***者运行服务器上的非授权的命令。无疑,SQL注入式***是很常见的、被广泛使用的***形式。幸运的是,一旦我们理解了这个问题,就可以很容易地防止SQL注入式***。更妙的是,现在微软的数据访问技术向.net开发人员提供了彻底地清除SQL注入漏洞的机会,当然前提是能够正确使用。这种技术称为“语言级集成查询”(Language Integrated Query (LINQ)),并随Visual Studio "Orcas" 和 .NET Framework 3.5一起发布。本文将讨论如何通过LINQ强化Web应用程序的数据访问代码,从而解决通过SQL注入进行***的问题。
SQL注入是一种Web应用程序的安全漏洞,通过它***者可以将恶意数据提交给应用程序,欺骗应用程序在服务器上执行恶意的SQL命令。理论上讲,这种***是容易预防的,不过由于其允许***者直接运行针对用户关键数据的数据库命令,从而成为一种常见的、危害性大的***形式。在非常极端的情况下,***者不但能够自由地控制用户的数据,还可以删除数据表和数据库,甚至控制整个数据库服务器。
如果这种***容易预防,那么为什么还如此危险呢?首先,由于众所周知的经济上的原因,你的应用数据库是非常诱人的,可以引起***者的极大注意。如果SQL注入漏洞在Web应用程序中可能存在着,那么对于一个***者来说是很容易检测到的,然后就可以利用它。很显然,即使SQL注入错误并不是开发人员最经常犯的错误,它们也很容易被发现和利用。
对SQL注入的剖析
这里我们给出一个SQL注入的例子来说明两个问题,一是SQL注入这种错误是很容易犯的,二是只要进行严格的程序设计,这种错误是很容易预防的。
这个示例用的Web应用程序包含一个名为SQLInjection.aspx简单的客户搜索页面,这个页面易于受到SQL注入***。此页面包含一个CompanyName的输入服务器控件,还有一个数据表格控件,用于显示从微软的示例数据库Northwind的搜索结果(这个数据库可从SQL Server 2005中找到)。在搜索期间执行的这个查询包含一个应用程序设计中很普通的错误:它动态地从用户提供的输入中生成查询。这是Web应用程序数据访问中的一个主要的错误,因为这样实际上潜在地相信了用户输入,并直接将其发送给你的服务器。在从“搜索”的单击事件启动时,这个查询看起来是这个样子:
protected void btnSearch_Click(object sender, EventArgs e){      String cmd = "SELECT [CustomerID], [CompanyName], [ContactName]FROM [Customers] WHERE CompanyName ='" + txtCompanyName.Text+ "'";SqlDataSource1.SelectCommand = cmd;GridView1.Visible = true;}
在这种情况下,如果一个用户输入“Ernst Handel”作为公司名,并单击“搜索”按钮,作为响应屏幕会向用户显示那个公司的记录,这正是我们所期望的理想情况。不过一个***者可以轻易地操纵这个动态查询。例如,***者通过插入一个UNION子句,并用一个注释符号终止这个语句的剩余部分。换句话说,***者不是输入“Ernst Handel”,而是输入如下的内容:
Ernst Handel' UNION SELECT CustomerID, ShipName, ShipAddressFROM ORDERS--
其结果是这个SQL语句在服务器端执行,由于添加了这个恶意的请求。它会将这个动态的SQL查询转换为下面的样子:
SELECT [CustomerID], [CompanyName],[ContactName]FROM [Customers]WHERE CompanyName ='Ernst Handel'UNION SELECT CustomerID, ShipName,ShipAddressFROM ORDERS--'
这是一个相当合法的SQL语句,它可以在应用程序数据库上执行,返回order表中所有的客户,这些客户通过应用程序已经处理了定单。
典型的SQL防护
可以看出,在你的应用程序中创造并利用一个SQL注入漏洞是多么容易。幸运的是,如前所述,只需要采取几项简单的对策通常就可以预防SQL注入***。最常用的、成本效率最高的预防SQL注入***的方法是验证应用程序中所有的最终用于数据访问的数据输入。用户发出的任何输入,不管是通过Web应用程序输入的或者是常驻于数据存储设备的,都要在服务器处理你的数据访问命令之前在服务器端验证其类型、长度、格式和范围。不幸的是,基于代码的对策并不十分安全,而且有可能失败,特别是当发生如下情况时:
验证程序设计不当
验证仅在客户层面执行
在应用程序中,验证时遗漏了字段(有时即使是一个字段)。
防止SQL注入的另外一层涉及正确地确定应用程序中所有SQL查询的参数,不管是在动态SQL语句中还是在存储过程中。例如,如果代码像下面这样构建查询,就比较安全:
SELECT [CustomerID], [CompanyName], [ContactName]FROM [Customers]WHERE CompanyName = @CompanyName
当作为SQL语句的一部分执行时,参数化查询将输入作为一个字面值,因此服务器就可能将带参数的输入作为可执行代码。即使你使用了存储过程,你仍然必须采取另外一步来确定输入的参数,因为存储过程并不对嵌入式查询中的SQL注入提供保护。
即使采取这上述的简单修正措施,SQL注入对许多公司来说仍然是一个大问题。对开发团队的挑战是要教育每一个开发人员谨慎对待这些类型的漏洞,采取有目的的和有效的安全标准来防止***,增强标准和操作安全的评估, 确认无任何疏漏。这样就会需要引入许多变量去保证应用程序安全,因此如果你选择一项能够使SQL注入式***成为不可能的数据访问技术,你的效率将会更高。这正是LINQ发挥作用之所在。
LINQ概述
LINQ增加了用任何类型的数据存储进行查询和更新数据的标准模式,无论是SQL数据库还是XML文档,还是.NET对象都是这样。在构建数据库驱动的应用程序时,LINQ能够使开发人员像管理C#或者VB中的对象那样管理相关数据,这称为“LINQ to SQL”,被看作是ADO.NET数据技术系统的一部分。在最初以CTP形式引入时,LINQ to SQL被认为是DLINQ。
LINQ to SQL使得你将应用程序中的数据作为你所使用的编程语言中的本地对象,简化相关数据管理和数据库连接的复杂性。事实上,你可以通过LINQ显示和操作数据库的数据,而无需你编写任何SQL语句。在运行时刻,LINQ to SQL将嵌入或“集成”到你的代码中的查询转换成SQL,并在数据库系统上执行它们。LINQ to SQL以对象的形式将查询结果返回到应用程序中,完全转移了你与数据库及SQL的交互形式。没有什么清除Web应用程序中的SQL注入的方法能够比从应用程序中清除SQL更快。停靠LINQ to SQL,你就可以实现。
保障LINQ数据库存取的安全
LINQ to SQL在专用于数据存取时,清除了SQL注入存在于你的应用程序中的可能性,原因很简单:LINQ代表你执行的每次查询都加上了具体的参数。在LINQ从你植入的查询语句中构建SQL查询时,无论源自何处,提交给查询的任何输入都被当作字面值。而且,通过IntelliSense和编译时的语法检查,LINQ与Visual Studio Orcas的集成可以帮助开发人员构建合法的查询。编译器可以捕捉大量的对查询的错误使用,这些错误使用可以将功能上的缺陷或其它类型的漏洞带入到你的应用程序中。与此不同的是,在你获知它正确与否之前,你编写的SQL语句只在运行时刻在数据库系统上解析。针对LINQ to SQL的唯一***途径是***者欺骗LINQ形成非法的或无意识的SQL。幸运的是,语言和编译器就是设计来保护这个方面的。
在清楚了上述的基本思想后,下面我们就展示应该如何运用LINQ to SQL防护SQL注入式***,并具体讨论一个客户搜索的例子。第一步是创建数据库中有关数据的对象模型。Visual Studio Orcas包含一个新的对象关系设计器(Object Relational Designer),这个设计器使你能够生成一个完全的对象模型。为了为我们的Northwind Customers表构建一个对象模型,你通过选择“增加新项目…”并选择“LINQ to SQL File”模板(这个模板是在对象关系设计器中打开的),在应用程序中创建一个LINQ to SQL的数据库。为了给 Customers表自动构建完全的对象模型,在服务器资源管理器 (Server Explorer)中选择这个表,并将它拖到对象关系设计器的设计层面上。在这个例子中,对象关系设计器增加了一个名为Customers.designer.cs的文件,这个文件以代码的形式定义了你将要使用的类,而不是编写代码直接与数据库进行交互。
在为Customers表中的数据定义了对象模型的类之后中,你可以为客户的数据搜索页面直接以代码的形式查询数据。LINQ-powered 页面(LINQtoSQL.aspx.cs)的Page_Load方法,具体展现了由对象关系设计器创建的CustomersDataContext类,重新使用了前面在SQLInjection.aspx页面中使用的连接字符串。下面的LINQ查询重新使用了与where子句匹配的Customer对象的集合。
protected void Page_Load(object sender, EventArgs e){string connectionString =ConfigurationManager.ConnectionStrings["northwndConnectionString1"].ConnectionString;CustomersDataContext db = newCustomersDataContext(connectionString);GridView1.DataSource =from customer in db.Customerswhere customer.CompanyName ==txtCompanyName.Textorderby customer.CompanyNameselect customer;GridView1.DataBind();}
在使用了LINQ to SQL之后,如果我们将“Ernst Handel”作为搜索值,由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] = @p0ORDER BY [t0].[CompanyName]}
可以看出,WHERE子句自动被加上了参数,因此,用传统的SQL注入式***是无法造成破坏的。不管用户将什么值作为输入提交给搜索页面,这个查询是安全的,它不允许用户的输入执行服务器上的命令。如果你输入了前面例子中用来实施SQL注入***的字符串,查询并不会返回任何信息。事实上,一个用户用这个查询可以进行的最大的破坏是执行一次强力***(或称蛮力***(Brute force attack)),主要通过使用搜索功能穷举Customers表中所有公司的记录,其使用的方法是猜测每一个可能的值。不过,即使这样也只提供了那个页面上所暴露的Customers表中的值,并不会给***者注入命令的机会,这里的命令指的是访问数据库中额外的数据表的命令。
LINQ与安全
正如前面的例子所显示的那样,在Web应用程序中引入SQL注入漏洞是很容易的,不过采用适当的方法也容易修正这些漏洞。但是,没有什么方法天生就能防止开发人员犯这些简单的但却是危险的错误。然而,微软的LINQ to SQL技术通过让开发人员直接与对象模型交互而不是直接与数据库交互,消除了来自数据库应用程序的SQL注入***的可能性。内建于c#和Visual Basic的 LINQ基础结构关注正确地表述合法而安全的SQL语句,可以防止SQL注入***,并使开发人员专注于对他们来说最自然的程序设计语言。不管你是将LINQ to SQL用作新的.NET应用程序开发的一部分,还是对它进行花样翻新,用于现有的实际应用程序的数据访问,你都是作了一个构建更安全的应用程序的选择。
数据库 SQL注入 休闲

0

收藏

上一篇:在WCF中的异常处理方法 下一篇:在Biztalk应用中调用程序集...
noavatar_middle.gif
高阳

45篇文章,17W+人气,4粉丝

关注
noavatar_middle.gif

Ctrl+Enter 发布

发布

取消

推荐专栏

45862f289339dc922ffda669fd74ad9b.jpg最近更新
网工2.0晋级攻略 ——零基础入门Python/Ansible

网络工程师2.0进阶指南

共30章 | 姜汁啤酒

¥51.00 1166人订阅
订   阅
9d82eccb4e3c371eaeac41193bbef757.png
基于Kubernetes企业级容器云平台落地与实践

容器私有云平台实践之路

共15章 | 李振良OK

¥51.00 433人订阅
订   阅
629650e188ddde78b213e564c2e9ebff.jpg
负载均衡高手炼成记

高并发架构之路

共15章 | sery

¥51.00 398人订阅
订   阅
5366d1f50328a62facbf5db1d91c319a.png
VMware vSAN中小企业应用案例

掌握VMware超融合技术

共41章 | 王春海

¥51.00 253人订阅
订   阅
dc6736c5fd50474b5df8b76b040e3d03.jpg
带你玩转高可用

前百度高级工程师的架构高可用实战

共15章 | 曹林华

¥51.00 390人订阅
订   阅

猜你喜欢

我的友情链接 私有云的时代将给企业管理带来质的飞跃 开学季出大事:某教育局丢失3台虚拟机 EVA4400存储虚拟机+数据库数据恢复成功案例 服务器数据恢复通用方法+服务器分区丢失恢复案例 在CentOS7上部署squid缓存服务器及代理功能 EMC 5400服务器raid阵列瘫痪数据恢复成功案例 服务器数据恢复案例 / raid5阵列多块硬盘离线处理方法
078772c84eb23213ea90f577d9316ce4.png
left-qr.jpg

扫一扫,领取大礼包

0

分享
qr-url?url=http%3A%2F%2Fblog.51cto.com%2Fxiaoyinnet%2F196451
关注
高阳
noavatar_middle.gif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/407819.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HTTPS下导出excel失败解决办法

要在导出文件名前加HttpUtility.UrlEncode 如下例 Response.AddHeader("Content-Disposition", "attachment; filename" HttpUtility.UrlEncode(fileName) ".xls");转载于:https://www.cnblogs.com/xiayan/p/3699287.html

SHA-1算法的C语言实现(源码来自网络)

来自网络上的SHA-1算法,自己加了少量注释,方便以后需要的时候可以利用。 代码: /* sha1sum.c - print SHA-1 Message-Digest Algorithm * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. * Copyright (…

移动端隐藏滚动条(最全面)

网上查的基本都是坑爹的,都没写全 html,body{//隐藏滚动条 height: 100vh; overflow-y: scroll; &::-webkit-scrollbar { display: none; } } 需要设置高度,还要设置哪个方向的滚动scrol,一个都不能少

505宿舍10

发表时间:2007年5月17日 1时38分51秒 中午没睡觉,下午又热又闷,所以一路小跑到球场,我两腿就已经开始发软,可是有球赛,球员不足,所以不得不去. 热得不行,赛前热身就免了.只看到土匪彪光着膀子蹲在球场边,满身是水. 第一节开始没什么说的,可第一节结束时就来了突发事…

计算几何算法

http://blog.csdn.net/shahdza/article/details/6367851 转载于:https://www.cnblogs.com/thefirstfeeling/p/4410796.html

JavaScript toLocaleString()时间转化为字符串

根据本地时间把 Date 对象转换为字符串: var dnew Date(); var nd.toLocaleString(); n 输出结果: 2020/9/23 下午2:29:43 还可以将数字变成千分位格式: let num12345678; console.log(num.toLocaleString()); // 12,345,678

屏蔽基于对话框的MFC程序中按下ESC关闭窗口的功能

在基于对话框的MFC程序中,如果你按下ESC,将会关闭对话框。如何屏蔽这个键呢,其实很简单,只要重载下PreTranslateMessage()即可。 方法:在对话框类上右击,选择“Add virtual Function...",在…

漫画兔善搞2007-等待爱玛马士基号的垃圾

转自:[url]http://blog.sina.com.cn/s/blog_4992fa8b010007f5.html[/url]英国对华倾泻垃圾废物 中国进口商进口为获利益[url]http://www.sina.com.cn[/url] 2007年01月12日 21:49 CCTV《经济信息联播》英国的天空电视台近日报道,素有“欧洲垃圾箱”之称的…

cocos2dx CCLayerColor和CCLayerColor

在cocos2dx中,默认的CCLayer背景是黑色的,有些时候需要特殊的Layer,所以cocos2dx中提供了这两种LayerCCLayerColor是可以改变背景色的Layer,示例如下:CCSize size __winSize;CCLayerColor* layer CCLayerColor::crea…

当按下ESC键时,关闭应用程序

在一个单文档MFC应用程序中,按下ESC时关闭应用程序,实现方法:在CMainFrame类里重载PreTranslateMessage(),代码如下: BOOL CMainFrame::PreTranslateMessage(MSG* pMsg){ if(pMsg->message WM_KEYDOWN &&…

JQ ajax解决跨域

JQ ajax请求失败 “No Transport”,浏览器跨域的意思。 jQuery.support.cors true;请求前添加这行代码,解决跨域问题

工程师和销售人员的差别

今天上完课,我对工程师和销售人员的差别感触特别深。我问两个学生一个项目问题,主要做技术他搞速我这个很简单,讲了好多从技术角度怎样去处理这个东西。技术上的东西思路很清楚。但是我问他怎样去和用户沟通,用户需求是达到要求&a…

支付宝的一些小问题,注意事项等等,等用得时候在来写写

根据今天下午看得结果来看吧,一边写一边总结,还没开始测试,但大致的流程已经知道了: 首先:必须准备的是测试的id,校检码,这2个只要通过支付宝的审核都会有的,然后就是私钥(这个通过o…

HDC,CDC,CClientDC,CPaintDC,CWindowDC的区别

CDC是MFC的DC的一个类 HDC是DC的句柄,API中的一个类似指针的数据类型.MFC类的前缀都是C开头的 H开头的大多数是句柄 首先说一下什么是DC(设备描述表)解:Windows应用程序通过为指定设备(屏幕,打印机等)创建…

[转]经典的C语言著作,“C语言四书五经”

http://blog.chinaunix.net/u/22520/showart_308803.html 经典的C语言著作,“C语言四书五经”一、The C Programming Language C程序设计语言(第2版新版) 原出版社: Prentice Hall PTR 作者: [美]Brian W.Kernighan,De…

d3.js(相当于svg的JQ)

学习文档 https://d3js.org/ 官网 https://github.com/xswei/d3js_doc/tree/master/d3js_doc_old 中文文档 https://www.cnblogs.com/fastmover/p/7779660.html 学习demo

Taro+react开发(10)--多行选择

<Pickermode"multiSelector"onChange{this.multiChange}onColumnChange{this.columnChange}value{code}range{multiArray}range-key"code"><AtList><AtListItem title"三级级联" extraText{this.state.scaleSel} /></AtLis…

INI文件读写--VC6.0

新建一个dialog based MFC Windows Application,命名为&#xff1a;d, 界面为&#xff1a; 为按钮Read和Write添加单击事件&#xff0c;并自定义一个函数GetIniFileName()用来取得ini文件的路径&#xff0c;主要函数代码如下&#xff1a;// read data from config file void CD…