Pytanie:
Would removing spaces in a string protect against SQL injection?
XaolingBao
2016-06-21 09:47:13 UTC
view on stackexchange narkive permalink

Byłem ciekawy, czy można chronić się przed atakiem typu SQL injection, usuwając wszystkie spacje z danych wejściowych typu String?

Czytałem o SQL Injection w OWASP, ale nie wspominają o usuwaniu spacji, więc byłem ciekawy, dlaczego to zadziała lub nie?


Patrzyłem na to pytanie, które pyta o trim , a górna odpowiedź brzmi tak:

Nie, dodanie trymowania nie zapobiegnie iniekcji sql. trim usuwa tylko spację na zewnątrz ciągu.

  Wybierz * z tabeli, gdzie nazwa taka jak '%' + @ SearchString + '%'  

Jeśli @SearchString miał coś takiego jak

  '' update aTable set someColumn = 'JackedUpValue', gdzie jakaś kolumna wygląda jak ' 

Następnie, gdy złożyć to wszystko w całość i wykonać dynamicznie, aby uzyskać

  Wybierz * z tabeli, gdzie nazwa taka jak '%' zaktualizuj aTable set someColumn = 'JackedUpValue' gdzie jakaś kolumna jak '%'  

Jednak jeśli wziąłeś ten ciąg wyszukiwania

  update aTable set someColumn = 'JackedUpValue' gdzie jakaś kolumna taka jak  

i wykonałeś operację pokazaną w tym pytaniu, czy nie dostaniesz

  updateaTablesetsomeColumn = 'JackedUpValue'wheresomeColumnlike  

który nie powinien być wykonywany, prawda?

Jestem ciekawy, czy istnieje jakaś forma wstrzyknięcia SQL, która mogłaby to pokonać? Czy jest jedno słowo niebezpieczne polecenia? Jeśli można to pokonać, czy usunięcie spacji przynajmniej pomogłoby trochę w obronie?

Uwaga: zadaję to pytanie z czystej ciekawości, a nie w celu obejścia „właściwe” metody zapobiegania wstrzykiwaniu kodu SQL.

Ale czemu miałoby to służyć?Twoim głównym celem jest zebranie danych wejściowych, drugim jest zapobieganie iniekcji SQL.Albo twoje dane wejściowe muszą zachować spacje (więc nie możesz tego zrobić), albo nie (w takim przypadku po prostu je usuń).Sam mówisz, że to nie będzie twoja jedyna obrona, więc przygotuj odpowiednią obronę i zapomnij o tej „sztuczce ze względu na bezpieczeństwo”.
jest to rozwiązany problem - wystarczy sparametryzować wszystkie zapytania
czy mogę użyć tabulatora zamiast spacji?
Miło widzieć, że nadchodzi nowy HBGary.Chłopaki bardzo "myślący przyszłościowo" ;-)
@JanDoggen Po prostu pytam „co by było, gdyby…” W moim przypadku nie potrzebuję spacji, dlatego pytam, czy usunięcie spacji mogłoby zadziałać.Jestem również ciekawy, czy zdezynfekowałem dane wejściowe tylko dla określonego zakresu znaków ASCII / Unicode, chroniłoby to lepiej, ponieważ wydaje się, że istnieje wiele znaków Unicode w przestrzeni ...
Chociaż jest to ważne pytanie teoretyczne, nie ma absolutnie żadnego praktycznego znaczenia.Istnieje sposób na zabezpieczenie się przed wstrzyknięciem SQL, który jest zwykle nawet prostszy niż jakakolwiek alternatywna dezynfekcja;po prostu użyj tego bez pytania, czy jakaś alternatywna technika faktycznie obejmuje wszystkie twoje zasady.
To dziwne, że po tych wszystkich pozytywnych opiniach zaczynam otrzymywać głosy przeciwne. Chciałbym, żeby ludzie przynajmniej komentowali, dlaczego ... Może moja edycja ???
„Nie sugeruję, żeby to była moja jedyna forma obrony, ale jestem po prostu ciekawy, gdzie ta forma„ obrony ”mieści się w spektrum dobra lub bezużyteczna.” Nie powinieneś rozważać jej użycia jako jakiejkolwiek formy obrony.Ponieważ jest to pytanie oparte wyłącznie na ciekawości naukowej, nie ma w tym nic złego.
Usunięcie odwrotnych ukośników, apostrofów i podwójnych cudzysłowów najprawdopodobniej zapobiegłoby iniekcji SQL.Praktyczne jest również usuwanie wartości NUL, aby zapobiec błędom podczas analizowania zapytań.Ale oczywiście łatwym w utrzymaniu, najmniej zaskakującym rozwiązaniem jest osobne przekazywanie argumentów zapytania (i oznaczanie ich pozycji znakiem „?” W zapytaniu), więc sterownik klienta bazy danych zajmuje się ucieczką lub używaniem ORM.
@XaolingBao Nie mam wystarczającego przedstawiciela, aby głosować przeciw, ale zrobiłbym to, gdybym mógł, ponieważ pytanie wydaje się po prostu mówić `` Wiem, że są wszystkie te odpowiednie metody, których mógłbym użyć, ale czy mogę zamiast tego użyć tej leniwej ''kaleczy to, co moi użytkownicy są w stanie wprowadzić, i rażąco pomija prawie wszystkie sytuacje, gdybym miał wziąć pod uwagę rzeczywisty kod SQL i rozszerzone zestawy znaków?
Jak wspomniano wcześniej, zawsze używaj zapytań parametrycznych.Po prostu żyj założeniem, że nie sparametryzowany SQL będzie zawsze wykorzystywany, ponieważ, szczerze mówiąc, istnieje tak wiele sposobów jego nadużywania, że nie można ustrzec się przed nimi wszystkimi.Jako prosty przykład weź pod uwagę, że odfiltrowujesz liczby, a atakujący potrzebuje „3” w swoim zapytaniu z dowolnego powodu.Co on robi?`PODŁOGA (PI ())`.
@XaolingBao Zgaduję, że głosy negatywne są takie, ponieważ jak wielokrotnie stwierdzałem w odpowiedzi na to pytanie, jest to problem rozwiązany
@Jasper Edytowałem ten fragment, zanim zobaczyłem twój komentarz, aby nadać mu nieco więcej sensu, ale tak, tak naprawdę nie rozważam tego, chyba że zadziałało, więc edytuję tę część, aby była bardziej przejrzysta. Po prostu patrzęw tym z hipotetycznego punktu widzenia, a jak powiedziałeś „ciekawość naukowa”
@underscore_d Wspomniałem, że używam odpowiednich procedur, to tylko hipotetyczne pytanie, żeby zobaczyć "co by było, gdybym" usunął spacje, a nie używał tego jako sposobu na pokonanie SQL Injection, chyba że zadziałało bardzo dobrze.
Sześć odpowiedzi:
wireghoul
2016-06-21 10:40:22 UTC
view on stackexchange narkive permalink

