Вопрос

Фон

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

Вопрос

Какой параметр «Ключ» может нарушить PrepareString функцию и позвольте мне выполнить DROP заявление?

Фрагмент кода

Public Shared Function GetRecord(ByVal Key As String) As Record
    Dim Sql As New StringBuilder()

    With Sql
        .Append("SELECT * FROM TableName")
        If String.IsNullOrEmpty(Agency) Then
            .Append(" ORDER BY DateAdded")
        Else
            .Append(" WHERE Key = '")
            .Append(PrepareString(Key))
            .Append("'")
        End If
    End With

    Return ExecuteQuery(Sql.ToString())
End Function

Public Shared Function PrepareString(ByVal Value As String) As String
    Return Value.Replace("''", "'") _
                .Replace("'", "''") _
                .Replace("`", "''") _
                .Replace("´", "''") _
                .Replace("--", "")
End Function
Это было полезно?

Решение

В ответ на ваш прямой вопрос: предотвращает ли этот код SQL-инъекцию? Нет

Вот доказательство - протолкните эту строку через метод PrepareString:

Dim input = "'" & Chr(8) & "; Drop Table TableName; - " & Chr(8) & "-"
Dim output = PrepareString(input)

Console.WriteLine(input)
Console.WriteLine(output)

Я изменил опубликованный вами метод GetRecord, чтобы он возвращал полностью подготовленную строку SQL, а не получал запись из базы данных:

Console.WriteLine(GetRecord(output))

И это вывод

Input  = ; Drop Table TableName; --
Output = '; Drop Table TableName; --
Query  = SELECT * FROM TableName WHERE Key = ''; Drop Table TableName; --'

Добавьте 1 дополнительную строку кода:

My.Computer.Clipboard.SetText(input)

И у вас есть строка, которую нужно скопировать прямо в буфер обмена, чтобы вставить в поле ввода на веб-сайте для завершения SQL-инъекции:

'; Drop Table TableName; - -

[Принимая во внимание, что управляющие символы были исключены из пост-вывода в StackOverflow, поэтому вам придется следовать примеру кода для создания вывода]

После запуска метода PrepareString он будет иметь точно такой же результат - код Chr (8) ASCII - это обратная область, которая удалит лишний " '" что вы добавляете ко мне, что закроет вашу строку, и тогда я свободен, чтобы добавить все, что я хочу в конце. Ваша PrepareString не видит моего - потому что я на самом деле использую - символа возврата, чтобы удалить пробел.

Полученный в результате SQL-код будет беспрепятственно выполнять мой оператор Drop Table и быстро игнорировать остальную часть вашего запроса.

Самое интересное в том, что вы можете использовать непечатные символы, чтобы обойти любую проверку символов, которую вы можете придумать. Поэтому безопаснее использовать параметризованные запросы (это не то, что вы просили, но лучший способ избежать этого).

Другие советы

Чтобы ответить на ваш сомнительный вопрос, нет, это не сработает.

.Replace (" `` " ;, " '' ") будет препятствовать законным запросам с `` '

.Replace (" & # 180; " ;, " '' ") будет препятствовать допустимым запросам с '& # 180;'

.Replace (" - " ;, " ") будет препятствовать допустимым запросам с '-' в них

.Replace (" '' " ;, " '") неправильно модифицирует допустимые запросы с использованием' '' 'в них

и т. д.

Кроме того, полный набор escape-символов может варьироваться от одной RDBMS к другой. Параметризованные запросы FTW.

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

Я думаю, что это безопасно (по крайней мере, на сервере SQL), и я также думаю, что единственное, что вам действительно нужно сделать, это s = s.Replace (" '" ;, "' '") . Конечно, вы должны использовать параметризованные запросы, но вы уже знаете это.

Этот Статья MSDN охватывает большую часть вещей, на которые вам следует обратить внимание (боюсь сказать все, когда дело касается SQL-инъекций).

Но я поддержу мнение всех остальных о параметрах параметров.

Что касается вашего примера, некоторые ошибки [Редактировать:Обновлено]:

  • разве строка «1 OR 1=1» не позволит пользователю вернуть все

  • или хуже "1;удалить таблицу sometablename"

Согласно статье, которую вы хотите проверить:

;- Разделитель запросов.

' - Символьный разделитель строки данных.

-- - Разделитель комментариев.

/* ... / — разделители комментариев.СМС между/ и */ не оценивается сервера.

xp_ - Используется в начале имени хранимые процедуры, расширенные каталогом, таких как xp_cmdshell.

Вы пытаетесь создать черный список символов для реализации собственной версии SQL Escaping. Я бы посоветовал просмотреть этот URL - экранирование SQL не обязательно является худшим выбором (т.е. быстро исправление существующих приложений), но это нужно сделать правильно, чтобы избежать уязвимостей.

Этот URL-адрес ссылается на другой страница для выхода из SQL Server, где автор дает советы, которые помогут вам избежать уязвимостей без ограничения функциональности.

Если это поможет, в статьях также предлагается избегать скобок (я называю их квадратными скобками - но []).

Если вы попытаетесь использовать свой код, кто-то может передать ключ (; выберите * из таблицы; и получите список таблиц, которые ему нужны.

В вашем коде вы не проверяете точку с запятой, которая позволяет вам завершить оператор t-sql и запустить другой.

Я бы пошел с параметризованным запросом.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top