Linux за българи: Форуми

Програмиране => Web development => Темата е започната от: toti84 в Mar 14, 2010, 13:07



Титла: Достатъчно сигурен ли е този php скрипт ?
Публикувано от: toti84 в Mar 14, 2010, 13:07
Здравейте колеги,
Ще ви помоля за мемието ви дали тези два скрипта са достатъчно сигурни за което за предазначени.
Доста търсих из интернета, а и книги четох и това успях да измисля:

Целта ми в пръвия е да почисти входните данни от пост масива, като в същото верме, като и
прекрати автоматизирани ботове.

Код
GeSHi (PHP):
  1. <?php
  2. if ((isset($_POST['add']) && $_POST['add']=='1'))
  3.      { if (isset($_SESSION['token']) && $_POST['token'] == $_SESSION['token'])
  4.            {
  5.   $token_age = time() - $_SESSION['token_time'];
  6. if (($token_age < $maxTime) && ($token_age > $minTime ))
  7. {
  8. $valueTitle=array('Господин','Госпожа','Госпожица');text
  9. if(in_array($_POST['title'],$valueTitle)) {$clean['title']=$_POST['title'];}
  10. if(preg_match("/^[a-zA-ZА]{3,32}$/",$_POST['name'])) {$clean['name']=$_POST['name'];}
  11. }}}
  12. echo clean ['name'];
  13.  
  14.  
  15. $token = md5(uniqid(rand(), true)); $_SESSION['token'] = $token;
  16. $_SESSION['token_timestamp'] = time();
  17. echo "<form action='' method='POST'>
  18. Username: <input type='text' name='username' />    
  19. <input type='hidden' value=".$token." name='token' />  
  20. <input type='submit' />                            
  21. </form>";      
  22.  
  23. ?>
  24.  
  25.  
  26.  


А врория от тях е създаването на сесия, за оторизиран потребител, до ограничена част на сайта.