Nie. Usunięcie spacji nie zapobiegnie iniekcji SQL, ponieważ istnieje wiele innych sposobów na przetworzenie przez parser danych wejściowych. Spójrzmy na przykład. Wyobraź sobie, że masz adres URL, który w zapytaniu w sposób niebezpieczny używał danych wprowadzonych przez użytkownika:

http: //example/index.php? Id = 1 => SELECT * ze strony, gdzie id = 1

W Twoim przykładzie osoba atakująca użyłaby spacji:

http: //example/index.php? id = 1% 20 lub% 201 = 1 => SELECT * ze strony, gdzie id = 1 lub 1 = 1 .

Usunięcie spacji spowodowałoby zwinięcie iniekcji w ciąg.

Teraz wyobraźmy sobie, że atakujący użył innej formy spacji, tj. tabulatorów:

http: //example/index.php? id = 1% 09 lub% 091 = 1 => SELECT * ze strony, na której id = 1 lub 1 = 1 .

Usunięcie spacji nadal umożliwiłoby wykonanie wstrzyknięcia.

W zależności od używanej technologii osoba atakująca może zastąpić spacje kodem / ** / % 00 % 09 % 0a % 0d lub dowolna liczba unikodów, która powoduje tokenizację przez parser SQL. Podczas gdy przywoływany przykład usunął więcej niż tylko spacje, wspomniany powyżej przykład wykorzystuje komentarze SQL, aby spowodować tokenizację, które nie są białymi znakami. Nadal byłbyś podatny na ataki.

Jedynym niezawodnym sposobem zapobiegania wstrzykiwaniu SQL jest używanie zapytań parametrycznych.

