Chciałbym mieć funkcję zachowującą się jak mysql_real_escape_string bez łączenia się z bazą danych, ponieważ czasami potrzebuję przeprowadzić suche testy bez połączenia z bazą danych. mysql_escape_string jest przestarzałe i dlatego jest niepożądane. Niektóre z moich ustaleń:
http://www.gamedev.net/community/forums/topic.asp?topic_id=448909
Odpowiedzi:
Nie można bezpiecznie uciec z łańcucha bez połączenia DB.
mysql_real_escape_string()
a przygotowane instrukcje wymagają połączenia z bazą danych, aby mogły uciec z ciągu przy użyciu odpowiedniego zestawu znaków - w przeciwnym razie ataki SQL injection są nadal możliwe przy użyciu znaków wielobajtowych.Jeśli tylko testujesz , możesz równie dobrze użyć
mysql_escape_string()
, nie jest to w 100% gwarantowane przed atakami iniekcji SQL, ale nie można zbudować nic bezpieczniejszego bez połączenia z bazą danych.źródło
mysql_escape_string
bez połączenia (wciąż próbuje dowiedzieć się, dlaczego). Ponieważ ta funkcja jest przestarzała, zastanawiam się tylko, jak ją zastąpić. Z pewnością wydaje się rozsądne, że można określić „odpowiedni zestaw znaków” w dowolnej funkcji, która go zastępuje, bez otwierania połączenia.Cóż, zgodnie ze stroną referencyjną funkcji mysql_real_escape_string : „mysql_real_escape_string () wywołuje funkcję biblioteczną MySQL mysql_real_escape_string, która wymyka następujące znaki: \ x00, \ n, \ r, \, '," i \ x1a. "
Mając to na uwadze, funkcja podana w drugim opublikowanym linku powinna zrobić dokładnie to, czego potrzebujesz:
function mres($value) { $search = array("\\", "\x00", "\n", "\r", "'", '"', "\x1a"); $replace = array("\\\\","\\0","\\n", "\\r", "\'", '\"', "\\Z"); return str_replace($search, $replace, $value); }
źródło
mb_strpos()
(imb_substr()
tworzyć zachowanie podobne dosubstr_replace()
), aby to zrobić?W przeciwieństwie do mojej innej odpowiedzi, ta następująca funkcja jest prawdopodobnie bezpieczna, nawet w przypadku znaków wielobajtowych.
// replace any non-ascii character with its hex code. function escape($value) { $return = ''; for($i = 0; $i < strlen($value); ++$i) { $char = $value[$i]; $ord = ord($char); if($char !== "'" && $char !== "\"" && $char !== '\\' && $ord >= 32 && $ord <= 126) $return .= $char; else $return .= '\\x' . dechex($ord); } return $return; }
Mam nadzieję, że ktoś bardziej obeznany ode mnie może mi powiedzieć, dlaczego powyższy kod nie zadziała ...
źródło
Z dalszych badań odkryłem:
http://dev.mysql.com/doc/refman/5.1/en/news-5-1-11.html
Poprawka bezpieczeństwa:
W przetwarzaniu kodowania wielobajtowego wykryto lukę w zabezpieczeniach typu SQL-injection. Błąd znajdował się na serwerze, niepoprawnie analizując ciąg znaków uciekających za pomocą funkcji API mysql_real_escape_string () C.
Luka ta została odkryta i zgłoszona przez Josha Berkusa i Toma Lane'a w ramach międzyprojektowej współpracy konsorcjum OSDB w zakresie bezpieczeństwa. Więcej informacji na temat wstrzykiwania SQL można znaleźć w poniższym tekście.
Dyskusja. Znaleziono lukę w zabezpieczeniach iniekcji SQL w przetwarzaniu kodowania wielobajtowego. Luka w zabezpieczeniach typu SQL injection może obejmować sytuację, w której użytkownik podał dane do wstawienia do bazy danych, może wprowadzić instrukcje SQL do danych, które wykona serwer. W odniesieniu do tej luki, gdy używane jest uciekanie się z niewiadomym zestawem znaków (na przykład addlashes () w PHP), możliwe jest obejście tego znaku w niektórych zestawach znaków wielobajtowych (na przykład SJIS, BIG5 i GBK). W rezultacie funkcja taka jak addlashes () nie jest w stanie zapobiec atakom typu SQL-injection. Nie można tego naprawić po stronie serwera. Najlepszym rozwiązaniem jest używanie przez aplikacje funkcji ucieczki uwzględniającej zestaw znaków, oferowanej przez funkcję taką jak mysql_real_escape_string ().
Jednak wykryto błąd w sposobie, w jaki serwer MySQL analizuje dane wyjściowe mysql_real_escape_string (). W rezultacie, nawet jeśli użyto funkcji mysql_real_escape_string () obsługującej zestaw znaków, możliwe było wstrzyknięcie SQL. Ten błąd został naprawiony.
Obejścia. Jeśli nie możesz zaktualizować MySQL do wersji, która zawiera poprawkę błędu w analizie mysql_real_escape_string (), ale uruchomisz MySQL 5.0.1 lub nowszą, możesz użyć trybu SQL NO_BACKSLASH_ESCAPES jako obejścia. (Ten tryb został wprowadzony w MySQL 5.0.1.) NO_BACKSLASH_ESCAPES włącza tryb zgodności ze standardem SQL, w którym ukośnik odwrotny nie jest traktowany jako znak specjalny. W rezultacie zapytania będą kończyć się niepowodzeniem.
Aby ustawić ten tryb dla bieżącego połączenia, wprowadź następującą instrukcję SQL:
SET sql_mode='NO_BACKSLASH_ESCAPES';
Możesz także ustawić tryb globalnie dla wszystkich klientów:
SET GLOBAL sql_mode='NO_BACKSLASH_ESCAPES';
Ten tryb SQL można również włączyć automatycznie podczas uruchamiania serwera, używając opcji wiersza poleceń --sql-mode = NO_BACKSLASH_ESCAPES lub ustawiając sql-mode = NO_BACKSLASH_ESCAPES w pliku opcji serwera (na przykład my.cnf lub my.ini w zależności od systemu). (Błąd nr 8378, CVE-2006-2753)
Zobacz także Bug # 8303.
źródło
NO_BACKSLASH_ESCAPES
inne luki w zabezpieczeniach .