Код
GeSHi (PHP):
  1. //someWhereInSite.php
  2. <?php
  3. if (isset($_SESSION['HTTP_USER_AGENT']))
  4. {                                      
  5.    if ($_SESSION['HTTP_USER_AGENT'] != md5($_SERVER['HTTP_USER_AGENT']))
  6.    {                                                                    
  7. echo "<form action='login_check.php' method='POST'>                      
  8. Username: <input type='text' name='username' />                          
  9. <input type='submit' />                                                  
  10. </form>";                                                                
  11.  
  12.        /* Prompt for password */
  13.        exit;                    
  14.    }                            
  15.  
  16.    else
  17.        { echo "Inside security zone";
  18.  
  19.        exit;                                          
  20.        }                                              
  21.  
  22. }
  23.  
  24. if (!isset($_SESSION['HTTP_USER_AGENT']))
  25. {                                        
  26. echo "<form action='login_check.php' method='POST'>
  27. Username: <input type='text' name='username' />    
  28. <input type='submit' />                            
  29. </form>";                                          
  30. }                                                  
  31. ?>
  32.  
  33.  
  34.  
  35.  
  36. //login_check.php
  37. <?php
  38. if (!isset($_SESSION['HTTP_USER_AGENT']) && isset($_POST['username']))
  39. {                                                                    
  40.  if ($_POST['username'] == 1)                                        
  41.    {                                                                
  42.    $_SESSION['HTTP_USER_AGENT'] = md5($_SERVER['HTTP_USER_AGENT']);  
  43.    echo "Inside security zone<br>";
  44.    }                                                                            
  45.  else {echo "greshna parola";exit;}  
  46.  
  47. ?>
  48.  

Моля дайте ваште мнения, изказвания и препръки.




Титла: Re: Достатъчно сигурен ли е този php скрипт ?
Публикувано от: go_fire в Mar 14, 2010, 13:15
Поне аз не забелязах частта, където обработваш постъпилата от формата информация и я вкарваш в базата. Тук са повечето пробойни. И там са задължителни неща от сорта на trim и addslashes.


Иначе кода поне на мен (но аз съм ламер) ми изглежда добре.


Титла: Re: Достатъчно сигурен ли е този php скрипт ?
Публикувано от: toti84 в Mar 14, 2010, 13:39
В горния случай според мен променливата $clean['name'] е достатъчно почистена да се вкара директно в базата данни. Или греша ?


Титла: Re: Достатъчно сигурен ли е този php скрипт ?
Публикувано от: go_fire в Mar 14, 2010, 14:23
както казах, не съм баш най-напред, но на доста места, съветват в конфига да имаш нещо такова:

Код
GeSHi (PHP):
  1. {
  2. $_GET = array_map('mysql_real_escape_string', $_GET);
  3. $_POST = array_map('mysql_real_escape_string', $_POST);
  4. $_COOKIE = array_map('mysql_real_escape_string', $_COOKIE);
  5. }
  6. else
  7. {
  8. $_GET = array_map('stripslashes', $_GET);
  9. $_POST = array_map('stripslashes', $_POST);
  10. $_COOKIE = array_map('stripslashes', $_COOKIE);
  11. $_GET = array_map('mysql_real_escape_string', $_GET);
  12. $_POST = array_map('mysql_real_escape_string', $_POST);
  13. $_COOKIE = array_map('mysql_real_escape_string', $_COOKIE);
  14. }

Хора дето много уважавам и знаят много, съветват всичко, което влиза в базата да минава през трим и адслашес, за да няма инжекции. Първото по-скоро за удобство на потребителя, отколкото за сигурност, но усигурява и такава. И съответно, когато излиза да има пък htmlspecialchars, за да не чупи html и js. Има и други функции, но тези са най-препоръчвани.


Титла: Re: Достатъчно сигурен ли е този php скрипт ?
Публикувано от: VladSun в Mar 14, 2010, 14:44
За ДБ данни, *трябва* се ползва *sql_real_escape_string() - няма нужда от add/stripslashes и други такива.

Trim не би трябвало да се прилага върху входните данни.

Този скрипт, който "чисти" всички входни данни може да доведе до неприятности - прилага се mysql_real_escape_string върху данни, които може изобщо да не са предназначени за ДБ.



Титла: Re: Достатъчно сигурен ли е този php скрипт ?
Публикувано от: lkr в Mar 14, 2010, 18:26
Най-добре е да ползваш mysqli или ADO.


Титла: Re: Достатъчно сигурен ли е този php скрипт ?
Публикувано от: d0ni в Mar 15, 2010, 03:08
Автоматичното escape-ването на всички входни данни е грешен подход. Аз предпочитам да се грижа за всяка стойност, която влиза в базата, да е от правилния тип и ако е нужно - да е escape-ната.

Ако не мислите така си пуснете magic_quotes и си карайте както знаете :-)


Титла: Re: Достатъчно сигурен ли е този php скрипт ?
Публикувано от: Warstomp в Mar 15, 2010, 08:37
Сигурен бях че ще се появят поне 5 различни мнения :)
Всеки си го прави както си знае.


Титла: Re: Достатъчно сигурен ли е този php скрипт ?
Публикувано от: VladSun в Mar 15, 2010, 12:24
Сигурен бях че ще се появят поне 5 различни мнения :)
Всеки си го прави както си знае.

А не трябва да е така... Има си утвърдени от опита правила, които трябва да се спазват.

Автоматичното escape-ването на всички входни данни е грешен подход. Аз предпочитам да се грижа за всяка стойност, която влиза в базата, да е от правилния тип и ако е нужно - да е escape-ната.

Ако не мислите така си пуснете magic_quotes и си карайте както знаете :-)

Съгласен, magic_quotes внесе повече проблеми отколкото успя да реши :)


Титла: Re: Достатъчно сигурен ли е този php скрипт ?
Публикувано от: VladSun в Mar 15, 2010, 12:29
@toti84
Мисля си, че ако искаш повече помощ, ще трябва да форматираш кода в някой от по-общовъзприетите стандарти... За мен е абсолютно нечетлив - напр. идея си нямам къде свършват if блоковете.


Титла: Re: Достатъчно сигурен ли е този php скрипт ?
Публикувано от: VladSun в Mar 15, 2010, 12:46
В горния случай според мен променливата $clean['name'] е достатъчно почистена да се вкара директно в базата данни. Или греша ?

Това което си направил е по-скоро проверка за "валидност въз основа на бизнес правила" - *ти* искаш *твоят* сайт да приема потребителски имена съставени само от a-z, A-Z символи. Но това няма нищо общо с ДБ. Утре можеш да решиш, че имена като Brent O'Connor са ОК за *твоя* сайт и да промениш regexp-a. Но това не би трябвало да влияе на съхраняването на данните и тяхното представяне.

Всеки път когато променяш дестинацията на данните, трябва да правиш подходящо трансформиране на данните.

Примери:

1) приемаш HTTP данни от потребителя, правиш им проверка за "бизнес" валидност, и искаш да ги съхраниш в ДБ - новата дестинация е ДБ контекстът. То тогава транформираш данните чрез инструмент предложен от дестинацията като "сигурен" - напр. *sql_real_escape_string.

2) приемаш HTTP данни от потребителя, правиш им проверка за "бизнес" валидност, и искаш да ги представиш обратно на потребителя - новата дестинация е HTML контекстът. То тогава транформираш данните чрез инструмент предложен от дестинацията като "сигурен" - напр. htmlspecialchars или strip_tags.

3) искаш да ги представиш на потребителя  данни прочетени от ДБ - новата дестинация е HTML контекстът. То тогава транформираш данните чрез инструмент предложен от дестинацията като "сигурен" - напр. htmlspecialchars или strip_tags.


Титла: Re: Достатъчно сигурен ли е този php скрипт ?
Публикувано от: toti84 в Mar 15, 2010, 15:26
OK.
Благодаря на всички за интереса към моя въпрос.
Напълно разбрах смисъла на вашите отговори. т.е. аз правя доста строго филтриране на входящите
данни от потребителите.

Вие нищо не казахте за втория ми скрипт за отвариянето на сигурна сесия. Сигурен ли е ?


Титла: Re: Достатъчно сигурен ли е този php скрипт ?
Публикувано от: VladSun в Mar 15, 2010, 15:46
session_regenerate_id() се прави само при смяна на правата чрез успешна автентификация (т.е. успешен логин). Само тогава може да се осъществи session fixation атака. Във всички останали случаи, session_regenerate_id() е източник на проблеми при използването на Back бутона на браузера.


Титла: Re: Достатъчно сигурен ли е този php скрипт ?
Публикувано от: VladSun в Mar 15, 2010, 15:47
аз правя доста строго филтриране на входящите
данни от потребителите.

Ти или използваната от теб framework. Във всички случаи трябва да е прозрачно (и централизирано) за твоите скриптове-клиенти - примерно чрез използването на DAL в случая на ДБ. Така е сигурно, че всички данни подавани към ДБ ще бъдат правилно "изчистени".


Титла: Re: Достатъчно сигурен ли е този php скрипт ?
Публикувано от: go_fire в Mar 15, 2010, 18:57
@offfffff

Владсън, винаги съм знаел, че си голям, ама с тая тема направо ми скри топката, като Миньор на Левски ;)

Привети!


Титла: Re: Достатъчно сигурен ли е този php скрипт ?
Публикувано от: go_fire в Mar 15, 2010, 19:20
Нарочно пускам ново мнение, ако Марчето реши да затрие другото да не ми иде инфото. Значи пуснах същата тема в друг форум. Всички бяха съгласни, че трябва да е едно от двете, но никога и двете, като единия от другите "младоци " даде и една връзка:

http://cognifty.com/blog.entry/id=6/addslashes_dont_call_it_a_comeback.html

После се намесиха истинските програмисти. И там стигнаха до мнението, че нито разните слашес, нито real_escape в продукционна система. Трябвало да се ползва prepared statements и ORM (и двете ги чувам сефте), а всичко друго било средновековие и в никакъв случай не трябвало да се ползват.


Титла: Re: Достатъчно сигурен ли е този php скрипт ?
Публикувано от: victim70 в Mar 15, 2010, 20:58
Приятелю, умният програмист не разчита на безгрешен код и на 1000 мнения - единственно разчита на тестове.
Всичко създадено от хора може да се строши от хора. Според мене го пускай така както си го написал. Събери малко инфо за това как работи, и има-няма проблеми, и продължавай.
Дори лошо работещият код е по добър от перфектният но неработещ.
Според мене ако работи го пускай. И чакай отзиви от тестерите. Е и ти пусни няколко тестчета да видиш какво става де.
Успех