Dziękuję za interesującą odpowiedź, ale w którym momencie ten adres URL zmieniłby się w instrukcję zapytania i dlaczego w tym momencie nie można usunąć spacji?Wydaje się też, że ma to wpływ tylko na adresy URL, czy może być również używane w aplikacjach?Nie jestem do końca pewien, czy w aplikacji coś takiego jak „\ n” spowodowałoby spację po próbie usunięcia białych znaków ze ciągu znaków ... Jestem również ciekawy, czy zgadzasz się z poniższym, że iniekcje nie są tak dużeumowa i „rzecz z przeszłości”?Uważam, że wszystkie moje zapytania są przygotowane / sparametryzowane.Dzięki.
To ogólny przykład sieciowy, ponieważ odwołałeś się do owasp.„Wyobraź sobie”, w jaki sposób dane wejściowe użytkownika znalazły się w zapytaniu.W jaki sposób występują zastrzyki SQL to zupełnie inna kwestia niż twój OP.Metody wykorzystywania iniekcji SQL mają zastosowanie wszędzie tam, gdzie występują iniekcje SQL, czy to w aplikacji Windows, serwerze FTP, wtyczce odtwarzacza muzyki czy na stronie internetowej.Wstrzykiwanie SQL jest bardzo aktualnym problemem i chociaż programiści stają się coraz bardziej świadomi, wciąż jest to powszechny problem.
Rozumiem, nie spojrzałem na to właściwie i nie zdawałem sobie sprawy, że możesz wykonać tylko id = 1 lub inne polecenia, które były takie.Pomyślałem, że aplikacja może być w stanie lepiej chronić przed atakiem niż zapytanie URL, ale nie jestem pewien, jak to działa w porównaniu.Muszę jednak poszukać tej firmy o identyfikatorach = 1 i 1 = 1 .. Wielkie dzięki.
+1 dla „*** Jedynym niezawodnym sposobem zapobiegania iniekcji SQL jest użycie zapytań parametrycznych ***” - wydaje się, że nie możemy tego wystarczająco powtórzyć!
@TobySpeight, chyba że wydaje się, że sparametryzowane zapytania nie chronią przed wszystkimi formami SQL Injection?
Nie wiem nawet, dlaczego ludzie nadal próbują rozwiązywać wstrzykiwanie SQL bez sparametryzowanych zapytań, jakby nigdy o nich nie słyszeli.To sprawia, że mam ochotę rozwalić moją twarz przez drewniany stół, razem z tym głupim memem Bobby Tables.
Julie Pelletier
2016-06-21 10:11:12 UTC
view on stackexchange narkive permalink

Mamy 2016 rok! Zastrzyki SQL należą do przeszłości, chyba że używasz niezabezpieczonego kodu.

Niezależnie od używanego języka, jeśli chcesz zapobiec jakimkolwiek wszystkim iniekcjom SQL, użyj przygotowanych instrukcji lub dowolnego innego rodzaju wiązania danych.

Przygotowane instrukcje oddzielają zapytanie od danych, przez co dane nie mają wpływu na zapytanie.

Aby bezpośrednio odpowiedzieć na Twoje pytanie, usunięcie spacji zmniejszyłoby liczbę wstrzyknięć SQL (w przypadku użycia przestarzałego kod i biblioteki), ale z pewnością ograniczyłby wprowadzany tekst (nigdzie nie ma spacji).

