2017-01-24 4 views
0

мне нужно некоторое наведение на следующее, если возможно, пожалуйста,App_Code SQL Inject/Выбрать

Объяснение У меня есть главный project.cs файл в App_Code, который содержит основные функции. Одной из этих функций является SQL_Inject, который вставляет данные в базу данных.

У меня есть несколько страниц, которые используют эту функцию на нескольких клиентских компьютерах одновременно.

Вопрос Ответ, который я получил после, является ли это безопасным методом выбора? Или я должен создавать новое соединение отдельно на каждой странице .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(); 
} 
+1

Можете ли вы предоставить код, чтобы все получили лучшее понимание. – Izzy

+0

см. Обновление – oldman

+0

Да. Не пытайтесь использовать/повторно использовать объекты SqlConnection * * (и любые другие классы, подобные этому). Вы можете поместить соединение * string * в поле 'static', но создайте свои' SqlConnection' и 'SqlCommand' * внутри *' SqlInject' и поместите их создание внутри 'using' операторов. –

ответ

0

SQL может обрабатывать несколько соединений одновременно. Однако вы, скорее всего, будете работать одновременно с двумя клиентами, и они будут использовать одно соединение, а не два отдельных соединения. Это плохо # 1.

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(); 
    } 
    } 
} 

Обратите внимание, что вам не придется беспокоиться о закрытии соединения по себе; блоки using обрабатывают расположение открытых активных объектов. Это в значительной степени то, как люди делают прямые SQL от c#. Кстати, ни ваш код, ни мой не используют аргумент dataBase. Может быть, вы должны отредактировать базовую строку соединения с ней?

Но подождите - есть еще!

Сказав все это, и поскольку вы подняли озабоченность по поводу безопасности, вы должны знать, что это не безопасный код вообще - ваш или мой. SqlInject, вероятно, является хорошим именем, потому что он позволяет почти что угодно в аргументе query (который, BTW, если вы делаете ExecuteNonQuery, то, возможно, query - нехорошее имя).

Вы гораздо лучше разрешаете аргументы в библиотеке известных утверждений (возможно, хранимых процедур), проверяя эти аргументы и применяя смягчение атаки SQL Injection для параметризации ваших известных утверждений (найдите эту фразу, и вы найдете изобилие примеров и рекомендаций).

Просто для 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"); 
     }   
    } 
    } 
} 

Я не пытался написать фактический аргумент метода проверяющий, потому что это все завернутые в вашей логики приложения ... но Я хотел дать вам представление о том, как вы можете добраться до состояния безопаснее.

+0

Большое вам спасибо за это! помогает мне много! теперь имеет для меня гораздо больше смысла. Ваш эшафот выглядит впечатляюще! обязательно рассмотрит это – oldman

0

Нет причин, по которым код базы данных внутри App_Code не должен работать. Это похоже на то, что ваш пул соединений не работает очень хорошо. Посмотрите на строку подключения, параметры IIS и производительность вашей базы данных. Если по какой-то причине пул соединений невозможен, то время работы запроса становится проблемой.

Смежные вопросы