Microsoft SQL Server
Dynamiczny SQL
Szukaj…
Wykonaj instrukcję SQL podaną jako ciąg
W niektórych przypadkach konieczne jest wykonanie zapytania SQL umieszczonego w ciągu. EXEC, EXECUTE lub procedura systemowa sp_executesql może wykonać dowolne zapytanie SQL podane jako ciąg znaków:
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')
Ta procedura zwróci ten sam zestaw wyników, co zapytanie SQL podane jako tekst instrukcji. sp_executesql może wykonać zapytanie SQL podane jako literał ciągu, zmienna / parametr, a nawet wyrażenie:
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
Potrzebujesz funkcji QUOTENAME do zmiany znaków specjalnych w zmiennej @table. Bez tej funkcji wystąpiłby błąd składniowy, jeśli zmienna @table zawiera coś takiego jak spacje, nawiasy kwadratowe lub dowolny inny znak specjalny.
Dynamiczny SQL wykonywany jako inny użytkownik
Możesz wykonać zapytanie SQL jako inny użytkownik, używając AS USER = „nazwa użytkownika bazy danych”
EXEC(N'SELECT * FROM product') AS USER = 'dbo'
Zapytanie SQL zostanie wykonane przez użytkownika bazy danych dbo. Wszystkie kontrole uprawnień dotyczące użytkownika dbo zostaną sprawdzone w zapytaniu SQL.
Wstrzykiwanie SQL z dynamicznym SQL
Dynamiczne zapytania to
SET @sql = N'SELECT COUNT(*) FROM AppUsers WHERE Username = ''' + @user + ''' AND Password = ''' + @pass + ''''
EXEC(@sql)
Jeśli wartość zmiennej użytkownika to myusername '' OR 1 = 1 - zostanie wykonane następujące zapytanie:
SELECT COUNT(*)
FROM AppUsers
WHERE Username = 'myusername' OR 1=1 --' AND Password = ''
Komentarz na końcu wartości zmiennej @ nazwa_użytkownika wykomentuje końcową część zapytania, a warunek 1 = 1 zostanie oceniony. Aplikacja, która to sprawdza, co najmniej jeden użytkownik zwrócony przez to zapytanie zwróci liczbę większą niż 0 i logowanie się powiedzie.
Korzystając z tego podejścia, atakujący może zalogować się do aplikacji, nawet jeśli nie zna prawidłowej nazwy użytkownika i hasła.
Dynamiczny SQL z parametrami
Aby uniknąć problemów z wstrzykiwaniem i ucieczką, dynamiczne zapytania SQL powinny być wykonywane z parametrami, np .:
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
Drugi parametr to lista parametrów używanych w zapytaniu wraz z ich typami, po tej liście podano zmienne, które zostaną użyte jako wartości parametrów.
sp_executesql usunie znaki specjalne i wykona zapytanie SQL.