Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: Безопасность
Форумы портала PHP.SU » PHP » Программирование на PHP » Безопасность

Страниц (2): [1] 2 »
 

1. Ammy - 10 Января, 2010 - 19:43:08 - перейти к сообщению
Решила создать тему, где хотелось бы обсудить различные варианты обработки входящих данных с целью безопасности и избежания занесения в базу разного рода мусора.

Из всего этого следует несколько вопросов:

1. Какими методами вы пользуетесь для обработки форм?
2. Используете ли вы регулярные выражения для проверки правильности составления логина, или иной информации, визуальная корректность которой необходима для записи в базу данных?
3. Используете ли вы разного рода фильтры в ущерб целостности данных?
4. Чему вы отдаёте больший приоритет: краткости и безопасности, или юзабельности и расширяемости?

А вот, собственно, сомнительные моменты, которые очень часто встречаются в скриптах:

PHP:
скопировать код в буфер обмена
  1.  
  2.  
  3. $login = $_POST['login'];
  4.  
  5. // и пошло поехало.. x_X
  6.  
  7. $login = stripslashes($login); // зачем это нужно, если, скажем, волшебные кавычки выключены? А иначе тот, кто захочет исковеркать свой ник, обязательно найдёт такой способ
  8. $login = htmlspecialchars($login); // зачем преобразовывать, если всё тотчас улетит в базу? Кому ты сделаешь лучше?
  9.  
  10. $login = trim($login); // и после густой каши ещё и обрезам пробелы с обоих концов
  11.  
  12. if (empty($login)) {
  13.   echo 'ого ничёсибе как безопасно у вас';
  14. }
  15.  
  16. $result2 = mysql_query ("INSERT INTO users (login) VALUES('$login')");
  17.  
  18. // или же составить огромную кашу из таких проверок, подключив в добавок функцию strip_tags
  19.  
  20. // из многомерного кода Попова
  21.  


или

PHP:
скопировать код в буфер обмена
  1.  
  2.  
  3. if(!preg_match("/^[a-zA-Z0-9]+$/",$_POST['login']))
  4.     {
  5.         $err[] = "Логин может состоять только из букв английского алфавита и цифр";
  6.     }
  7. // http://habrahabr.ru/blogs/php/13726/
  8.  


Мясорубка (фильтр):

PHP:
скопировать код в буфер обмена
  1.  
  2.  
  3.  function antihack () {  
  4.    
  5. $uri = $_SERVER['REQUEST_URI']; //определяем адрес запрашиваемой страницы  
  6.    
  7. $arr_u = explode("?", $uri ); //разделяем адрес на массив  
  8. $url = $arr_u[0];  //того что до знака ?    
  9. $p_url = $arr_u[1]; // и того что после  
  10.    
  11.    
  12. $inj='/script|http|<|>|<|>|SELECT|UNION|UPDATE|AND|exe|exec|INSERT|tmp/i'; //это паттерн возможных типов атак в адресе (их можно дополнить своими)  
  13.    
  14.    
  15. if (preg_match($inj, $p_url )) { // ищем патерн в нашем адресе, в том что за знаком ?  
  16.    
  17.     die("Hacking attempt!"); //если находим - посылаем куда подальше :=)  
  18. }  
  19. }
  20.  
  21. // Откуда: http://phpmaster.su/php-faq/8-kak-zashhititsya-ot-sql-inekcij-xss-atak-na-php.html
  22. // Раскрытие:  http://forum.antichat.ru/threadnav30641-8-10.html
  23.  
  24.  


Я за границей, или примите в дар SQL инъекцию:

http://www[dot]swish-db[dot]com/tutorial[dot][dot][dot]view.php/tid/601
http://www[dot]olate[dot]co[dot]uk/articles/185
http://www[dot]astahost[dot]com/info.php[dot][dot][dot]cript_t2659[dot]html
... + в запасе более 25 лже-статей
2. SAD - 10 Января, 2010 - 19:49:01 - перейти к сообщению

