Blog JSystems - uwalniamy wiedzę!

Szukaj

Dynamiczny SQL jest to sposób na konstruowanie ciągów znaków zawierających wyrażenia SQL w aplikacji działającej na serwerze (albo nawet po stronie klienta) i wykonywanie ich w locie. W praktyce jest on wykorzystywany do pisania złożonych zapytań w trakcie wykonywania, co w niektorych przypadkach może zwiększyć wydajność jak i pomóć w wykonaniu zadań teoretycznie niemożliwych do wykonania.

Przy dynamicznym SQL nalezy jednak pamiętać, że w przypadku niepoprawnego jego wykorzystania narażamy się na otwarcie luk w systemie bepieczeństwa (tzw. SQL injection).

EXECUTE (EXEC)

Za pomocą wyrażenia EXECUTE (lub jego skrótu EXEC) możemy w najprostszy sposób skorzystać w funkcjonalności jaką jest dynamiczne tworzenie zapytania lub innej instrukcji. Wystarczy jako łańcuch znaków podać treść takiego wyrażenia. EXECUTE przyjmuje stałe, zmienne typów char/nchar, varchar/nvarchar albo ciągi poleceń zawierające poprawne wyrażenia języka T-SQL.

EXECUTE (EXEC): SQL dynamiczny w T-SQL

Powyższy przykład to jedynie pogląd jak skorzytać z SQL'a dynamicznego, bo przecież wystarczyłby sam SELECT i otrzymalibyśmy identyczny wynik. Jednakże prawdziwa moc dynamicznego SQL polega na tym, że możemy dynamicznie budować całe polecenie jakie mamy w planach uruchomić.

Poniżej przykład takiego dynamicznego zapytania, jakie zostało uruchomione.

EXECUTE (EXEC): SQL dynamiczny w T-SQL (2)

Oczywiście złączenie moglibyśmy zrobić wcześniej niż w klauzuli EXECUTE, np wynik łączenia można by było przypisać do dodatkowej zmiennej.

EXECUTE (EXEC): SQL dynamiczny w T-SQL (3)

Jednakże korzystanie z funkcjonalności jaką daje SQL dynaimczny, niesie za sobą ryzyko ataków typu SQL Injection, czyli wstrzyknięcie obcego kodu do wykonania.

Zmienna @vSQL ma w sobie zapytanie jakie ma zostać uruchomione, a co jeśli przed wykonaniem tego zapytania ktoś podmieni w nim instrukcje jakie mają być wykonane i np. wstrzyknie tam jakiegoś dropa?

EXECUTE (EXEC): SQL dynamiczny w T-SQL (4)

Polecenie się powiedzie, a nam zniknie z produkcji być może dosyć istotna tabela.

Przyjrzyjmy się jescze jednemu przykładowi, gdzie wartość zmiennej @vNazwisko pochodziła z interfejcu użytkownika, np ze strony internetowej.

EXECUTE (EXEC): SQL dynamiczny w T-SQL (5)

Na pierwszy rzut oka nie wygląda to groźnie, ale co gdyby ktoś do zmiennej @vNazwisko przypisał taki łańcuch:

EXECUTE (EXEC): SQL dynamiczny w T-SQL (6)

Wtedy również z naszej produkcji zniknęłaby tabelka. Cały łańcuch zostałby natomiast odczytany w ten sposób:

EXECUTE (EXEC): SQL dynamiczny w T-SQL (7)

Za pomocą dynamicznego SQL, ktoś nieupoważniony mógłby pobrać dowolne dane, wykonać dowolne wyrażenia INSERT, UPDATE, DELETE, DROP TABLE, TRUNCATE TABLE czy inne, wstawiające/modyfikujące/usuwające dane lub otwierające możliwość wejścia do systemu poprzez np przydzielenie sobie specjalnych uprawnień.

Jeśli jednak zdecydujemy się już na wykorzystanie korzyści jakie daje dynamiczny SQL, z łańcuchów znaków przekazywanych z interfejsu użytkownika to powinniśmy podjąć wszelkie znane znam środki ostrorożności, takie jak np:

