视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
.Net防sql注入的几种方法
2020-11-27 22:34:27 责编:小采
文档


防sql注入的常用方法:

1、服务端对前端传过来的参数值进行类型验证;

2、服务端执行sql,使用参数化传值,而不要使用sql字符串拼接;

3、服务端对前端传过来的数据进行sql关键词过来与检测;

着重记录下服务端进行sql关键词检测:

1、sql关键词检测类:

public class SqlInjectHelper:System.Web.UI.Page
 {
 private static string StrKeyWord = "select|insert|delete|from|count(|drop table|update|truncate|asc(|mid(|char(|xp_cmdshell|exec|master|net local group administrators|net user|or|and";
 private static string StrSymbol = ";|(|)|[|]|{|}|%|@|*|'|!";

 private HttpRequest request;
 public SqlInjectHelper(System.Web.HttpRequest _request)
 {
 this.request = _request;
 }
 public bool CheckSqlInject()
 {
 return CheckRequestQuery() || CheckRequestForm();
 }

 ///<summary> 
 ///检查URL中是否包含Sql注入 
 /// <param name="_request">当前HttpRequest对象</param> 
 /// <returns>如果包含sql注入关键字,返回:true;否则返回:false</returns> 
 ///</summary> 
 public bool CheckRequestQuery()
 {
 if (request.QueryString.Count > 0)
 {
 foreach (string sqlParam in this.request.QueryString)
 {
 if (sqlParam == "__VIEWSTATE") 
 continue;
 if (sqlParam == "__EVENTVALIDATION") 
 continue;
 if (CheckKeyWord(request.QueryString[sqlParam].ToLower()))
 {
 return true;
 }
 }
 }
 return false;
 }
 ///<summary> 
 ///检查提交的表单中是否包含Sql注入关键字
 /// <param name="_request">当前HttpRequest对象</param> 
 /// <returns>如果包含sql注入关键字,返回:true;否则返回:false</returns> 
 ///</summary> 
 public bool CheckRequestForm()
 {
 if (request.Form.Count > 0)
 {
 foreach (string sqlParam in this.request.Form)
 {
 if (sqlParam == "__VIEWSTATE") 
 continue;
 if (sqlParam == "__EVENTVALIDATION") 
 continue;
 if (CheckKeyWord(request.Form[sqlParam]))
 {
 return true;
 }
 }
 }
 return false;
 }
 ///<summary> 
 ///检查字符串中是否包含Sql注入关键字 
 /// <param name="_key">被检查的字符串</param> 
 /// <returns>如果包含sql注入关键字,返回:true;否则返回:false</returns> 
 ///</summary> 
 private static bool CheckKeyWord(string _key)
 {
 string[] pattenKeyWord = StrKeyWord.Split('|');
 string[] pattenSymbol = StrSymbol.Split('|');
 foreach (string sqlParam in pattenKeyWord)
 {
 if (_key.Contains(sqlParam + " ") || _key.Contains(" " + sqlParam))
 {
 return true;
 }
 }
 foreach (string sqlParam in pattenSymbol)
 {
 if (_key.Contains(sqlParam))
 {
 return true;
 }
 }
 return false;
 }

 }

SqlInjectHelper类中,对request的query参数和form参数进行的检测,没有对cookie的检测,如有需要,可自行加上;

2、SqlInjectHelper在哪调用呢?

1)、如果想对整个web站点的所有请求都做sql关键字检测,那就在Global.asax 的 Application_BeginRequest方法中调用;

protected void Application_BeginRequest(object sender, EventArgs e)
 {
 SqlInjectHelper myCheck = new SqlInjectHelper(Request);
 bool result = myCheck.CheckSqlInject();
 if (result)
 {
 Response.ContentType = "text/plain";
 Response.Write("您提交的数据有恶意字符!");
 Response.End();
 }
 }

