Pytanie Wady mysql_real_escape_string?


Widziałem kilka osób tutaj, że łączenie zapytań za pomocą mysql_real_escape_string nie ochroni Cię (całkowicie) przed atakami SQL injection.

Jednak nie widzę jeszcze przykładu danych wejściowych ilustrujących atak mysql_real_escape_string nie chroniłoby cię. Większość przykładów o tym zapomina mysql_query ogranicza się do jednego zapytania i użycia mysql_real_escape_string nieprawidłowo.

Jedyny przykład, jaki mogę wymyślić, to:

mysql_query('DELETE FROM users WHERE user_id = '.mysql_real_escape_string($input));

Nie chroniłoby Cię to przed wprowadzeniem następujących danych:

5 OR 1=1

Uznałbym to za nieprawidłowe użycie mysql_real_escape_string zamiast niedociągnięć jest przeznaczony dla łańcuchów, a nie wartości numerycznych. Powinieneś albo rzucić na numeryczny typ, albo jeśli zamierzasz traktować dane wejściowe jako ciąg podczas dezynfekcji, powinieneś zrobić to samo w zapytaniu i zawijać wokół niego cudzysłowy.

Czy ktoś może podać przykład danych wejściowych, które mogą ominąć? mysql_real_escape_string to nie polega na niewłaściwym posługiwaniu się wartościami liczbowymi lub o tym zapomina mysql_query może wykonać tylko jedno zapytanie?

Edycja: interesują mnie ograniczenia mysql_real_escape_string i nie porównując go do alternatyw, zdaję sobie sprawę, że są lepsze opcje dla nowych projektów i nie kwestionuję tego.


12
2017-10-03 07:02


pochodzenie


To pytanie jest przestarzałe. Po co szukać rozwiązań mysql_* kiedy masz dobre alternatywy? - Mihai Iorga
To jest świetne pytanie. Widziałem już ten sam FUD kilka razy bez żadnej konkretnej kopii zapasowej, która nie była oparta na niewłaściwym użyciu. Niezależnie od tego, że nie powinieneś używać mysql_ na początku, chciałbym zobaczyć odpowiedź na to pytanie. - deceze♦
Mihai, nie przeczę, że istnieją lepsze alternatywy, takie jak PDO, to nie jest kwestia tego pytania. - Mitch Satchwell
"Widziałem tu kilka osób ... Czy próbowałeś zapytać tych ludzi? Dobre pytanie - NullUserException
Ta funkcja nie uwalnia wartości procentowej i podkreślenia (%_), które są znakami wieloznacznymi w LIKE. Czy to się liczy jako wada? - NullUserException


Odpowiedzi:


Głównym mankamentem mysql_real_escape_stringlub, ogólnie mówiąc, rozszerzenie mysql_, jest trudniejsze do poprawnego zastosowania niż inne, bardziej nowoczesne interfejsy API, w szczególności przygotowane instrukcje. mysql_real_escape_string ma być użyty dokładnie w jednym przypadku: ucieczka treści tekstowej, która jest używana jako wartość w zapytaniu SQL między cudzysłowami. Na przykład.:

$value = mysql_real_escape_string($value, $link);
$sql = "... `foo` = '$value' ...";
                     ^^^^^^

mysql_real_escape_string upewnia się, że $value w powyższym kontekście nie zepsuć składni SQL. To nie działa tak, jak myślisz tutaj:

$sql = "... `foo` = $value ...";

lub tu:

$sql = "... `$value` ...";

lub tu:

$sql = mysql_real_escape_string("... `foo` = '$value' ...");

Jeśli zostanie zastosowany do wartości, które są używane w dowolnym kontekście innym niż ciąg znaków w instrukcji SQL, jest niewłaściwie zastosowany i może lub nie może zepsuć wynikowej składni i / lub pozwolić komuś przekazać wartości, które mogą umożliwić ataki SQL injection. Przypadek użycia mysql_real_escape_string jest bardzo wąski, ale rzadko jest właściwie rozumiany.

Innym sposobem, aby dostać się do ciepłej wody przy użyciu mysql_real_escape_string jest po ustawieniu kodowania połączenia z bazą danych przy użyciu niewłaściwej metody. Powinieneś to zrobić:

mysql_set_charset('utf8', $link);

ty mogą rób tak również:

mysql_query("SET NAMES 'utf8'", $link);

Problem polega na tym, że ten ostatni omija interfejs API mysql_, który wciąż uważa, że ​​rozmawiasz z bazą danych za pomocą latin1 (albo coś innego). Podczas używania mysql_real_escape_string teraz przyjmie błędne kodowanie znaków i ciągi znaków ewakuacyjnych inaczej niż baza danych zinterpretuje je później. Uruchamiając SET NAMES zapytanie, utworzyłeś rozłam między tym, jak API mysql_ traktuje łańcuchy i jak baza danych zinterpretuje te łańcuchy. Może to być użyte do ataków iniekcyjnych w pewnych sytuacjach wielobajtowych.

Nie ma żadnych podatności na podstawowe iniekcje w mysql_real_escape_string które znam jeśli jest prawidłowo zastosowany. Znowu jednak główny problem polega na tym, że jest on niezwykle łatwy w użyciu, co otwiera luki w zabezpieczeniach.


6
2017-10-04 04:40



Dziękuję deceze, wydaje się, że roszczenia tutaj mysql_real_escape_string Otwarcie na wtrysk działa tylko wtedy, gdy jest niewłaściwie używane. Przyjmuję to jako odpowiedź. - Mitch Satchwell
Zobacz też Dodatkowa luka w zabezpieczeniach podczas używania NO_BACKSLASH_ESCAPES. - eggyal


Ok, więc oprócz mysql_* będąc przestarzałym, rozumiem, że tego chcesz wiedzieć o możliwym obejściu, które może istnieć. może ten wpis na blogu a slajdy mogą ujawnić niektóre z nich.
Ale jako to starsze pytanie tutaj pokazuje, casting i cytowanie nie jest pełnym dowodem. Po prostu Tyle rzeczy, które mogą być złei prawo Murphy'ego, połączone z tą zawsze aktualną mantrą "Nigdy nie ufaj sieci", pójdzie okropnie źle.

Być może Ten artykuł, ale najważniejsze, działania następcze w związku z tym artykułem może ujawnić jeszcze więcej problemów związanych z bezpieczeństwem. Szczerze mówiąc, wiem mysql_real_escape_string nie jest w pełni odporne, nawet w połączeniu z formatami odlewania i ciągami znaków:

printf('WHERE id = \'%d\'',(int)mysql_real_escape_string($_REQUEST['id']));

nie obejmuje każdego możliwego ataku.
Nie jestem ekspertem w tej sprawie, ale mogę ci powiedzieć, że oczyszcza każdy wkład, woli, jeśli w ogóle, da ci FAŁSZYWY poczucie bezpieczeństwa. Przez większość czasu wiesz (początkowo) co i dlaczego oraz jak chronisz się przed atakami, ale twoi koledzy mogą tego nie robić. Mogą coś zapomnieć, a cały twój system jest zagrożony.

Podsumowując: Tak, możesz temu zapobiec każda forma złośliwego wejścia od uzyskania dostępu do bazy danych, ale każda dodatkowa czynność, której wymaga, jest dodatkowym ryzykiem. W tym scenariuszu największą odpowiedzialnością (jak zawsze) jest deweloper, który nie miał czwartej filiżanki kawy w poniedziałkowy poranek. Żaden kod, bez względu na to, jak defensywny i dobrze przemyślany, może uchronić się przed potworem, który jest zmęczonym deweloperem o złym usposobieniu, wychodząc z zimnego indyka na kofeinę i nikotynę.


0
2017-10-03 07:39



W jaki sposób dokładnie wykorzystasz fragment kodu, który pokazujesz? Pytanie (i ja) prosi o konkretny, praktyczny przykład. - deceze♦
Pierwsze dwa odnośniki, do których się odwołujesz, to klasyczne ataki za pomocą niewłaściwej aplikacji, trzecie stany parzyste "Aby uniknąć tego rodzaju luki, użyj mysql_real_escape_string() [...] ". Uznałbym to za kolejną nie-odpowiedź. - deceze♦
@deceze: w sobie, opublikowany fragment kodu nie może być wykorzystywany, AFAIK, ale może generować błędy i pf z kiepskimi intencjami, takimi jak dobry stos wywołań podczas badania luk. Jest także całkiem prawdopodobne, że będziesz używał więcej niż 1 parametru w WHERE klauzula, z której każda wymaga trzech dodatkowych operacji (format ciągu, typ rzutowania i wywołania ewakuacyjnego), więc takie podejście jest podatne na błędy (otrzymaj błędną obsadę lub element zastępczy i nie jest już bezpieczny). W pytaniu, które również łączyłem, podnoszona jest również kwestia sortowania, której mój fragment w ogóle nie dotyczy - Elias Van Ootegem
Najlepsze, o czym można wspomnieć w tych artykułach, to dobrze znana nieprawidłowa aplikacja problemu GBK / charset. To znaczy. kiedy znajdziesz się w sytuacji, w której mysql_real_escape_string zakłada inny zestaw znaków podczas wykonywania swojej pracy niż baza danych. Można tego łatwo uniknąć, używając mysql_ API, aby zmienić zestaw znaków zamiast ominąć go za pomocą a SET NAMES pytanie. Zgadzam się, że jest to wada interfejsu API, ale w rzeczywistości nie jest to usterka _real_escape_string. Interfejs API mysql_ może być trudniejszy do zastosowania niż PDO, ale jeszcze nie widzę fundamentalny luka w nim. - deceze♦
@deceze: Zgadzam się z tobą, nie powiem, że istnieje podstawowa luka w zabezpieczeniach rozbudowa. Dlatego podsumowałem, mówiąc, że największą odpowiedzialność spoczywa na programistach, ponieważ jest o wiele więcej rzeczy one muszą rozważyć w danej chwili. - Elias Van Ootegem