Czy mogę zabezpieczyć się przed wstrzyknięciem SQL, unikając apostrofów i otaczających dane wejściowe użytkownika apostrofami?

139

Zdaję sobie sprawę, że sparametryzowane zapytania SQL są optymalnym sposobem oczyszczenia danych wejściowych użytkownika podczas tworzenia zapytań zawierających dane wejściowe użytkownika, ale zastanawiam się, co jest złego w przyjmowaniu danych wejściowych użytkownika i unikaniu pojedynczych cudzysłowów i otaczaniu całego ciągu pojedynczymi cudzysłowami. Oto kod:

sSanitizedInput = "'" & Replace(sInput, "'", "''") & "'"

Wszelkie pojedyncze cudzysłowy, które wprowadzi użytkownik, są zastępowane podwójnymi pojedynczymi cudzysłowami, co eliminuje możliwość zakończenia ciągu przez użytkownika, więc wszystko inne, co mogą wpisać, takie jak średniki, znaki procentu itp., Będzie częścią ciągu i faktycznie nie wykonywane jako część polecenia.

Używamy Microsoft SQL Server 2000, w przypadku którego uważam, że pojedynczy cudzysłów jest jedynym ogranicznikiem ciągu i jedynym sposobem na uniknięcie tego separatora, więc nie ma możliwości wykonania czegokolwiek wpisanego przez użytkownika.

Nie widzę żadnego sposobu na przeprowadzenie ataku SQL injection przeciwko temu, ale zdaję sobie sprawę, że gdyby było to tak kuloodporne, jak mi się wydaje, ktoś inny by już o tym pomyślał i byłoby to powszechną praktyką.

Co jest nie tak z tym kodem? Czy istnieje sposób, aby atak polegający na wstrzyknięciu kodu SQL przeszedł przez tę technikę oczyszczania? Przykładowe dane wejściowe użytkownika wykorzystujące tę technikę byłyby bardzo pomocne.


AKTUALIZACJA:

Nadal nie znam żadnego sposobu na skuteczne przeprowadzenie ataku SQL injection na ten kod. Kilka osób zasugerowało, że ukośnik odwrotny pomija jeden pojedynczy cudzysłów, a drugi kończy ciąg, tak aby reszta ciągu została wykonana jako część polecenia SQL, i zdaję sobie sprawę, że ta metoda zadziała, aby wstrzyknąć SQL do baza danych MySQL, ale w SQL Server 2000 jedynym sposobem (jaki udało mi się znaleźć) na uniknięcie pojedynczego cudzysłowu jest użycie innego pojedynczego cudzysłowu; ukośniki odwrotne tego nie zrobią.

I chyba że istnieje sposób na zatrzymanie zmiany znaczenia pojedynczego cudzysłowu, żadna z pozostałych danych wejściowych użytkownika nie zostanie wykonana, ponieważ całość zostanie potraktowana jako jeden ciągły ciąg.

Rozumiem, że istnieją lepsze sposoby odkażania danych wejściowych, ale naprawdę jestem bardziej zainteresowany dowiedzeniem się, dlaczego metoda, którą podałem powyżej, nie działa. Jeśli ktoś zna jakiś konkretny sposób przeprowadzenia ataku typu SQL injection przeciwko tej metodzie dezynfekcji, bardzo chciałbym to zobaczyć.

Patrick
źródło
17
@BryanH Przyznanie się, że nie rozumiesz, w jaki sposób powszechnie przyjęta mądrość odnosi się do konkretnego przypadku, i proszenie o przykład w takim konkretnym przypadku nie jest pychą, to pokora. Irytacja, gdy ktoś zapyta o przykład, dlaczego powszechnie przyjęta mądrość jest słuszna, może z drugiej strony zostać odebrana jako arogancka. Rozumowanie na podstawie konkretnych przykładów jest często świetnym sposobem badania i uczenia się. Sposób, w jaki OP zajął się tą wątpliwością, był bardzo przydatny dla mojego zrozumienia tematu, zwłaszcza gdy wyjaśnił odpowiedź, którą znalazł.
SantiBailors,
@patrik Właśnie natknąłem się na to, ponieważ pracuję nad tym samym fragmentem kodu, ale próbuję uciec od ciągu i zagnieździć zapytanie. Czy kiedykolwiek to rozgryzłeś?
3therk1ll
1
@ 3therk1ll lepiej nie próbować, lepiej jest używać sparametryzowanego SQL: blog.codinghorror.com/…
Patrick
@Patrick, podchodzę do tego z perspektywy napastników!
3therk1ll

Odpowiedzi:

87

Przede wszystkim to po prostu zła praktyka. Sprawdzanie poprawności danych wejściowych jest zawsze konieczne, ale jest też zawsze niepewne.
Co gorsza, sprawdzanie poprawności czarnej listy zawsze jest problematyczne, znacznie lepiej jest wyraźnie i ściśle określić, jakie wartości / formaty akceptujesz. Wprawdzie nie zawsze jest to możliwe - ale do pewnego stopnia zawsze trzeba to robić.
Niektóre artykuły naukowe na ten temat:

Chodzi o to, że każdą utworzoną przez Ciebie czarną listę (i zbyt liberalne białe listy) można ominąć. Ostatni link do mojej pracy pokazuje sytuacje, w których można ominąć nawet ucieczkę cytatu.

Nawet jeśli te sytuacje Cię nie dotyczą, nadal jest to zły pomysł. Co więcej, jeśli Twoja aplikacja nie jest trywialnie mała, będziesz musiał zajmować się konserwacją, a może pewną ilością zarządzania: jak zapewnić, że jest wykonywana dobrze, wszędzie przez cały czas?

Jak to zrobić:

  • Walidacja białej listy: typ, długość, format lub akceptowane wartości
  • Jeśli chcesz umieścić na czarnej liście, nie wahaj się. Ucieczka cytat jest dobra, ale w kontekście innych środków zaradczych.
  • Użyj obiektów Command i Parameter, aby przygotować i zweryfikować
  • Wywołaj tylko zapytania sparametryzowane.
  • Jeszcze lepiej, używaj wyłącznie procedur składowanych.
  • Unikaj używania dynamicznego języka SQL i nie używaj konkatenacji ciągów do tworzenia zapytań.
  • Jeśli używasz SP, możesz również ograniczyć uprawnienia w bazie danych do wykonywania tylko potrzebnych SP bez bezpośredniego dostępu do tabel.
  • możesz również łatwo sprawdzić, czy cała baza kodów uzyskuje dostęp do bazy danych tylko przez SP ...
Zachłanny
źródło
2
Przy prawidłowym użyciu dynamicznego SQL i konkatenacji ciągów znaków można bezpiecznie używać z zapytaniami sparametryzowanymi (tj. Z sp_executesqlzamiast EXEC). Oznacza to, że można dynamicznie generować instrukcję SQL, o ile żaden z połączonych tekstów nie pochodzi od użytkownika. Ma to również zalety w zakresie wydajności; sp_executesqlobsługuje buforowanie.
Brian,
2
@Brian, no cóż :). Ale w rzeczywistości, jak często widzisz, że programiści to robią? Co więcej, typowy scenariusz, w którym dynamiczny SQL jest „potrzebny”, wymaga (podobno) wprowadzenia danych przez użytkownika w ramach zapytania. Gdybyś mógł wykonać sp_executesql, (zwykle) nie potrzebujesz dynamicznego sql w pierwszej kolejności.
AviD
W końcu znalazłem się w sytuacji, która uświadomiła mi, że można użyć Unicode, aby przemknąć obok zamiany ciągu. Tekst wejściowy został wpisany do programu Word, co zmieniło apostrof z wersji prostej na apostrof „zawijany” (który wygląda bardziej jak przecinek), na który nie miało wpływu zamiana ciągu, ale został potraktowany jako separator ciągu przez SQL Serwer. Dzięki za odpowiedź AviD (i wszystkim innym)!
Patrick
1
@ElRonnoco jasne, ale nie dyskontuję tego, ponieważ widziałem to na wolności więcej razy niż myślisz ...
AviD
1
@AviD Zaktualizowałem łącze do pliku PDF przemytniczego SQL, który napisałeś, do jedynej wersji, jaką udało mi się znaleźć w Internecie ... daj nam znać, jeśli jest inna lokalizacja dla twojego artykułu.
Michael Fredrickson,
41

OK, ta odpowiedź będzie dotyczyła aktualizacji pytania:

„Jeśli ktoś zna jakiś konkretny sposób przeprowadzenia ataku typu SQL injection przeciwko tej metodzie dezynfekcji, z przyjemnością to zobaczę”.

Teraz, oprócz odwrotnego ukośnika MySQL - i biorąc pod uwagę, że tak naprawdę mówimy o MSSQL, są właściwie 3 możliwe sposoby, aby nadal wstrzykiwać kod SQL przez SQL

sSanitizedInput = "'" & Replace (sInput, "'", "''") & "'"

Weź pod uwagę, że nie wszystkie one będą ważne przez cały czas i są bardzo zależne od twojego obecnego kodu:

  1. Wstrzyknięcie SQL drugiego rzędu - jeśli zapytanie SQL jest przebudowywane na podstawie danych pobranych z bazy danych po ucieczce , dane są łączone bez zmiany znaczenia i mogą być pośrednio wstrzykiwane SQL. Widzieć
  2. Obcinanie ciągu znaków - (nieco bardziej skomplikowane) - Scenariusz polega na tym, że masz dwa pola, powiedz nazwę użytkownika i hasło, a SQL łączy je oba. A oba pola (lub tylko pierwsze) mają sztywny limit długości. Na przykład nazwa użytkownika jest ograniczona do 20 znaków. Powiedz, że masz ten kod:
username = left(Replace(sInput, "'", "''"), 20)

Wtedy to, co otrzymujesz - to nazwa użytkownika, ucieczka, a następnie skrócenie do 20 znaków. Problem tutaj - wstawię swój cytat do 20. znaku (np. Po 19 a), a Twój uciekający cytat zostanie obcięty (w 21. znaku). Następnie SQL

sSQL = "select * from USERS where username = '" + username + "'  and password = '" + password + "'"

w połączeniu z wyżej wymienioną źle sformułowaną nazwą użytkownika spowoduje, że hasło będzie już poza cudzysłowami i będzie zawierało bezpośrednio ładunek.
3. Przemyt Unicode - w pewnych sytuacjach możliwe jest przekazanie wysokiego poziomu znaku Unicode, który wygląda jak cudzysłów, ale nie jest - dopóki nie dotrze do bazy danych, gdzie nagle się znajduje . Ponieważ nie jest to cytat, kiedy go zatwierdzisz, przejdzie przez proste ... Zobacz moją poprzednią odpowiedź, aby uzyskać więcej informacji i link do oryginalnych badań.

Zachłanny
źródło
28

W skrócie: nigdy nie uciekaj przed zapytaniami. Z pewnością coś pójdzie nie tak. Zamiast tego użyj zapytań parametrycznych lub jeśli z jakiegoś powodu nie możesz tego zrobić, użyj istniejącej biblioteki, która zrobi to za Ciebie. Nie ma powodu, żeby robić to samemu.

Nick Johnson
źródło
2
A co, jeśli masz do czynienia z czymś w rodzaju „tabel Google Fusion”, gdzie, afaik, nie ma żadnej dostępnej biblioteki abstrakcji, która obsługuje ten dialekt? Co byś zasugerował?
systempuntoout
20

Zdaję sobie sprawę, że minęło dużo czasu po zadaniu pytania, ale ...

Jednym ze sposobów przeprowadzenia ataku na procedurę „cytowania argumentu” jest obcięcie łańcucha. Według MSDN w SQL Server 2000 SP4 (i SQL Server 2005 SP1) zbyt długi ciąg zostanie po cichu obcięty.

Kiedy cytujesz łańcuch, zwiększa się jego rozmiar. Każdy apostrof się powtarza. Można to następnie wykorzystać do wypchnięcia części kodu SQL poza bufor. Możesz więc skutecznie odciąć części klauzuli where.

Byłoby to prawdopodobnie najbardziej przydatne w scenariuszu ze stroną „administratora użytkownika”, w którym można by nadużywać instrukcji „aktualizacja”, aby nie wykonywać wszystkich sprawdzeń, które powinien wykonać.

Więc jeśli zdecydujesz się zacytować wszystkie argumenty, upewnij się, że wiesz, co się dzieje z rozmiarami ciągów i dopilnuj, aby nie doszło do obcięcia.

Poleciłbym iść z parametrami. Zawsze. Żałuję tylko, że nie mogę wymusić tego w bazie danych. Efektem ubocznym jest większe prawdopodobieństwo uzyskania lepszych trafień w pamięci podręcznej, ponieważ więcej instrukcji wygląda tak samo. (Z pewnością było to prawdą w przypadku Oracle 8)

Jørn Jensen
źródło
1
Po opublikowaniu zdecydowałem, że post AviD dotyczy tego i bardziej szczegółowo. Mam nadzieję, że mój post nadal komuś pomoże.
Jørn Jensen
10

Użyłem tej techniki podczas korzystania z funkcji „wyszukiwania zaawansowanego”, gdzie jedyną realną odpowiedzią było zbudowanie zapytania od podstaw. (Przykład: pozwól użytkownikowi wyszukiwać produkty w oparciu o nieograniczony zestaw ograniczeń dotyczących atrybutów produktu, wyświetlając kolumny i ich dozwolone wartości jako elementy sterujące GUI w celu zmniejszenia progu uczenia się dla użytkowników).

Sam w sobie jest bezpieczny AFAIK. Jak zauważył inny odpowiadający, może jednak zajść potrzeba zajęcia się ucieczką wsteczną (choć nie podczas przekazywania zapytania do SQL Server za pomocą ADO lub ADO.NET, przynajmniej - nie może ręczyć za wszystkie bazy danych lub technologie).

Problem polega na tym, że naprawdę musisz być pewien, które ciągi zawierają dane wejściowe użytkownika (zawsze potencjalnie złośliwe), a które są poprawnymi zapytaniami SQL. Jedną z pułapek jest użycie wartości z bazy danych - czy te wartości zostały pierwotnie podane przez użytkownika? Jeśli tak, trzeba im też uciec. Moja odpowiedź brzmi: staram się przeprowadzić dezynfekcję tak późno, jak to możliwe (ale nie później!) Podczas konstruowania zapytania SQL.

Jednak w większości przypadków wiązanie parametrów jest drogą do zrobienia - jest po prostu prostsze.

Pontus Gagge
źródło
2
Nadal możesz używać podstawiania parametrów, nawet jeśli tworzysz własne zapytania.
Nick Johnson,
1
Ciąg instrukcji SQL należy zbudować od podstaw, ale nadal używać podstawiania parametrów.
JeeBee
Nie, NIGDY nie twórz instrukcji SQL od podstaw.
AviD,
8

Warunki sanitarne wejściowe nie są czymś, co chcesz być pół-dupkiem. Użyj całego swojego tyłka. Używaj wyrażeń regularnych w polach tekstowych. TryCast swoje liczby na odpowiedni typ liczbowy i zgłoś błąd walidacji, jeśli to nie zadziała. Bardzo łatwo jest wyszukać wzorce ataków w danych wejściowych, takie jak „-. Załóżmy, że wszystkie dane wejściowe od użytkownika są wrogie.

tom.dietrich
źródło
4
A kiedy przegapisz JEDEN przypadek na JEDNYM wejściu, jesteś pwnd.
BryanH,
4
„Niektórzy ludzie w obliczu problemu myślą:„ Wiem, użyję wyrażeń regularnych ”. Teraz mają dwa problemy.
MickeyfAgain_BeforeExitOfSO
1
@mickeyf Wiem, że to powszechny sentyment, ale szczerze mówiąc, wyrażenia regularne są całkiem niesamowite, gdy je grepujesz.
tom.dietrich
@ tom.dietrich To zawsze zależy od rzeczywistej sytuacji życiowej. F.ex. Składnia regexpr nie jest standardowa, więc generalnie odradzałbym używanie regexpr w kontekstach, w których różne systemy są zintegrowane do współpracy. Dzieje się tak, ponieważ różne silniki regexpr różnie oceniają wyrażenia regularne, a co ważniejsze, ten trudny fakt jest zwykle bagatelizowany lub ignorowany, co może prowadzić programistów do nie przejmowania się tymi niezgodnościami, dopóki nie zostaną ugryzieni. Jest wiele takich niezgodności; patrz np. regular-expressions.info/shorthand.html (wyszukaj na flavorstej stronie).
SantiBailors
6

Jak się wydaje, to i tak zły pomysł.

A co z czymś takim jak ucieczka przed cudzysłowem w ciągu: \ '

Twoja zamiana spowodowałaby: \ ''

Jeśli ukośnik odwrotny zmienia znaczenie pierwszego cudzysłowu, to drugi cudzysłów kończy ciąg.

W W.
źródło
3
Dzięki za odpowiedzi! Wiem, że ten atak zadziałałby dla bazy danych mySQL, ale jestem prawie pewien, że MS SQL Server nie zaakceptuje ukośnika odwrotnego jako znaku ucieczki (próbowałem). Kilka wyszukiwań w Google nie ujawniło żadnych innych znaków ucieczki, co naprawdę sprawiło, że zacząłem się zastanawiać, dlaczego to nie zadziała.
Patrick,
6

Prosta odpowiedź: czasami zadziała, ale nie zawsze. Chcesz używać sprawdzania poprawności białej listy we wszystkim, co robisz, ale zdaję sobie sprawę, że nie zawsze jest to możliwe, więc jesteś zmuszony wybrać najlepszą czarną listę. Podobnie, chcesz używać sparametryzowanych przechowywanych procesów we wszystkim , ale po raz kolejny nie zawsze jest to możliwe, więc musisz użyć sp_execute z parametrami.

Istnieją sposoby na obejście wszelkich użytecznych czarnych list, które możesz wymyślić (a także niektórych białych list).

Przyzwoity zapis jest tutaj: http://www.owasp.org/index.php/Top_10_2007-A2

Jeśli chcesz to zrobić jako szybką naprawę, aby mieć czas na zainstalowanie prawdziwego, zrób to. Ale nie myśl, że jesteś bezpieczny.

Nieprawidłowy znak
źródło
6

Są na to dwa sposoby, bez wyjątków, aby uchronić się przed wstrzyknięciami SQL; przygotowane instrukcje lub sparametryzowane procedury składowane.

olle
źródło
4

Jeśli masz sparametryzowane zapytania, powinieneś ich używać przez cały czas. Wystarczy, że jedno zapytanie przejdzie przez sieć i Twoja baza danych jest zagrożona.

Kev
źródło
4

Tak, to powinno działać, dopóki ktoś nie uruchomi SET QUOTED_IDENTIFIER OFF i nie użyje podwójnego cudzysłowu.

Edycja: nie jest to tak proste, jak uniemożliwienie złośliwemu użytkownikowi wyłączenia cytowanych identyfikatorów:

Sterownik ODBC klienta SQL Server Native Client i dostawca OLE DB klienta SQL Server dla programu SQL Server automatycznie ustawiają QUOTED_IDENTIFIER na ON podczas łączenia. Można to skonfigurować w źródłach danych ODBC, atrybutach połączenia ODBC lub właściwościach połączenia OLE DB. Wartość domyślna SET QUOTED_IDENTIFIER jest wyłączona dla połączeń z aplikacji DB-Library.

Po utworzeniu procedury składowanej ustawienia SET QUOTED_IDENTIFIER i SET ANSI_NULLS są przechwytywane i używane do kolejnych wywołań tej procedury składowanej .

SET QUOTED_IDENTIFIER odpowiada również ustawieniu QUOTED_IDENTIFER na ALTER DATABASE.

SET QUOTED_IDENTIFIER jest ustawiana w czasie analizy . Ustawienie w czasie analizy oznacza, że ​​jeśli instrukcja SET jest obecna w procedurze wsadowej lub procedurze składowanej, ma ona skutek niezależnie od tego, czy wykonanie kodu faktycznie osiągnie ten punkt; a instrukcja SET zaczyna obowiązywać przed wykonaniem jakichkolwiek instrukcji.

QUOTED_IDENTIFIER może się wyłączyć na wiele sposobów bez Twojej wiedzy. Trzeba przyznać - nie jest to exploit dymiący, którego szukasz, ale jest to dość duża powierzchnia ataku. Oczywiście, jeśli uniknąłeś podwójnych cudzysłowów - to wracamy do punktu wyjścia. ;)

Mark Brackett
źródło
1
To mogłoby zadziałać, ale znowu, jak mogliby zmusić ten kod do wykonania, skoro wszystkie dane wejściowe użytkownika są otoczone pojedynczymi cudzysłowami? Bardzo pomocna byłaby konkretna linia (wiersze) kodu, które byłyby w stanie wstrzyknąć SQL do powyższego kodu. Dzięki!
Patrick
4

Twoja obrona zawiodłaby, gdyby:

  • zapytanie oczekuje liczby zamiast ciągu
  • istniał inny sposób przedstawienia pojedynczego cudzysłowu, w tym:
    • sekwencja ucieczki, taka jak \ 039
    • znak Unicode

(w tym drugim przypadku musiałoby to być coś, co zostało rozwinięte dopiero po wykonaniu wymiany)

AJ.
źródło
4

Patrick, czy dodajesz pojedyncze cudzysłowy wokół WSZYSTKICH danych wejściowych, nawet liczbowych? Jeśli masz dane numeryczne, ale nie otaczasz go pojedynczymi cudzysłowami, masz ekspozycję.

Rob Kraft
źródło
1

Cóż za brzydki kod byłoby takie oczyszczanie danych wprowadzanych przez użytkownika! Następnie niezgrabny StringBuilder dla instrukcji SQL. Przygotowana metoda instrukcji daje w efekcie znacznie czystszy kod, a zalety SQL Injection to naprawdę fajny dodatek.

Po co też odkrywać koło na nowo?

JeeBee
źródło
1

Zamiast zamieniać pojedynczy cytat na (jak wygląda) dwa pojedyncze cudzysłowy, dlaczego nie zmienić go po prostu na apostrof, cytat lub całkowicie go usunąć?

Tak czy inaczej, jest to trochę kłopotliwe ... zwłaszcza, gdy legalnie masz rzeczy (takie jak nazwy), które mogą używać pojedynczych cudzysłowów ...

UWAGA: Twoja metoda zakłada również, że wszyscy pracujący nad aplikacją zawsze pamiętają o wyczyszczeniu danych wejściowych, zanim trafią one do bazy danych, co prawdopodobnie nie jest realistyczne przez większość czasu.

Kevin Fairchild
źródło
Głosowano w dół, ponieważ odpowiedź nie dotyczy pytania. Pytanie dotyczy unikania ciągów znaków w SQL. Kiedy uciekasz przed dowolnym ciągiem znaków (tak jak próbuje to zrobić pytający, aby poradzić sobie z nieanityzowanymi danymi), nie możesz po prostu zastąpić problematycznych znaków dowolnymi innymi; które psują dane. (Również pojedynczy cytat JEST apostrofem (przynajmniej w ASCII).)
andrewf,
-1

Chociaż możesz znaleźć rozwiązanie, które działa dla łańcuchów, w przypadku predykatów liczbowych musisz również upewnić się, że przekazują one tylko liczby (proste sprawdzenie, czy można je przeanalizować jako int / double / decimal?).

To dużo dodatkowej pracy.

Joseph Daigle
źródło
-2

To może zadziałać, ale wydaje mi się to trochę dziwne. Zalecam sprawdzenie, czy każdy ciąg jest prawidłowy, testując go zamiast tego w wyrażeniu regularnym.

Obrabować
źródło
-3

Tak, możesz, jeśli ...

Po przestudiowaniu tematu uważam, że wejście odkażone, jak sugerowałeś, jest bezpieczne, ale tylko na tych zasadach:

  1. nigdy nie pozwalasz, aby wartości łańcuchowe pochodzące od użytkowników stały się czymś innym niż literały łańcuchowe (tj. unikaj podawania opcji konfiguracyjnej: „Wprowadź tutaj dodatkowe nazwy kolumn / wyrażenia SQL:”). Typy wartości inne niż łańcuchy (liczby, daty, ...): przekonwertuj je na ich rodzime typy danych i zapewnij procedurę dla literału SQL z każdego typu danych.

    • Sprawdzanie poprawności instrukcji SQL jest problematyczne
  2. albo używasz nvarchar/ ncharkolumny (i prefiksujesz literały łańcuchowe z N) LUB ograniczasz wartości wchodzące do varchar/ charkolumny tylko do znaków ASCII (np. rzucaj wyjątek podczas tworzenia instrukcji SQL)

    • w ten sposób unikniesz automatycznej konwersji apostrofów z CHAR (700) na CHAR (39) (i być może innych podobnych hacków Unicode)
  3. zawsze sprawdzasz długość wartości, aby pasowała do rzeczywistej długości kolumny (wyjątek, jeśli jest dłuższy)

    • wystąpił znany błąd w SQL Server pozwalający ominąć błąd SQL zgłaszany przy obcięciu (prowadzący do cichego obcięcia)
  4. upewniasz się, że tak SET QUOTED_IDENTIFIERjest zawszeON

    • uwaga, jest to uwzględniane w czasie parsowania, tj. nawet w niedostępnych sekcjach kodu

Przestrzegając tych 4 punktów, powinieneś być bezpieczny. Jeśli naruszysz którekolwiek z nich, otworzy się sposób na wstrzyknięcie SQL.

miroxlav
źródło
1
To tak, jakbyś nie przeczytał wszystkich innych odpowiedzi na to 8-letnie pytanie , ponieważ dowolna liczba z nich wskazuje, że jego metoda nie zatrzymuje wstrzykiwania, jeśli atakujący po prostu używa znaków Unicode.
Hogan
@Hogan - tak, ale myślę, że moje pytanie ma dodatkową wartość. Mam duże doświadczenie i testy związane z tym, co napisałem. Wiem, że użycie parametrów zapytania jest lepsze, ale też w pełni rozumiem sytuację, w której ktoś musi tego unikać z różnych powodów (np. Żądanie od pracodawcy zachowania starego sposobu). W tym przypadku myślę, że moja odpowiedź jest bardzo wyczerpująca i ma większą wartość niż odpowiedzi „po prostu tego nie rób”, ponieważ wskazuje drogę. Pokaż mi inne odpowiedzi, które pokazują ten sam sposób, a rozważę usunięcie moich.
miroxlav
Ok, kiedy (nie jeśli) twój system zostanie naruszony, wróć i usuń tę odpowiedź ... lub możesz użyć sparametryzowanego zapytania.
Hogan,
@Hogan - nie mam problemu z zrobieniem tego :) Ale obecnie twierdzę, że nie ma znanego sposobu na obejście tego, jeśli będziesz przestrzegać 4 zasad, które opublikowałem. Jeśli naprawdę myślisz, że jest na to sposób, po prostu wskaż, gdzie.
miroxlav
Zła rada hombre. każdą interpolację można pokonać.
Shayne