Кажется, что libc ++ следует этому требованию:
Каждая форматированная входная функция начинает выполнение, создавая объект класса
sentry
сnoskipws
(вторым) аргументомfalse
. Если часовой объект возвращаетtrue
, при преобразовании в значение типаbool
, эта функция пытается получить запрошенный вход. Если во время ввода выбрано исключение, тогдаios::badbit
включается312 в состоянии ошибки*this
. Если(exceptions()&badbit) != 0
, то исключение будет восстановлено. В любом случае отформатированная функция ввода уничтожает объект часовой. Если исключение не было выбрано, оно возвращает*this
.312) Это выполняется, не вызывая выброса
blockquote>ios::failure
.(цитируется по N4567 § 27.7.2.2.1 [istream.formatted.reqmts], но C ++ IS содержит идентичную формулировку. Акцент мой)
Я не знаю, действительно ли это означает «если
(exceptions()&badbit) == 0
, то входная функция должна но не исключение »
Заполнителей достаточно для предотвращения инжекций. Вы могли бы все еще быть открыты для переполнения буфера, но это - совершенно другая разновидность нападения от Внедрения SQL (вектор атаки не был бы синтаксисом SQL, но двоичным файлом). Так как параметры передали, будет все оставлен правильно, нет никакого способа для взломщика передать данные, которые будут рассматривать как "живой" SQL.
Вы не можете использовать функции в заполнителях, и Вы не можете использовать заполнителей в качестве имен столбцов или имен таблиц, потому что их оставляют и заключают в кавычки как строковые литералы.
Однако, если Вы используете параметры как часть конкатенация строк внутренняя часть Ваш динамический запрос, Вы все еще уязвимы для инжекции, потому что Ваших строк не оставят, но будут литеральными. Используя другие типы для параметров (таких как целое число) безопасно.
Однако если Вы используете вход использования для устанавливания значения чего-то как security_level
, тогда кто-то мог просто сделать себя администраторами в системе и иметь дискуссию. Но это - просто основной контроль ввода и не имеет никакого отношения к Внедрению SQL.
Нет, существует все еще риск Внедрения 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-выражений динамично, это - более сложная проблема.
Кажется, существует некоторый беспорядок в этом потоке об определении "параметризированного запроса".
, Учитывая бывшее определение, многие из шоу ссылок, работающего нападения.
, Но "нормальное" определение последний. Учитывая, что определение, я не знаю ни о какой атаке с использованием кода на 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();
}
любой 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
Переполнением буфера не является Внедрение SQL.
Параметрические запросы гарантируют, что Вы в безопасности против Внедрения SQL. Они не гарантируют, что нет возможного использования в форме ошибок в Вашем SQL-сервере, но ничто не гарантирует это.
Ваши данные не безопасны при использовании динамического sql, всегда формируют или формируются, потому что полномочия должны быть на уровне таблицы. Да Вы ограничили тип и объем инжекционного нападения от того особого запроса, но не ограничили доступ, который может получить пользователь, если он находит путь в систему, и Вы абсолютно vunerable внутренним пользователям, получающим доступ, что они не были должны, чтобы совершить мошенничество или украсть персональные данные для продажи. Динамический SQL любого типа является опасной практикой. Если Вы используете нединамичный, сохранил procs, можно установить полномочия на procesdure уровне, и никакой пользователь не может сделать ничего кроме того, что определяется procs (кроме системных администраторов, конечно).
Для сохраненного proc возможно быть уязвимым для специальных типов Внедрения SQL через переполнение/усечение, видеть: Инжекция, Включенная Усечением Данных здесь:
Просто помните что с параметрами вы можете легко сохранить строку или сказать имя пользователя, если у вас нет политик, "); drop table users; -"
Само по себе это не причинит никакого вреда, но вам лучше знать, где и как эта дата используется в дальнейшем в вашем приложении (например, сохраняется в куки, извлекается позже для других целей.