1

我有问题。我希望这个工作,但它没有:

SqlDataSource.SelectCommand = "SELECT blah1, blah2 FROM myTable WHERE @ColumnName = @Value";

SqlDataSource.SelectParameters.Add("ColumnName", System.Data.DbType.String, "one");
SqlDataSource.SelectParameters.Add("Value", System.Data.DbType.String, "two");

它不会替换第一个参数“ColumnName”。如果我删除该参数并像这样将列名放入其中,它将起作用:

SqlDataSource.SelectCommand = "SELECT blah1, blah2 FROM myTable WHERE one = @Value";

SqlDataSource.SelectParameters.Add("Value", System.Data.DbType.String, "two");

我有一个用户界面,用户可以在其中选择要搜索的数据库列名。我想保护自己免受任何形式的注射攻击。有什么想法可以让我完成这项工作吗?

我读到的一个想法是使用查找表从索引中获取索引DropDownList并以这种方式提取列名。我可以完成这项工作,但如果可能的话,我宁愿让参数化工作,因为这对我来说似乎更自然。

提前感谢您提供的任何帮助。

4

3 回答 3

2

由于查询参数是在解析完 SQL 并生成执行计划后才解析的,因此实际上无法动态构建带参数的 SQL。当然,我建议以安全的方式构建 SQL 字符串本身。也许首先创建一个enum有效的列名:

enum DbColumns { One, Two, Three };

然后像这样构建 SQL 字符串:

DbColumns colName = (DbColumns)Enum.Parse(typeof(DbColumns), "One");
SqlDataSource.SelectCommand = String.Format("SELECT blah1, blah1 FROM myTable WHERE {0} = @Value", colName);

另一个想法是使用正则表达式验证列名,可能只允许[a-z].

于 2013-03-14T21:25:08.043 回答
1

恐怕你不能这样做,你可以做的是一个小技巧:

SELECT blah1, blah1 FROM myTable 
WHERE (@blah1 is null or blah1 = @blah1)
   or (@blah2 is null or blah2 = @blah2)

并提供所有参数@blah1、@blah2,但只分配您需要的参数。

Mike Christensen 为您提供的 NB 解决方案基本上是在正确的条件下构建字符串,在最简单的情况下是

public bool BuildQueryWithCondition(string fieldName, string fieldValue) {
   var queryTemplate = "SELECT blah1, blah1 FROM myTable WHERE {0} = @Value"
     , query = string.Format(queryTemplate, fieldName)
   SqlDataSource.SelectCommand = query;
   SqlDataSource.SelectParameters.Add("Value", System.Data.DbType.String, fieldValue);
}
于 2013-03-14T21:11:10.653 回答
0

I have figured out a way to include a work around for parametrized column names. I had the same problem but came up with a different way and since I would be the only one using the column names then I believe this is still a safe bet.

            String sqlcomm = "SELECT * FROM Asset WHERE " + assetColName + " = ";
            command.CommandText = sqlcomm + "$assetColValue";

            //command.CommandText = @"SELECT * FROM Asset WHERE $assetColName = '$assetColValue'";
            //command.Parameters.AddWithValue("$assetColName", assetColName);

            command.Parameters.AddWithValue("$assetColValue", assetColValue);

As you can see from the code above. I tried almost what you did which I then had to comment out. I then concatenated strings together and was able to use my paramterized column name and value which then the value is securely added. The column name however is not secured but this is a method that only I will be using so its still somewhat safe. You can add regular expressions if you want to be more secure but you get the idea of the fix.

于 2013-09-25T15:14:27.763 回答