Параметров действительно достаточно для предотвращения Внедрений SQL?

Кажется, что libc ++ следует этому требованию:

Каждая форматированная входная функция начинает выполнение, создавая объект класса sentry с noskipws (вторым) аргументом false. Если часовой объект возвращает true, при преобразовании в значение типа bool, эта функция пытается получить запрошенный вход. Если во время ввода выбрано исключение, тогда ios::badbit включается312 в состоянии ошибки *this. Если (exceptions()&badbit) != 0, то исключение будет восстановлено. В любом случае отформатированная функция ввода уничтожает объект часовой. Если исключение не было выбрано, оно возвращает *this.

312) Это выполняется, не вызывая выброса ios::failure.

(цитируется по N4567 § 27.7.2.2.1 [istream.formatted.reqmts], но C ++ IS содержит идентичную формулировку. Акцент мой)

Я не знаю, действительно ли это означает «если (exceptions()&badbit) == 0, то входная функция должна но не исключение »

82
задан Adam Bellaire 18 September 2009 в 17:40
поделиться

8 ответов

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

Вы не можете использовать функции в заполнителях, и Вы не можете использовать заполнителей в качестве имен столбцов или имен таблиц, потому что их оставляют и заключают в кавычки как строковые литералы.

Однако, если Вы используете параметры как часть конкатенация строк внутренняя часть Ваш динамический запрос, Вы все еще уязвимы для инжекции, потому что Ваших строк не оставят, но будут литеральными. Используя другие типы для параметров (таких как целое число) безопасно.

Однако если Вы используете вход использования для устанавливания значения чего-то как security_level, тогда кто-то мог просто сделать себя администраторами в системе и иметь дискуссию. Но это - просто основной контроль ввода и не имеет никакого отношения к Внедрению SQL.

49
ответ дан Adam Bellaire 24 November 2019 в 09:20
поделиться

Нет, существует все еще риск Внедрения SQL любое время, Вы интерполируете непроверенные данные в SQL-запрос.

Параметры запроса помогают избежать этого риска путем разделения литеральных значений от синтаксиса SQL.

'SELECT * FROM mytable WHERE colname = ?'

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

'SELECT * FROM ' + @tablename + ' WHERE colname IN (' + @comma_list + ')'
' ORDER BY ' + @colname'

не имеет значения, используете ли Вы хранимые процедуры или выполняете динамические SQL-запросы непосредственно от кода приложения. Риск все еще там.

средство в этих случаях должно использовать FIEO по мере необходимости:

  • Вход Фильтра: проверяют это, данные похожи на законные целые числа, имена таблиц, имена столбцов, и т.д. перед интерполяцией их.

  • Вывод Escape: в этом случае "вывод" означает помещать данные в SQL-запрос. Мы используем функции для преобразования переменных, используемых в качестве строковых литералов в SQL-выражении, так, чтобы меток кавычки и других специальных символов в строке оставили. Мы должны также использовать функции для преобразования переменных, которые использовались бы в качестве имен таблиц, имен столбцов, и т.д. Что касается другого синтаксиса, как запись целых SQL-выражений динамично, это - более сложная проблема.

13
ответ дан Bill Karwin 24 November 2019 в 09:20
поделиться

Кажется, существует некоторый беспорядок в этом потоке об определении "параметризированного запроса".

  • SQL, такой как сохраненный proc, который принимает параметры.
  • SQL, который называют с помощью набора Параметров DBMS.

, Учитывая бывшее определение, многие из шоу ссылок, работающего нападения.

, Но "нормальное" определение последний. Учитывая, что определение, я не знаю ни о какой атаке с использованием кода на SQL, которая будет работать. Это не означает, что нет один, но я должен все же видеть его.

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

Этот подход открыт для Внедрения SQL

exec dbo.MyStoredProc 'DodgyText'

, Этот подход не открыт для Внедрения SQL

using (SqlCommand cmd = new SqlCommand("dbo.MyStoredProc", testConnection))
{
    cmd.CommandType = CommandType.StoredProcedure;
    SqlParameter newParam = new SqlParameter(paramName, SqlDbType.Varchar);
    newParam.Value = "DodgyText";
    .....
    cmd.Parameters.Add(newParam);
    .....
    cmd.ExecuteNonQuery();
}
12
ответ дан RoadWarrior 24 November 2019 в 09:20
поделиться

любой sql параметр строкового типа (varchar, nvarchar, и т.д.), который используется для построения динамического запроса, все еще уязвим

иначе, преобразование типов параметра (например, к интервалу, десятичному числу, дате, и т.д.) должно устранить любую попытку ввести sql через параметр

РЕДАКТИРОВАНИЕ: пример, где параметр @p1 предназначается, чтобы быть именем таблицы

create procedure dbo.uspBeAfraidBeVeryAfraid ( @p1 varchar(64) ) 
AS
    SET NOCOUNT ON
    declare @sql varchar(512)
    set @sql = 'select * from ' + @p1
    exec(@sql)
GO

, Если @p1 выбран из выпадающего списка, это - потенциальный вектор атаки внедрения SQL;

, Если @p1 формулируется программно w/out способность пользователя вмешаться тогда, это не потенциальный вектор атаки внедрения SQL

10
ответ дан Jonathan Leffler 24 November 2019 в 09:20
поделиться

Переполнением буфера не является Внедрение SQL.

Параметрические запросы гарантируют, что Вы в безопасности против Внедрения SQL. Они не гарантируют, что нет возможного использования в форме ошибок в Вашем SQL-сервере, но ничто не гарантирует это.

6
ответ дан Blorgbeard 24 November 2019 в 09:20
поделиться

Ваши данные не безопасны при использовании динамического sql, всегда формируют или формируются, потому что полномочия должны быть на уровне таблицы. Да Вы ограничили тип и объем инжекционного нападения от того особого запроса, но не ограничили доступ, который может получить пользователь, если он находит путь в систему, и Вы абсолютно vunerable внутренним пользователям, получающим доступ, что они не были должны, чтобы совершить мошенничество или украсть персональные данные для продажи. Динамический SQL любого типа является опасной практикой. Если Вы используете нединамичный, сохранил procs, можно установить полномочия на procesdure уровне, и никакой пользователь не может сделать ничего кроме того, что определяется procs (кроме системных администраторов, конечно).

2
ответ дан HLGEM 24 November 2019 в 09:20
поделиться

Для сохраненного proc возможно быть уязвимым для специальных типов Внедрения SQL через переполнение/усечение, видеть: Инжекция, Включенная Усечением Данных здесь:

http://msdn.microsoft.com/en-us/library/ms161953.aspx

1
ответ дан Booji Boy 24 November 2019 в 09:20
поделиться

Просто помните что с параметрами вы можете легко сохранить строку или сказать имя пользователя, если у вас нет политик, "); drop table users; -"

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

1
ответ дан 24 November 2019 в 09:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: