日期:2014-05-17  浏览次数:20476 次

请教可变的查询字符串的安全过滤问题?
请教可变的查询字符串的安全过滤问题?


如 http://www.abc.com/list.aspx?T=1&P=1&C=1&D=1&C1=1&C2=2&C3=3
有多个传递值,而且值的个数是可变的,会有n个,list.aspx页面根据这些可变个数的参数生成查询语句。

问题来了:因为个数是变化的,不能用参数化查询语名,要不然要在逻辑层、数据层根据参数个数写n个方法。现用where来组合sql,在list.aspx.cs页面用if(T!=null) then sqlWhere+="T=1"之类的来拼sql,然后把where句子传给DAL.getListByWhere(sqlWhere)来执行查询。

请问1:用where拼sql时,如何有效防sql注入啊?

请问2:不用用where拼sql,有可变的条件的参数化查询吗?

------解决方案--------------------
考虑到安全性,你可以在底层代码中定义一个集合,存放你支持那些字段进行查询,不在支持查询集合里面的数据就舍弃掉,这样最后到数据库执行的SQL语句不至于太长,而且还可以防止随意构造的参数名在数据表里面不存在从而导致错误。
public List<string> Columns {
get {
List<string> _columns = new List<string>();
_columns.Add("UserName");
_columns.Add("MobileNo");

return _columns;
}
}
public void GetList(Dictionary<string, string> ps) {
string sql = "SELECT * FROM Users WHERE 1 = 1 ";
string sqlWhere = "";

List<SqlParameter> lst = new List<SqlParameter>();
foreach (var p in ps) {
if (Columns.Contains(p.Key)) {
lst.Add(new SqlParameter(p.Key, p.Value));
sqlWhere += string.Format("AND {0} = @{0}", p.Key);
}
}

SqlConnection conn = new SqlConnection("Initial Catalog=UseAdmin;Data Source=(local);Integrated Security=true;");
SqlCommand cmd = new SqlCommand(sql + sqlWhere, conn);

foreach (var p in lst) { cmd.Parameters.Add(p); }

cmd.ExecuteNonQuery();
}

------解决方案--------------------
写一个包含所有参数的SQL,给每个参数假定一个特殊值,表示不以该参数为条件,参考如下:
where xxx 
and (@par1='' or par1=@par1)
and (@par2=0 or par2=@par2)
...