C# 使用'防止SQL注入;AS查询';

C# 使用'防止SQL注入;AS查询';,c#,sql-injection,C#,Sql Injection,我有下面的代码,它表面上看起来很标准,但是inquery是另一个SQL语句,因此“AS query”位于SQL字符串的末尾。我想知道是否有一种复杂的方法来参数化下面的SQL命令,而不是将整个查询连接在一起 我能想到的唯一解决方案是将查询作为字符串,而将其作为SQLCommandtype对象,并启动2个命令。1到CAN,另一个显示数据预览 public static CommandStatus<int> GetQueryRecordCount(SqlConnection connect

我有下面的代码,它表面上看起来很标准,但是inquery是另一个SQL语句,因此“AS query”位于SQL字符串的末尾。我想知道是否有一种复杂的方法来参数化下面的SQL命令,而不是将整个查询连接在一起

我能想到的唯一解决方案是将查询作为字符串,而将其作为
SQLCommand
type对象,并启动2个命令。1到CAN,另一个显示数据预览

public static CommandStatus<int> GetQueryRecordCount(SqlConnection connection, String query)
{
    String sql = "SELECT COUNT(1) FROM (" + query + ") AS QUERY";
    SqlCommand cmd = new SqlCommand();
    cmd.CommandType = CommandType.Text;
    cmd.CommandText = sql;
    cmd.Connection = connection;
    cmd.CommandTimeout = GetTimeout();

    try
    {
        SqlDataReader dataReader = cmd.ExecuteReader();
        dataReader.Read();

        String count = dataReader[0].ToString();
        dataReader.Close();

        return new CommandStatus<int>(Int32.Parse(count));
    }
    catch (Exception e)
    {
        return new CommandStatus<int>("Failed to GetQueryRecordCount[" + sql + "]:" + e.Message, e);
    }
}


这个函数实际上是SQL注入的设计

白名单此函数将接受的SQL查询是使其安全的唯一方法

也就是说,调用方将无法注入任何SQL查询,他们只能从预先检查过的查询的固定列表中进行选择。该列表甚至可以定义为所显示函数中的静态字符串数组


但是,他们不需要将整个查询作为字符串传递,他们只需要传递一个序数整数来标识白名单中要运行的查询。

该字符串中没有值,因此除了
TOP
返回的行数之外,没有参数
因为查询
不是关键字,它只是子查询的别名。这段代码到底有什么意义?如果样本数少于20,则返回20或样本数。“query”参数来自何处?如果它是同一模块中的一个可用值,那么sql注入的风险就非常小。另一方面,如果它来自一些用户输入,那么它就是一个真正的sql注入风险。这通常用于以“安全”方式传递参数way@DanielSchmid表名和列名不能作为SQL参数提供。@艾米:好吧,它们可以,只要您随后动态生成结果查询。(我提到这一点并不是为了迂腐,而是因为将它们作为参数传递给存储过程,然后根据白名单进行检查是一种合法的业务处理方式,而不是必须动态构建整个过程并为完全任意的查询打开大门。)
"SELECT COUNT(1) FROM (SELECT TOP 20 [RecordID],[Name],[SonsName],[DadsName],[MothersName],[DaughtersName] FROM [dbo].[sample] ) AS QUERY"