Хм... А как вообще с этим Null Byte борятся? А вообще имя файла я хотел формировать не зависимо от того, какое оно было у пользователя. Просто проверка типа файла нужна, чтобы потом файлу присвоить аналогичный тип. Ну вроде того: PHP: <?php ... ... $file_ext = explode(".", $userfilename); $num_parts = count($file_ext); switch($file_ext[($num_parts - 1)]) { case "jpg": $ext = "jpg"; break; case "jpeg": $ext = "jpg"; break; case "gif": $ext = "gif"; break; default: echo "Тип загружаемого файла должен быть ..."; break; } # Проверяем сколько записано файлов в каталог # и присваиваем это число переменной $numfiles $newfilename = "photo-" . ($numfiles + 1) . $ext; # сохраняем файл с именем $newfilename ... ... ?> Я так понимаю, что в этом случае если то файл всё равно сохранится как photo-xxx.jpg ?
Вот, чтобы собрать наконец-то "в кучку" то что прочитал, хочу спросить. Допустим я получаю в массиве $_GET (или $_POST) что-то от пользователя. PHP: <?php $page_num = $_GET['page']; $name = $_GET['name']; $search_word = $_GET['word']; ?> Что необходимо и достаточно сделать с переменными $page_num (д.б. числового типа), $name (д.б. строкового типа) и $search_word (может быть любого типа, смотря что пользователь искать вздумает, вдруг число), чтобы без опаски делать SQL - запросы к базе, в которых будут эти переменные (или одна какая-то)? (ну, например: PHP: <?php $sql = "SELECT post, post_date, poster_name FROM posts WHERE post LIKE '%" . $search_word . "%'"; ?> Какой посоветуете минимальный и достаточный набор функций для обработки трёх вышепредставленных переменных?
sobachnik PHP: <? $page_num = isset($_GET['page']) ? intval($_GET['page']) : 1; $name = isset($_GET['name']) ? mysql_real_escape_string($_GET['name']) : null; $search_word = isset($_GET['word']) ? mysql_real_escape_string($_GET['word']) : null; ?> Ещё и не забывать про Magic Quotes. http://ru2.php.net/manual/ru/security.magicquotes.php http://php.net/mysql_real_escape_string http://php.net/intval
Mete0 С числами не всё так просто *** intval неправильно обработает числа выше 2^31 (~2млрд) *** intval пропустит отрицательное значение (в случаях с вставкой его в LIMIT и включенными error_reporting) мы получаем уязвимость раскрытия пути Так что проверять (кроме isset) пожалуй лучше is_numeric (вместо intval) и ещё и потом на отрицательность Со строками аналогично не всё так просто. Для начала надо проверить не пустая ли строка пришла, или например не пришли ли только пробелы, опять-же как и было сказано Magic Quotes, короче РНР штука "зверская" Вот примерный разврат который реально стоило бы использовать. PHP: <?php $page_num = 1; if (isset($_GET['page'])) { if (is_numeric($_GET['page'])) { if ($_GET['page'] > 0) { $page_num = $_GET['page']; } } } $name = null; // аналогично и с search_word if (isset($_GET['name'])) { if ('' != trim($_GET['name'])) { if (get_magic_quotes_gpc()) { $_GET['name'] = stripslashes($_GET['name']); } // чуть главное не забыл :) $name = mysql_real_escape_string($_GET['name']); } } ?> Кстати недавно так-же был прикол, выяснилось что "красивее" использовать array_key_exists('page', $_GET) вместо isset($_GET['page']) но это важно только для извращенцев (типа меня)
Про intval. На 32-х битной платформе да, в связи с тем что integer в php знаковый (signed), потому и от -2147483648 to 2147483647. На 64-х разрядной платформе обрабатывает нормально, ну не суть. Особого смысла проверять на то что число является отрицательным я не вижу. Про строки. Можно и добавить проверок, я не стал расписывать очевидные вещи, хотя для автора они могут таковыми не являться.
"не вижу" и "нету" вещи немного разные, поищи как местные админы над интернет магазинами прикалывались, ссылку не даю, лень искать. Увы Попов тоже мало чего описал, итоги на лицо Вопрос всё-же был про
Могут понадобится отрицательные значения. Более того, он еще любитель конструкций типа do {} while там где им не место, printf'ов и прочей ерунды. Вот только не надо меня к нему приравнивать
По этому я и написал про LIMIT да и рассматриваем мы $page_num (как раз тот случай) Не приравниваю, вам до него ещё как до луны пешком
Да, что-то я оплошал Если рассматривать конкретно лимит то конечно отрицательные значения не нужны Чем дальше от него, тем лучше
Спасибо Вам большое!!! Да-да, вопрос был именно про минимальный и достаточный набор функций, я даже жирным выделил это сразу! В Вашем ответе хочется увидеть именно всё, что нужно сделать, но чтобы и лишнего не было. Просто я вот решил посмотреть, что в phpbb делается с пользовательскими данными перед отправкой sql-запроса. Сперва немного помучался с поиском, потом нашёл, офигел и написал тут свой вопрос. В phpbb (применительно к $username) это выглядело так: PHP: <?php ... ... ... $username = isset($HTTP_POST_VARS['username']) ? phpbb_clean_username($HTTP_POST_VARS['username']) : ''; $sql = "SELECT user_id, username, user_password, user_active, user_level, user_login_tries, user_last_login_try FROM " . USERS_TABLE . " WHERE username = '" . str_replace("\\'", "''", $username) . "'"; ... ... ... function phpbb_clean_username($username) { $username = substr(htmlspecialchars(str_replace("\'", "'", trim($username))), 0, 25); $username = phpbb_rtrim($username, "\\"); $username = str_replace("'", "\'", $username); return $username; } function phpbb_rtrim($str, $charlist = false) { if ($charlist === false) { return rtrim($str); } $php_version = explode('.', PHP_VERSION); // php version < 4.1.0 if ((int) $php_version[0] < 4 || ((int) $php_version[0] == 4 && (int) $php_version[1] < 1)) { while ($str{strlen($str)-1} == $charlist) { $str = substr($str, 0, strlen($str)-1); } } else { $str = rtrim($str, $charlist); } return $str; } Тута :roll: ничего лишнего..?
Не лучший пример для подражания... Короче лучше прочитать http://phpfaq.ru/slashes так как с числами в LIMIT это одни танцы, с обычными цифрами другие, с текстом третьи, а уж с LIKE и вовсе отдельные...
Vladson Кстати в твоём примере есть "бага". Если пользователь сделает вот так: ?name[]=bug, то получим нотис вида: Notice: Array to string conversion. Я бы ещё добавил проверку is_array(), например так: PHP: <? $name = null; if (isset($_GET['name'])) if (!is_array($_GET['name'])) if (trim($_GET['name']) != '') $name = mysql_real_escape_string($_GET['name']); ?> А с Magic quotes поступил бы так: PHP: <? if (get_magic_quotes_gpc()) { function stripslashes_deep($value) { $value = is_array($value) ? array_map('stripslashes_deep', $value) : stripslashes($value); return $value; } $_POST = array_map('stripslashes_deep', $_POST); $_GET = array_map('stripslashes_deep', $_GET); $_COOKIE = array_map('stripslashes_deep', $_COOKIE); $_REQUEST = array_map('stripslashes_deep', $_REQUEST); } ?> Где-нибудь в начале...
Лучше не is_array а is_string (нам кроме стрингов ничего не надо, и то что кроме стрингов в гетах могут быть только массивы это справедливо только для тех версий что существуют сейчас, но нет гарантий что это не изменится к 99-й версии)
Собственно, на самом деле в GET в любом случае передается строка, просто строку определенного формата, полученую GET или POST, PHP преобразовывает в массив. Поэтому is_string правильнее.
Спасибо всем за отклики!!! Вот хочу ещё поинтересоваться. Тут недавно говорили про так называемый null-byte. Если честно, я толком так и не понял, что это вообще и как хакер может вставить его в запрос, но сейчас не об этом. Приведённого выше Вашего примера достаточно, чтобы обезопасить свой скрипт и от этого null-byte? Функция mysql_real_escape_string() его умеет обрабатывать правильно? Не подкините (кто знает) статейку, где рассказывается про null-byte достаточно просто и подробно?
1 - обычный символ, просто которого нет на клавиатуре 2 - Вот так http://php.ru/forum/viewtopic.php?t=%00
sobachnik в другой теме я давал ссылку (можно в инете и самому поискать ). емнип: выросла такая атака давно-давно еще из C (а PHP это оно, в частности). конструкции форматинга в sprintf (и не только) имели слабость в том, что могло быть переполнение буфера как раз через null-byte. Соответственно записывая бинарные инструкции (после нуллбайта) 'интерпретатору' можно было вставлять свой кусочек EXE (так понятнее). Ну, что вспомнил, рассказал (это конечно одно ИЗ и весьма условно рассказаное).
флоппик Ага, сейчас переведу себе на счёт все деньги БГ (и я не имею в виду Бориса Гребенщикова) Йа мега хацкер, все меня бойтесь
Ошибкой в некоторых скриптах является отсутствие проверки имён форм. Сами данные проверяются, а название форм -- нет. И они подставляются сразу в базу. Еще одной ошибкой является отсутствие проверки SELECT-формы. Я запросто могу подставить вместо 1го числа -1ое...
А если бабахнуть проверку Яваскриптами (на корректное заполнение полей) а в начале страницы поставить. <?php $referer=getenv("HTTP_REFERER"); if (!ereg("www......")) { echo "Меня типо хакают\n"; exit; } ?> толк есть?
Нет. От любой проверки яваскриптами есть только один толк - удобство пользователя, которому не надо ждать релоада чтобы узнать что он неправильно заполнил поле. На безопасность это не влияет вообще.