Как добавить параметры в мои запросы при использовании clr / c ++ для нескольких переменных - PullRequest
0 голосов
/ 29 января 2020

Я хочу иметь возможность добавлять параметры в мои запросы, чтобы сделать мои заявления менее уязвимыми для sql инъекций

Мой код (ключевые части заключены в **, поскольку я не могу выделить код жирным шрифтом)

        OleDbConnection^ existingSqlConnection = nullptr;
        existingSqlConnection = gcnew OleDbConnection("Provider = Microsoft.ACE.OLEDB.12.0;" +
            "Data Source =" + "myDatabaseV3.accdb");
        **String^ sqlText = "SELECT * FROM @tableName WHERE @fieldName = @fieldEntityName";
        OleDbCommand^ dbCommand = gcnew OleDbCommand(sqlText, existingSqlConnection);
        OleDbParameterCollection^ paramCollection = dbCommand->Parameters;
        dbCommand->Parameters->Add(gcnew OleDbParameter("@tableName", tableName->ToString()));
        dbCommand->Parameters->AddWithValue("@fieldName", field);**
        dbCommand->Parameters->AddWithValue("@fieldEntityName", fieldEntity);
        **Console::WriteLine(dbCommand->CommandText);
        Console::WriteLine(paramCollection->Count);** 
        existingSqlConnection->Open();
        OleDbDataReader^ reader = dbCommand->ExecuteReader(System::Data::CommandBehavior::CloseConnection);

        return reader;

Выходные данные для этого:

SELECT * FROM @tableName WHERE @fieldName = @ fieldEntityName

3

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

1 Ответ

0 голосов
/ 29 января 2020

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

Вдоль этих строк, Параметры могут использоваться только там, где переменные могут использоваться в запросах. И переменные не могут использоваться для имен объектов, поэтому люди прибегают к использованию SQL Injection, когда имена таблиц и / или столбцов необходимо изменить. В вашем примере кода:

  • @tableName никогда не может быть переменной в запросе, следовательно, это не может быть параметр
  • @fieldName никогда не может быть переменной в запросе, следовательно, он не может быть параметром
  • @fieldEntityName, если предполагается, что это значение, а не имя столбца, может быть параметром, и в этом случае он останется как @fieldEntityName в запросе, и это будет иметь значение fieldEntity.

Пожалуйста, посмотрите второй вариант мой ответ на ваш связанный вопрос о том, как предотвратить SQL Инъекцию (краткий ответ: дезинфицировать входы ).

Кроме того, использование AddWithValue() является плохой практикой. Создайте параметр с предполагаемым максимальным размером, затем присвойте ему значение и, наконец, добавьте его в коллекцию параметров. Вы не хотите, чтобы он автоматически определял максимальный размер параметра, так как он будет использовать первое полученное значение, и любое последующее значение, которое длиннее, будет молча усечено.

...