Есть ли риск SQL-инъекций с этим запросом?Если так, как я могу избежать этого? - PullRequest
4 голосов
/ 09 февраля 2012

Я обычно создаю параметризованные запросы, чтобы избежать атак SQL-инъекций. Тем не менее, у меня есть конкретная ситуация, когда я не смог сделать это полностью:

public DataSet getLiveAccountingDSByParameterAndValue(string parameter, string value)
{
    string sql = "select table_ref as Source, method as Method, sip_code as Code, " +
        " from view_accountandmissed " +
        " where " + parameter + " like @value " +
        " order by time DESC ";
    MySqlCommand cmd = commonDA.createCommand(sql);
    cmd.Parameters.Add("@value", MySqlDbType.String);
    cmd.Parameters["@value"].Value = "%" + value + "%";

    MySqlDataAdapter objDA = commonDA.createDataAdapter(cmd);
    DataSet objDS = new DataSet();
    objDA.Fill(objDS);
    return objDS;
}

Как видите, я создаю @ value в качестве параметра, но если я попытаюсь сделать то же самое с параметром , запрос завершится неудачей.

Итак, есть ли риск SQL-инъекции с этим запросом? Кроме того, учтите, что параметр устанавливается с помощью SelectedValue DropDownList (не TextBox, поэтому ввод ограничен). Если да, как я могу улучшить этот запрос?

Ответы [ 4 ]

4 голосов
/ 09 февраля 2012

Да, есть:

" where " + parameter + " like @value " +

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

Сделайте параметр перечислением и передайте перечисление вашей функции. Это устранит риск (что-то вроде: не проверено):

public DataSet getLiveAccountingDSByParameterAndValue(ParameterEnum parameter, string value)
.....
    " where " + parameter.ToString() + " like @value " +

ParameterEnum содержит список всех возможных значений в раскрывающемся списке. В вашем коде разберите выбранное значение на enum.

2 голосов
/ 09 февраля 2012

Итак, есть ли риск SQL-инъекции с этим запросом?

Я думаю, что да, он уязвим для SQL-инъекций. Например, параметр = "1 = 1 ИЛИ значение"

Кроме того, примите во внимание, что параметр устанавливается DropDownList's SelectedValue (не TextBox, поэтому ввод ограничен)

Не имеет значения. Злонамеренный пользователь может ввести любое значение в сам исполняемый файл или в сетевой пакет (и, таким образом, отправить значение, которое не существует в DropDown).

Если так, как я могу улучшить этот запрос?

Вы должны проверить параметр аргумент и сравнить со значениями DropDown. Для более общих данных, я думаю, должны быть библиотеки, которые проверяют такие вещи (но у меня нет идеи C # ...).

1 голос
/ 09 февраля 2012

Начиная с 2.0 ASP.NET автоматически проверяет аргументы обратной передачи и обратного вызова, чтобы определить, отличаются ли они. Так что это хороший пример, когда полезно EnableEventValidation.

http://odetocode.com/blogs/scott/archive/2006/03/20/asp-net-event-validation-and-invalid-callback-or-postback-argument.aspx

Тогда вы получите следующее исключение:

«Недопустимый аргумент обратной передачи или обратного вызова»

Вы можете убедиться, что он установлен на true, явно указав его в codebehind, например, в событии Init Пейджа:

protected void Page_Init( object sender, EventArgs e )
{
    // don't remove this
    Page.EnableEventValidation = True;
}

Редактировать : Ой, на самом деле этот параметр нельзя изменить из codebehind, он компилируется, но выдает следующую ошибку времени выполнения:

Свойство EnableEventValidation можно установить только на странице. директива или в разделе конфигурации.

1 голос
/ 09 февраля 2012
var columns = new [] {"column1", column2", ....};
if (!columns.Contains(parameter))
   return or do something else

РЕДАКТИРОВАТЬ Единственный риск внедрения SQL-кода - передача имени столбца в предложении where с использованием конкатенации строк.Другого пути нет.Настоящим щитом является проверка того, что имя столбца является правильным, оно существует в таблице.Даже ASP .Net имеет проверку событий (проверяет, что опубликованное значение является одним из раскрывающихся списков), вы не можете основываться на этом, поскольку эту защиту можно отключить.Параметр, используемый с like, не является объектом для внедрения SQL

...