SQL, klauzula LIKE i operatory

Pytania i problemy
brunoww22
brunoww22 Pionier

Zapytanie wygląda następująco: SELECT tools.nick FROM tools WHERE nick LIKE '%_%'

To wynik tego zapytania: image|325x112

Wiem, że znak podkreślenia obok procentu to operator LIKE, więc co zrobić aby nim nie był? Jeśli jest przy nim znak procentu.

Chcę, aby wynik powyższego zapytania wyglądał tak: image|325x61

Czyli, zapytanie z samym podkreślnikiem lub podreślnikami wyrzuca wszystko z bazy. Chcę, aby wyrzucało tylko te rekordy co faktycznie go zawierają.

Nieznajomy11
Nieznajomy11 Moderator forum.lvlup.pro

Escape character a.k.a. znak modyfikacji:

SELECT tools.nick FROM tools WHERE nick LIKE '%\_%'
brunoww22
brunoww22 Pionier

Tylko jak to tutaj teraz wrzucić, żeby zapytanie się nie wysypało? '% $search %'

Tak dokładnie wygląda zapytanie: SELECT tools.nick FROM tools WHERE nick LIKE '%" . $search . "%'"

Nieznajomy11
Nieznajomy11 Moderator forum.lvlup.pro

Nie powinieneś tak konstruować zapytania przede wszystkim, bo jest ono podatne na SQL Injection.

Bezpieczny przykład z PDO:

$search = "_";
 
$search = "%" . str_replace(['\\', '_', '%'], ['\\\\', '\\_', '\\%'], $search) . "%";
$sth = $pdo->prepare("SELECT tools.nick FROM tools WHERE nick LIKE :query");
$sth->bindParam(":query", $query, PDO::PARAM_STR);
$sth->execute();
 
// dalsze pobieranie z $sth
brunoww22
brunoww22 Pionier

Input jest zabezpieczony przed SQL Injection Da się wpisać tylko znaki: [a-zA-Z0-9_] oraz zapytanie tylko sie wykona gdy przejdzie przez mysqli_real_escape_string

Wydaje mi się, że owe zabezpieczenie jest dobre? Czy jestem w błędzie?

Nieznajomy11
Nieznajomy11 Moderator forum.lvlup.pro

Nadal nie zmienia to faktu, że korzystanie z metody mysqli_real_escape_string jest mocno nie na miejscu w 2020 i powinno się skorzystać z prepared statement gdziekolwiek przyjmujemy wejście od użytkownika, filtry zawodzą. To tylko czekanie na katastrofę, z nadzieją, że jednak może będzie ok.

brunoww22
brunoww22 Pionier

Rozumiem, ale jeśli są jedynie dozwolone znaki w inpucie to [a-zA-Z0-9_] chyba nie da się tego obejść. Czy się da? 😃

Nieznajomy11
Nieznajomy11 Moderator forum.lvlup.pro

Zakładając, że wszystko pójdzie ok i nie ma błędu gdzie indziej, to może tak. Tylko czy warto ryzykować, zamiast nauczyć się korzystać z lepszej metody pod każdym względem? Czytelniejszej, bezpieczniejszej, nowocześniejszej.

brunoww22
brunoww22 Pionier

Racja Edit: w inpucie znaki blokuję poprzez AJAX, po prostu nie da sie ich wpisac w inputa

Nieznajomy11
Nieznajomy11 Moderator forum.lvlup.pro

Już w dokumentacji (https://www.php.net/manual/en/mysqli.real-escape-string.php) można znaleźć notkę o dodatkowym składniku, na który trzeba uważać, żeby funkcja zapewniła bezpieczeństwo:

image|690x129

Taki problem nie występuje z prepared statement, to po prostu działa. 😎

brunoww22:

w inpucie znaki blokuję poprzez AJAX, po prostu nie da sie ich wpisac w inputa

Zakładanie, że użytkownik nie wyśle spreparowanego zapytania ręcznie, jest okropną metodą na bezpieczeństwo, to tylko pozorna ochrona.

brunoww22
brunoww22 Pionier

Nieznajomy11:

Zakładanie, że użytkownik nie wyśle spreparowanego zapytania ręcznie, jest okropną metodą na bezpieczeństwo, to tylko pozorna ochrona. Ano racja, tego nie wziąłem pod uwagę

system
system

Ten temat został automatycznie zamknięty 32 dni po ostatnim wpisie. Tworzenie nowych odpowiedzi nie jest już możliwe.