用于目录扩展存储过程的名称的开头,如 xp_cmdshell。
注:验证输入是最被常用和联想到的,但是个人感觉这种方式不但代码显得肥胖,而且效率不是很好
2.使用类型安全的 SQL 参数
SQL Server 中的 Parameters 集合提供了类型检查和长度验证。如果使用 Parameters 集合,则输入将被视为文字值而不是可执行代码。使用 Parameters 集合的另一个好处是可以强制执行类型和长度检查。范围以外的值将触发异常。以下代码段显示了如何使用 Parameters 集合:
1 SqlDataAdapter myCommand = new SqlDataAdapter("AuthorLogin", conn);
2 myCommand.SelectCommand.CommandType = CommandType.StoredProcedure;
3 SqlParameter parm = myCommand.SelectCommand.Parameters.Add("@au_id",
4 SqlDbType.VarChar, 11);
5 parm.Value = Login.Text;
在此示例中,@au_id 参数被视为文字值而不是可执行代码。将对此值进行类型和长度检查。如果 @au_id 值不符合指定的类型和长度约束,则将引发异常。
存储过程如果使用未筛选的输入,则可能容易受 SQL Injection 攻击。例如,以下代码容易受到攻击:
SqlDataAdapter myCommand = new SqlDataAdapter("LoginStoredProcedure '" + Login.Text + "'", conn);
如果使用存储过程,则应使用参数作为存储过程的输入。
注:在鄙人现在的项目中,这种方法应用最为广泛
3.在动态 SQL 中使用参数集合
如果不能使用存储过程,您仍可使用参数,如以下代码示例所示:
1 SqlDataAdapter myCommand = new SqlDataAdapter(
2 "SELECT au_lname, au_fname FROM Authors WHERE au_id = @au_id", conn);
3 SQLParameter parm = myCommand.SelectCommand.Parameters.Add("@au_id",
4 SqlDbType.VarChar, 11);
5 Parm.Value = Login.Text;
注:和第二种雷同,这种方法是为了补充方法2存在,因为往往在很多时候业务简单不需要用proc的时候,可以用这种方法
4.筛选输入
筛选输入可以删除转义符,这也可能有助于防止 SQL 注入。但由于可引起问题的字符数量很大,因此这并不是一种可靠的防护方法。以下示例可搜索字符串分隔符。
1 private string SafeSqlLiteral(string inputSQL)
2 {
3 return inputSQL.Replace("'", "''");
4 }
注:Filtering Input有种类似方法1
5.LIKE 子句
请注意,如果要使用 LIKE 子句,还必须对通配符字符进行转义:
1
2 s = s.Replace("[", "[[]");
3 s = s.Replace("%", "[%]");
4 s = s.Replace("_", "[_]");
注:针对like子句,在使用时的效率这里就不多说了,总之要慎用了。
以上所有方法及其注释高亮显示部分,均为本人愚见,如果对方法有补充或者对高亮部分有不同意见的,欢迎大家给出意见,共同进步.