ASP.NET防止Sql注入的解决方法

12 篇文章 0 订阅

1. 什么是SQL注入
     所谓SQL注入,就是通过把SQL命令插入到表单窗体递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行一些恶意的SQL命令。通过递交参数构造巧妙的SQL语句,从而成功获取想要的数据。

2. SQL注入的种类
从具体而言,SQL注入可分为五大类,分别是:数字型注入、字符型注入、搜索型注入(like)、in型的注入、句语连接型注入。
从应用来说,要特别注意IP、搜索、批量删除、从数据库转到数据库等地方的SQL注入。

3,如何进行的注入

下面我们看一个典型例子

 

1 SqlCommand cmd  =  new SqlCommand(" SELECT   *   FROM  PE_USERS  WHERE  UserName  =   ' "
2 + UserName + " '   AND  UserPassword  =   ' " + PassWord + " ' ", conn);


由于没有对UserName和PassWord进行任何验证,如果UserName=” admin’ OR 1=1--“
所执行的SQL语句就成了:

1 SELECT   *   FROM  PE_USERS  WHERE  UserName = ’admin’  OR   1 = 1 —‘  AND  UserPassword = ’’
2

 

这就造成了SQL注入,条件永远为真,也就不用密码也能登陆成功。

 

4.如何防止SQL注入

1.过滤或转换可疑字符串

      通过编写过滤或者转换危险字符串的函数,然后在GLOBAL.ASAX或者重写上下文实例来实现防止SQL注入

     这里有个例子

   

复制代码
 1 public  static bool SqlFilter2(string InText)
 2   {
 3    string word = " and| exec | insert | select | delete | update | chr | mid | master |or| truncate | char | declare |join ";
 4     if (InText == null )
 5      return  false;
 6    foreach(string i  in  word.Split( ' | ' ))
 7    {
 8      if ((InText.ToLower().IndexOf(i + " ") >- 1 ) || (InText.ToLower().IndexOf(" " + i) >- 1 ))
 9     {
10       return  true;
11     }
12    }
13     return  false;
14   }
复制代码

二,Global.asax

 

复制代码
 1 protected void Application_BeginRequest(Object sender, EventArgs e)
 2   {
 3     // 遍历Post参数,隐藏域除外
 4    foreach(string i  in  this.Request.Form)
 5    {
 6      if (i == "__VIEWSTATE") continue ;
 7     this.goErr(this.Request.Form [ i ] .ToString());    
 8    }
 9     // 遍历Get参数。
10    foreach(string i  in  this.Request.QueryString)
11    {
12     this.goErr(this.Request.QueryString [ i ] .ToString());    
13    }
14   }
复制代码

 

1 private void goErr(string tm)
2   {
3     if (WLCW.Extend.CValidity.SqlFilter2(tm))
4     this.Response. end ()
5   }

 

优点:该种方面是大多数初级程序员用来防止SQL注入,看起来效果还不错,能防止大多数情况下的注入。

缺点:1.会过滤一些本来不是用来进行注入的字符,造成意想不到的问题。比如,一个论坛的会员名字里如果含有和所过滤字符相同的字符的话,会造成一些列意想不到的问题和麻烦。

        2.每次都需要进行过滤或者转换,降低程序效率

2.使用存储过程进行参数化查询

 SQL注入主要目的是想通过提交恶意的SQL代码,来达到在数据库里执行恶意命令的目的。所以只要在执行SQL命令前做处理,就可以有效防止SQL注入。进行参数化查询可以达到有效防止SQL注入的目的。

实例

 

1 const string strSql  =  " SELECT   *   FROM   [ PE_Users ]   WHERE  UserName  =   @UserName ";
2 Parameters parms  =  new Parameters(" @UserName ", DbType.String, userName);

上面有一个参数@UserName, 使用Prarmeter对象,通过它把参数添加到Command对象上,
这样就获得参数化查询。
如上述语句,ADO.NET 会向SQL Server 发送下面的SQL语句:

