Przekazywałem zarówno moim kolegom, jak i tutaj w SO, zalety używania parametrów w zapytaniach SQL, zwłaszcza w aplikacjach .NET. Posunąłem się nawet do obietnicy, że dają im odporność na ataki typu SQL injection.
Ale zaczynam się zastanawiać, czy to naprawdę prawda. Czy istnieją znane ataki polegające na iniekcji SQL, które zakończą się sukcesem w przypadku sparametryzowanego zapytania? Czy możesz na przykład wysłać napis, który powoduje przepełnienie bufora na serwerze?
Istnieją oczywiście inne kwestie, które należy wziąć pod uwagę, aby upewnić się, że aplikacja internetowa jest bezpieczna (np. Oczyszczanie danych wejściowych użytkownika i tym podobne), ale teraz myślę o wstrzyknięciach SQL. Szczególnie interesują mnie ataki na MsSQL 2005 i 2008, ponieważ są to moje podstawowe bazy danych, ale wszystkie bazy danych są interesujące.
Edycja: Aby wyjaśnić, co mam na myśli przez parametry i sparametryzowane zapytania. Używając parametrów, mam na myśli używanie „zmiennych” zamiast budowania zapytania sql w ciągu.
Więc zamiast tego robić:
SELECT * FROM Table WHERE Name = 'a name'
My to robimy:
SELECT * FROM Table WHERE Name = @Name
a następnie ustaw wartość parametru @Name w obiekcie zapytania / polecenia.
źródło
Odpowiedzi:
Aby zapobiec zastrzykom, wystarczą symbole zastępcze . Nadal możesz być otwarty na przepełnienia bufora, ale jest to zupełnie inny rodzaj ataku niż wstrzyknięcie SQL (wektor ataku nie byłby składnią SQL, ale binarny). Ponieważ wszystkie przekazane parametry zostaną odpowiednio zmienione, atakujący nie może w żaden sposób przekazać danych, które będą traktowane jak „aktywny” kod SQL.
Nie możesz używać funkcji wewnątrz symboli zastępczych i nie możesz używać symboli zastępczych jako nazw kolumn lub tabel, ponieważ są one chronione i cytowane jako literały ciągu.
Jeśli jednak użyjesz parametrów jako części konkatenacji ciągów wewnątrz zapytania dynamicznego, nadal jesteś narażony na iniekcję, ponieważ twoje ciągi nie zostaną zmienione, ale będą dosłowne. Używanie innych typów parametrów (takich jak liczba całkowita) jest bezpieczne.
To powiedziawszy, jeśli używasz danych wejściowych do ustawiania wartości czegoś podobnego
security_level
, ktoś może po prostu stać się administratorami w twoim systemie i mieć swobodę dla wszystkich. Ale to tylko podstawowa walidacja danych wejściowych i nie ma nic wspólnego z iniekcją SQL.źródło
Nie, nadal istnieje ryzyko wstrzyknięcia SQL za każdym razem, gdy interpolujesz niezatwierdzone dane do zapytania SQL.
Parametry zapytania pomagają uniknąć tego ryzyka, oddzielając wartości literałów od składni SQL.
'SELECT * FROM mytable WHERE colname = ?'
To dobrze, ale istnieją inne cele interpolacji danych do dynamicznego zapytania SQL, które nie mogą używać parametrów zapytania, ponieważ nie jest to wartość SQL, ale nazwa tabeli, nazwa kolumny, wyrażenie lub inna składnia.
'SELECT * FROM ' + @tablename + ' WHERE colname IN (' + @comma_list + ')' ' ORDER BY ' + @colname'
Nie ma znaczenia, czy używasz procedur składowanych, czy wykonujesz dynamiczne zapytania SQL bezpośrednio z kodu aplikacji. Ryzyko wciąż istnieje.
Środkiem zaradczym w takich przypadkach jest zatrudnienie FIEO w razie potrzeby:
Filtruj dane wejściowe: sprawdź, czy dane wyglądają jak prawidłowe liczby całkowite, nazwy tabel, nazwy kolumn itp. Przed ich interpolacją.
Wyjście Escape: w tym przypadku „wyjście” oznacza wprowadzenie danych do zapytania SQL. Używamy funkcji do transformacji zmiennych używanych jako literały łańcuchowe w wyrażeniu SQL, tak aby cudzysłowy i inne znaki specjalne wewnątrz ciągu były chronione przed ucieczką. Powinniśmy również używać funkcji do przekształcania zmiennych, które będą używane jako nazwy tabel, nazw kolumn itp. Jeśli chodzi o inną składnię, jak dynamiczne zapisywanie całych wyrażeń SQL, jest to bardziej złożony problem.
źródło
Wydaje się, że w tym wątku jest pewne zamieszanie co do definicji „sparametryzowanego zapytania”.
Biorąc pod uwagę poprzednią definicję, wiele linków wskazuje na działające ataki.
Ale „normalna” definicja to ta druga. Biorąc pod uwagę tę definicję, nie znam żadnego ataku SQL injection, który zadziała. Nie oznacza to, że takiego nie ma, ale jeszcze go nie widziałem.
Z komentarzy nie wyrażam się wystarczająco jasno, więc mam nadzieję, że oto przykład, który będzie jaśniejszy:
To podejście jest otwarte dla iniekcji SQL
To podejście nie jest otwarte dla iniekcji SQL
źródło
każdy parametr sql typu string (varchar, nvarchar itp.), który jest używany do konstruowania dynamicznego zapytania, jest nadal podatny na ataki
w przeciwnym razie konwersja typu parametru (np. na int, decimal, date, itp.) powinna wyeliminować wszelkie próby wprowadzenia sql przez parametr
EDYCJA: przykład, gdzie parametr @ p1 ma być nazwą tabeli
create procedure dbo.uspBeAfraidBeVeryAfraid ( @p1 varchar(64) ) AS SET NOCOUNT ON declare @sql varchar(512) set @sql = 'select * from ' + @p1 exec(@sql) GO
Jeśli @ p1 zostanie wybrane z listy rozwijanej, jest to potencjalny wektor ataku sql-injection;
Jeśli @ p1 jest sformułowane programowo bez możliwości interwencji użytkownika, to nie jest to potencjalny wektor ataku typu sql-injection
źródło
Przepełnienie buforu nie jest iniekcją SQL.
Sparametryzowane zapytania gwarantują bezpieczeństwo przed iniekcją SQL. Nie gwarantują, że na twoim serwerze SQL nie będzie możliwości exploitów w postaci błędów, ale nic tego nie gwarantuje.
źródło
Twoje dane nie są bezpieczne, jeśli używasz dynamicznego sql w jakimkolwiek kształcie lub formie, ponieważ uprawnienia muszą być na poziomie tabeli. Tak, ograniczyłeś typ i ilość ataku iniekcyjnego z tego konkretnego zapytania, ale nie ograniczyłeś dostępu, jaki użytkownik może uzyskać, jeśli znajdzie drogę do systemu, i jesteś całkowicie podatny na dostęp dla użytkowników wewnętrznych, którzy mają dostęp do tego, czego nie powinni w celu popełnienia oszustwa lub kradzieży danych osobowych w celu sprzedaży. Dynamiczny SQL dowolnego typu to niebezpieczna praktyka. Jeśli używasz niedynamicznych przechowywanych procesów, możesz ustawić uprawnienia na poziomie procesu i żaden użytkownik nie może zrobić nic poza tym, co jest zdefiniowane przez proces (z wyjątkiem oczywiście administratorów systemu).
źródło
Istnieje możliwość, że przechowywany proces będzie podatny na specjalne typy iniekcji SQL poprzez przepełnienie / obcięcie, zobacz: Wstrzykiwanie włączone przez obcięcie danych tutaj:
http://msdn.microsoft.com/en-us/library/ms161953.aspx
źródło
Pamiętaj tylko, że za pomocą parametrów możesz łatwo zapisać ciąg lub powiedzieć nazwę użytkownika, jeśli nie masz żadnych zasad, "); porzuć użytkowników tabeli; -"
To samo w sobie nie spowoduje żadnej szkody, ale lepiej wiesz, gdzie i jak ta data jest używana w dalszej części aplikacji (np. Przechowywana w pliku cookie, pobierana później w celu wykonania innych czynności.
źródło
Możesz na przykład uruchomić dynamiczny 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'
źródło