防止SQL注入

一个恐怖的例子:

注入式攻击的详细解释SQL下面我们将以一个简单的用户登陆为例,结合代码详细解释一下SQL注入式攻击,与及他的防范措施。对于一个简单的用户登陆可能的代码如下:
try
{
 string strUserName = this.txtUserName.Text;
 string strPwd = this.txtPwd.Text;
 string strSql = "select * from userinfo where UserName='" + strUserName + "' and Password='" + strPwd + "'";
 SqlConnection objDbConn = new SqlConnection("数据库连接字符串");
 SqlDataAdapter objAdapter = new SqlDataAdapter(strSql,objDbConn);
 DataSet objDataSet = null;
 objAdapter.Fill(objDataSet);//TODO 对获取的数据进行判断。
}
catch (System.Exception e)
{
 this.lblMsg.Text = e.Message;
 this.lblMsg.Visible = true;
}
  在上面这段代码中,如果用户的输入是正常的用户名和密码的话,那么执行都会比较正常,但是,假如输入用户名的时候,输入的是“johny’--”的话,在 SQLServer里面执行的语句将会是“select * from userinfo where UserName=’johny’--‘ and Password=’密码’”,只要数据库中存在johny这个用户的话,那么不管密码是什么,语句都能够执行成功,并且能够顺利通过登陆。还 有更加厉害的,我们知道SQLServer里面有一些系统的存储过程,能够执行操作系统的很多命令,比如xp_cmdshell,假如上面用户登陆的时 候,用户名部分输入的是“johny’ exec xp_cmdshell ‘format d:/s’--”,大家想想一下后果是什么?有恶意的用户,只要把’format d:/s’这个命令稍加改造就能够做很多不合法的事情。

 

.NET防SQL注入方法


1,利用SqlCommand传参数的方法:

string strSQL="SELECT * FROM [user] WHERE user_id=@id";
SqlCommand cmd = new SqlCommand();
cmd.CommandText = strSQL;
cmd.Parameters.Add("@id",SqlDbType.VarChar,20).Value=Request["id"].ToString();

  

2,过滤禁止运行法:

/// <summary>
/// 过滤SQL语句,防止注入
/// </summary>
/// <param name="strSql"></param>
/// <returns>0 - 没有注入, 1 - 有注入 </returns>
public int filterSql(string sSql)
{ 
    int srcLen, decLen = 0;
    sSql = sSql.ToLower().Trim();
    srcLen = sSql.Length;
    sSql = sSql.Replace("exec", "");
    sSql = sSql.Replace("delete", "");
    sSql = sSql.Replace("master", "");
    sSql = sSql.Replace("truncate", "");
    sSql = sSql.Replace("declare", "");
    sSql = sSql.Replace("create", "");
    sSql = sSql.Replace("xp_", "no");
    decLen = sSql.Length;
    if (srcLen == decLen) return 0; else return 1;         
}

3,存储过程


js版的防范SQL注入式攻击代码:

<script language="javascript">
<!--
var url = location.search;
var re=/^?(.*)(select%20|insert%20|delete%20from%20|count(|drop%20table|update%20truncate%20|asc(|mid(|char(|xp_cmdshell|exec%20master|net%20localgroup%20administrators|"|:|net%20user||%20or%20)(.*)$/gi;
var e = re.test(url);
if(e) {
    alert("地址中含有非法字符~");
    location.href="error.asp";
}
//-->
<script>

  


总结:在编写代码前一定要细心考虑每种存在的安全性隐患。

 
 
 
 二.http://www.oschina.net/code/snippet_2623534_54893

代码片段(1) [全屏查看所有代码]

1. [代码][C#]代码     跳至 [1] [全屏预览]

#region 防止sql注入式攻击(可用于UI层控制)

/// 
/// 判断字符串中是否有SQL攻击代码
/// 
/// 传入用户提交数据
/// true-安全;false-有注入攻击现有;
public bool ProcessSqlStr(string inputString)
{
    string SqlStr = @"and|or|exec|execute|insert|select|delete|update|alter|create|drop|count|*|chr|char|asc|mid|substring|master|truncate|declare|xp_cmdshell|restore|backup|net +user|net +localgroup +administrators";
    try
    {
        if ((inputString != null) && (inputString != String.Empty))
        {
            string str_Regex = @"(" + SqlStr + @")";

            Regex Regex = new Regex(str_Regex, RegexOptions.IgnoreCase);
            //string s = Regex.Match(inputString).Value; 
            if (true == Regex.IsMatch(inputString))
                return false;

        }
    }
    catch
    {
        return false;
    }
    return true;
}


/// 
/// 处理用户提交的请求,校验sql注入式攻击,在页面装置时候运行
/// System.Configuration.ConfigurationSettings.AppSettings["ErrorPage"].ToString(); 为用户自定义错误页面提示地址,
/// 在Web.Config文件时里面添加一个 ErrorPage 即可
/// 
///     
/// 
public void ProcessRequest()
{
    try
    {
        string getkeys = "";
        string sqlErrorPage = System.Configuration.ConfigurationSettings.AppSettings["ErrorPage"].ToString();
        if (System.Web.HttpContext.Current.Request.QueryString != null)
        {

            for (int i = 0; i < System.Web.HttpContext.Current.Request.QueryString.Count; i++)
            {
                getkeys = System.Web.HttpContext.Current.Request.QueryString.Keys[i];
                if (!ProcessSqlStr(System.Web.HttpContext.Current.Request.QueryString[getkeys]))
                {
                    System.Web.HttpContext.Current.Response.Redirect(sqlErrorPage + "?errmsg=" + getkeys + "有SQL攻击嫌疑!");
                    System.Web.HttpContext.Current.Response.End();
                }
            }
        }
        if (System.Web.HttpContext.Current.Request.Form != null)
        {
            for (int i = 0; i < System.Web.HttpContext.Current.Request.Form.Count; i++)
            {
                getkeys = System.Web.HttpContext.Current.Request.Form.Keys[i];
                if (!ProcessSqlStr(System.Web.HttpContext.Current.Request.Form[getkeys]))
                {
                    System.Web.HttpContext.Current.Response.Redirect(sqlErrorPage + "?errmsg=" + getkeys + "有SQL攻击嫌疑!");
                    System.Web.HttpContext.Current.Response.End();
                }
            }
        }
    }
    catch
    {
        // 错误处理: 处理用户提交信息!
    }
}
#endregion




#region 转换sql代码(也防止sql注入式攻击,可以用于业务逻辑层,但要求UI层输入数据时候进行解码)
/// 
/// 提取字符固定长度
/// 
/// 
/// 
/// 
public string CheckStringLength(string inputString, Int32 maxLength)
{
    if ((inputString != null) && (inputString != String.Empty))
    {
        inputString = inputString.Trim();

        if (inputString.Length > maxLength)
            inputString = inputString.Substring(0, maxLength);
    }
    return inputString;
}

/// 
/// 将输入字符串中的sql敏感字,替换成"[敏感字]",要求输出时,替换回来
/// 
/// 
/// 
public string MyEncodeInputString(string inputString)
{
    //要替换的敏感字
    string SqlStr = @"and|or|exec|execute|insert|select|delete|update|alter|create|drop|count|*|chr|char|asc|mid|substring|master|truncate|declare|xp_cmdshell|restore|backup|net +user|net +localgroup +administrators";
    try
    {
        if ((inputString != null) && (inputString != String.Empty))
        {
            string str_Regex = @"(" + SqlStr + @")";

            Regex Regex = new Regex(str_Regex, RegexOptions.IgnoreCase);
            //string s = Regex.Match(inputString).Value; 
            MatchCollection matches = Regex.Matches(inputString);
            for (int i = 0; i < matches.Count; i++)
                inputString = inputString.Replace(matches[i].Value, "[" + matches[i].Value + "]");

        }
    }
    catch
    {
        return "";
    }
    return inputString;

}

/// 
/// 将已经替换成的"[敏感字]",转换回来为"敏感字"
/// 
/// 
/// 
public string MyDecodeOutputString(string outputstring)
{
    //要替换的敏感字
    string SqlStr = @"and|or|exec|execute|insert|select|delete|update|alter|create|drop|count|*|chr|char|asc|mid|substring|master|truncate|declare|xp_cmdshell|restore|backup|net +user|net +localgroup +administrators";
    try
    {
        if ((outputstring != null) && (outputstring != String.Empty))
        {
            string str_Regex = @"[(" + SqlStr + @")]";
            Regex Regex = new Regex(str_Regex, RegexOptions.IgnoreCase);
            MatchCollection matches = Regex.Matches(outputstring);
            for (int i = 0; i < matches.Count; i++)
                outputstring = outputstring.Replace(matches[i].Value, matches[i].Value.Substring(1, matches[i].Value.Length - 2));

        }
    }
    catch
    {
        return "";
    }
    return outputstring;
}
#endregion
原文地址:https://www.cnblogs.com/xdot/p/7095956.html