Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 应用程序代码SQL注入/选择_C#_Sql Insert_App Code - Fatal编程技术网

C# 应用程序代码SQL注入/选择

C# 应用程序代码SQL注入/选择,c#,sql-insert,app-code,C#,Sql Insert,App Code,如果可能的话,我需要以下方面的指导 解释 我在App_代码中有一个main project.cs文件,其中包含主要功能。其中一个函数是SQL_注入,它将数据插入数据库 然后,我有多个页面同时从多台客户机使用此功能 问题: 我想要的答案是,这是一种安全的选择方法吗?或者我应该在每个.cs页面上分别创建一个新连接 原因/问题 由于这个原因,我们目前是一家小公司,但正在成长。由于SQL连接仍处于打开状态,某个页面发生崩溃。我担心这是由于两个连接试图在同一时间。我不确定这是问题所在还是其他原因造成的 /

如果可能的话,我需要以下方面的指导

解释 我在App_代码中有一个main project.cs文件,其中包含主要功能。其中一个函数是SQL_注入,它将数据插入数据库

然后,我有多个页面同时从多台客户机使用此功能

问题: 我想要的答案是,这是一种安全的选择方法吗?或者我应该在每个.cs页面上分别创建一个新连接

原因/问题 由于这个原因,我们目前是一家小公司,但正在成长。由于SQL连接仍处于打开状态,某个页面发生崩溃。我担心这是由于两个连接试图在同一时间。我不确定这是问题所在还是其他原因造成的

//GLOBAL DECLARATIONS

//DB CONNECTIONS - retrieve from config file

public static string ConProjectms = System.Configuration.ConfigurationManager.ConnectionStrings["conProject"].ConnectionString;

//DB CONNECT TO SQL
public static SqlConnection SqlConn = new SqlConnection();
public static SqlCommand SqlCmd = new SqlCommand();
public static SqlDataReader SqLdr;
public static string SqlStr;
public static string ConnString;


public static void SqlInject(string query, string dataBase)
{

    SqlConn.ConnectionString = ConProjectms;
    //Set the Connection String
    SqlConn.Open();
    //Open the connection 
    SqlCmd.Connection = SqlConn;
    //Sets the Connection to use with the SQL Command
    SqlCmd.CommandText = query;
    //Sets the SQL String
    SqlCmd.ExecuteNonQuery();
    //put Data 
    SqlClose();

}


public static void SqlClose()
{
    if (SqlConn.State != ConnectionState.Open) return;
    SqlConn.Close();
    SqlCmd.Parameters.Clear();
}

应用程序代码中的数据库代码没有理由不起作用。听起来你的连接池工作得不太好。查看连接字符串、IIS设置和数据库的性能。如果由于某种原因无法进行连接池,那么查询的运行时间就成了问题。

SQL可以同时处理多个连接。但是,您的代码很可能由两个客户端同时运行,并且它们将使用相同的连接,而不是两个单独的连接。那是件坏事

SQL Server在连接池方面做得非常出色——我假设其他数据库也有类似的功能。在这样一个世界中,您不应该尝试保留和重用任何与数据相关的对象,而是根据需要创建它们,当SQL发现您正在使用一个连接时,它会使用它在释放之前和释放之后创建的连接。你不必做任何奇怪的事情来获得这个功能

考虑到这一点,您的静态对象应该基本消失,您的SQLInject方法可能如下所示:

public static void SqlInject(string query, string dataBase)
{
   var connectionString = 
     System 
     .Configuration 
     .ConfigurationManager 
     .ConnectionStrings["conProject"] 
     .ConnectionString;

  using ( var connection = new SqlConnection( connectionString ) )
  {
    connection.Open( );
    using ( var command = connection.CreateCommand( ) )
    {
      command.CommandText = query;
      command.CommandType = CommandType.Text;
      command.ExecuteNonQuery( );
    }
  }
}
请注意,您不必担心关闭连接本身;使用块处理打开的活动对象的处置。这在很大程度上是人们从c直接执行SQL的方式。顺便说一下,您的代码和我的代码都没有使用数据库参数。也许你应该用它来编辑基本连接字符串

但是等等,还有更多

说到这里,既然您提出了对安全性的担忧,那么您应该知道这根本不是安全的代码——您的代码还是我的代码。SqlInject可能是一个好名字,因为它允许查询参数中几乎任何东西,顺便说一句,如果您正在执行ExecuteOnQuery,那么查询可能不是一个好名字

允许参数进入已知语句库(可能是存储过程)要好得多,验证这些参数,并使用SQL注入攻击缓解来参数化已知语句查找该短语,您将找到大量的示例和建议

仅针对yuks,以下是您可能会考虑的脚手架:

public static void SqlInject(string commandName, params[] object commandArgs )
{
   //--> no point in going on if we got no command...
   if ( string.IsNullOrEmpty( commandName ) )
     throw new ArgumentNullException( nameof( commandName ) );

   var connectionString = 
     System 
     .Configuration 
     .ConfigurationManager 
     .ConnectionStrings["conProject"] 
     .ConnectionString;

  using ( var connection = new SqlConnection( connectionString ) )
  {
    connection.Open( );
    using ( var command = connection.CreateCommand( ) )
    {
      command.CommandType = CommandType.Text;
      command.CommandText = "select commandText from dbo.StatementRepository where commandName = @commandName";
      command.Parameters.AddWithValue( "@commandName", commandName );
      var results = command.ExecuteScalar( );
      if ( results != null && results != DbNull.Value )
      {            
        //--> calling a separate method to validate args, that returns
        //--> an IDictionary<string,object> of parameter names
        //--> and possibly modified arguments.
        //--> Let this validation method throw exceptions.
        var validatedArgs = ValidateArgs( commandName, commandArgs );

        command.Parameters.Clear( );
        command.CommandText = query;
        foreach( var kvp in validatedArgs )
        {
          command.Parameters.AddWithValue( kvp.Key, kvp.Value );
        }
        command.ExecuteNonQuery( );
      }
      else
      {
        throw new InvalidOperationException( "Invalid command" );
      }          
    }
  }
}

我没有尝试编写一个实际的参数验证方法,因为这都包含在您的应用程序逻辑中……但我想让您了解如何达到更安全的状态。

您能提供代码以便每个人都能更好地理解请参阅updateYeah。不要尝试共享/重用SqlConnection对象或任何其他类似的类。您可以将连接字符串放在静态字段中,但是可以在SqlInject中创建您的SqlConnection和SqlCommand,并使用语句将它们的创建放在其中。非常感谢!帮了我很多忙!现在对我来说更有意义了。你的脚手架看起来很漂亮!一定会考虑它