谈谈防 SQL 注入式攻击策略
要防范 SQL 注入式攻击, 应该注意以下几点:
(1). 检查输入的 SQL 语句的内容, 如果包含敏感字符, 则删除敏感字符, 一般敏感字符包括: ', >, <=, !, -, +, *, /, |, 空格等.
(2). 不要在用户输入过程中构造 WHERE 子句, 应该利用参数来使用存储过程.
因为 SQL 注入一般出现在程序开发构造一个 WHERE 子句伴随着用户输入的时候.
过滤非法字符的两种方法:
(1). 在 ASP.NET 可以自定义一个方法过滤非法字符, 效率较底, 但对敏感字符的过滤比较彻底. 实现如下:
///<summary>
///防止 SQL 注入式攻击
///</summary>
///<param name="inputString">用户输入字符串</param>
public string ConvertSql(string inputString)
{
inputString = inputString.Trim(); //去空格
inputString = inputString.Replace("'", ""); //去单引号
inputString = inputString.Replace(";", ""); //去分号
inputString = inputString.Replace("=", ""); //去等号
inputString = inputString.Replace("or", ""); //去 or
inputString = inputString.Replace("and", ""); //去 and
inputString = inputString.Replace("like", ""); //去 通配符
//............用户可以根据需要定义任何敏感字符
return inputString;
}
(2).由于上面这种枚举的方法对程序效率显然有影响, 因此并不是最有效的途径.
其实最佳途径可以通过 SqlCommandParameners 属性的参数传值实现, 将非法字符过滤.
原理是SQL 语句在传送过程中参数(用户输入的内容)是不可见的. 自然失去了攻击的机会.
以登录为例, 实现如下:
public int checkLogin(string loginName, string loginPwd)
{
SqlConnection con = new SqlConnection("Server=***;database=***;Uid=sa;Pwd=***");
SqlCommand myCommand = new SqlCommand("select count(*) from user where userName=@loginName and userPwd=@loginPwd", con);
myCommand.Parameters.Add(new SqlParameter("@loginName", SqlDbType.NVarChar, 20));
myCommand.Parameters["@loginName"].Value = loginName;
myCommand.Parameters.Add(new SqlParameter("@loginPwd", SqlDbType.NVarChar, 20));
myCommand.Parameters["@loginPwd"].Value = loginPwd;
myCommand.Connection.Open();
int i = (int)myCommand.ExecuteScalar();
myCommand.Connection.Close();
return i;
}
(3).最实用的方法: 建议大家多写存储过程, 它的作用不再仅仅是大家认为的那样起到提供一个接口, 提高执行速度等作用, 当今系统对性能和安全的要求已上升到主要位置.不用担心过多的建立存储过程会给服务器带来负担, 也不要认为书写存储过程麻烦, 当一个庞大的系统把大量的时间花在 SQL 语句的维护与解析和对系统安全的防范时, 这种麻烦完全是值得的. 最明显的优点是当你多建一个存储过程, 少一句前台 SQL 语句时: 便可兼得提高效率与防 SQL 注入式攻击, 何乐而不为呢?