C# SQL注入漏洞代码c

C# SQL注入漏洞代码c,c#,sql,ado.net,veracode,secure-coding,C#,Sql,Ado.net,Veracode,Secure Coding,Veracode报告显示以下查询的SQL注入缺陷 private const string DropDatabaseTemplate = @"DROP DATABASE [{0}]"; ExecuteNonQuery(connection, string.Format(DropDatabaseTemplate, databaseName)); private static int ExecuteNonQuery(SqlConnection connection, strin

Veracode报告显示以下查询的SQL注入缺陷

private const string DropDatabaseTemplate = @"DROP DATABASE [{0}]";
ExecuteNonQuery(connection, string.Format(DropDatabaseTemplate, databaseName));

private static int ExecuteNonQuery(SqlConnection connection, string commandText)
        {
            using (var command = new SqlCommand(commandText, connection))
            {
                return command.ExecuteNonQuery();
            }
        }
他们建议使用参数化的预置语句。 我将如何消除此安全漏洞


提前谢谢。

看起来怎么样

private const string DropDatabaseTemplate = @"DROP DATABASE [{0}]";


private static int ExecuteNonQuery(SqlConnection connection, string commandText)
{
    string dbNamesQuery_ = @"SELECT [name]
                FROM sys.databases d
                WHERE d.database_id > 4";

    DataTable tableNames = new DataTable();
    using (var command = new SqlCommand(dbNamesQuery_, connection))
    {
        SqlDataReader dataReader_ = command.ExecuteReader();
        tableNames.Load(dataReader_);        //allow you dynamically load actual list DB, but you can fill table manually.
        //find exactly same name of DB that user requared.
        var rowsData_ = tableNames.Select(String.Format("name = '{0}'", commandText));        
        if (rowsData_.Length == 1)        //it will be prevent any kind of injection.
        {
            command.CommandText = String.Format(DropDatabaseTemplate, commandText);
            return command.ExecuteNonQuery();
        }
        else
        {
            return -1;
        }
    }
}

我从未尝试过,但我怀疑它会起作用:

    private static void DropDbNamed(SqlConnection connection, string name)
    {
        using (var command = new SqlCommand("EXEC @q", connection))
        {
            command.Parameters.AddWithValue("@q", $"DROP DATABASE [{name}]"); 
            var command.ExecuteScalar();
        }
    }

注意:Joel使用AddWithValue的标准停止在此处不适用

这是否回答了您的问题?虽然这段代码确实易受攻击,但您不能将其参数化。在SQL中,只能参数化数据,不能参数化标识符。您唯一能做的就是在尝试删除数据库之前确保数据库确实存在,这是为了防止在出现异常时向用户泄漏信息。该特定语句无法参数化,因此您收到的建议,尽管总体上是正确的,但在这种情况下无法应用。Aving说,我建议不要在代码库中使用此方法选项。删除数据库应该是设计时操作,而不是运行时操作。顺便说一句,这适用于所有数据库结构更改。当然,可能存在此规则不适用的情况,但此类情况很少。为什么不直接从sys.databases where[name]中选择[name]=@databaseName?@Zohar Peled我相信databaseName可能是漏洞的另一个地方,如果它是我写的一个参数的话。参数化查询可以防止SQL注入。这是他们的主要观点。