SQL, klauzula LIKE i operatory

brunoww22 | 2021-02-17 10:25:11 UTC | #1

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 | 2020-11-05 17:25:49 UTC | #2

Escape character a.k.a. znak modyfikacji:

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

brunoww22 | 2020-11-05 17:38:47 UTC | #3

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 | 2020-11-05 18:32:11 UTC | #4

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 | 2020-11-05 17:52:20 UTC | #5

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

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


Nieznajomy11 | 2020-11-05 17:51:27 UTC | #6

Nadal nie zmienia to faktu, że korzystanie z metody mysqlirealescape_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 | 2020-11-05 17:54:29 UTC | #7

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


Nieznajomy11 | 2020-11-05 17:54:42 UTC | #8

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 | 2020-11-05 17:57:30 UTC | #9

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


Nieznajomy11 | 2020-11-05 17:58:12 UTC | #10

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. :sunglasses:

[quote=”brunoww22, post:9, topic:16629”]
w inpucie znaki blokuję poprzez AJAX, po prostu nie da sie ich wpisac w inputa
[/quote]

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


brunoww22 | 2020-11-05 17:59:28 UTC | #11

[quote=”Nieznajomy11, post:10, topic:16629, full:true”]
Zakładanie, że użytkownik nie wyśle spreparowanego zapytania ręcznie, jest okropną metodą na bezpieczeństwo, to tylko pozorna ochrona.
[/quote]
Ano racja, tego nie wziąłem pod uwagę


system | 2021-02-17 10:31:42 UTC | #12

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