Будет время, такого рода тему создам в базах данных, а то одно и тоже каждая 4 тема
3. JustUserR - 10 Января, 2010 - 19:49:46 - перейти к сообщению
Ammy По мне самое главное это правильно заэкранировать кавычки и все данные в SQL запросах обрамлять в кавычки - тогда никаких проблем не может быть в принципе
4. Champion - 10 Января, 2010 - 19:55:45 - перейти к сообщению
Ammy пишет:
3. Используете ли вы разного рода фильтры в ущерб целостности данных?
Что ты пол этим имеешь в виду? Я не очень представляю, как фильтры могут навредить целостности? Которые удаляют из строки потенциально нехорошие символы вместо того, чтоб их экранировать?
Ammy пишет:
4. Чему вы отдаёте больший приоритет: краткости и безопасности, или юзабельности и расширяемости?
А почему краткость и безопасность с другой стороны от юзабельности и расширяемости?

2 - да.

По коду: $login = stripslashes($login); - согласен с комментарием.
if (get_magic_quotes_gpc()) {
$value = stripslashes($value);
}
Ammy пишет:
$login = htmlspecialchars($login); // зачем преобразовывать, если всё тотчас улетит в базу? Кому ты сделаешь лучше?
Видимо, потом планируется многократно выводить это в браузер. Сделано из соображений, что лучше один раз обработать при вставке, чем постоянно при выводе.
Ammy пишет:
подключив в добавок функцию strip_tags
Вот это, может быть, и есть иногда фильтры, которые вредят целостности: убрав тэги мы может сделать данные неполными и недостоверными. особенно забавно применять эту функцию после htmlentities))
(Добавление)
Пример с хабрахабра не заметил сразу. А если я хочу логин o'connor? Логин перед вставкой в базу можно обработать htmlentities и mysql_real_escape_string.
5. Ammy - 10 Января, 2010 - 20:40:59 - перейти к сообщению
Цитата:
А почему краткость и безопасность с другой стороны от юзабельности и расширяемости?

Вкладывался следующий смысл:
1. Описывать какой-то отдельный момент кратко, безопасно, делая упор на производительность и безопасность, не торопиться переходить от одного к другому.

PHP:
скопировать код в буфер обмена
  1.  
  2. $extract = array_flip(array_intersect(array_keys($_POST), $options));
  3.  
  4. // написан Ch_chov в теме: http://forum.php.su/topic.php?forum=45&topic=114&v=l#1263029599
  5.  


2. Описывать момент быстро, и оставлять его в первоначальном виде, делая упор на реализацию дальнейших моментов.

PHP:
скопировать код в буфер обмена
  1.  
  2.  
  3. $options = array('dcore', 'idle', 'jcache', 'hle', 'jrec', 'intpret', 'ttco', 'quant', 'dspt');
  4.             $extract = array();
  5.  
  6.             foreach ($options as $key => $value) {
  7.  
  8.                 if (isset($_POST[$value]) && $_POST[$value] == 'on') $extract[$value] = 'on';
  9.  
  10.             }
  11.  
  12.        
  13.  
  14.             echo serialize($extract); // подготовка для занесения в базу
  15.  
  16. // написан мною в той же теме
  17.  
  18.  


Цитата:
Что ты пол этим имеешь в виду? Я не очень представляю, как фильтры могут навредить целостности? Которые удаляют из строки потенциально нехорошие символы вместо того, чтоб их экранировать?

Функции, типа strip_tags, или вовсе самодельные, где применяется целый комплекс проверок и вырезаний (а главное то на них всей душой и телом полагаются, как на потенциальных защитников данных, мол, прикручу очередной стрип тагс и я на небе), что ни к чему хорошему не приводит. Вот, допустим, функция, анализирующая входящие данные, которая не пропускает пробелов:

PHP:
скопировать код в буфер обмена
  1.  
  2.  
  3. function analyze($var) {
  4.  
  5.         $var = (preg_match('#[^a-zA-Z0-9_]#', $var)) ? '' : $var;
  6.         return $var;
  7.  
  8. }
  9.  
  10. // используется в SLAED CMS
  11.  


Под ущербом целостности подразумевается нарушение структуры чего-либо в результате проверки какой-нибудь очередной хлеборезкой. Или, например, когда ты прощаешь себе необходимый в передаваемом параметре символ, который вырезается твоим великим смертельным анти-хакиравским аружием.
6. biperch - 10 Января, 2010 - 20:59:45 - перейти к сообщению
Ammy пишет:
делая упор на производительность

пусть у тебя сценарий работает 4-6с., а пользователь получает результат 5-20с в зависимости от загруженности линий нета у пользователя и тд. это можно пережить, а вот безопасность это другое дело
7. Champion - 10 Января, 2010 - 21:05:59 - перейти к сообщению
Ammy пишет:
Под ущербом целостности подразумевается нарушение структуры чего-либо в результате проверки какой-нибудь очередной хлеборезкой.
Это уже не фильтр. Это хлеборезка, действительно. Такое не надо использовать.
Ammy пишет:
preg_match('#[^a-zA-Z0-9_]#'
Проверять логин таким способом совсем не надо. Тем более, что [^a-zA-Z0-9_] - это \W. Вообще, такая хлеборезка еще и когда она без предупреждения выбрасывает какие-то данные - это нехорошо.

Ammy пишет:
1. Описывать какой-то отдельный момент кратко, безопасно, делая упор на производительность и безопасность, не торопиться переходить от одного к другому.
Ammy пишет:
2. Описывать момент быстро, и оставлять его в первоначальном виде, делая упор на реализацию дальнейших моментов.
Ну возвращаться к уже написанному и оптимизировать - это нормально. Но лучше сразу конечно по возможности, а то тут на потом оставил, тут решил потом подумать, а потом получаются разные забавные вещи...

В твоем примере просто второй вариант получился из-за незнания (ye или забывчивости) того, что в PHP есть готовые функции. Конечно, готовые функции быстрее работают, чем самописные.
Хотя, знаешь, конкретно тут мне второй вариант больше нравится. Тут за один проход всё делается, а там три шага: получаем ключи одного массива, берем из них те, которые есть в другом, превращаем ключи в значения...
8. Ammy - 10 Января, 2010 - 21:15:23 - перейти к сообщению
Из кода системы регистрации Попова:

PHP:
скопировать код в буфер обмена
  1.  
  2.  
  3. if (isset($_POST['login'])) { $login = $_POST['login']; if ($login == '') { unset($login);} }
  4. if (isset($_POST['password'])) { $password=$_POST['password']; if ($password =='') { unset($password);} }
  5. if (isset($_POST['code'])) { $code = $_POST['code']; if ($code == '') { unset($code);} }
  6. if (isset($_POST['email'])) { $email = $_POST['email']; if ($email == '') { unset($email);} }
  7.  
  8. // Не много ли?
  9.  
  10.  



PHP:
скопировать код в буфер обмена
  1.  
  2. // Зачем это? Далее забавный комментарий автора:
  3.  
  4. //если логин и пароль введены,то обрабатываем их, чтобы теги и скрипты не работали, мало ли что люди могут ввести
  5.  
  6. // Но зачем, если  переменные не выводятся в дальнейшем? Или в базе они научились работать, теги эти? Чего уж говорить о stripslashes..
  7.  
  8. $login = stripslashes($login);
  9. $login = htmlspecialchars($login);
  10.  
  11. $password = stripslashes($password);
  12. $password = htmlspecialchars($password);
  13.  
  14. $login = trim($login);
  15. $password = trim($password);
  16.  
  17. // и краткость, кстати, пострадала
  18.  
9. Champion - 10 Января, 2010 - 21:21:57 - перейти к сообщению
Тут первый код - ужас просто. Е-мейл, кстати, лучше бы регуляркой проверить тут как раз. логин, пароль мы выше обсудили. Зачем unset - вообще непонятно.

По второму коду, пароль действительно не выводится, а вот логин может и выводится. Его можно в безопасном виде сразу в базу писать.
О stripslashes тоже в начале было.
10. Ammy - 10 Января, 2010 - 21:28:03 - перейти к сообщению
PHP:
скопировать код в буфер обмена
  1.  
  2. $login = (isset($_POST['login'])) ? (($_POST['login'] != '') ? trim($_POST['login']) : '') : '';
  3.  
  4. if(empty($login)) die();
  5.  


Не достойная альтернатива первому коду? Улыбка
(Добавление)
Цитата:

По второму коду, пароль действительно не выводится, а вот логин может и выводится.

Нет, логин нигде не выводится. Для них эдакая обработка - это решение проблем безопасности в целом, как видно.

Цитата:
Его можно в безопасном виде сразу в базу писать.


Есть ставит вопрос о визуальной важности, то некоторые решают эту проблему подобными не менее устрашающими функциями:

PHP:
скопировать код в буфер обмена
  1.  
  2. function validusername($username)
  3. {
  4.         if ($username == "")
  5.           return false;
  6.  
  7.         // The following characters are allowed in user names
  8.         $allowedchars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_".
  9.                 "абвгдеёжзиклмнопрстуфхшщэюяьъАБВГДЕЁЖЗИКЛМНОПРСТУФХШЩЭЮЯЬЪ";
  10.  
  11.         for ($i = 0; $i < strlen($username); ++$i)
  12.           if (strpos($allowedchars, $username[$i]) === false)
  13.             return false;
  14.  
  15.         return true;
  16. }
  17.  
  18. // TBDev YSE
  19.  


Решают и регулярными выражениями, но это всем известно. Зависит от составления и непробиваемости.

Но почему никто не смотрит на ctype?
http://php.net/manual/en/book.ctype.php
11. DimKA - 10 Января, 2010 - 23:12:22 - перейти к сообщению
и все таки что лучше использовать?

я писал



но я пока учусь)) и хочется писать правильно так что если не сложно объясните Не понял
12. Мелкий - 10 Января, 2010 - 23:24:33 - перейти к сообщению
А зачем убирать экранирование?
13. Champion - 11 Января, 2010 - 08:42:56 - перейти к сообщению
Короче:
- все строки, которые вставляются в БД:
* обрабатывать mysql_real_escape_string
* проверять длину
- строки, которые должны иметь определенный формат (e-mail, например) проверять регуляркой
- строки, которые предназначены для вывода в браузер, обрабатывать htmlentites:
* перед добавлением в базу, если потом прийдется их часто выводить
* при выводе (тоже бывает надо).
В любом случае есть html_entity_decode()
- числа проверять is_float, (float) ...
- данные, не удовлетворяющие регуляркам, проверкам типа is_float() по возможности не обрубать молча, а просить пользователя повторить ввод.
- скрипты, интенсивно работающие с базой не давать возможности запускать часто: писать в сессию время последнего обращения к скрипта и если скрипт повторно вызвался спустя секунду, например, то не начинать работу с БД, а ругнуться. По-моему, всё.

