Предупреждение: атаки с использованием SQL-инъекций

Я пытался адаптировать свой код к правилам FxCop и обнаружил это предупреждение: CA2100 Просмотрите строку запроса, переданную в «OleDbDataAdapter.OleDbDataAdapter(string, OleDbConnection)» в «WavesShaperNew.Parse(string, int)» на предмет возможных атак путем внедрения SQL. . Если строка составлена ​​с использованием любого пользовательского ввода, рассмотрите возможность использования хранимой процедуры или параметризованного SQL-запроса вместо создания запроса с конкатенацией строк.

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

ComboBox sheets = new ComboBox();
TextBox startRange = new TextBox();
TextBox endRange = new TextBox();

string query = string.Format("SELECT * FROM[" + sheets.SelectedItem + startRange.Text + ":" + endRange.Text + "]");
query = query.Replace("'", "");

OleDbDataAdapter adapter = new OleDbDataAdapter(query, con);

person Community    schedule 20.08.2020    source источник
comment
SELECT * FROM customers; delete from customers; blah blah blah Вы только что потеряли всех своих клиентов... Когда вы обнаружите, что конструируете параметры из пользовательского ввода и необработанного sql, вы только что открыли себе мир боли. Исправление состоит в том, чтобы ВСЕГДА использовать параметризованные запросы.   -  person TheGeneral    schedule 20.08.2020
comment
Или показан другой способ   -  person TheGeneral    schedule 20.08.2020
comment
@MichaelRandall Единственная проблема здесь в том, что имена таблиц не могут быть параметризованы. Способом избежать SQL-инъекций здесь было бы добавление имен таблиц в белый список.   -  person Johnathan Barclay    schedule 20.08.2020
comment
@JohnathanBarclay, а как было бы добавить имена таблиц в белый список?   -  person    schedule 20.08.2020


Ответы (1)


Как правило, вы должны параметризовать все SQL-запросы, чтобы избежать all-input" rel="nofollow noreferrer">инъекция SQL вместо использования конкатенации/интерполяции строк.

Однако имена таблиц не могут быть параметризованы.

Чтобы избежать SQL-инъекций, вы можете внести в белый список допустимые имена таблиц:

var queryableTables = new HashSet<string>
{
    "table1",
    "table2",
    // etc.
};

string tableName = sheets.SelectedItem + startRange.Text;

if (!queryableTables.Contains(tableName))
{
    throw new InvalidOperationException($"{tableName} is not queryable");
}

string query = $"SELECT * FROM [{tableName}]");
person Johnathan Barclay    schedule 20.08.2020
comment
Это не очень эффективно. Таблица 1; удалить из таблицы1; по-прежнему является допустимым вводом, так как он содержит допустимое имя таблицы. - person oerkelens; 20.08.2020
comment
@oerkelens Нет, это не так. Contains здесь HashSet<T>.Contains не string.Contains. Ваша логика применима к queryableTables.Any(tableName.Contains). - person Johnathan Barclay; 20.08.2020
comment
Спасибо @JohnathanBarclay - person ; 20.08.2020