Я проповедовал своим коллегам и здесь, в SO, о пользе использования параметров в запросах SQL, особенно в приложениях .NET. Я даже зашел так далеко, что пообещал им защиту от атак SQL-инъекций.
Но я начинаю задаваться вопросом, правда ли это на самом деле. Существуют ли какие-либо известные атаки с использованием SQL-инъекций, которые будут успешными против параметризованного запроса? Можете ли вы, например, отправить строку, которая вызывает переполнение буфера на сервере?
Конечно, есть и другие соображения, которые необходимо учитывать для обеспечения безопасности веб-приложения (например, дезинфекция пользовательского ввода и все такое), но теперь я думаю о SQL-инъекциях. Меня особенно интересуют атаки на MsSQL 2005 и 2008, поскольку они являются моими основными базами данных, но все базы данных интересны.
Изменить: чтобы прояснить, что я имею в виду под параметрами и параметризованными запросами. Под использованием параметров я подразумеваю использование «переменных» вместо построения запроса sql в строке.
Поэтому вместо этого:
SELECT * FROM Table WHERE Name = 'a name'
Делаем так:
SELECT * FROM Table WHERE Name = @Name
а затем установите значение параметра @Name в объекте запроса / команды.
источник
Ответы:
Заполнители достаточно , чтобы предотвратить инъекции. Возможно, вы по-прежнему открыты для переполнения буфера, но это совершенно другой вид атаки, нежели SQL-инъекция (вектор атаки будет не синтаксисом SQL, а двоичным). Поскольку все переданные параметры будут экранированы должным образом, злоумышленник не сможет передать данные, которые будут обрабатываться как «живой» SQL.
Вы не можете использовать функции внутри заполнителей, и вы не можете использовать заполнители в качестве имен столбцов или таблиц, потому что они экранированы и заключены в кавычки как строковые литералы.
Однако, если вы используете параметры как часть конкатенации строк внутри вашего динамического запроса, вы по-прежнему уязвимы для внедрения, потому что ваши строки не будут экранированы, но будут буквальными. Использование других типов для параметров (таких как целое число) безопасно.
Тем не менее, если вы используете input для установки значения чего-то вроде
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 Output: в этом случае «вывод» означает ввод данных в SQL-запрос. Мы используем функции для преобразования переменных, используемых в качестве строковых литералов в выражении SQL, чтобы экранировать кавычки и другие специальные символы внутри строки. Мы также должны использовать функции для преобразования переменных, которые будут использоваться в качестве имен таблиц, столбцов и т. Д. Что касается другого синтаксиса, например, динамического написания целых выражений SQL, это более сложная проблема.
источник
Похоже, в этой теме есть некоторая путаница по поводу определения "параметризованного запроса".
Учитывая первое определение, многие ссылки показывают рабочие атаки.
Но «нормальное» определение - это последнее. Учитывая это определение, я не знаю ни одной атаки с использованием SQL-инъекции, которая сработает. Это не значит, что его нет, но я его еще не видел.
Судя по комментариям, я недостаточно четко выражаюсь, поэтому вот пример, который, надеюсь, будет более ясным:
Этот подход является открытым для SQL инъекций
Этот подход не подходит для SQL-инъекций
источник
любой параметр sql строкового типа (varchar, nvarchar и т. д.), который используется для создания динамического запроса, по-прежнему уязвим
в противном случае преобразование типа параметра (например, в int, decimal, date и т. д.) должно исключить любую попытку внедрить 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 сформулирован программно без возможности вмешательства пользователя, то это не потенциальный вектор атаки sql-инъекции.
источник
Переполнение буфера - это не SQL-инъекция.
Параметризованные запросы гарантируют защиту от SQL-инъекций. Они не гарантируют, что на вашем сервере SQL нет возможных эксплойтов в виде ошибок, но ничто не гарантирует этого.
источник
Ваши данные небезопасны, если вы используете динамический sql в любой форме или форме, потому что разрешения должны быть на уровне таблицы. Да, вы ограничили тип и количество инъекционных атак по этому конкретному запросу, но не ограничили доступ, который пользователь может получить, если он или она найдет путь в систему, и вы полностью защищены для внутренних пользователей, имеющих доступ к тому, в чем они не должны чтобы совершить мошенничество или украсть личную информацию для продажи. Динамический SQL любого типа - опасная практика. Если вы используете нединамические хранимые процессы, вы можете устанавливать разрешения на уровне процесса, и ни один пользователь не может делать ничего, кроме того, что определено процессами (кроме системных администраторов, конечно).
источник
Сохраненная процедура может быть уязвима для специальных типов SQL-инъекций через переполнение / усечение, см .: Внедрение, активируемое усечением данных здесь:
http://msdn.microsoft.com/en-us/library/ms161953.aspx
источник
Просто помните, что с помощью параметров вы можете легко сохранить строку или произнести имя пользователя, если у вас нет политик, "); drop table users; -"
Само по себе это не причинит никакого вреда, но вам лучше знать, где и как эта дата используется в дальнейшем в вашем приложении (например, сохраняется в cookie, извлекается позже для других целей.
источник
Вы можете запустить динамический sql в качестве примера
DECLARE @SQL NVARCHAR(4000); DECLARE @ParameterDefinition NVARCHAR(4000); SELECT @ParameterDefinition = '@date varchar(10)' SET @SQL='Select CAST(@date AS DATETIME) Date' EXEC sp_executeSQL @SQL,@ParameterDefinition,@date='04/15/2011'
источник