Czy sparametryzowana instrukcja może zatrzymać wszystkie wstrzyknięcia SQL?


80

Jeśli tak, dlaczego wciąż jest tak wiele udanych wstrzyknięć SQL? Tylko dlatego, że niektórzy programiści są zbyt głupi, aby używać sparametryzowanych instrukcji?


6
To świetne pytanie, z absolutnie okropnymi odpowiedziami (w chwili, gdy komentuję)
Ibu.

Życzę, aby ktoś z dobrą reputacją co najmniej 15 000 lub z dużym doświadczeniem mógł dodać cenny wkład do tego pytania.
Ibu,

4
Zobacz wykład i slajdy Billa Karwina Sql Injection Myths and Fallacies po więcej informacji na ten temat. Wyjaśnia, czym jest iniekcja SQL, dlaczego ucieczka zwykle nie jest wystarczająco dobra i jak mogą zostać naruszone procedury składowane i sparametryzowane instrukcje.
Mike,

2
Zobacz także niektóre odpowiedzi Billa Karwina na podobne pytania: Co to jest wstrzyknięcie SQL?
Mike,

Odpowiedzi:


66

Linki, które zamieściłem w komentarzach do pytania, bardzo dobrze wyjaśniają problem. Poniżej podsumowałem swoje odczucia dotyczące przyczyny problemu:

  1. Ci, którzy dopiero zaczynają, mogą nie mieć świadomości iniekcji SQL.

  2. Niektórzy zdają sobie sprawę z iniekcji SQL, ale uważają, że ucieczka jest (jedynym?) Rozwiązaniem. Jeśli przeprowadzisz szybkie wyszukiwanie w Google php mysql query, pierwszą wyświetloną stroną jest mysql_querystrona, na której znajduje się przykład pokazujący interpolację wprowadzonych przez użytkownika znaków ucieczki w zapytaniu. Nie ma wzmianki (przynajmniej tego nie widzę) o używaniu zamiast tego przygotowanych instrukcji. Jak powiedzieli inni, istnieje tak wiele samouczków, które używają interpolacji parametrów, że nie jest zaskakujące, jak często jest ona nadal używana.

  3. Brak zrozumienia działania sparametryzowanych instrukcji. Niektórzy uważają, że to tylko wymyślny sposób na ucieczkę od wartości.

  4. Inni są świadomi sparametryzowanych instrukcji, ale nie używają ich, ponieważ słyszeli, że są zbyt wolne. Podejrzewam, że wiele osób słyszało, jak niewiarygodnie powolne są sparametryzowane oświadczenia, ale tak naprawdę nie przeprowadzili żadnych własnych testów. Jak zauważył Bill Karwin w swoim wystąpieniu, różnica w wykonaniu rzadko powinna być brana pod uwagę jako czynnik przy rozważaniu wykorzystania przygotowanych wypowiedzi. Korzyści płynące z jednorazowego przygotowania, wykonania wielu , często wydają się zapomniane, podobnie jak ulepszenia w zakresie bezpieczeństwa i łatwości utrzymania kodu.

  5. Niektórzy używają sparametryzowanych instrukcji wszędzie, ale z interpolacją niesprawdzonych wartości, takich jak nazwy tabel i kolumn, słowa kluczowe i operatory warunkowe. Wyszukiwania dynamiczne, takie jak te, które pozwalają użytkownikom na określenie wielu różnych pól wyszukiwania, warunków porównania i porządku sortowania, są tego najlepszym przykładem.

  6. Fałszywe poczucie bezpieczeństwa podczas korzystania z ORM. ORM nadal umożliwiają interpolację części instrukcji SQL - patrz 5.

  7. Programowanie to duży i złożony temat, zarządzanie bazą danych to duży i złożony temat, bezpieczeństwo to duży i złożony temat. Tworzenie bezpiecznej aplikacji bazodanowej nie jest łatwe - nawet doświadczeni programiści mogą dać się złapać.

  8. Wiele odpowiedzi na stackoverflow nie pomaga. Kiedy ludzie piszą pytania, które wykorzystują dynamiczny SQL i interpolację parametrów, często brakuje odpowiedzi sugerujących użycie zamiast tego sparametryzowanych instrukcji. Przy kilku okazjach ludzie odrzucali moją sugestię użycia przygotowanych stwierdzeń - zwykle z powodu postrzeganego niedopuszczalnego narzutu wydajności. Poważnie wątpię, czy osoby zadające większość z tych pytań są w sytuacji, w której kilka dodatkowych milisekund potrzebnych na przygotowanie sparametryzowanej instrukcji będzie miało katastrofalny wpływ na ich zastosowanie.


