В разрезе фетишизма написал пост, но сюда он тоже подходит http://php.ru/forum/viewtopic.php?p=124494#124494
Нашёл тут в мануале по mysql_real_escape_string примерчик и сделал, как в нём. PHP: <?php function quote_smart($value) { // если magic_quotes_gpc включена - используем stripslashes if (get_magic_quotes_gpc()) { $value = stripslashes($value); } // Если переменная - число, то экранировать её не нужно // если нет - то окружем её кавычками, и экранируем if (!is_numeric($value)) { $value = "'" . mysql_real_escape_string($value) . "'"; } return $value; } ?> PHP: <?php $query = sprintf("SELECT * FROM `recipe_table` WHERE `recipeStatus`='SHOWN' AND `recipeID`=%s", quote_smart($recipe)); $reciperesult=mysql_query($query, $lnk); ?> Какие-нибудь комментарии есть по этому коду? Вполне надёжен?
Понатыкают тут sprintf, а потом выясняется что это тормоз и на его вырезании можно съекономить довольно много процессорного времени. Чем обычная конкатенция не угодила, особенно в данном случае, а SkyKiller?
есть, использовать лучше этот mysql_query("SELECT * FROM `recipe_table` WHERE `recipeStatus`='SHOWN' AND `recipeID`='".mysql_real_escape_string($value)."'");
Mr.M.I.T., хороший вариант. Гораздо лучше, чем вариант с sprintf. Тем более, что $value встречается всего один раз в запросе. Спасибо. Вариант с sprintf заремил.
Вот вам ещё вариантик (но это уже не для чисел а для слов) безопаснее ну просто вааще некуда (из разряда реально х№% сломаешь) PHP: <?php mysql_query('SELECT * FROM `table` WHERE `word` = 0x' . bin2hex($_GET['word'])); ?>
Ты не внимательно смотришь, запрос в шестнадцатиричном но запрашивает он вполне обычно (не надо путать то что мы пихаем в запрос, и то что мы ищем) Пояснение для новичков: "Следующие два запроса абсолютно одинаковы, и вернут одинаковый результат!" [sql]SELECT * FROM `table` WHERE `word` = 0x566C6164736F6E;[/sql] [sql]SELECT * FROM `table` WHERE `word` = 'Vladson';[/sql]
Теперь, уважаемые господа, возник вопрос по обработке данных, получаемых из форм ввода (INPUT и TEXTAREA). Я обрабатываю их следующим образом: PHP: <?php // Принудительно обрезаем введённую строку до приемлемой длины $tmpvar = @substr($_POST["recipetitle"],0,60); // Удаляем из неё потенциально опасный код и другой "мусор" $recipetitle = htmlspecialchars(stripslashes($tmpvar), ENT_NOQUOTES); ?> Правильно ли (с точки зрения безопасности и защиты от XSS) я делаю? Спасибо!
Нет, правильно так: PHP: <?php // Принудительно обрезаем введённую строку до приемлемой длины $_POST['recipetitle'] = isset($_POST['recipetitle']) ? substr($_POST["recipetitle"],0,60) : null; // Удаляем лишние слеши, если включены magic_quotes_gpc $recipetitle = get_magic_quotes_gpc() ? stripslashes($_POST["recipetitle"]) : $_POST['recipetitle']; // Подготавливаем строку к записи в БД $recipetitle = mysql_real_escape_string($recipetitle); .... // Ну и собственно для защиты от XSS ПРИ ВЫВОДЕ В HTML обрабатываем строку: $recipetitle = htmlspecialchars($recipetitle); ?>
SkyKiller Для всего массива: PHP: <?php function stripslashes_array ($var) { foreach ($var as $key=>$value){ if(is_array($value)){ //На случай вложеного массива $value=StripslashesArray(&$value); } else { $value=stripslashes($value); } $var[$key]=$value; } return $var; } $_POST = get_magic_quotes_gpc() ? stripslashes_array($_POST) : $_POST;
[vs] PHP: <?php function Strips(&$arr) { if (is_array($arr)) foreach($arr as $k=>$v) Strips($arr[$k]); else $arr = stripslashes($arr); } ?> так короче
В-общем, для верности я обрабатываю функцией htmlspecialchars все данные, которые выводятся в браузер с помощью echo или ей подобными...
Я так как являюсь чаще всего и кодером и верстальщиком одновременно делаю это уже в шаблоне, чтоб не путать данные, данные идущие на страничку и данные отсылаемые на мыло или RSS (это всё разные форматы, но данные одни и теже) PHP: <?while($row = mysql_fetch_assoc($posts)):?> <p><i><?php echo $row['date'];?></i><br><?php echo text2html($row['text']);?></p><hr> <?endwhile?> (text2html это функция в целом htmlspecialchars+nl2br+trim, а в первом случае обработка не нужна так как дата хранится в базе сразу в нужном формате)
Само собой другой порядок, я просто перечислил, а не пересказал что и как. (на самом деле там даже nl2br нету потому что для HTML я юзаю не <br /> а просто <br>, а кроме этого ещё кучу примочек вплоть до обработки bbcode)
Меня интересует другой вопрос... Вот если я ВСЕ данные, которые выводятся через ECHO (неважно, каким образом они получены - из формы или непосредственное жесткое присваивание переменной в скрипте) буду обрабатывать через htmlspecialchars - грозит ли это критичной потерей производительности? Согласен, это будет ОЧЕНЬ надёжно, но я не хочу, чтобы у меня сервер встал колом, когда ко мне на сайт будет заходить 15-20 тысяч уников в сутки. Какие данные НЕОБХОДИМО обрабатывать, а какие - нет надобности? Хочется максимально защититься от злобных хацкеров-пионэров (и их XSS-гадостей) и, в тоже время, не потерять производительности... Вот, например: PHP: <?php // 1. Простое присваивание в скрипте. Переменная "b" НЕ берётся из базы или из формы ввода. Она определяется раньше в скрипте (например, $b = 3; ) $a = $b + 1; echo "<a href=\"/recipe/".$a."/\">".$a."</a>"; // htmlspecialchars or not? // 2. Переменная из GET-запроса. Получена из строки ввода. Обрезана до нужной длины. $a = $_GET['recipeID']; echo "<a href=\"/recipe/".$a."/\">".$a."</a>"; // htmlspecialchars or not? // 3. Переменная из MySQL-запроса. while($row=mysql_fetch_array($cooking)) { $a = $row['recipeID']; echo "<a href=\"/recipe/".$a."/\">".$a."</a>"; // htmlspecialchars or not? } ?> Какие из этих вариантов обрабатывать htmlspecialchars? Не хотелось бы выглядеть идиотом и параноиком, но меня очень беспокоит безопасность моего кода. Тем более, что на днях я запускаю проект, который (надеюсь) проживёт долго. И не хочу, чтобы его сломали в первый же день. Я, конечно, совершил большую глупость, что не озаботился этим раньше, на этапе написания кода. Теперь вот, на этапе отладки приходится шерстить весь код и править. В общем, буду рад любым правильным советам. Спасибо!
С точки зрения защиты от XSS, обрабатывать при выводе функцией htmlspecialchars следует все данные, полученые от клиента. Обрабатывать ВСЁ нет смысла. Не нужно обрабатывать переменные, значение которым присваивается в скрите. Обязательно надо отключать register_globals. Надо помнить, например, что User Agent или данные из куки - тоже полученые от пользователя данные, их тоже надо обрабатывать (при выводе, разумеется). Сама фнукция htmlspecialchars достаточно ресурсоёмкая.
C точки зрения здравого смысла, обрабатывать специальные символы HTML (htmlspecialchars) нужно только при отображении данных на HTML странице. Не надо. Достаточно писать так, как будто она отключена.
Ну я это и имел ввиду, речь как раз шла о выводе данных. Согласен, если писать правильно, то и со включеными скрипт будет безопасен. Но если они включены, такая допусиммая конструкция становится уязвимой: PHP: <?php if (....) { ... $var=1; } ...bla-bla-bla... if($var) { ....