Czy parametry naprawdę wystarczą, aby zapobiec zastrzykom Sql?

Głosiłem zarówno moim kolegom, jak i tutaj na temat dobroci korzystania z parametrów w zapytaniach SQL, szczególnie w aplikacjach. NET. Posunąłem się nawet do tego, aby obiecać im odporność na ataki SQL injection.

Ale zaczynam się zastanawiać, czy to prawda. Czy są jakieś znane ataki SQL injection, które będą skuteczne wobec parametryzowanego zapytania? Czy można na przykład wysłać ciąg znaków, który powoduje przepełnienie bufora na serwer?

Istnieją oczywiście inne względy, aby zapewnić, że aplikacja internetowa jest Bezpieczna (jak dezynfekcja danych wejściowych użytkowników i takie tam), ale teraz myślę o iniekcjach 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.

Edit: aby wyjaśnić, co mam na myśli przez parametry i parametryzowane zapytania. Używając parametrów mam na myśli używanie "zmiennych" zamiast budowania zapytania sql w sznurek.
Więc zamiast tego:

SELECT * FROM Table WHERE Name = 'a name'

Robimy to:

SELECT * FROM Table WHERE Name = @Name

A następnie ustaw wartość parametru @Name w obiekcie query / command.

Author: Adam Bellaire, 2008-11-20

9 answers

Placeholdery są wystarczające, aby zapobiec zastrzykom. Możesz nadal być otwarty na przepełnienia bufora, ale jest to zupełnie inny smak ataku niż SQL injection (wektor ataku nie będzie składnią SQL, ale binarną). Ponieważ wszystkie przekazane parametry zostaną odpowiednio zabezpieczone, nie ma sposobu, aby atakujący przekazał dane, które będą traktowane jak "na żywo" SQL.

Nie można używać funkcji wewnątrz elementów zastępczych ani jako kolumn ani tabeli nazwy, ponieważ są one wymawiane i cytowane jako literały łańcuchowe.

Jednakże, jeśli użyjesz parametrów JAKO CZĘŚCI string concatenation wewnątrz dynamicznego zapytania, nadal będziesz podatny na Wtrysk, ponieważ twoje ciągi znaków nie będą miały znaków unikalnych, ale będą literalne. Używanie innych typów parametrów (np. integer) jest bezpieczne.

To powiedziawszy, jeśli używasz use input do ustawiania wartości czegoś takiego jak security_level, to ktoś może po prostu zrobić sobie administratorów w Twój system i mieć za darmo dla wszystkich. Ale to tylko podstawowa walidacja danych wejściowych i nie ma nic wspólnego z SQL injection.

 50
Author: Adam Bellaire,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-10 13:49:23

Nie, nadal istnieje ryzyko wtrysku SQL za każdym razem, gdy interpolujesz niezaliczone dane do zapytania SQL.

Parametry zapytań pomagają uniknąć tego ryzyka, oddzielając wartości dosłowne od składni SQL.

'SELECT * FROM mytable WHERE colname = ?'

W porządku, 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 zamiast tego 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 przechowywanych lub wykonujesz dynamiczne zapytania SQL bezpośrednio z kodu aplikacji. Ryzyko nadal istnieje.

Remedium w tych przypadkach jest zastosowanie FIEO W razie potrzeby:

  • Wejście filtra: sprawdź, czy dane wyglądają jak prawdziwe liczby całkowite, nazwy tabel, nazwy kolumn itp. zanim je interpolujesz.

  • Wyjście awaryjne: w tym przypadku "wyjście" oznacza umieszczenie danych w zapytaniu SQL. Używamy funkcji do przekształca zmienne używane jako literały łańcuchowe w wyrażeniu SQL, tak aby znaki cudzysłowu i inne znaki specjalne wewnątrz łańcucha były unikane. Powinniśmy również używać funkcji do przekształcania zmiennych, które będą używane jako nazwy tabel, kolumn itp. Podobnie jak w przypadku innych składni, takich jak dynamiczne pisanie całych wyrażeń SQL, jest to bardziej złożony problem.

 13
Author: Bill Karwin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-20 20:48:58

W tym wątku wydaje się być pewne zamieszanie co do definicji "parametryzowanego zapytania".

  • SQL, taki jak zapisany proc, który akceptuje parametry.
  • SQL, który jest wywoływany przy użyciu kolekcji parametrów DBMS.

