Поиск…


Выполнить инструкцию SQL в виде строки

В некоторых случаях вам необходимо выполнить SQL-запрос, помещенный в строку. EXEC, EXECUTE или системная процедура sp_executesql может выполнять любой SQL-запрос, предоставляемый как строка:

sp_executesql N'SELECT * FROM sys.objects'
-- or
sp_executesql @stmt = N'SELECT * FROM sys.objects'
-- or
EXEC sp_executesql N'SELECT * FROM sys.objects'
-- or
EXEC('SELECT * FROM sys.columns')
-- or
EXECUTE('SELECT * FROM sys.tables')

Эта процедура вернет тот же результат, что и SQL-запрос, предоставленный в виде текста инструкции. sp_executesql может выполнять SQL-запрос, предоставляемый как строковый литерал, переменная / параметр или даже выражение:

declare @table nvarchar(40) = N'product items'
EXEC(N'SELECT * FROM ' + @table)
declare @sql nvarchar(40) = N'SELECT * FROM ' + QUOTENAME(@table);
EXEC sp_executesql @sql

Вам нужна функция QUOTENAME для вызова специальных символов в переменной @table. Без этой функции вы получите синтаксическую ошибку, если переменная @table содержит что-то вроде пробелов, скобок или любого другого специального символа.

Динамический SQL, выполняемый как пользователь

Вы можете выполнять SQL-запрос как другой пользователь, используя AS USER = 'имя пользователя базы данных'

EXEC(N'SELECT * FROM product') AS USER = 'dbo'

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

SQL Injection с динамическим SQL

Динамические запросы

SET @sql = N'SELECT COUNT(*) FROM AppUsers WHERE Username = ''' + @user + ''' AND Password = ''' + @pass + ''''
EXEC(@sql)

Если значением переменной пользователя является myusername '' OR 1 = 1 - будет выполнен следующий запрос:

SELECT COUNT(*)
FROM AppUsers 
WHERE Username = 'myusername' OR 1=1 --' AND Password = ''

Комментарий в конце значения переменной @username будет закомментировать конечную часть запроса и условие 1 = 1 будет оценено. Приложение, которое проверяет его там, по крайней мере, на одного пользователя, возвращаемого этим запросом, вернет счет больше 0, и логин будет успешным.

Используя этот подход, злоумышленник может войти в приложение, даже если он не знает правильного имени пользователя и пароля.

Динамический SQL с параметрами

Чтобы избежать проблем с впрыском и экранированием, динамические SQL-запросы должны выполняться с параметрами, например:

SET @sql = N'SELECT COUNT(*) FROM AppUsers WHERE Username = @user AND Password = @pass
EXEC sp_executesql @sql, '@user nvarchar(50), @pass nvarchar(50)', @username, @password

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

sp_executesql избежит специальных символов и выполнит sql-запрос.



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow