Категорически приветствую всех! 8) Составил следующий запрос: PHP: <?php $reciperesult = mysql_query('SELECT * FROM `recipe_table` WHERE `recipeStatus`="SHOWN" AND `recipeID`="'.$recipe.'"', $lnk); ?> recipeID - целочисленное положительное. Предварительно, перед этим переменная $recipe обрабатывается из GET-запроса следующей конструкцией: PHP: <?php $recipe = 0; // Если GET-параметру recipe присвоено значение, если оно не пустое и является числом - присвоить переменной $recipe значение этого параметра if ( isset($_GET['recipe']) ) { if ( !empty($_GET['recipe']) ) { if ( is_numeric($_GET['recipe']) ) { $recipe = $_GET['recipe']; } else { // Иначе присвоить переменной 0 $recipe = 0; } } } ?> Интересует мнение опытных гуру на предмет безопасности этой конструкции с точки зрения XSS- и SQL-инъекций, а также правильная расстановка кавычек. Прошу сильно не ругаться на предмет чтения манов и т.д. - маны по кавычкам читал и курил. Просто на днях запускаю проект в массы и последние 2-3 дня стал просто параноиком в плане безопасности и защиты от хака - уже каша в голове...
PHP: <?php // Проверяет целое число в диапазоне | start и stop обязательные параметры public static function int_range($num = NULL, $start = NULL, $stop = NULL) { if($start == NULL) trigger_error('Error. Class: XXX_VALID. Method: int_range(). Argument "start" was empty.', E_USER_ERROR); if($stop == NULL) trigger_error('Error. Class: XXX_VALID. Method: int_range(). Argument "stop" was empty.', E_USER_ERROR); if($num == NULL) { $ERROR->reg(self::$lang['valid']['int_range']['empty']); return false; } if(is_numeric($num) and !strstr($num, '.')) { if($num < $start) return false; if($num > $stop) return false; return true; } else { return false; } }
Имхо так немного короче.: PHP: <?php $recipe = !empty($_GET['recipe']) ? (int)$_GET['recipe'] : 0; ?> Но тот вариант вполне имеет право на жизнь... Впрочем, а если нам передадут очень очень большое число? Что тогда?
Hight, у него если число не является числом оно становиться нулем. У меня тоже, так в чем проблема? А про то что нужно перед записью еще и собственно "размер" числа проверить я написал.
Это ты меня озадачил... :roll: Хотя GET-параметр передаётся не из пользовательского ввода, а из предварительго скрипта (фиксированная ссылка), но ведь могут и подделать его, верно? Надо думать... Ограничение ввести, как Hight посоветовал
Вопрос заключается именно в безопасности этой конструкции. А защиту от дурака я сейчас буду дописывать.
PHP: <?php if (isset($_GET['recipe'])) { $query='SELECT * FROM `recipe_table` WHERE `recipeStatus`="SHOWN" AND `recipeID`="'.$_GET['recipe'].'"'.$lnk; $reciperesult=mysql_query(mysql_real_escape_string($query)); Защита 100%, и если recipe - не число, результат запроса, соответственно, будет пустым.
PHP: <?php $recipe = isset($_GET['recipe']) && is_numeric($_GET['recipe']) ? $_GET['recipe'] : 0; ?> или короче но неправильно (точнее почти правильно, но не до параноидального уровня) PHP: <?php $recipe = @is_numeric($_GET['recipe']) ? $_GET['recipe'] : 0; ?> Update: О ещё вариант (тоже рабочий и тоже с собакой) PHP: <?php $recipe = sprintf("%d", @$_GET['recipe']); ?>
Насчёт "@" меня терзают смутные сомнения (после прочтения соседнего топика) А вот уровень безопасности интересует именно параноидальный (насколько это возможно и не в ущерб производительности)
SkyKiller, ну вообще то когда уровень защиты дейтвительно паронаидальный, а тебя нужно хакнуть, то взламывают соседний сайт на этом же хостинге, а потом уже получают доступ к твоему
Одинаковый, параноидальность только как раз в собаке (юзать её теоретически нельзя, но с практической точки зрения в данном конкретном случае вреда будет не больше чем подорожание лимузинов на 5 копеек)
Hight, о_О. Даже сейчас проверил, на всякий случай, подумал что у меня помутнение сознания: PHP: <?php $a = 3.14; $a = (int)$a; // выводит 3 echo $a; $b = 3.14; $b = (float)$b; // выводит 3.14 echo $b; ?>
Hight, спасибо! Сейчас исправлю. Всем огромное спасибо за советы и помощь! Если можете ещё что-то посоветовать - велком! Если возникнут вопросы - тему подниму.
Hight не совсем так, скорее PHP: <?php mysql_query("SELECT * FROM `recipe_table` WHERE `recipeStatus`='SHOWN' AND `recipeID`=$recipe;", $lnk); ?>
Не надо ничего приводить. Надо проверять, а в случае некорректности значения присваивать значение по умолчанию. Целые числа отличаются от дробных наличием . точки. Ну можно 'x' поискать в строке.
SkyKiller Если переменная - целое число, то намного проще насильно привести ее к целому и подставлять в запрос безо всяких кавычек: PHP: <?php $recipe=(int)ifset($_GET['recipe']); // благодаря (int), $recipe теперь гарантированно целое mysql_query("SELECT ... recipeID=$recipe"); Функции ifset в языке нет, но она очень удобна, я ее определяю так: PHP: <?php function ifset(&$value, $default=false) { return isset($value)?$value:$default; }
Не не, у тебя всё норм, это я ещё не проснулся. Vladson Скорее так: гы гы =) Красиво подсветицо в редакторе.