2)、如果只需对某个接口文件的接口进行sql关键字检测,那只需在该文件开始处调用SqlInjectHelper类即可;

public class Handler1 : IHttpHandler
 {
 public void ProcessRequest(HttpContext context)
 {
 SqlInjectHelper myCheck = new SqlInjectHelper(context.Request);
 bool result = myCheck.CheckSqlInject();
 context.Response.ContentType = "text/plain";
 context.Response.Write(result?"您提交的数据有恶意字符!":"");
 context.Response.StatusCode = result ? 500 : 200;
 }
 public bool IsReusable
 {
 get
 {
 return false;
 }
 }
 }

上面的代码就是对某个一般处理程序(ashx)添加了sql关键字检测;

3、补充说明:asp.net中的 __VIEWSTATE、__EVENTVALIDATION、

  在sql关键字检测方法中,排除了__VIEWSTATE、__EVENTVALIDATION这两个参数;

1)、__VIEWSTATE

  ViewState是ASP.NET中用来保存WEB控件回传时状态值一种机制。在WEB窗体(FORM)的设置为runat="server",这个窗体(FORM)会被附加一个隐藏的属性_VIEWSTATE。_VIEWSTATE中存放了所有控件在ViewState中的状态值。

ViewState是类Control中的一个域,其他所有控件通过继承Control来获得了ViewState功能。它的类型是system.Web.UI.StateBag,一个名称/值的对象集合。

  当请求某个页面时,ASP.NET把所有控件的状态序列化成一个字符串,然后做为窗体的隐藏属性送到客户端。当客户端把页面回传时,ASP.NET分析回传的窗体属性,并赋给控件对应的值;

2)、__EVENTVALIDATION

  __EVENTVALIDATION只是用来验证事件是否从合法的页面发送,只是一个数字签名,所以一般很短。

“id”属性为“__EVENTVALIDATION”的隐藏字段是ASP.NET 2.0的新增的安全措施。该功能可以阻止由潜在的恶意用户从浏览器端发送的未经授权的请求.;

4、sql关键词检测的另一个版本:该版本将所有危险字符都放在了一个正则表达式中;

该类不仅检测了sql常用关键字还有xss攻击的常用关键字

public class SafeHelper
 {
 private const string StrRegex = @"<[^>]+?style=[\w]+?:expression\(|\b(alert|confirm|prompt)\b|^\+/v(8|9)|<[^>]*?=[^>]*?&#[^>]*?>|\b(and|or)\b.{1,6}?(=|>|<|\bin\b|\blike\b)|/\*.+?\*/|<\s*script\b|<\s*img\b|\bEXEC\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\s+(TABLE|DATABASE)";
 public static bool PostData()
 {
 bool result = false;
 for (int i = 0; i < HttpContext.Current.Request.Form.Count; i++)
 {
 result = CheckData(HttpContext.Current.Request.Form[i].ToString());
 if (result)
 {
 break;
 }
 }
 return result;
 }

 public static bool GetData()
 {
 bool result = false;
 for (int i = 0; i < HttpContext.Current.Request.QueryString.Count; i++)
 {
 result = CheckData(HttpContext.Current.Request.QueryString[i].ToString());
 if (result)
 {
 break;
 }
 }
 return result;
 }
 public static bool CookieData()
 {
 bool result = false;
 for (int i = 0; i < HttpContext.Current.Request.Cookies.Count; i++)
 {
 result = CheckData(HttpContext.Current.Request.Cookies[i].Value.ToLower());
 if (result)
 {
 break;
 }
 }
 return result;

 }
 public static bool referer()
 {
 bool result = false;
 return result = CheckData(HttpContext.Current.Request.UrlReferrer.ToString());
 }
 public static bool CheckData(string inputData)
 {
 if (Regex.IsMatch(inputData, StrRegex))
 {
 return true;
 }
 else
 {
 return false;
 }
 }
 }

总结

下载本文
显示全文
专题