Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: механизм авторизации (оцените)
 
 автор: victoor   (25.06.2007 в 23:17)   письмо автору
 
 

Здравствуйте!
Сделал авторизацию у себя на сайте...
Не могли бы вы оценить механизм входа на безопасность...
<?php
if(!provercka($_POST['name'], REG_FOR_NICK)) # проверяем принятый ник на соответствие допустимым символам.
   
{echo("Неправильный логин. Попробуйте зайти заново.");} # Во введенном логине есть недопустимые символы!!!
  
else
   { 
# Во введенном символе нет недопустимых символов
     
$res=mysql_query("SELECT id FROM `люди` WHERE `name`='".$_POST['name']."';"); # Извлекаем из базы id для пользователя с введенным ником.
     
if ($res# Если есть ответ
        
{
          
$res_id=mysql_fetch_array($res); # Получаем результат запроса.
          
$id=$res_id['id']; # Извлекаем id пользователя из запроса
          
$res2=mysql_query("SELECT * FROM `люди` WHERE `id`='".$id."';"); # Получаем данные пользователя по его id из пред. запроса
          
if ($res2# Если есть ответ на 2-ой запрос
             
{
                
$ress=mysql_fetch_array($res2); # Получаем результат 2-ого запроса
#                echo("-".$id." -- ".$ress['name'].' - '.$ress['код']." - ".$ress['создание_пользователей']."-<br />");
                # Проверяем соответствие полученных через форму логина и пароля и логина и пароля из базы.
                
if(($ress['name']==$_POST['name']) and ($ress['код']==md5($_POST['pass'])))
                   { 
# пароли и логины равны.
                      # Пользователь вошел!!!
                      # Устанавливаем все права из полей
                      
$_SESSION['name']=$_POST['name'];
                      
$_SESSION['создание_пользователей']=$ress['создание_пользователей'];
                      
$_SESSION['статус']=$ress['статус'];
                      
# устанавливаем дату и время последнего входа
                      
mysql_query("UPDATE `люди` SET `последний_вход`=NOW() WHERE `id`=".$id." LIMIT 1;");
                   }
                  else
                   {  
# пароли и/или логины не равны.
                      # Попытка взлома?
                      # надо бы сделать вывод в лог...
                      
echo("пара логин/пароль не является правильной. попробуйте повторить вход.");
                   };
             }; 
# END  if ($res2) # Если есть ответ на 2-ой запрос
        
# END  if ($res) # Если есть ответ
       
else
        { 
# Если нету ответа - выводим ошибку и завершаем выполнение проги.
          
echo "<p><b>Error: ".mysql_error()."</b></p>";
          exit();
        }
   }
?>

функция provercka($str, $reg_str) проверяет, есть ли в строке $str какие-нибудь символы, кроме символов, имеющихся в $reg_str. Если обнаружены лишние символы - выводит False, если присутствуют только разрешенные символы - True.
Константа REG_FOR_NICK определена как define('REG_FOR_NICK', '/^[a-zа-я;ё0-9-_ ~@\!\^\(\)\.\d]+$/i');
register_globals установлен в положение off

Заранее спасибо за оценку, буду благодарен за любые найденные уязвимости...


UpDate

функция provercka имеет следующий вид:
<?php
function provercka($string$reg_str$echo_fl=''$echo_tr='')  #Проверка введенных данных на корректность.
{
  if(
preg_match($reg_str$string) or $string=='')
  {
     if (
$echo_tr) {echo('<font color=GREEN>'.$echo_tr.'</font><br>');};
     return 
true;
  }
  else
  {
     if (
$echo_fl) {echo('<font color=RED>'.$echo_fl.'</font>'.$string.'<br>');};
     return 
false;
  }
}
?>


Структура таблицы `люди` в БД:
CREATE TABLE `люди` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(30) NOT NULL,
  `код` varchar(32) NOT NULL,
  `статус` set('админ','пользователь','соклан','Глава клана') NOT NULL DEFAULT 'пользователь',
  `последний_вход` datetime NOT NULL,
  `создание_пользователей` set('разрешено','запрещено') NOT NULL DEFAULT 'запрещено',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=cp1251 COMMENT='список пользователей';


Регистрация пользователей осуществяется админом указанием имени пользователя и пароля, все остальное делается автоматически.

   
 
 автор: Равечка   (25.06.2007 в 23:22)   письмо автору
 
   для: victoor   (25.06.2007 в 23:17)
 

del

   
 
 автор: TXC   (26.06.2007 в 01:41)   письмо автору
 
   для: victoor   (25.06.2007 в 23:17)
 

Меня смущает вот этот кусок

$res_id=mysql_fetch_array($res); # Получаем результат запроса.
          $id=$res_id['id']; # Извлекаем id пользователя из запроса


догадаться, что Ваш скрипт прочитает из базы, не зная как у Вас организована регистрация сложно.
Но если предположить, что в регистрации уязвимости нет, то в целом ИМХО нормально.

   
 
 автор: moonfox   (26.06.2007 в 01:56)   письмо автору
 
   для: TXC   (26.06.2007 в 01:41)
 

а вот это как?

USER.PHP
<?
class login{

var 
$status='';
var 
$session='';

function 
auth($name,$password)

{

//$password=mysql_escape_string($password);
$sql "select * from ".USER_TABLE." where login='".mysql_escape_string($name)."';";
$res mysql_query($sql);
$data=mysql_fetch_array($res);
if(
$data['login']==$name && $data['pass']==md5($password))
{
$this->session=$data['id'];
//echo $p;
}
else{
$this->status="Пароль или логин не верный";
    }
}


    }
        
?>



INDEX.PHP
<?
require 'user.php';

foreach(
$_POST as $key => $val){$$key=$val;}

$login = new login();
if(isset(
$Submit) && $name!='' && $password!='')
  {
$login->auth($name,$password);
$_SESSION['valid_user']=$login->session

$smarty->assign('message',$login->status);
  } 
else {if(isset(
$Submit) && ($name=='' || $password==''))
$smarty->assign('message','Заполните все поля!');
  }
?>

   
 
 автор: victoor   (26.06.2007 в 14:29)   письмо автору
 
   для: TXC   (26.06.2007 в 01:41)
 

>Меня смущает вот этот кусок
>

>$res_id=mysql_fetch_array($res); # Получаем результат запроса.
>          $id=$res_id['id']; # Извлекаем id пользователя из запроса
>

>
>догадаться, что Ваш скрипт прочитает из базы, не зная как у Вас организована регистрация сложно.
>Но если предположить, что в регистрации уязвимости нет, то в целом ИМХО нормально.
Пока регистрация работает через админа... =) так что ее пока можно считать условно-безопасной...

   
 
 автор: cheops   (26.06.2007 в 11:36)   письмо автору
 
   для: victoor   (25.06.2007 в 23:17)
 

>Константа REG_FOR_NICK определена как define('REG_FOR_NICK', '/^[a-zа-я;ё0-9-_ ~@\!\^\(\)\.\d]+$/i');
Т.е. одиночные кавычки допускаются? Ваша авторизация взломана при помощи SQL-инъекции.

   
 
 автор: isset   (26.06.2007 в 11:41)   письмо автору
 
   для: cheops   (26.06.2007 в 11:36)
 

почему допускаются?

   
 
 автор: cheops   (26.06.2007 в 11:45)   письмо автору
 
   для: isset   (26.06.2007 в 11:41)
 

Потому, что отсуствуют в регулярном выражении...

PS Правда с SQL-инъекцией я поторопился, хотя её можно провернуть - при помощи её авторизоваться не удасться, но всё равно лучше не допускать одиночных кавычек или экранировать их - проверка может использоваться в других частях Web-приложения.

   
 
 автор: victoor   (26.06.2007 в 14:26)   письмо автору
 
   для: cheops   (26.06.2007 в 11:45)
 

нет, одиночные кавычки (как и двойные) не допускаются. в константе перечислены все ДОПУСТИМЫЕ символы... любой символ, которого нету в этой константе, считается запрещенным и вызывает сообщение о недопустимости символа и, как следствие, авторизации не происходит...
Возможно, я как-то коряво описал, но кавычки не пропускаются, проверено на тестах...

функция как-то заумно написана (писал я сам), но, т.к. она нормально работает, мне лень переписывать еее.
функция имеет вид:
<?php
function provercka($string$reg_str$echo_fl=''$echo_tr='')  #Проверка введенных данных на корректность.
{
  if(
preg_match($reg_str$string) or $string=='')
  {
     if (
$echo_tr) {echo('<font color=GREEN>'.$echo_tr.'</font><br>');};
     return 
true;
  }
  else
  {
     if (
$echo_fl) {echo('<font color=RED>'.$echo_fl.'</font>'.$string.'<br>');};
     return 
false;
  }
}
?>

   
 
 автор: moonfox   (27.06.2007 в 01:37)   письмо автору
 
   для: victoor   (26.06.2007 в 14:26)
 

что хорошего можно сказть о тои коде чтоя привел?

   
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования