Czy mogę zabezpieczyć się przed wstrzyknięciem kodu SQL, zapisując pojedyncze cudzysłowy i otaczając dane wejściowe użytkownika pojedynczymi cudzysłowami?
Rozumiem, że sparametryzowane zapytania SQL są najlepszym sposobem na wyczyszczenie 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, "'", "''") & "'"
Każdy pojedynczy cudzysłów wprowadzony przez użytkownika jest zastępowany podwójnymi pojedynczymi cudzysłowami, co eliminuje możliwość zakończenia linii, więc wszystko inne, co mogą wprowadzić, takie jak średniki, znaki procentu itp., Będzie częścią ciągu i nie zostanie wykonane jako część zespołu.
Używamy Microsoft SQL Server 2000, dla którego uważam, że pojedynczy cudzysłów jest jedynym separatorem ciągów i jedynym sposobem na uniknięcie tego znaku, więc nie ma możliwości wykonania czegokolwiek wprowadzonego przez użytkownika.
Nie widzę żadnego sposobu na przeprowadzenie ataku SQL injection przeciwko temu, ale rozumiem, że gdyby był tak kuloodporny, jak mi się wydaje, ktoś inny by 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 SQL przeszedł przez tę technikę leczenia? Bardzo pomocny byłby przykład danych wprowadzanych przez użytkownika, który wykorzystuje tę technikę.
UPDATE:
Nadal nie znam żadnego sposobu na skuteczne przeprowadzenie ataku SQL injection na ten kod. Kilka osób zasugerowało, że ukośnik odwrotny pominie jeden cudzysłów i pozostawi drugi na końcu ciągu, tak że reszta ciągu zostanie wykonana jako część polecenia SQL, i rozumiem, że ta metoda będzie działać do wstrzykiwania SQL do baza danych MySQL, ale w SQL Server 2000 jedynym sposobem (jaki mogłem znaleźć) na uniknięcie pojedynczego cudzysłowu jest użycie innego pojedynczego cudzysłowu; ukośniki odwrotne tego nie zrobią.
A jeśli nie ma sposobu na zatrzymanie zmiany znaczenia pojedynczego cudzysłowu, żadna z pozostałych danych wejściowych użytkownika nie zostanie wykonana, ponieważ wszystkie zostaną potraktowane jako jeden ciągły ciąg.
Rozumiem, że istnieją lepsze sposoby oczyszczenia wkładu, ale naprawdę jestem bardziej zainteresowany tym, dlaczego metoda, którą podałem powyżej, nie działa. Jeśli ktoś zna jakiś konkretny sposób przeprowadzenia ataku SQL injection przeciwko tej metodzie dezynfekcji, z chęcią przyjrzę się temu.
Nie znaleziono powiązanych wyników
Zaproszony:
Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się
18 odpowiedzi
Anonimowy użytkownik
Potwierdzenie od:
Co gorsza, sprawdzanie czarnej listy zawsze jest problematyczne, znacznie lepiej jest wyraźnie i ściśle określić, jakie wartości/formaty akceptujesz. Oczywiście nie zawsze jest to możliwe, ale do pewnego stopnia zawsze należy to robić.
Niektóre prace naukowe na ten temat:
Chodzi o to, że każdą czarną listę, którą tworzysz (i zbyt liberalne białe listy), można ominąć. Ostatni link do mojego artykułu pokazuje sytuacje, w których można obejść 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 banalnie mała, będziesz musiał zająć się konserwacją i być może pewną dozą kontroli: jak upewnić się, że jest wykonywana dobrze, wszędzie i zawsze?
Prawidłowy sposób to:
Anonimowy użytkownik
Potwierdzenie od:
„Jeśli ktoś wie o jakimś konkretnym ataku typu mount i SQL injection przeciwko tej metodzie dezynfekcji, z przyjemnością go obejrzę”.
Teraz, oprócz ucieczki odwrotnym ukośnikiem MySQL - i biorąc pod uwagę, że tak naprawdę mówimy o MSSQL, istnieją właściwie 3 możliwe sposoby, aby nadal wstrzykiwać SQL do kodu
sSanitizedInput = "'" & amp; replace (sInput, "'", "" ") & amp;"' "
Należy pamiętać, że nie wszystkie będą ważne przez cały czas i są w dużym stopniu zależne od rzeczywistego kodu wokół nich:
- Wstrzyknięcie SQL drugiego rzędu - jeśli zapytanie SQL jest przebudowywane na podstawie danych pobranych z bazy danych po przesiewie , dane są łączone bez zmiany znaczenia i mogą być pośrednio wprowadzane przez SQL. Widzieć
- Obcinanie ciągów - (nieco bardziej złożony) - Scenariusz jest taki, ż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. Powiedzmy, że masz ten kod:
Otrzymujesz wtedy nazwę użytkownika, z ucieczką, a następnie skróconą do 20 znaków. Problem jest tutaj - wstawię swój cytat na 20. znak (np. Po 19 A), a Twój cytat ucieczki zostanie obcięty (na 21. znak). Następnie SQLw połączeniu z wyżej wymienioną nieprawidłową nazwą użytkownika spowoduje to, że hasło zostanie już znalezione
na zewnątrz
cudzysłowy i będzie zawierać bezpośrednio ładunek.
Przemyt Unicode - w pewnych sytuacjach możliwe jest przesłanie wysokopoziomowego znaku Unicode
wygląda jak
jak cytat, ale
nie
jest taka - dopóki nie trafi do bazy danych, gdzie nagle
będzie
... Ponieważ to nie jest cytat, kiedy go zaznaczysz, przejdzie łatwo ... Zobacz moją poprzednią odpowiedź, aby uzyskać więcej informacji i link do oryginalnych badań.
Anonimowy użytkownik
Potwierdzenie od:
Anonimowy użytkownik
Potwierdzenie od:
Jednym ze sposobów rozpoczęcia ataku na procedurę „cytuj argument” jest obcięcie łańcucha.
Według MSDN w SQL Server 2000 SP4 (i SQL Server 2005 SP1) zbyt długi ciąg będzie na nim łatwy.
Kiedy cytujesz wiersz, rośnie on. Każdy apostrof jest powtarzany.
Można to następnie wykorzystać do wypchnięcia części kodu SQL z bufora. W ten sposób możesz skutecznie przyciąć części klauzuli where.
Byłoby to prawdopodobnie najbardziej przydatne w przypadku stron typu „administrator użytkowników”, na których można by nadużywać instrukcji „aktualizacja”, aby nie wykonywać wszystkich czynności sprawdzających, które powinien był wykonać.
Jeśli więc zdecydujesz się zacytować wszystkie argumenty, upewnij się, że wiesz, co się dzieje z rozmiarami linii i uważaj, aby nie doszło do obcięcia.
Poleciłbym wybrać opcje. Jest zawsze. Szkoda tylko, że nie mogę tego zrobić w bazie danych. Efektem ubocznym jest większe prawdopodobieństwo lepszych trafień w pamięci podręcznej, ponieważ więcej operatorów wygląda tak samo. (Z pewnością było to prawdą w przypadku Oracle 8)
Anonimowy użytkownik
Potwierdzenie od:
Sam w sobie jest bezpieczny AFAIK. Jednak, jak wskazał inny respondent, możesz również zająć się ucieczką wsteczną (chociaż nie podczas wysyłania zapytania do SQL Server za pomocą ADO lub ADO.NET, przynajmniej - nie mogę ręczyć za wszystkie bazy danych lub technologie).
Problem polega na tym, że naprawdę musisz mieć pewność, które wiersze zawierają dane wejściowe użytkownika (zawsze potencjalnie złośliwe), a które wiersze są prawidłowymi zapytaniami SQL. Jedną z pułapek jest to, że używasz wartości z bazy danych - czy te wartości zostały pierwotnie dostarczone przez użytkownika? Jeśli tak, to i oni muszą zostać zbawieni. Moja odpowiedź brzmi: staram się oczyścić jak najpóźniej (ale nie później!) Podczas budowania zapytania SQL.
Jednak w większości przypadków wiązanie parametrów jest właściwą drogą, jest po prostu łatwiejsze.
Anonimowy użytkownik
Potwierdzenie od:
Anonimowy użytkownik
Potwierdzenie od:
Anonimowy użytkownik
Potwierdzenie od:
Co powiesz na coś takiego jak unikanie cudzysłowu w ciągu takim jak ten: \ '
Twoja zamiana spowoduje: \ "
Jeśli ukośnik odwrotny zmienia znaczenie pierwszego cudzysłowu, to drugi cudzysłów kończy ciąg.
Anonimowy użytkownik
Potwierdzenie od:
Czy chcesz użyć weryfikacji białej listy dla
Całkowity
co robisz, ale rozumiem, że nie zawsze jest to możliwe, dlatego jesteś zmuszony wybrać czarną listę z lepszym zgadywaniem. Podobnie chcesz użyć sparametryzowanych procesów przechowywanych w
wszystko
ale znowu, nie zawsze jest to możliwe, więc musisz użyć sp_execute z parametrami.
Istnieją sposoby na obejście każdej przydatnej czarnej listy, o której możesz pomyśleć (a także niektórych białych list).
Przyzwoity wpis jest tutaj:
http://www.owasp.org/index.php/Top_10_2007-A2
http://www.owasp.org/index.php/Top_10_2007-A2
Jeśli chcesz to zrobić szybko, aby mieć czas na znalezienie prawdziwego rozwiązania, zrób to. Ale nie myśl, że jesteś bezpieczny.
Anonimowy użytkownik
Potwierdzenie od:
Anonimowy użytkownik
Potwierdzenie od:
Anonimowy użytkownik
Potwierdzenie od:
SET QUOTED_IDENTIFIER
http://msdn.microsoft.com/en-u ... .aspx
i nie używa podwójnego cudzysłowu na tobie.
Edycja: nie jest to tak łatwe, jak uniemożliwienie atakującemu wyłączenia identyfikatorów w cudzysłowie:
Sterownik ODBC klienta SQL Server Native Client i dostawca OLE DB dla klienta macierzystego programu SQL Server dla programu SQL Server automatycznie ustawia QUOTED_IDENTIFIER na ON po nawiązaniu połączenia. Można to skonfigurować w źródłach danych ODBC, atrybutach połączenia ODBC lub właściwościach połączenia OLE DB.
Domyślnie wartość parametru jest ustawiona na WYŁ. Do łączenia się z bazą danych bibliotek aplikacji.
Podczas tworzenia procedury składowanej parametry
SET QUOTED_IDENTIFIER i SET ANSI_NULLS są rejestrowane i używane do kolejnych wywołań tej procedury składowanej
.
SET QUOTED_IDENTIFIER odpowiada również parametrowi QUOTED_IDENTIFER bazy danych ALTER.
SET QUOTED_IDENTIFIER
ustawione podczas składni
analiza. Ustawienie podczas analizowania oznacza, że jeśli instrukcja SET jest obecna w pakiecie lub procedurze składowanej, to działa 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żna wyłączyć na wiele sposobów bez Twojej wiedzy. Wprawdzie nie jest to dymiący exploit dla broni, którego szukasz, ale jest to dość duża powierzchnia ataku. Oczywiście, jeśli uniknąłeś również podwójnych cudzysłowów, to wracamy do punktu wyjścia. ;)
Anonimowy użytkownik
Potwierdzenie od:
[/*]
[/list]
(w tym drugim przypadku powinno to być coś, co zostanie rozszerzone dopiero po dokonaniu wymiany)
Anonimowy użytkownik
Potwierdzenie od:
Poza tym, po co odkrywać koło na nowo?
Anonimowy użytkownik
Potwierdzenie od:
W każdym razie to trochę Kluge ... zwłaszcza jeśli legalnie masz rzeczy (takie jak imiona), 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 wejdą one do bazy danych, co prawdopodobnie nie jest realistyczne w większości przypadków.
Anonimowy użytkownik
Potwierdzenie od:
To dużo dodatkowej pracy.
Anonimowy użytkownik
Potwierdzenie od:
Anonimowy użytkownik
Potwierdzenie od:
Tak, możesz, jeśli ...
>
Po zbadaniu tego wątku myślę, że wejście wyczyściło się w sposób, który sugerowałeś, jest bezpieczny, ale tylko zgodnie z tymi zasadami:
[/*]
[*]
albo używasz kolumn / (i prefiksów literałów ciągu ) LUB wartości granicznych zawartych w
varchar <!-- code kolumny-->/[code]char
, tylko do znaków ASCII (np. rzut wyjątek podczas tworzenia instrukcji SQL) [/code][/*]
[*]
zawsze sprawdzasz długość wartości, aby pasowała do rzeczywistej długości kolumny (wyjątek rzutowania, jeśli jest większa)
[/*]
[*]
gwarantujesz, że jest zawsze
[/*]
[/list]
Przestrzegając tych 4 punktów, musisz być bezpieczny. Jeśli złamiesz którykolwiek z nich, otworzy się ścieżka do wstrzyknięcia SQL.