65

Kiedy artykuły mówią o sparametryzowanych zapytaniach zatrzymujących ataki SQL, tak naprawdę nie wyjaśniają dlaczego. Często jest to przypadek „Tak, więc nie pytaj dlaczego” - prawdopodobnie dlatego, że sami nie wiedzą. Pewnym znakiem złego nauczyciela jest taki, który nie może przyznać się, że czegoś nie wie. Ale błądzę. Kiedy mówię, że jest to całkowicie zrozumiałe, bycie zdezorientowanym jest proste. Wyobraź sobie dynamiczne zapytanie SQL

sqlQuery='SELECT * FROM custTable WHERE User=' + Username + ' AND Pass=' + password

więc proste wstrzyknięcie sql byłoby po prostu wstawieniem nazwy użytkownika jako `` LUB 1 = 1 - to skutecznie spowodowałoby, że zapytanie sql '':

sqlQuery='SELECT * FROM custTable WHERE User='' OR 1=1-- ' AND PASS=' + password

Oznacza to, że wybierz wszystkich klientów, których nazwa użytkownika jest pusta („”) lub 1 = 1, co jest wartością logiczną równą prawdzie. Następnie używa - do skomentowania pozostałej części zapytania. Więc to po prostu wydrukuje całą tabelę klientów lub zrobi z nią co chcesz, jeśli się zalogujesz, zaloguje się z uprawnieniami pierwszego użytkownika, którym często może być administrator.

Teraz sparametryzowane zapytania robią to inaczej, z kodem takim jak:

sqlQuery='SELECT * FROM custTable WHERE User=? AND Pass=?'

parameters.add("User", username)
parameters.add("Pass", password)

gdzie nazwa użytkownika i hasło to zmienne wskazujące na skojarzoną, wprowadzoną nazwę użytkownika i hasło

W tym momencie możesz pomyśleć, że to niczego nie zmienia. Z pewnością nadal możesz po prostu wpisać w pole nazwy użytkownika coś takiego jak Nikt LUB 1 = 1 '-, skutecznie tworząc zapytanie:

sqlQuery='SELECT * FROM custTable WHERE User=Nobody OR 1=1'-- AND Pass=?'

Wydaje się, że to ważny argument. Ale byłbyś w błędzie.

Sposób działania zapytań sparametryzowanych polega na tym, że sqlQuery jest wysyłane jako zapytanie, a baza danych dokładnie wie, co zrobi to zapytanie, i dopiero wtedy wstawi nazwę użytkownika i hasła jedynie jako wartości. Oznacza to, że nie mogą wykonać zapytania, ponieważ baza danych już wie, co zrobi zapytanie. Więc w tym przypadku szukałby nazwy użytkownika „Nikt LUB 1 = 1 '-” i pustego hasła, co powinno być fałszywe.

Nie jest to jednak kompletne rozwiązanie i nadal trzeba będzie przeprowadzić walidację danych wejściowych, ponieważ nie wpłynie to na inne problemy, takie jak ataki XSS, ponieważ nadal można umieścić javascript w bazie danych. Następnie, jeśli zostanie to odczytane na stronie, wyświetli to jako normalny skrypt javascript, w zależności od walidacji wyjścia. Więc naprawdę najlepszą rzeczą do zrobienia jest nadal sprawdzanie poprawności danych wejściowych, ale używanie sparametryzowanych zapytań lub procedur składowanych w celu powstrzymania wszelkich ataków SQL.


1
To znacznie zwiększa to, czego szukałem, ale czy mógłbyś wyjaśnić więcej na temat tego, co zrobiłbyś dla „walidacji danych wejściowych”? Wspomniałeś również, że istnieją inne ataki, które mogą mieć miejsce przy użyciu zapytania, np. XSS, ale czy możesz wyjaśnić, jak to się stało? Zatem, w jaki sposób w pełni chronilibyśmy się przed SQL Injection, czy też szukamy wszystkich typów iniekcji? dzięki.
XaolingBao

3
@JosipIvic: Biorąc pod uwagę, jak wiele osób pytało, jak działają sparametryzowane instrukcje, szokujące jest zobaczenie tak niewielu - jeśli w ogóle innych, naprawdę - ułożyło odpowiedź tak, jak to zrobiłeś. Dziękuję za napisanie tak jasnego wyjaśnienia z dość intuicyjnym przykładem.
daOnlyBG

