网站开发者乐园

工作着,并快乐着,享受生活每一天……

Web站点的SQL注入与防御总结

最近,我们的网站出现了SQL注入的问题,或许是网站关注的人多了,还是有人在捣乱,总归数据库被注入恶意代码,让人一时间不知如何是好,从网上搜索SQL 注入,那个数据可叫多呀,耐着性子阅读(不读也没办法),但是大部分是过滤恶意字符串的方法,方法如下:

一、过滤恶意字符串

string XH_In, XH_In2;
//自定义需要过滤的字串,用 "|" 分隔
XH_In = "'|;|and|exec|insert|select|delete%20from|update|count|*|%|chr|mid|master|truncate|char|declare|drop%20table|from|net%20user|xp_cmdshell|/add|net%20localgroup%20administrators|Asc|char";
XH_In2 = "'|;|and|exec|insert|select|delete%20from|update|count|chr|mid|master|truncate|char|declare|drop%20table|from|net%20user|xp_cmdshell|/add|net%20localgroup%20administrators|Asc|char";

string[] SqlInject = XH_In.Split('|');
string[] SqlInject2 = XH_In2.Split('|');
//--------POST部份------------------
if (!Request.Form.Equals(""))
{
  foreach (string XH_Post in Request.Form)
  {
    for (int j = 0; j < SqlInject.GetLength(0); j++)
    {
      if (Request.Form[XH_Post].ToLower().IndexOf(SqlInject[j]) != -1)
      {
        Response.Write("操作IP:"+Request.ServerVariables["REMOTE_ADDR"]);
        Response.Write("操作页面:"+Request.ServerVariables["URL"]);
        Response.Write("提交方式:"+"POST");
        Response.Write("提交参数:"+XH_Post);
        Response.Write("提交数据:"+Request.Form[XH_Post]);
      }
    }
  }
}

//--------GET部份------------------
if (!Request.QueryString.Equals(""))
{
  foreach (string XH_Get in Request.QueryString)
  {
    for (int j = 0; j < SqlInject.GetLength(0); j++)
    {
      if (Request.QueryString[XH_Get].ToLower().IndexOf(SqlInject[j]) != -1)
      {
        Response.Write("操作IP:"+Request.ServerVariables["REMOTE_ADDR"]);
        Response.Write("操作页面:"+Request.ServerVariables["URL"]);
        Response.Write("提交方式:"+"GET");
        Response.Write("提交参数:"+XH_Get);
        Response.Write("提交数据:"+Request.Form[XH_Get]);
      }
    }
  }
}

//--------COOKIE部份------------------
if (!Request.Cookies.Equals(""))
{
  foreach (string XH_Cookie in Request.Cookies)
  {
    for (int j = 0; j < SqlInject2.GetLength(0); j++)
    {
      if (Request.Cookies[XH_Cookie].ToString().ToLower().IndexOf(SqlInject2[j]) != -1)
      {
        Response.Write("操作IP:"+Request.ServerVariables["REMOTE_ADDR"]);
        Response.Write("操作页面:"+Request.ServerVariables["URL"]);
        Response.Write("提交方式:"+"Cookie");
        Response.Write("提交参数:"+XH_Cookie);
        Response.Write("提交数据:"+Request.Form[XH_Cookie]);
      }
    }
  }
}
这种方法,有一定的可行性,但是不能每一个页面都加呀,这会儿就只能写到HttpModule模块中了,将上的代码做一定的变化,写入到自定义的一个模块中,然而,这样做之后,又出来一个问题,就是我们发布的正常信息,由于包含了这样的关键字,而无法正常添加,这也是一个很难受的问题,那怎么办呢,最后,我发现不能偷懒,写SQL语句时,每个语句都进行相应的检查,确实很困难,这时,我建议,尽量采用Parameter参数化的SQL命令来执行了,这种办法可以彻底杜绝SQL 注入,代码样例如下:

添加数据:

  public bool Add(ECorpSite.Model.SiteNewsCls model)
  {
   StringBuilder strSql=new StringBuilder();
   strSql.Append("insert into SiteNewsCls(");
   strSql.Append("infoClsID,clsName,parentID,childCount,depth,userClsID,isHasPic,picSize)");
   strSql.Append(" values (");
   strSql.Append("@infoClsID,@clsName,@parentID,@childCount,@depth,@userClsID,@isHasPic,@picSize)");
   OleDbParameter[] parameters = {
     new OleDbParameter("@infoClsID", OleDbType.VarChar,12),
     new OleDbParameter("@clsName", OleDbType.VarChar,30),
     new OleDbParameter("@parentID", OleDbType.VarChar,12),
     new OleDbParameter("@childCount", OleDbType.Integer,4),
     new OleDbParameter("@depth", OleDbType.Integer,4),
   parameters[0].Value = model.infoClsID;
   parameters[1].Value = model.clsName;
   parameters[2].Value = model.parentID;
   parameters[3].Value = model.childCount;
   parameters[4].Value = model.depth;

            DbHelperOleDb.ExecuteSql(strSql.ToString(), parameters);

            strSql.Remove(0, strSql.Length);
            strSql.Append("update SiteNewsCls set ");
            strSql.Append("childCount=childCount+1");
            strSql.Append(" where infoClsID='" + model.parentID + "'");

            return DbHelperOleDb.ExecuteSql(strSql.ToString()) > 0;
  }

删除数据:

  /// <summary>
  /// 删除一条数据
  /// </summary>
  public bool Delete(string infoClsID)
  {
            bool rtnValue = false;
   StringBuilder strSql=new StringBuilder();
           
            strSql.Append("select infoClsID from SiteNewsCls where parentID=@infoClsID");
            OleDbParameter[] parameters = {
     new OleDbParameter("@infoClsID", OleDbType.VarChar,50)};
            parameters[0].Value = infoClsID;

     return DbHelperOleDb.ExecuteSql(strSql.ToString(), parameters)>0;

  }

上面两个为参考代码,其它代码类同,这种方法比较好,初一看,好像写起来很费事,但是,在实际应用中,却可以提高速度与降低出错率,当然更可防止SQL注入,写出来供大家参考,有不同意见的回帖讨论。

对于我们的数据库被注入问题,主要也是由于早期写的代码没有使用参数化的SQL语句造成的,还望新手引以为鉴。

posted on 2009-01-19 12:54  舒健  阅读(447)  评论(0编辑  收藏  举报

导航

百思特网络学习基地 www.bestwl.com 欢迎各位朋友前来访问