Привет всем! Есть функция редактирования статьи по ее int id public function edit($id='') { $safe_id = (int)$id; if ($id!=$safe_id) { echo 'неверный номер статьи '; return false; } echo 'все верно'; // ... и далее выполняется код'; } если $id = '123n456'; получаем переменные - $id: 123n456 strlen:7 var_dump: string(7) "123m456" $safe_id:123 strlen:3 var_dump: int(123) т.е. $id точно не равно $safe_id но при этом результат 'все верно' Не могу понять где грабли в if ( $id != $safe_id) { почему в данном примере $id == $safe_id
Излишне сложно. Просто преобразуйте получаемый параметр в тип int/ Например так PHP: if(isset($_GET['id'])) $id = sprintf('%d', $_GET['id']);
Вот что делаешь PHP: $id = '1'; $id != $id; // ой забыл еще ( int ) для красоты --- Добавлено --- используй строгое сравнение PHP: !== --- Добавлено --- @Drunkenmunky, не надо преобразовывать ничего https://www.php.net/manual/ru/function.filter-var.php с FILTER_VALIDATE_INT --- Добавлено --- @Drunkenmunky кстати, а потом $id ты проверяешь на существование ?
Зачем? Явно задаем ноль. Потом проверяем глобальный массив и преобразовываем полученное. Полторы строчки. - просто, понятно, надежно, безопасно. PHP: $id = 0; if(isset($_GET['id'])) $id = sprintf('%d', $_GET['id']);
Строгое сравнение тут не поможет, т.к. разные типы. id = string а safe_id = int и всегда будет фальш Пока ждал модерацию, читал мануалы, получилось что если php 7 сравнивает строку и число, то он строку приводит к числу, а потом сравнивает 2 числа. и тогда получается что 123 == '123n234' это (true) и будет дыра. можете проверить а если я указал if ($id != (string)$safe_id) { то сравнение идет символьное, т.к. сравниваются 2 строки
Если присмотритесь к моему первому(уточняю - в этом топике, #3) сообщению, то заметите "например так". Когда так говорят, обычно имеют в виду, что есть и другие варианты. Дескать, если заинтересует, то прикинь всякое к носу.
Я вообще такими вещами не занимаюсь. Такие id обычно идут в запросы базы, запросы нормальные люди делают через подготовленные выражения, если кто-то вставит что-то плохое, база просто поищет у себя пост с айди Код (Text): ' union delete from users; Его там не будет, и мы со спокойной душой выдадим 404-ю. Преобразование в int обычно используется, когда запросы собираются конкатенацией, а не через подготовленные выражения. Например, OpenCart этим грешит - там все запросы безопасные, но собраны конкатенацией и явным экранированием, там где предполагается строка, и явным преобразованием в int там, где предполагается число. Но, при всём уважении к этому классному движку, его код - это образец, как делать не надо, хотя всё и работает.