За последние 24 часа нас посетили 17414 программистов и 1726 роботов. Сейчас ищут 1492 программиста ...

Правильно ли я предохраняюсь? :)

Тема в разделе "PHP для новичков", создана пользователем SkyKiller, 31 окт 2008.

  1. Vladson

    Vladson Старожил

    С нами с:
    4 фев 2006
    Сообщения:
    4.040
    Симпатии:
    26
    Адрес:
    Estonia, Tallinn
  2. SkyKiller

    SkyKiller Активный пользователь

    С нами с:
    1 ноя 2007
    Сообщения:
    166
    Симпатии:
    0
    Адрес:
    Новосибирск
    Нашёл тут в мануале по mysql_real_escape_string примерчик и сделал, как в нём.

    PHP:
    1. <?php
    2. function quote_smart($value)
    3. {
    4.     // если magic_quotes_gpc включена - используем stripslashes
    5.     if (get_magic_quotes_gpc()) {
    6.         $value = stripslashes($value);
    7.     }
    8.     // Если переменная - число, то экранировать её не нужно
    9.     // если нет - то окружем её кавычками, и экранируем
    10.     if (!is_numeric($value)) {
    11.         $value = "'" . mysql_real_escape_string($value) . "'";
    12.     }
    13.     return $value;
    14. }
    15. ?>
    16.  
    PHP:
    1. <?php
    2. $query = sprintf("SELECT * FROM `recipe_table` WHERE `recipeStatus`='SHOWN' AND `recipeID`=%s", quote_smart($recipe));
    3. $reciperesult=mysql_query($query, $lnk);
    4. ?>
    5.  
    Какие-нибудь комментарии есть по этому коду? Вполне надёжен?
     
  3. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    Понатыкают тут sprintf, а потом выясняется что это тормоз и на его вырезании можно съекономить довольно много процессорного времени. Чем обычная конкатенция не угодила, особенно в данном случае, а SkyKiller? :)
     
  4. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    есть,
    использовать лучше этот
    mysql_query("SELECT * FROM `recipe_table` WHERE `recipeStatus`='SHOWN' AND `recipeID`='".mysql_real_escape_string($value)."'");
     
  5. SkyKiller

    SkyKiller Активный пользователь

    С нами с:
    1 ноя 2007
    Сообщения:
    166
    Симпатии:
    0
    Адрес:
    Новосибирск
    А что же тогда sprintf в официальном мануале делает, если он тормозной? :)
     
  6. SkyKiller

    SkyKiller Активный пользователь

    С нами с:
    1 ноя 2007
    Сообщения:
    166
    Симпатии:
    0
    Адрес:
    Новосибирск
    Mr.M.I.T., хороший вариант. Гораздо лучше, чем вариант с sprintf. Тем более, что $value встречается всего один раз в запросе. Спасибо.
    Вариант с sprintf заремил.
     
  7. Vladson

    Vladson Старожил

    С нами с:
    4 фев 2006
    Сообщения:
    4.040
    Симпатии:
    26
    Адрес:
    Estonia, Tallinn
    Вот вам ещё вариантик (но это уже не для чисел а для слов) безопаснее ну просто вааще некуда (из разряда реально х№% сломаешь)
    PHP:
    1. <?php
    2. mysql_query('SELECT * FROM `table` WHERE `word` = 0x' . bin2hex($_GET['word']));
    3. ?>
     
  8. SkyKiller

    SkyKiller Активный пользователь

    С нами с:
    1 ноя 2007
    Сообщения:
    166
    Симпатии:
    0
    Адрес:
    Новосибирск
    То есть, в базе всё хранить в шестнадцатиричном варианте? :lol:
     
  9. Vladson

    Vladson Старожил

    С нами с:
    4 фев 2006
    Сообщения:
    4.040
    Симпатии:
    26
    Адрес:
    Estonia, Tallinn
    Ты не внимательно смотришь, запрос в шестнадцатиричном но запрашивает он вполне обычно (не надо путать то что мы пихаем в запрос, и то что мы ищем)

    Пояснение для новичков: "Следующие два запроса абсолютно одинаковы, и вернут одинаковый результат!"
    [sql]SELECT * FROM `table` WHERE `word` = 0x566C6164736F6E;[/sql]
    [sql]SELECT * FROM `table` WHERE `word` = 'Vladson';[/sql]
     
  10. SkyKiller

    SkyKiller Активный пользователь

    С нами с:
    1 ноя 2007
    Сообщения:
    166
    Симпатии:
    0
    Адрес:
    Новосибирск
    Всё равно, пока ещё не до конца въехал. Завтра на примере попробую проверить.
     
  11. SkyKiller

    SkyKiller Активный пользователь

    С нами с:
    1 ноя 2007
    Сообщения:
    166
    Симпатии:
    0
    Адрес:
    Новосибирск
    Теперь, уважаемые господа, возник вопрос по обработке данных, получаемых из форм ввода (INPUT и TEXTAREA).
    Я обрабатываю их следующим образом:

    PHP:
    1. <?php
    2. // Принудительно обрезаем введённую строку до приемлемой длины
    3. $tmpvar = @substr($_POST["recipetitle"],0,60);
    4. // Удаляем из неё потенциально опасный код и другой "мусор"
    5. $recipetitle = htmlspecialchars(stripslashes($tmpvar), ENT_NOQUOTES);
    6. ?>
    Правильно ли (с точки зрения безопасности и защиты от XSS) я делаю?
    Спасибо!
     
  12. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    Нет, правильно так:
    PHP:
    1. <?php
    2. // Принудительно обрезаем введённую строку до приемлемой длины
    3. $_POST['recipetitle'] = isset($_POST['recipetitle']) ? substr($_POST["recipetitle"],0,60) : null;
    4. // Удаляем лишние слеши, если включены magic_quotes_gpc
    5. $recipetitle = get_magic_quotes_gpc() ? stripslashes($_POST["recipetitle"]) : $_POST['recipetitle'];
    6. // Подготавливаем строку к записи в БД
    7. $recipetitle = mysql_real_escape_string($recipetitle);
    8.  
    9. ....
    10.  
    11. // Ну и собственно для защиты от XSS ПРИ ВЫВОДЕ В HTML обрабатываем строку:
    12. $recipetitle = htmlspecialchars($recipetitle);
    13. ?>
     
  13. SkyKiller

    SkyKiller Активный пользователь

    С нами с:
    1 ноя 2007
    Сообщения:
    166
    Симпатии:
    0
    Адрес:
    Новосибирск
    [vs], спасибо за подсказку!
    Пошёл править код.
     
  14. Luge

    Luge Старожил

    С нами с:
    2 фев 2007
    Сообщения:
    4.680
    Симпатии:
    1
    Адрес:
    Минск
    м для каждой переменой это с собой таскать?
     
  15. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    SkyKiller
    Для всего массива:
    PHP:
    1. <?php
    2. function stripslashes_array ($var) {
    3.     foreach ($var as $key=>$value){
    4.         if(is_array($value)){ //На случай вложеного массива
    5.             $value=StripslashesArray(&$value);
    6.         } else {
    7.             $value=stripslashes($value);
    8.         }
    9.         $var[$key]=$value;
    10.     }
    11.     return $var;
    12. }
    13. $_POST = get_magic_quotes_gpc() ? stripslashes_array($_POST) : $_POST;
     
  16. Luge

    Luge Старожил

    С нами с:
    2 фев 2007
    Сообщения:
    4.680
    Симпатии:
    1
    Адрес:
    Минск
    [vs]
    PHP:
    1. <?php
    2. function Strips(&$arr)
    3. {
    4.   if (is_array($arr))
    5.     foreach($arr as $k=>$v)
    6.       Strips($arr[$k]);
    7.     else
    8.       $arr = stripslashes($arr);
    9. }
    10. ?>
    так короче
     
  17. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    o_0 круто!
     
  18. SkyKiller

    SkyKiller Активный пользователь

    С нами с:
    1 ноя 2007
    Сообщения:
    166
    Симпатии:
    0
    Адрес:
    Новосибирск
    В-общем, для верности я обрабатываю функцией htmlspecialchars все данные, которые выводятся в браузер с помощью echo или ей подобными...
     
  19. Vladson

    Vladson Старожил

    С нами с:
    4 фев 2006
    Сообщения:
    4.040
    Симпатии:
    26
    Адрес:
    Estonia, Tallinn
    Я так как являюсь чаще всего и кодером и верстальщиком одновременно делаю это уже в шаблоне, чтоб не путать данные, данные идущие на страничку и данные отсылаемые на мыло или RSS (это всё разные форматы, но данные одни и теже)

    PHP:
    1. <?while($row = mysql_fetch_assoc($posts)):?>
    2.         <p><i><?php echo $row['date'];?></i><br><?php echo text2html($row['text']);?></p><hr>
    3. <?endwhile?>
    (text2html это функция в целом htmlspecialchars+nl2br+trim, а в первом случае обработка не нужна так как дата хранится в базе сразу в нужном формате)
     
  20. Luge

    Luge Старожил

    С нами с:
    2 фев 2007
    Сообщения:
    4.680
    Симпатии:
    1
    Адрес:
    Минск
    А! Акелла промахнулся :D Порядок другой ведь…

    не обращай внимания, пофлудить захотелось
     
  21. Vladson

    Vladson Старожил

    С нами с:
    4 фев 2006
    Сообщения:
    4.040
    Симпатии:
    26
    Адрес:
    Estonia, Tallinn
    Само собой другой порядок, я просто перечислил, а не пересказал что и как. (на самом деле там даже nl2br нету потому что для HTML я юзаю не <br /> а просто <br>, а кроме этого ещё кучу примочек вплоть до обработки bbcode)
     
  22. SkyKiller

    SkyKiller Активный пользователь

    С нами с:
    1 ноя 2007
    Сообщения:
    166
    Симпатии:
    0
    Адрес:
    Новосибирск
    Меня интересует другой вопрос... Вот если я ВСЕ данные, которые выводятся через ECHO (неважно, каким образом они получены - из формы или непосредственное жесткое присваивание переменной в скрипте) буду обрабатывать через htmlspecialchars - грозит ли это критичной потерей производительности? Согласен, это будет ОЧЕНЬ надёжно, но я не хочу, чтобы у меня сервер встал колом, когда ко мне на сайт будет заходить 15-20 тысяч уников в сутки.
    Какие данные НЕОБХОДИМО обрабатывать, а какие - нет надобности?
    Хочется максимально защититься от злобных хацкеров-пионэров (и их XSS-гадостей) и, в тоже время, не потерять производительности...
    Вот, например:

    PHP:
    1. <?php
    2. // 1. Простое присваивание в скрипте. Переменная "b" НЕ берётся из базы или из формы ввода. Она определяется раньше в скрипте (например, $b = 3; )
    3. $a = $b + 1;
    4.     echo "<a href=\"/recipe/".$a."/\">".$a."</a>";  // htmlspecialchars or not?
    5. // 2. Переменная из GET-запроса. Получена из строки ввода. Обрезана до нужной длины.
    6. $a = $_GET['recipeID'];
    7.     echo "<a href=\"/recipe/".$a."/\">".$a."</a>";  // htmlspecialchars or not?
    8. // 3. Переменная из MySQL-запроса.
    9. while($row=mysql_fetch_array($cooking)) {
    10.     $a = $row['recipeID'];
    11.     echo "<a href=\"/recipe/".$a."/\">".$a."</a>";  // htmlspecialchars or not?
    12. }
    13. ?>
    Какие из этих вариантов обрабатывать htmlspecialchars?
    Не хотелось бы выглядеть идиотом и параноиком, но меня очень беспокоит безопасность моего кода. Тем более, что на днях я запускаю проект, который (надеюсь) проживёт долго. И не хочу, чтобы его сломали в первый же день. Я, конечно, совершил большую глупость, что не озаботился этим раньше, на этапе написания кода. Теперь вот, на этапе отладки приходится шерстить весь код и править.
    В общем, буду рад любым правильным советам. :)
    Спасибо!
     
  23. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    С точки зрения защиты от XSS, обрабатывать при выводе функцией htmlspecialchars следует все данные, полученые от клиента. Обрабатывать ВСЁ нет смысла. Не нужно обрабатывать переменные, значение которым присваивается в скрите. Обязательно надо отключать register_globals. Надо помнить, например, что User Agent или данные из куки - тоже полученые от пользователя данные, их тоже надо обрабатывать (при выводе, разумеется). Сама фнукция htmlspecialchars достаточно ресурсоёмкая.
     
  24. C точки зрения здравого смысла, обрабатывать специальные символы HTML (htmlspecialchars) нужно только при отображении данных на HTML странице.
    Не надо. Достаточно писать так, как будто она отключена.
     
  25. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    Ну я это и имел ввиду, речь как раз шла о выводе данных.
    Согласен, если писать правильно, то и со включеными скрипт будет безопасен. Но если они включены, такая допусиммая конструкция становится уязвимой:
    PHP:
    1. <?php
    2. if (....) {
    3.  ...
    4.  $var=1;
    5. }
    6.  
    7. ...bla-bla-bla...
    8.  
    9. if($var) {
    10. ....