Co to znaczy uciec przed ciągiem?

85

Czytałem: Czy przed przejściem do zapytania SQL należy zastosować znak ucieczki $ _SESSION ['username']? i powiedział: „Musisz uciec przed każdym ciągiem przekazanym do zapytania sql, niezależnie od jego pochodzenia”. Teraz wiem, że coś takiego jest naprawdę podstawowe. Wyszukiwarka Google dała ponad 20 000 wyników. Sam Stackoverflow miał 20 stron wyników, ale nikt tak naprawdę nie wyjaśnia, czym jest ucieczka przed ciągiem znaków ani jak to zrobić. Po prostu zakłada się. Możesz mi pomóc? Chcę się uczyć, ponieważ jak zwykle tworzę aplikację internetową w PHP.

Patrzyłem na: Wstawianie znaków ucieczki , jakie są wszystkie znaki ucieczki w Javie? , Nie można uciec przed ciągiem za pomocą addcslashes () , Znak ucieczki , co naprawdę robi mysql_real_escape_string ()? , Jak uniknąć podwójnych cudzysłowów w ciągu znaków w php? , MySQL_real_escape_string nie dodaje ukośników? , usuń sekwencje ucieczki ze stringów w php Mógłbym kontynuować, ale jestem pewien, że rozumiesz. To nie jest lenistwo.

Brett
źródło
10
PS Mogłem po prostu zapytać przyjaciela i nie zrobić z siebie głupka, ale pomyślałem, że wiele osób takich jak ja będzie się zastanawiać, co to za rzecz, o której wszyscy mówią.
Brett

Odpowiedzi:

135

Unikanie łańcucha oznacza zmniejszenie niejednoznaczności w cudzysłowach (i innych znakach) używanych w tym ciągu. Na przykład, kiedy definiujesz ciąg, zazwyczaj umieszczasz go w podwójnych lub pojedynczych cudzysłowach:

"Hello World."

Ale co by było, gdyby mój ciąg zawierał podwójne cudzysłowy?

"Hello "World.""

Teraz mam dwuznaczność - interpreter nie wie, gdzie kończy się mój ciąg. Jeśli chcę zachować podwójne cudzysłowy, mam kilka opcji. Mógłbym użyć pojedynczych cudzysłowów wokół mojego ciągu:

'Hello "World."'

Lub mogę uciec od moich cytatów:

"Hello \"World.\""

Wszelkie cytat, który jest poprzedzony ukośnikiem jest uciekł , i rozumie się część wartości łańcucha.

Jeśli chodzi o zapytania, MySQL ma pewne słowa kluczowe, które obserwuje, a których nie możemy używać w naszych zapytaniach bez powodowania zamieszania. Załóżmy, że mamy tabelę wartości, w której kolumna nosi nazwę „Wybierz”, i chcieliśmy ją wybrać:

SELECT select FROM myTable

Wprowadziliśmy teraz pewne niejednoznaczności do naszego zapytania. W ramach naszego zapytania możemy zredukować tę niejednoznaczność za pomocą zwrotów wstecznych:

SELECT `select` FROM myTable

Eliminuje to zamieszanie, które wprowadziliśmy, kierując się złą oceną przy wyborze nazw pól.

Wiele z tych problemów można rozwiązać, po prostu przekazując swoje wartości mysql_real_escape_string(). W poniższym przykładzie widać, że przekazujemy dane przesłane przez użytkownika za pomocą tej funkcji, aby upewnić się, że nie spowoduje to żadnych problemów dla naszego zapytania:

// Query
$query = sprintf("SELECT * FROM users WHERE user='%s' AND password='%s'",
            mysql_real_escape_string($user),
            mysql_real_escape_string($password));

Inne metody istnieją dla uciekających ciągów, takich jak add_slashes, addcslashes, quotemeta, i więcej, chociaż przekonasz się, że gdy celem jest uruchomienie bezpiecznego zapytanie, przez duże i deweloperzy wolą mysql_real_escape_stringlub pg_escape_string(w kontekście PostgreSQL.

Sampson
źródło
6
Należy zauważyć, że wykonywanie funkcji ucieczki ciągów znaków w celu zwalczania problemów SQL Injection jest uważane za złą praktykę i może łatwo prowadzić do problemów z bezpieczeństwem, jeśli nie jest wykonywane prawidłowo (szczególnie w przypadku niektórych typów źle sformułowanych ataków wielobajtowych znaków). Z tego powodu nigdy nie używaj funkcji ucieczki ciągów i zamiast tego używaj sparametryzowanych zapytań sql lub procedur składowanych.
Cheekysoft
22

Niektóre znaki mają specjalne znaczenie dla używanej bazy danych SQL. Gdy te znaki są używane w zapytaniu, mogą powodować nieoczekiwane i / lub niezamierzone zachowanie, w tym umożliwienie atakującemu złamania zabezpieczeń bazy danych. Aby znaki te nie wpływały na zapytanie w ten sposób, że wymagają one zmiany znaczenia, lub mówiąc inaczej, należy poinstruować bazę danych, aby nie traktowała ich jako znaków specjalnych w tym zapytaniu.

W przypadku mysql_real_escape_string()jego ucieczki \x00, \n, \r, \, ', "i \x1ajako takie, kiedy nie uciekł, może spowodować wcześniej wspomniane problemy, które obejmuje SQL injection z bazą danych MySQL.

John Conde
źródło
1

Dla uproszczenia można w zasadzie wyobrazić sobie odwrotny ukośnik „\” jako polecenie dla interpretera w czasie wykonywania.

Na przykład przy interpretacji tego stwierdzenia:

$txt = "Hello world!";

w słownikowego etapu analizy (lub gdy podział w rachunku do poszczególnych znaczników), które z kolei są określone znaczniki $, txt, =, ", Hello world!, ", i;

Jednak ukośnik odwrotny w ciągu spowoduje dodatkowy zestaw tokenów i jest interpretowany jako polecenie zrobienia czegoś ze znakiem, który następuje bezpośrednio po nim: np.

$txt = "this \" is escaped";

Wyniki w następujących tokenów: $, txt, =, ", this, \, ", is escaped, ", i;

interpreter już wie (lub ma ustawione trasy, które może przyjąć), co zrobić w oparciu o postać, która zastąpiła \token. Więc w przypadku "tego kontynuuje traktowanie go jako znaku a nie jako polecenia końca łańcucha.

supi
źródło