-sprawdzanie pobieranych danych, jeśli oczekujemy jedynie liczb lub jedynie liter to powinniśmy sprawdzić czy dany łańcuch rzeczywiście tylko takie dane zawiera

-nie powinniśmy pozwalać na korzystanie z apostrofów, średników, nawiasów, komentarzy jednowierszowych (dwa minusy), komentarzy wielowierszowych (kombinacji /* */)

-powinniśmy sprawdzać zgodność danych wejściowych XML ze schematem XML, jeśli to tylko możliwe

-powinniśmy zachować szczególną ostrożność, jeśli dane wejściowe zawierają xp_ lub sp_, ponieważ może to oznaczać próbę uruchomienia procedur na lub XP serwerze.

SP_EXECUTESQL

Dynamiczny SQL można również uruchomić za pomocą procedury składowanej SP_EXECUTESQL. Procedura ta również przyjmuje łańcuch znaków jako polecenie do wykonania. Sposób ten wspiera parametry wejściowe jak i wyjściowe, pozwala parametryzować kod z minimalnym ryzykiem ataków typu SQL Injection. Często również plan wykonania zapytania może być lepszy niż przy samym uruchomieniu dynamicznego kodu za pomocą EXECUTE (bardziej optymalny).

Poniżej przykład wykorzystania procedury składowanej SP_EXECUTESQL

SP_EXECUTESQL: SQL dynamiczny w T-SQL

 

Baner szkolenia Kompleksowe SQL w Microsoft SQL Server w JSystems, terminy gwarantowane

Szkolenie Kompleksowe SQL w Microsoft SQL Server →

To szkolenie może być dofinansowane dla Ciebie z KFS lub BUR.

★★★★★Średnia ocena naszych szkoleń w Google: 5/5

Najczęściej zadawane pytania

Czym jest dynamiczny SQL w T-SQL?
Dynamiczny SQL to sposób konstruowania łańcuchów znaków zawierających wyrażenia SQL w trakcie działania aplikacji i wykonywania ich w locie. Pozwala budować złożone zapytania podczas wykonywania, co w niektórych przypadkach zwiększa wydajność i umożliwia zadania trudne lub niemożliwe do wykonania statycznym kodem.
Czym różni się EXECUTE od SP_EXECUTESQL?
EXECUTE (w skrócie EXEC) to najprostszy sposób uruchomienia tekstu jako polecenia SQL, przyjmujący stałe lub zmienne tekstowe. SP_EXECUTESQL to procedura składowana, która także uruchamia łańcuch znaków, ale wspiera parametry wejściowe i wyjściowe, pozwala parametryzować kod i mocno ogranicza ryzyko wstrzyknięcia SQL.
Na czym polega ryzyko SQL injection przy dynamicznym SQL?
Jeśli fragment zapytania pochodzi z interfejsu użytkownika, ktoś nieupoważniony może podmienić jego treść i dopisać własne polecenia, na przykład usunięcie tabeli albo pobranie cudzych danych. Cały spreparowany łańcuch trafia do wykonania, więc atak może modyfikować dane, kasować obiekty lub nadawać sobie uprawnienia.
Jak zabezpieczyć dynamiczny SQL przed wstrzyknięciem?
Warto sprawdzać dane wejściowe, na przykład czy zawierają wyłącznie oczekiwane liczby lub litery, i nie dopuszczać znaków takich jak apostrofy, średniki, nawiasy czy komentarze. Trzeba też zachować ostrożność wobec wpisów z przedrostkami xp_ i sp_, a najlepiej korzystać z parametryzowanego SP_EXECUTESQL.
Dlaczego SP_EXECUTESQL bywa wydajniejszy od EXECUTE?
Przy SP_EXECUTESQL plan wykonania zapytania często bywa lepszy i bardziej optymalny niż przy zwykłym EXECUTE, bo parametryzacja pozwala serwerowi lepiej wykorzystać plany. Dodatkowo parametryzacja ogranicza ryzyko wstrzyknięcia SQL, więc jest to zwykle bezpieczniejszy i skuteczniejszy wybór.

Komentarze (0)

Musisz być zalogowany by móc dodać komentarz. Zaloguj się przez Google

Brak komentarzy...