Znakomity. Przykład mówi o tysiącach słów!
Drenai

10

Cóż, dobre pytanie. Odpowiedź jest bardziej stochastyczna niż deterministyczna i spróbuję wyjaśnić swój pogląd na małym przykładzie.

W sieci jest wiele odniesień, które sugerują użycie parametrów w naszych zapytaniach lub użycie procedury składowanej z parametrami w celu uniknięcia iniekcji SQL (SQLi). Pokażę ci, że procedury składowane (na przykład) nie są magicznym kijem przeciwko SQLi. Odpowiedzialność nadal spoczywa na programiście.

Rozważ następującą procedurę składowaną SQL Server, która pobierze wiersz użytkownika z tabeli „Użytkownicy”:

create procedure getUser
 @name varchar(20)
,@pass varchar(20)
as
declare @sql as nvarchar(512)
set @sql = 'select usrID, usrUName, usrFullName, usrRoleID '+
           'from Users '+
           'where usrUName = '''+@name+''' and usrPass = '''+@pass+''''
execute(@sql)

Możesz uzyskać wyniki, przekazując jako parametry nazwę użytkownika i hasło. Zakładając, że hasło jest w postaci dowolnego tekstu (tylko dla uproszczenia tego przykładu), normalne połączenie wyglądałoby tak:

DECLARE @RC int
DECLARE @name varchar(20)
DECLARE @pass varchar(20)

EXECUTE @RC = [dbo].[getUser] 
   @name = 'admin'
  ,@pass = '!@Th1siSTheP@ssw0rd!!'
GO

Ale tutaj mamy złą technikę programowania używaną przez programistę wewnątrz procedury składowanej, więc osoba atakująca może wykonać następujące czynności:

DECLARE @RC int
DECLARE @name varchar(20)
DECLARE @pass varchar(20)

EXECUTE @RC = [TestDB].[dbo].[getUser] 
   @name = 'admin'
  ,@pass = 'any'' OR 1=1 --'
GO

Powyższe parametry zostaną przekazane jako argumenty do procedury składowanej, a polecenie SQL, które ostatecznie zostanie wykonane, to:

select usrID, usrUName, usrFullName, usrRoleID 
from Users 
where usrUName = 'admin' and usrPass = 'any' OR 1=1 --'

.. co spowoduje odzyskanie wszystkich wierszy od użytkowników

Problem polega na tym, że nawet my przestrzegamy zasady „Utwórz procedurę składowaną i przekaż pola do wyszukiwania jako parametry”, SQLi jest nadal wykonywany. Dzieje się tak, ponieważ po prostu kopiujemy nasze złe praktyki programistyczne do procedury składowanej. Rozwiązaniem problemu jest przepisanie naszej procedury składowanej w następujący sposób:

alter procedure getUser
 @name varchar(20)
,@pass varchar(20)
as
select usrID, usrUName, usrFullName, usrRoleID 
from Users 
where usrUName = @name and usrPass = @pass

Próbuję powiedzieć, że programiści muszą najpierw dowiedzieć się, czym jest atak SQLi i jak można go wykonać, a następnie odpowiednio zabezpieczyć swój kod. Ślepe podążanie za „najlepszymi praktykami” nie zawsze jest bezpieczniejszym sposobem… i może dlatego mamy tak wiele „najlepszych praktyk” - niepowodzeń!


Rozumiem twój punkt widzenia i jestem tego winny. Czasami zachodzi potrzeba utworzenia dynamicznego zapytania sql, którego użyłem do łączenia parametrów. Jak byś zaproponował, żebym to zrobił?
TheProvost

@TheProvost to dobre pytanie. Rozważ sp_executesql: msdn.microsoft.com/en-us/library/ms188001.aspx
Tim

@Tim Cześć tim. Jestem nowy w dynamicznym sql. Jaka jest różnica między sp_executesql i EXECUTE (@SqlQuery)
TheProvost

2
Myślę, że ten post dobrze wyjaśnia prosty przykład: codeproject.com/Tips/586207/ ... - ale w zasadzie EXECUTE (@SqlQuery) nie robi nic, aby zapobiec iniekcji sql, jednak sp_executesql (@SqlQuery, ..., ...) temu zapobiega. Przykłady z artykułu Microsoft powinny pomóc.
Tim

Tim ma rozwiązanie TheProvost ...;) Możesz użyć sp_executesql (@QUERY, @PARAMETERS, @VARS) ... dla dynamicznego przypadku SQL ...;)
Andreas Venieris

5

Tak, użycie przygotowanych instrukcji zatrzymuje wszystkie wstrzyknięcia SQL, przynajmniej w teorii. W praktyce sparametryzowane instrukcje mogą nie być faktycznie przygotowanymi instrukcjami, np. PDOW PHP domyślnie je emuluje, więc jest otwarty na atak typu edge case .

Jeśli używasz naprawdę przygotowanych wyciągów, wszystko jest bezpieczne. Cóż, przynajmniej tak długo, jak nie dołączasz niebezpiecznego kodu SQL do swojego zapytania, na przykład w reakcji na brak możliwości przygotowania nazw tabel.

Jeśli tak, dlaczego wciąż jest tak wiele udanych wstrzyknięć SQL? Tylko dlatego, że niektórzy programiści są zbyt głupi, aby używać sparametryzowanych instrukcji?

Tak, edukacja jest tutaj głównym punktem i starsze podstawy kodu. Wiele tutoriali używa ucieczki i niestety nie można ich łatwo usunąć z sieci.


1
Połączona odpowiedź nie ma właściwie nic wspólnego z przygotowanymi oświadczeniami.
Your Common Sense

1
@YourCommonSense: chodzi o sparametryzowane zapytania, mogą nie być rzeczywistymi przygotowaniami, ale emulowanymi w zależności od używanego sterownika. Ważne jest, aby wiedzieć i być bardzo związanym ...
kelunik

1
Inna odpowiedź na tej samej stronie ma bardzo dobry komentarz: „Jeśli WSZYSTKIE Twoje zapytania są sparametryzowane, jesteś również chroniony przed wstrzyknięciem drugiego rzędu. Wstrzyknięcie pierwszego rzędu to zapominanie, że dane użytkownika są niewiarygodne. Wstrzyknięcie drugiego rzędu zapomina, że ​​dane z bazy danych są niewiarygodne (ponieważ pochodzi od użytkownika). ”
Rodrigo

@kelunik, połączona odpowiedź nie dotyczy również zapytań parametrycznych, ale biblioteki, która je w istocie fałszuje. Zapytanie sparametryzowane to takie, które jest wysyłane do serwera z oddzielnymi wartościami parametrów.
Panagiotis Kanavos

@PanagiotisKanavos: Całkiem dobrze znam treść tej odpowiedzi. To tylko przykład (i dość powszechny), że sparametryzowane zapytania, których używasz, mogą w rzeczywistości nie zostać zaimplementowane jako przygotowane instrukcje ...
kelunik

3

Unikam absolutów w programowaniu; zawsze jest wyjątek. Bardzo polecam procedury składowane i obiekty poleceń. Większość mojego zaplecza to SQL Server, ale od czasu do czasu gram w MySql. Procedury składowane mają wiele zalet, w tym plany zapytań w pamięci podręcznej; tak, można to osiągnąć za pomocą parametrów i wbudowanego kodu SQL, ale otwiera to więcej możliwości ataków iniekcyjnych i nie pomaga w oddzieleniu problemów. Dla mnie znacznie łatwiej jest również zabezpieczyć bazę danych, ponieważ moje aplikacje generalnie mają uprawnienia do wykonywania tylko tych procedur składowanych. Bez bezpośredniego dostępu do tabeli / widoku znacznie trudniej jest cokolwiek wstrzyknąć. Jeśli użytkownik aplikacji jest zagrożony, ma się tylko pozwolenie na wykonanie dokładnie tego, co zostało wstępnie zdefiniowane.

Moje dwa centy.


Jak to się ma do pytania? Jak zamierzasz wywołać i przekazać parametry do procedury składowanej? Używasz konkatenacji ciągów lub przy użyciu sparametryzowanego zapytania? Poza tym - co się stanie, jeśli ktoś użyje konkatenacji ciągów wewnątrz procedury składowanej do utworzenia zapytania „dynamicznego”? Tylko dlatego, że jest to procedura składowana, nie oznacza, że ​​jest bezpieczniejsza
Panagiotis Kanavos

Generalnie używam obiektu polecenia, a także unikam uruchamiania „dynamicznych zapytań” zgodnie z projektem.
Derek

2

Nie powiedziałbym „głupi”.

Myślę, że samouczki są problemem. Większość samouczków SQL, książek, cokolwiek wyjaśnia SQL za pomocą wbudowanych wartości, nie wspominając w ogóle o parametrach wiązania. Osoby uczące się z tych samouczków nie mają szansy nauczyć się tego poprawnie.


2
To nie wystarczy. Dlaczego ludzie nie używają frameworka lub jakiegoś orm? Dlaczego nie testują na „głupi zastrzyk” z jakimś głupim testerem? Ponieważ czasami szef ci nie płaci dobrze lub płaci X pieniędzy za projekt i musisz biegać od projektu do innego i od jednego do drugiego, aby zdobyć pieniądze. Musisz być coraz szybszy. Koder jest zestresowany i przeciążony, więc kod działa, ale jest źle napisany.
jedi

2

Ponieważ większość kodu nie jest napisana z myślą o bezpieczeństwie i zarządzaniu, biorąc pod uwagę możliwość wyboru między dodawaniem funkcji (zwłaszcza czymś widocznym, co można sprzedać) a bezpieczeństwem / stabilnością / niezawodnością (co jest znacznie trudniejsze do sprzedania), prawie zawsze będą wybierać były. Bezpieczeństwo jest problemem tylko wtedy, gdy staje się problemem.


2

Czy sparametryzowana instrukcja może zatrzymać wszystkie wstrzyknięcia SQL?

Tak, o ile sterownik bazy danych oferuje symbol zastępczy dla każdego możliwego literału SQL. Większość przygotowanych kierowców oświadczeń tego nie robi. Powiedzmy, że nigdy nie znajdziesz symbolu zastępczego dla nazwy pola lub tablicy wartości. Co zmusi programistę do powrotu do ręcznego dostosowywania zapytania przy użyciu konkatenacji i ręcznego formatowania. Z przewidywanym wynikiem.

Dlatego stworzyłem mój wrapper MySQL dla PHP, który obsługuje większość literałów, które można dynamicznie dodawać do zapytania, w tym tablice i identyfikatory.

Jeśli tak, dlaczego wciąż jest tak wiele udanych wstrzyknięć SQL? Tylko dlatego, że niektórzy programiści są zbyt głupi, aby używać sparametryzowanych instrukcji?

Jak widać, w rzeczywistości niemożliwe jest sparametryzowanie wszystkich zapytań, nawet jeśli nie jesteś głupi.


Jeśli WSZYSTKIE twoje zapytania są sparametryzowane (pochodzą z danych użytkownika lub danych z bazy danych), wydaje się, że jesteś chroniony, jak stwierdzono w najczęściej głosowanym komentarzu tutaj: stackoverflow.com/a/134138/1086511
Rodrigo

Poprosiłem o twoją opinię tylko dlatego, że wydawałeś się wystarczająco rozsądny. Nie sądzę, żeby twoja metoda była najlepsza, jeśli to, co przeczytałem gdzie indziej, jest prawdą. W każdym razie, spodoba mi się, jeśli ulepszysz "przy użyciu zwykłych narzędzi nie możesz sparametryzować WSZYSTKICH zapytań".
Rodrigo

Zacząłem czytać twoją odpowiedź, aż doszedłem do pomysłu identyfikacji „literałów SQL”. Pomysł nie wydawał mi się całkiem słuszny (wydawał się przesadny). Jeśli to prawda, że ​​sparametryzowane zapytania unikają iniekcji w PHP (wciąż badam), to następnym krokiem jest uniknięcie iniekcji javascript. Następnie wrócę, aby przestudiować twoje rozwiązanie. Używam również postgres, a może Twoje rozwiązanie jest specyficzne dla mysql?
Rodrigo

Ok, teraz to przeczytałem (ponownie) i nie sądzę, że „po prostu niemożliwe jest sparametryzowanie wszystkich zapytań” jest poprawą. Czy w MySQL jest to niemożliwe? Czy to niemożliwe również w PostgreSQL? Czemu? Czy jest jakieś zapytanie poza moim skryptem php? Gdzie? Myślę, że przez identyfikator masz na myśli zarezerwowane słowo, które próbujesz usunąć z tablicy $ _POST? Wydaje mi się, że to nie jest właściwa droga (intuicyjnie, oczywiście mogę się mylić). Nie rozumiałem też „Czy kiedykolwiek próbowałeś to związać?” Co związać?
Rodrigo

Nie jest to tak łatwe do znalezienia w sieci, jak myślałem. Jeśli możesz, dodaj numer referencyjny.
Rodrigo

2

Najpierw moja odpowiedź na Twoje pierwsze pytanie: Tak, z tego co wiem, przy użyciu zapytań parametrycznych nie będzie już możliwe wstrzykiwanie SQL. Co do poniższych pytań, nie jestem pewien i mogę jedynie wyrazić swoją opinię na temat powodów:

Myślę, że łatwiej jest „po prostu” napisać ciąg zapytania SQL, łącząc różne części (może nawet zależne od pewnych logicznych kontroli) wraz z wartościami do wstawienia. Po prostu tworzy zapytanie i wykonuje je. Kolejną zaletą jest to, że można wydrukować (echo, wyjście lub cokolwiek innego) ciąg zapytania sql, a następnie użyć tego ciągu do ręcznego zapytania do silnika bazy danych.

Pracując z przygotowanymi zestawieniami zawsze masz co najmniej jeden krok więcej: Musisz zbudować swoje zapytanie (w tym oczywiście parametry) Musisz przygotować zapytanie na serwerze Musisz przypisać parametry do rzeczywistych wartości, które chcesz użyć do zapytania Musisz wykonać zapytanie.

To trochę więcej pracy (i nie tak łatwe do zaprogramowania), zwłaszcza w przypadku niektórych „szybkich i brudnych” prac, które często okazują się bardzo długotrwałe ...

Z poważaniem,

Pudełko


2

Wstrzykiwanie SQL jest podzbiorem większego problemu związanego z wstrzykiwaniem kodu, w którym dane i kod są dostarczane przez ten sam kanał, a dane są mylone z kodem. Zapytania sparametryzowane zapobiegają temu, tworząc zapytanie przy użyciu kontekstu dotyczącego tego, czym są dane, a co kod.

W niektórych przypadkach to nie wystarczy. W wielu systemach DBMS możliwe jest dynamiczne wykonywanie kodu SQL za pomocą procedur składowanych, co wprowadza błąd iniekcji SQL na poziomie DBMS. Wywołanie takiej procedury składowanej przy użyciu zapytań sparametryzowanych nie zapobiegnie wykorzystaniu iniekcji SQL w procedurze. Inny przykład można zobaczyć w tym poście na blogu .

Częściej programiści używają tej funkcji nieprawidłowo. Zwykle kod wygląda mniej więcej tak, gdy jest wykonany poprawnie:

db.parameterize_query("select foo from bar where baz = '?'", user_input)

Niektórzy programiści łączą ze sobą ciągi znaków, a następnie używają sparametryzowanego zapytania, co w rzeczywistości nie czyni wspomnianego wyżej rozróżnienia między danymi a kodem, który zapewnia gwarancję bezpieczeństwa, której szukamy:

db.parameterize_query("select foo from bar where baz = '" + user_input + "'")

Prawidłowe użycie sparametryzowanych zapytań zapewnia bardzo silną, ale nie nieprzeniknioną ochronę przed atakami typu SQL injection.


1

Aby zabezpieczyć aplikację przed wstrzyknięciem SQL, wykonaj następujące czynności:

Krok 1. Ogranicz wprowadzanie. Krok 2. Użyj parametrów w procedurach składowanych. Krok 3. Użyj parametrów z dynamicznym SQL.

Zobacz http://msdn.microsoft.com/en-us/library/ff648339.aspx


8
Same procedury składowane nie są w rzeczywistości pomocne. Istnieje możliwość dynamicznego konstruowania ciągów zapytań w procedurze składowanej, tak jak w kodzie klienta.
Phil Miller,

@Fahad Mogę przeformułować # 2 na „Używaj sparametryzowanych instrukcji w zapytaniach i procedurach składowanych”. +1 do komentarza Novelocrat, że używanie procedur składowanych bez parametrów nie daje wiele.
Matthew,

1

Nawet jeśli przygotowane instrukcje są właściwie używane w całym kodzie aplikacji internetowej, błędy iniekcji SQL mogą nadal występować, jeśli komponenty kodu bazy danych konstruują zapytania na podstawie danych wejściowych użytkownika w niebezpieczny sposób. Poniżej znajduje się przykład procedury składowanej, która jest podatna na wstrzyknięcie SQL w parametrze @name:

CREATE PROCEDURE show_current_orders
(@name varchar(400) = NULL)
AS
DECLARE @sql nvarchar(4000)
SELECT @sql = ‘SELECT id_num, searchstring FROM searchorders WHERE ‘ +
‘searchstring = ‘’’ + @name + ‘’’’;
EXEC (@sql)
GO

Nawet jeśli aplikacja przekazuje wartość nazwy podaną przez użytkownika do procedury składowanej w bezpieczny sposób, sama procedura łączy ją bezpośrednio z zapytaniem dynamicznym i dlatego jest podatna na atak.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.