Это что касается безопасности работы с БД.
(Добавление)
Мелкий пишет:
А зачем убирать экранирование?
Чтобы не экранировать заново, если включены волшебные кавычки. Надо только проверить сначала, включены ли они.
Их, кстати, иногда достоточно бывает, так что можно обойтись без некоторой обработки.DimKA, выше написано.
14. valenok - 11 Января, 2010 - 10:37:16 - перейти к сообщению
Как поступаю с данными я.

Прием данных.
Никаких magic_quotes, автоматических добавлений всяких слэшей и прочей галиматьи.

Обработка данных
Числовые данные сначала преобразаую инвалом, потом проверяю на отличие от нуля.

Порой даже не проверяю на их присутсвие, если они там должны быть.
$id = @intval($_POST['id']); if(!$id) throw ..

имейлы проверяю регуляркой + на сопутсвующие mx записи во избежании ввода несуществующих адресов.

Иногда пользуюсь фильтрами валидации (validation filters)

Никогда и не при каких условиях не изменяю вводимые данные ( никаких стрип тагс, стриптиз, санитайз фильтров и любых других преобразований.

Ввод данных в БД
Любый строковые данные обязательно подвергаются обработке mysql_real_escape_string или чем-то подходящим для вашей конкретной БД.
Даже если мы 3 раза проверили имейл регулярками.
Всегда строки в запросах заключаются в кавычки.
Числа тоже, хоть mysql их и преобразовывает.
Все числа вводятся только после intvala (который я выполняю на этапе приема данных)

Вывод из БД
Любые данные из БД выводятся после обработки htmlspecialchars( , ENT_QUOTES);
15. EuGen - 11 Января, 2010 - 11:58:08 - перейти к сообщению
Свои предпочтения я изложил здесь в уроках (про безопасность, и красивые стили). Может, и субьективно, но пока что действенно.

 

Powered by ExBB FM 1.0 RC1