Biorąc pod uwagę poprzednią definicję, wiele linków pokazuje działające ataki.

Ale "normalną" definicją jest ta druga. Biorąc pod uwagę tę definicję, Nie wiem o żadnym ataku SQL injection, który zadziała. To nie znaczy, że nie ma jeden, ale jeszcze go nie widziałem.

Z komentarzy nie wyrażam się wystarczająco jasno, więc oto przykład, który miejmy nadzieję będzie jaśniejszy:

To podejście jest otwarte na SQL injection

exec dbo.MyStoredProc 'DodgyText'

To podejście nie jest otwarte na SQL injection

using (SqlCommand cmd = new SqlCommand("dbo.MyStoredProc", testConnection))
{
    cmd.CommandType = CommandType.StoredProcedure;
    SqlParameter newParam = new SqlParameter(paramName, SqlDbType.Varchar);
    newParam.Value = "DodgyText";
    .....
    cmd.Parameters.Add(newParam);
    .....
    cmd.ExecuteNonQuery();
}
 12
Author: HTTP 410,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-21 10:38:30

Każdy parametr SQL typu string (varchar, nvarchar, itp.), który jest używany do budowy dynamicznego zapytania, jest nadal podatny na ataki

W Przeciwnym Razie konwersja typu parametru (np. na int, decimal, date, itd.) powinno wyeliminować wszelkie próby wprowadzania sql poprzez parametr

EDIT: przykład, w którym 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 jest wybrany z rozwijanej listy, jest to potencjalny wektor ataku sql-injection;

Jeśli @ p1 jest sformułowany programowo w / out zdolność Użytkownika do interwencji, to nie jest potencjalny wektor ataku SQL-injection

 10
Author: Steven A. Lowe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-20 20:40:24

Przepełnienie bufora nie jest SQL injection.

Parametryzowane zapytania gwarantują bezpieczeństwo przed SQL injection. Nie gwarantują, że w Twoim serwerze SQL nie ma możliwych exploitów w postaci błędów, ale nic tego nie zagwarantuje.

 6
Author: Blorgbeard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-20 20:10:14

Twoje dane nie są bezpieczne, jeśli używasz dynamicznego sql w jakikolwiek sposób, ponieważ uprawnienia muszą być na poziomie tabeli. Tak, ograniczyłeś rodzaj i ilość ataku wtrysku z tego konkretnego zapytania, ale nie ograniczyłeś dostępu, który użytkownik może uzyskać, jeśli znajdzie drogę do systemu i jesteś całkowicie wolny od użytkowników wewnętrznych, którzy uzyskują dostęp do tego, czego nie powinni, aby popełnić oszustwo lub ukraść dane osobowe, aby sprzedać. Dynamiczny SQL dowolnego typu jest niebezpieczną praktyką. Jeśli uĺźywasz nie dynamicznych przechowywanych procăłw, moĹźesz ustawiaÄ ‡ uprawnienia na poziomie procesĂłw i ĺźaden uĺźytkownik nie moĹźe nic zrobiÄ ‡ poza tym co jest zdefiniowane przez procăłw (z wyjÄ ... tkiem administratăłw systemowych oczywiĹ"cie).

 2
Author: HLGEM,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-20 20:28:31

Możliwe jest, że przechowywany proc może być podatny na specjalne typy SQL injection poprzez overflow / truncation, zobacz: Injection Enabled by Data Truncation tutaj:

Http://msdn.microsoft.com/en-us/library/ms161953.aspx

 1
Author: Booji Boy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-20 20:36:34

Pamiętaj, że z parametrami możesz łatwo zapisać ciąg znaków, lub powiedzieć nazwa użytkownika, jeśli nie masz żadnych zasad,"); drop TABLE users; -- "

To samo w sobie nie spowoduje żadnej szkody, ale lepiej wiedzieć, gdzie i w jaki sposób data ta jest używana dalej w Twojej aplikacji (np. przechowywana w pliku cookie, pobierana później do innych rzeczy.

 1
Author: nos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-22 00:32:49

Możesz uruchomić dynamiczny sql jako przykład

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'
 1
Author: Mohamed Abbas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-12 14:47:07