Титла: Re: Достатъчно сигурен ли е този php скрипт ?
Публикувано от: VladSun в Mar 15, 2010, 21:35
@go_fire - хех, мерси, макар че не се считам за толкова "голям" ;)
ORM и prepared statements не са единствените решения за работа с ДБ - и за тях има много "за и против". Аз също работя с ORM - ползвам Doctrine, макар и някои да я считат за прекалено тежка.

В този случай единственото, което е сигурно е, че не трябва да се създава "суперобект" (било то и процедурно имплементиран), който да върши всичко - проверка за валидност, съхранение в ДБ, генериране на HTML и т.н.
Би трябвало кодът да е разделен на Model-View-Controller принципа, като Моделът да е композитен обект - да притежава инстанции на обект за валидация, обект за съхранение в ДБ и други необходими... т.е. да има отделни обекти, всеки с една единствена отговорност в целия механизъм на обработка и представяне на данните. При това връзката между обектите и знанията им за другите обекти трябва да е минимална, а в идеалния случай - никаква.

Самият факт, че първите два реда от всички скриптове показани от toti84 се повтарят във всеки един от тях говори, че нещо определено не е както трябва.

При мен реализацията на контрол над автентификацията (и авторизацията в проекти с роли) изпълянва един единствен обект:

CodeIgniter
Код
GeSHi (PHP):
  1. abstract class Auth_Controller extends Base_Auth_Controller
  2. {
  3. function __construct()
  4. {
  5. parent::__construct();
  6. $this->load->model('application/CurrentUser_Model', 'currentUser');
  7. }
  8.  
  9. protected function _hasPermission($method, $arguments)
  10. {
  11. return $this->currentUser->isLogged;
  12. }
  13.  
  14. protected function _notPermitted($method, $arguments)
  15. {
  16. Error::register('Не сте автентифицирали пред системата.');
  17. $this->view('response');
  18. }
  19. }

Всички останали контролери са наследници на този контролер. Няма HTML,  няма SQL, няма дори следа от DB, SESSION и т.н. Обектът Error съдържа масив от всички съобщения за грешки - без форматиране.

Login/logout действията също се изпълняват от наследник на този контролер:

Код
GeSHi (PHP):
  1. class CurrentUser extends Auth_Controller
  2. {
  3. function __construct()
  4. {
  5. parent::__construct();
  6.  
  7. $this->suspendPermissionCheck();
  8. }
  9.  
  10. public function login()
  11. {
  12. $this->currentUser->doLogin();
  13. $this->view('response');
  14. }
  15.  
  16. public function logout()
  17. {
  18. $this->currentUser->doLogout();
  19. $this->view('response');
  20. }
  21. }


Титла: Re: Достатъчно сигурен ли е този php скрипт ?
Публикувано от: VladSun в Mar 15, 2010, 21:42
Приятелю, умният програмист не разчита на безгрешен код и на 1000 мнения - единственно разчита на тестове.

В света на Agile Software Development ($2) едновременно си прав и грешиш.

1) Да, тестовете са задължителни, но те са измислени от теб самия и проверяват за проблеми, които ти поставяш. Поради това са ти нужни 1000+ мнения, за да покриеш непокритите от теб проблеми.

2) Според философията на Agile Software Development, решенията се базират на "добри практики", а това са точно решенията, получени чрез отсяване на 1000+ мнения ;)


Титла: Re: Достатъчно сигурен ли е този php скрипт ?
Публикувано от: toti84 в Mar 17, 2010, 09:15
@VladSun Много ли ще е нахално, ако те помоля да дадеш един прос пример как се използват твойте класове за автенитикация.

Благодаря предварително ...


Титла: Re: Достатъчно сигурен ли е този php скрипт ?
Публикувано от: VladSun в Mar 17, 2010, 11:12
Аз именно заради това пуснах темата за MVC - http://www.linux-bg.org/forum/index.php?topic=37459.0

От нея се надявам да излязат теми, които да покажат практически решения и да подтикнат хората да в този форум да ги ползват. Мисля си да започна с решения за твоята тема ;)


Титла: Re: Достатъчно сигурен ли е този php скрипт ?
Публикувано от: VladSun в Mar 18, 2010, 00:14
Както обещах, започваме дискусии на тема PHP MVC frameworks и тяхното ползване. Вече пуснах една тема с инсталация и начално конфигуриране на CodeIgniter - http://www.linux-bg.org/forum/index.php?topic=37480.msg193413

Би било добре да пробваш и да пишеш за възникнали проблеми.