1 Exec  sp_executesql N ‘ select   *   from   [ pe_users ]   where  username = @username  ‘,N
2 @username   nvarchar ( 20 ) ‘, @username = N ‘name’

SQL Server 把@username 替换成字符串”name”,然后再执行查询.
假设有下面的输入:

1 ' union select @@version,null,null— 
生成的SQL语句如下所示:
1 Exec  sp_executesql N ‘ select   *   from   [ pe_users ]   where  username = @username  ‘,N
2 @username   nvarchar ( 20 ) ‘, @username = N ‘’’  union   select   @@version , null , null --
可以看到ADO.NET转义了输入。
1 public  SqlParameter Add( string  parameterName, SqlDbType sqlDbType,  int  size);

DbTye或SqlDbType可以是多种数据类型。
可根据你的数据类型来选择。
在某些地方,也可似指定参数的长度:int size。这样也能有效防止数据库溢出和SQL注
入的可能性。
优点:有效地防止了SQL注入的产生。
缺点:有些地方不能应用,如 in 。

3.白名单

描述:
对于一些已知的参数范围,可用白名单的形式处理,能有交防止SQL注入和查询出
错,如:order by +列名,列名以参数形式传入时,可制定一个白名单,先判断一下参
数是否在白名单内,再进行查询,否则出错处理。
优点:安全可靠
缺点:应用范围小


ASP.NET防止Sql注入,通常一个一个文件修改不仅麻烦而且还有漏掉的危险,下面我说一上如何从整个系统防止注入。

做到以下三步,相信的程序将会比较安全了,而且对整个网站的维护也将会变的简单。

一、数据验证类

  
  
以下是代码片段: parameterCheck.cs public class parameterCheck{ public static bool isEmail(string emailString){ return System.Text.RegularExpressions.Regex.IsMatch(emailString, "['/w_-]+(/.['/w_-]+) *@['/w_-]+(/.['/w_-]+)*/.[a-zA-Z]{2,4}"); } public static bool isInt(string intString){ return System.Text.RegularExpressions.Regex.IsMatch(intString ,"^(/d{5}-/d{4})|(/d{5})  $"); } public static bool isUSZip(string zipString){ return System.Text.RegularExpressions.Regex.IsMatch(zipString ,"^-[0-9]+ $|^[0-9]+ $"); } }

二、Web.config

在你的Web.config文件中,在下面增加一个标签,如下:

  
  
以下是代码片段: <appSettings> <add key="safeParameters" value="OrderID-int32,CustomerEmail-email,ShippingZipcode-USzip" /> </appSettings>

其中key是后面的值为“OrderId-int32”等,其中“-”前面表示参数的名称比如:OrderId,后面的int32表示数据类型。

三、Global.asax

在Global.asax中增加下面一段:

  
  
以下是代码片段: protected void Application_BeginRequest(Object sender, EventArgs e){ String[] safeParameters = System.Configuration.ConfigurationSettings.AppSettings ["safeParameters"].ToString().Split(','); for(int i= 0 ;i < safeParameters.Length; i++){ String parameterName = safeParameters.Split('-')[0]; String parameterType = safeParameters.Split('-')[1]; isValidParameter(parameterName, parameterType); } }  public void isValidParameter(string parameterName, string parameterType){ string parameterValue = Request.QueryString[parameterName]; if(parameterValue == null) return; if(parameterType.Equals("int32")){ if(!parameterCheck.isInt(parameterValue)) Response.Redirect("parameterError.aspx"); } else if (parameterType.Equals("double")){ if(!parameterCheck.isDouble(parameterValue)) Response.Redirect("parameterError.aspx"); } else if (parameterType.Equals("USzip")){ if(!parameterCheck.isUSZip(parameterValue)) Response.Redirect("parameterError.aspx"); } else if (parameterType.Equals("email")){ if(!parameterCheck.isEmail(parameterValue)) Response.Redirect("parameterError.aspx"); } }

以后需要修改的时候我们只需要修改以上三个文件,对整个系统的维护将会大大提高效率,当然你可以根据自己的需要增加其它的变量参数和数据类型。

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值