Komentarze nie służą do rozszerzonej dyskusji;ta rozmowa została [przeniesiona do czatu] (http://chat.stackexchange.com/rooms/41512/discussion-on-answer-by-julie-pelletier-would-removing-spaces-in-a-string-protec).
Anders
2016-06-21 12:45:02 UTC
view on stackexchange narkive permalink

Ograniczyłoby to problem, ale go nie wyeliminował. Rozważmy następującą sytuację:

  $ un = str_replace ("", "", $ _POST ["nazwa użytkownika"]); $ pw = hash ($ _ POST ["hasło"]; $ sql = "SELECT * FROM users WHERE username = '$ un' AND password = '$ pw'";  

Powiedzmy, że opublikuję nazwę użytkownika admin '- . To spowodowałoby zalogowanie mnie jako administrator bez użycia ani jednej spacji.

Jak wskazuje wireghoul, musiałbyś również usunąć inne puste znaki, takie jak tabulator. Ale ponieważ Julie Pelletier wskazuje, po prostu używaj przygotowanych instrukcji. Wymyślanie sprytnych schematów zatrzymania SQLi bez tego może być zabawną grą, ale nigdy nie zapewni Ci bezpieczeństwa, które zapewnia przygotowane oświadczenia. tylko rozproszenie uwagi.

Dziękuję za odpowiedź, ale wydawało się, że możesz wprowadzić małe instrukcje, takie jak w odpowiedzi Wireghoula, w której mówi, że id = 1, ale nie jestem pewien, czy mogliby uzyskać hasła w ten sposób, i jestem ciekawy, gdzie dane wejściowe są zwracane, jeśli oneczy to w wierszu adresu URL?W swoim przykładzie z administratorem musiałbyś znać jego informacje, aby się zalogować, więc jestem trochę zdezorientowany, co twój przykład próbuje pokazać?Korzystam z przygotowanych stwierdzeń, ale hipotetycznie ciekawi mnie, jak dobre byłoby usuwanie przestrzeni i inne podobne zadania ... Dzięki!
W moim przykładzie wystarczy znać nazwę użytkownika (nie hasło), aby zalogować się jako ten użytkownik.To jest bardzo, bardzo złe.Możesz zrobić wiele innych rzeczy.Whireghoul ma kilka przykładów, podobnie jak Jimmy James.
„To bardzo, bardzo źle”, co oznacza brak hasła dla administratora lol?Co dokładnie oznacza `` admin '' - `` w SQL?Tak, wygląda na to, że zostałby pokonany przez inne małe komendy.Dzięki.
Oto otrzymany kod SQL: `` SELECT * FROM users WHERE nazwa_użytkownika = 'admin' - AND hasło = '' ``.Ale ponieważ `--` rozpoczyna komentarz, wykonywane zapytanie to` SELECT * FROM users WHERE nazwa_użytkownika = 'admin' '.Więc zwróci użytkownika admin tak, jakby hasło było zgodne, nawet jeśli nie było hasła.
Dziękuję bardzo ... To ma dużo sensu i jest brudne ....:) ... Ponieważ zredagowałem moje pytanie dotyczące odkażania danych wejściowych, aby zezwalać tylko na cyfry i litery, ten atak i inne wspomnianeze znakami takimi jak `= i%` należy zatrzymać, prawda?Wielkie dzięki!
JimmyJames
2016-06-21 18:54:52 UTC
view on stackexchange narkive permalink

Nie . Załóżmy, że masz to jako swój SQL:

  "wybierz * spośród osób, dla których last_name = '" + nazwisko + "'"  

Jeśli wpiszę: 'OR (1 = 1) OR'a' = ' na dane wejściowe, które zamienia w:

  select * from people where last_name =' 'OR (1 = 1) OR'a '=' ' 

Który jest wykonywany w Oracle i MySQL (przynajmniej) i zwraca wszystkie wiersze z tabeli.

Komentarze nie służą do rozszerzonej dyskusji;ta rozmowa została [przeniesiona do czatu] (http://chat.stackexchange.com/rooms/41582/discussion-on-answer-by-jimmyjames-would-removing-spaces-in-a-string-protect-aga).
nvuono
2016-06-23 18:09:35 UTC
view on stackexchange narkive permalink

Jednak gdybyś wziął ten ciąg wyszukiwania

update aTable set someColumn = 'JackedUpValue', gdzie jakaś kolumna taka jak i wykonała operację pokazaną w tym pytaniu, nie otrzymujesz

updateaTablesetsomeColumn = 'JackedUpValue'wheresomeColumn like które nie powinny być wykonywane, prawda?

Jak inni zauważyli, istnieją inne sposoby uzyskiwanie białych znaków w różnych implementacjach SQL Database, które należy uwzględnić, na przykład tabulatory i \ n (nowa linia). Prawie każdy silnik bazy danych z radością zaakceptowałby:

  updateaTablesetsomeColumn = 'JackedUpValue'  

Mogą istnieć różne znaki Unicode, które działają jako białe spacje w zależności od ustawień lokalizacji w różnych baz danych, ale naprawdę musiałbyś zagłębić się w szczegóły implementacji, aby to zrozumieć. Naprawdę nie ma powodu, aby próbować omawiać wszystkie te skrajne przypadki zastępowania ciągów, a nie tylko używania sparametryzowanych zapytań.

user126572
2016-10-06 07:23:28 UTC
view on stackexchange narkive permalink

Oto pomysł. Serwery baz danych przyjmują przychodzące zapytanie SQL i przepuszczają je przez parser, w wyniku czego powstaje drzewo parsowania. Następnie przekształcają drzewo w plan i wykonują plan.

Istotą iniekcji jest to, że parser tworzy drzewo inne niż to zamierzone przez programistę.

Więc poprawka jest w stanie wykryć nietypowe drzewa parsowania. Przejdź po drzewie po przeanalizowaniu i utwórz ciąg w formie kanonicznej bez wartości danych. Oblicz skrót SHA ciągu. Prowadź tabelę znanych skrótów dla użytkownika aplikacji / bazy danych. Ostrzegaj lub przerywaj, jeśli serwer napotka nieznany skrót.

Oczywiście wystąpił problem z uruchomieniem. Zatem programista musiałby uruchomić aplikację w trybie testowym, wyodrębnić skróty po wyczerpujących testach i załadować serwer hashami podczas uruchamiania aplikacji. Następnie włącz abort-on-new-hash i żadne więcej wstrzyknięć SQL nie powinno być możliwe.

Jak usuniesz dane z formy armatniej?Czy nie byłby to kolejny parser, którego można oszukać, wierząc, że dane to kod?Osoba atakująca musiałaby wykonać SQLi, a następnie działający parser wprowadziłby w błąd koniec / początek ciągu.To bardziej kłopotliwe niż zwykły SQLi, ale nie jest kuloodporne.


To pytanie i odpowiedź zostało automatycznie przetłumaczone z języka angielskiego.Oryginalna treść jest dostępna na stackexchange, za co dziękujemy za licencję cc by-sa 3.0, w ramach której jest rozpowszechniana.
Loading...