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

Форум PHP

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

 

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

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

тема: Прошу посмотреть - надежен ли мой скрипт авторизации?
 
 автор: provodnik   (09.01.2007 в 21:33)   письмо автору
 
 

Вечер добрый. Данная система полностью рабочая. Но я уверен в её "небронебойности" (взять хотя бы отсутствие шифрования пароля). Прошу знающих людей посмотреть, надежен ли нижеприведенный код как авторизация администратора:

Форма:


<form method=post>
Логин: <input type=text name=login><br>
Пароль: <input type=password name=password><br>
<input type=submit value=Войти>
</form>



<?
session_start
();
include(
"mysql.php"); //файл с переменными для коннекта к базе
include("config.php"); //файл с переменными для управления сайтом

$title "Панель администратора";
include(
"design/top.inc.php"); // шапчёнка

      
if($_GET['action'] == "logout"){
      if(isset(
$_SESSION['login']) && isset($_SESSION['password']))    {
            
session_unregister("login");
            
session_unregister("password");
      }
      }

if(isset(
$_POST['login']) && isset($_POST['password']) && !isset($_SESSION['login']) && !isset($_SESSION['password'])) {
$admins mysql_query("SELECT * FROM admin WHERE login = '"$_POST['login']."' AND password = '"$_POST['password']."'");

if(
mysql_numrows($admins) == 1) {
    
$login $_POST['login'];
    
$password $_POST['password'];
    
session_register("login");
    
session_register("password");
                                 }
 else echo 
"<center>Данные не верны!<br><br></center>
 
$admin_login_form"// форма 
}
    else if(!isset(
$_SESSION['login']) && !isset($_SESSION['password']))
    echo 
$admin_login_form;

if(isset(
$_SESSION['login']) && isset($_SESSION['password'])) {

$admins mysql_query("SELECT * FROM admin WHERE login = '"$_SESSION['login']."' AND password = '"$_SESSION['password']."'");

if(
mysql_numrows($admins) == 1) {
    if(
$_GET['action'] == "content") echo "<a href=\"http://"$_SERVER['HTTP_HOST'] ."/admin/content/\">Контент</a>"// используется мод реврайт
    
if($_GET['action'] == "catalog") echo "<a href=\"http://"$_SERVER['HTTP_HOST'] ."/admin/catalog/\">Каталог</a>";  // используется мод реврайт
    
if($_GET['action'] == "profile") echo "<td width=25% align=center><b class=\"no_underline\">Сменить&nbsp;пароль</b></td>"// используется мод реврайт
    
echo "<a href=\"http://"$_SERVER['HTTP_HOST'] ."/admin/logout/\">Выйти</a>"// используется мод реврайт
    
echo "<br><br>";

    if(isset(
$_GET['action'])) {
        if(
$_GET['action'] == "content") include("admin/content.php");
          if(
$_GET['action'] == "catalog") include("admin/catalog.php");
          if(
$_GET['action'] == "profile") include("admin/profile.php");
                                }
} else echo 
"Данные не верны!
             <br><br>
             
$admin_login_form";
}
include(
"design/foot.inc.php"); // подвальчик
?>


Еще прошу подсказать, как осуществить шифрование пароля md5.
Спасибо заранее.

   
 
 автор: elenaki   (09.01.2007 в 21:44)   письмо автору
 
   для: provodnik   (09.01.2007 в 21:33)
 

перед тем, как POST-переменные скармливать базе, их надо пропустить через mysql_escape_string(). это первое, что бросилось в глаза...

   
 
 автор: kis-kis   (09.01.2007 в 21:45)   письмо автору
 
   для: elenaki   (09.01.2007 в 21:44)
 

>>перед тем, как POST-переменные скармливать базе, их надо пропустить через mysql_escape_string(). это первое, что бросилось в глаза...

Это очень важно?

   
 
 автор: Sergey89   (09.01.2007 в 21:46)   письмо автору
 
   для: kis-kis   (09.01.2007 в 21:45)
 

>> Это очень важно?
Очень очень. Хотя хватит и addslashes()

   
 
 автор: kis-kis   (09.01.2007 в 21:44)   письмо автору
 
   для: provodnik   (09.01.2007 в 21:33)
 

$password = md5($password);

   
 
 автор: DEM   (09.01.2007 в 21:50)   письмо автору
 
   для: provodnik   (09.01.2007 в 21:33)
 

Нет не безопасный... через $_POST['login'] and $_POST['password'] могут передать очень разые данные и особено данные которые могут вас сломать... сделайте например так:
$login = htmlspecialchars(stripslashes($_POST['login']), ENT_QUOTES);
$'password' = htmlspecialchars(stripslashes($_POST['password']), ENT_QUOTES);

Ну что нить вроде этого...

   
 
 автор: elenaki   (09.01.2007 в 21:54)   письмо автору
 
   для: DEM   (09.01.2007 в 21:50)
 

а еще - не стоит хранить авторизацию в сессии. лучше хранить идентификатор сессии в базе. и проверять его при каждом обращении к админским файлам.

   
 
 автор: DEM   (09.01.2007 в 21:59)   письмо автору
 
   для: elenaki   (09.01.2007 в 21:54)
 

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

   
 
 автор: LuxeMate   (09.01.2007 в 22:08)   письмо автору
 
   для: DEM   (09.01.2007 в 21:59)
 

Я никогда не проверяю данные при записи,но за то всегда вывожу их с htmlspecialchars()

>а еще - не стоит хранить авторизацию в сессии.
А это ещё почему?

   
 
 автор: provodnik   (09.01.2007 в 22:41)   письмо автору
 
   для: DEM   (09.01.2007 в 21:50)
 

Значит поступаю так:


$login = $_POST['login']; 
$password = $_POST['password']; 

меняю на:

$login = htmlspecialchars(stripslashes($_POST['login']), ENT_QUOTES);
$'password' = htmlspecialchars(stripslashes($_POST['password']), ENT_QUOTES);

DEM - если не сложно, прошу объяснить действие этих строк.

elenaki - можно чуть подробнее о хранении идентификатора сессии в базе. и проверке его при каждом обращении к админским файлам. Хотелось бы с примерами кода, если не затруднит.

LuxeMate - тоже попрошу немного подробнее о выводе данных, используя htmlspecialchars().

kis-kis - мне во многих примерах кода попадается данный пример: $password = md5($password);
Нельзя ли подробнее, особенно о моменте сравнения данных полученных из базы.

Прошу прощения за такие вопросы... ( Только учусь...)
Заранее спасибо.

   
 
 автор: Poison   (09.01.2007 в 23:12)   письмо автору
 
   для: provodnik   (09.01.2007 в 22:41)
 

md5 возвращает хеш код строки=) Например когда пользователь регистрируется
создается хеш код его пароля тобишь

$password = md5($password);

и добавляеться в базу...
а потом при его авторизации сравниваються данные введенные пользователем (также хешируемые)
$user_pass = md5($_POST['pass']); 
и с бд=)) если
эти хеши совпадают то все верно!!!

   
 
 автор: NIK   (09.01.2007 в 23:28)   письмо автору
 
   для: provodnik   (09.01.2007 в 22:41)
 

попробую взять ответы на себя :)

1) функция htmlspecialchars() позволяет не выполнять любой код (тобишь PHP, JavaScript, PERL и тд и тп), который может быть как и безполезным, так и полезным. Проще говоря, любой код который злоумышленник может вписать в форме, не будет исполняться, а будет выводиться как обычный текст.
В частности у тебя этой функции нет, поэтому реально применить SQL-инъекцию. Если не слышал про это, то советую прочитать статью http://www.softtime.ru/info/articlephp.php?id_article=35
2) функция md5() возвращает хэш строки. Проще говоря строка кодируется. Раскодировать такую строку нереально. Это значительно повышает защищённость скрипта, так как если злоумышленнику удасться украсть у тебя этот md5-хэш, то расшифровать он его не сможет, а значит он будет бесполезным.

Больше со стороны безопасности вроде ничего не заметно..

LuxeMate, насчёт применения htmlcpecialchars при выводе из БД я тебя не понимаю. Это конечно же не помешает, но всё-таки применять её следует при внесении данных в БД. В противном случае можно вписать PHP-код, который удалит всё к чертям, и выводить тебе будет нечем :)

   
 
 автор: LuxeMate   (09.01.2007 в 23:36)   письмо автору
 
   для: NIK   (09.01.2007 в 23:28)
 

Ок....исправлюсь,а ведь при выводе тоже её нада,или не обязательно если при записи применяется htmlspecialchars()??

>2) функция md5() возвращает хэш строки. Проще говоря строка кодируется. Раскодировать такую строку нереально. Это значительно повышает защищённость скрипта, так как если злоумышленнику удасться украсть у тебя этот md5-хэш, то расшифровать он его не сможет, а значит он будет бесполезным.

Чтобы ф-ция стала действительно безопасной нада так зашифровать,по полной программе,так же это зависит и от сложности пароля))

   
 
 автор: Poison   (09.01.2007 в 23:37)   письмо автору
 
   для: LuxeMate   (09.01.2007 в 23:36)
 

Если при записи применял то нет смысла ее изпользовать еще и при выврде=) это извращение:)))

   
 
 автор: colix   (09.01.2007 в 23:45)   письмо автору
 
   для: Poison   (09.01.2007 в 23:37)
 

А кто мне объяснит чем функция шифрования md5 лучше crypt? Только больно не бейте! Я тоже только учусь)))
И ещё чем отличается
'$password'
от
$password

   
 
 автор: DEM   (09.01.2007 в 23:46)   письмо автору
 
   для: colix   (09.01.2007 в 23:45)
 

Если я не ошибаюсь, crypt можно дешифровать довольно легко...

   
 
 автор: colix   (09.01.2007 в 23:49)   письмо автору
 
   для: DEM   (09.01.2007 в 23:46)
 

Да?А как?

   
 
 автор: colix   (09.01.2007 в 23:50)   письмо автору
 
   для: colix   (09.01.2007 в 23:49)
 

Ещё мне непонятна строка
$_GET['action']

И если кто знает дайте плиз ссылку где про это можно прочесть.

   
 
 автор: NIK   (09.01.2007 в 23:58)   письмо автору
 
   для: colix   (09.01.2007 в 23:50)
 

чем отличается '$password' от $password - смотря где вы это увидели

строки зашифрованные crypt() насколько я помню расшифровать нельзя, это можно расшифровать зашифрованные ф-ей с похожим названием из какой-то доп. библиотеки..

$_GET['action'] - это переменная, которая передаётся методом GET. То есть если в адресе в браузере прописать localhost/index.php?action=true, то $_GET['action'] будет содержать в себе строку true

PS: а вообще это не ваша тема, так что лучше создать новую :)

   
 
 автор: colix   (10.01.2007 в 00:02)   письмо автору
 
   для: NIK   (09.01.2007 в 23:58)
 

А можно попросить ПРОСТОЙ ПРАКТИЧЕСКИЙ пример для понимания?

   
 
 автор: DEM   (09.01.2007 в 23:44)   письмо автору
 
   для: LuxeMate   (09.01.2007 в 23:36)
 

Как написал Poison это извращение, но лично я всё равно так делаю :) Мало ли )))

   
 
 автор: provodnik   (10.01.2007 в 00:05)   письмо автору
 
   для: NIK   (09.01.2007 в 23:28)
 

Т.е. мои действия замены ( в соответствии с подсказкой товарища DEM )


$login = $_POST['login'];  
$password = $_POST['password']; 

на

$login = htmlspecialchars(stripslashes($_POST['login']), ENT_QUOTES); 
$'password' = htmlspecialchars(stripslashes($_POST['password']), ENT_QUOTES);  

верны?

DEM - прошу подсказать на примере моего кода, как и где применить вывод, с использованием приведенных вами функций.

Так же прошу "тыкнуть" место, где применить md(5)

Спасибо за скорые и насыщенно_информационные ответы...

   
 
 автор: NIK   (10.01.2007 в 00:09)   письмо автору
 
   для: provodnik   (10.01.2007 в 00:05)
 

верны, только я не понимаю зачем в $'password' нужны апострофы.. это вызывает ошибку. Пиши просто $password. Только делать это бессмыслено, если эти переменные ($login & $password) нигде не применяются.

> DEM - прошу подсказать на примере моего кода, как и где применить вывод, с использованием приведенных вами функций.

DEM, можно я за тебя? :) provodnik, мы тут решили, что логичнее бедет применять эту функцию не для выводa, а наоборот, для занесения данных из формы в БД. Логично будет применить здесь:


$admins = mysql_query("SELECT * FROM admin WHERE login = '". htmlspecialchars(stripslashes($_POST['login']))."' AND password = '". htmlspecialchars(stripslashes($_POST['password']))."'");
...
$admins = mysql_query("SELECT * FROM admin WHERE login = '". htmlspecialchars(stripslashes($_SESSION['login']))."' AND password = '". htmlspecialchars(stripslashes($_SESSION['password']))."'");

   
 
 автор: colix   (10.01.2007 в 00:14)   письмо автору
 
   для: NIK   (10.01.2007 в 00:09)
 


$password = htmlspecialchars(stripslashes(md5($_POST['password')]), ENT_QUOTES);

Вроде так...
Далее пишем всю эту прелесть в базу...

   
 
 автор: Poison   (10.01.2007 в 00:20)   письмо автору
 
   для: colix   (10.01.2007 в 00:14)
 

Не так=)) Ты сначала создаешь хеш а потом убираешь все теги, которые посути та уже в хеше

   
 
 автор: colix   (10.01.2007 в 00:32)   письмо автору
 
   для: Poison   (10.01.2007 в 00:20)
 

Так?

$password = md5(htmlspecialchars(stripslashes($_POST['password']), ENT_QUOTES));

   
 
 автор: provodnik   (10.01.2007 в 00:47)   письмо автору
 
   для: colix   (10.01.2007 в 00:32)
 

Вот толь нюанс один ( :
у меня ручками была занесена строка в базу, с админ аккаунтом ( она там единственная)

Другими словами: как же мне занести "всё это дело" в базу то? (

   
 
 автор: Poison   (10.01.2007 в 01:07)   письмо автору
 
   для: provodnik   (10.01.2007 в 00:47)
 


INSERT INTO (name, password) VALUE ($_POST['n'], $_POST['p']);

   
 
 автор: provodnik   (10.01.2007 в 01:12)   письмо автору
 
   для: provodnik   (09.01.2007 в 21:33)
 

Всем спасибо за оказанное содействие начинающему...
Теперь буду вставлять ваши примеры кодов и тестировать.
Спасибо... (((

Добавляю после тестирования:
Сразу попрошу прощения у администраторов и пользователей за большие куски кода...


Вот код файла админ профиля ( "заливателя" в базу):

<?
if(isset($_POST['login']))
{    if(
$_POST['login'] != "" && $_POST['password'] != "")
    {    
$_POST['login'] = str_replace('"''"'$_POST['login']);
        
$_POST['login']  = htmlspecialchars(stripslashes($_POST['login']), ENT_QUOTES); 
        
$_POST['password'] = str_replace('"''"'$_POST['password']);
        
$_POST['password']  = md5(htmlspecialchars(stripslashes($_POST['password']), ENT_QUOTES)); 
        
$change mysql_query("UPDATE admin SET login = '"$_POST['login'] ."', password = '"$_POST['password'] ."'");
    }
}

if(isset(
$_GET['op']) && $_GET['op'] == "edit")
{    
$profile mysql_query("SELECT * FROM admin");

    if(
mysql_numrows($profile) == 1)
    {    
$profile mysql_fetch_array($profile);
        if(isset(
$_POST['login'])) $_POST['login'] = str_replace('"''&quot;'$_POST['login']);
        
$profile['login'] = str_replace('"''&quot;'$profile['login']);
        
$profile['login']  = htmlspecialchars(stripslashes($profile['login']), ENT_QUOTES);
        if(isset(
$_POST['password'])) $_POST['password'] = str_replace('"''&quot;'$_POST['password']);
        
$profile['password'] = str_replace('"''&quot;'$profile['password']);
        
$profile['password']  = htmlspecialchars(stripslashes($profile['password']), ENT_QUOTES);

    echo 
"<form method=post action=\"http://"$_SERVER['HTTP_HOST'] ."/admin/profile/\">";
    echo 
"Редактировать данные владельца";
    echo 
"Логин - <input size=50 name=login type=text value=\""$profile['login'] ."\">
          Пароль - <input size=50 name=password type=text value=\""
$profile['password'] ."\">
          <input type=submit value=\"Изменить\"></form>"
;
    } else echo 
"Ошибка!";
}
else 
{    
$profile mysql_query("SELECT * FROM admin");
    
    if(
mysql_numrows($profile) == 1)
    {    
$profile mysql_fetch_array($profile);
        echo 
"Данные админа";
        echo 
"Логин - "$profile['login'] ."
        Пароль - "
$profile['password'] ."
        <a href=\"http://"
$_SERVER['HTTP_HOST'] ."/admin/profile/edit/\">Изменить данные</a>";
    } else echo 
"Ошибка!";
}
?>


Теперь код страницы admin.php:


<? 
session_start
(); 
include(
"mysql.php"); //файл с переменными для коннекта к базе 
include("config.php"); //файл с переменными для управления сайтом 

$title "Панель администратора"
include(
"design/top.inc.php"); // шапчёнка 

      
if($_GET['action'] == "logout"){ 
      if(isset(
$_SESSION['login']) && isset($_SESSION['password']))    { 
            
session_unregister("login"); 
            
session_unregister("password"); 
      } 
      } 

if(isset(
$_POST['login']) && isset($_POST['password']) && !isset($_SESSION['login']) && !isset($_SESSION['password'])) { 

//это было
//$admins = mysql_query("SELECT * FROM admin WHERE login = '". $_POST['login']."' AND password = '". $_POST['password']."'"); 

//стало теперь:
$admins mysql_query("SELECT * FROM admin WHERE login = '"htmlspecialchars(stripslashes($_POST['login']))."' AND password = '".md5(htmlspecialchars(stripslashes($_POST['password'])))."'"); 

if(
mysql_numrows($admins) == 1) { 

//это было
 //   $login = $_POST['login']; 
 //   $password = $_POST['password']; 

//стало теперь:
$login htmlspecialchars(stripslashes($_POST['login']), ENT_QUOTES);  
$password md5(htmlspecialchars(stripslashes($_POST['password']), ENT_QUOTES));

    
session_register("login"); 
    
session_register("password"); 
                                 } 
 else echo 
"<center>Данные не верны!<br><br></center> 
 
$admin_login_form"// форма  

    else if(!isset(
$_SESSION['login']) && !isset($_SESSION['password'])) 
    echo 
$admin_login_form

if(isset(
$_SESSION['login']) && isset($_SESSION['password'])) { 

//это было
//$admins = mysql_query("SELECT * FROM admin WHERE login = '". $_SESSION['login']."' AND password = '". $_SESSION['password']."'"); 

//стало теперь:
$admins mysql_query("SELECT * FROM admin WHERE login = '"htmlspecialchars(stripslashes($_SESSION['login']))."' AND password = '".md5(htmlspecialchars(stripslashes($_SESSION['password'])))."'");

if(
mysql_numrows($admins) == 1) { 
    if(
$_GET['action'] == "content") echo "<a href=\"http://"$_SERVER['HTTP_HOST'] ."/admin/content/\">Контент</a>"// используется мод реврайт 
    
if($_GET['action'] == "catalog") echo "<a href=\"http://"$_SERVER['HTTP_HOST'] ."/admin/catalog/\">Каталог</a>";  // используется мод реврайт 
    
if($_GET['action'] == "profile") echo "<td width=25% align=center><b class=\"no_underline\">Сменить&nbsp;пароль</b></td>"// используется мод реврайт 
    
echo "<a href=\"http://"$_SERVER['HTTP_HOST'] ."/admin/logout/\">Выйти</a>"// используется мод реврайт 
    
echo "<br><br>"

    if(isset(
$_GET['action'])) { 
        if(
$_GET['action'] == "content") include("admin/content.php"); 
          if(
$_GET['action'] == "catalog") include("admin/catalog.php"); 
          if(
$_GET['action'] == "profile") include("admin/profile.php"); 
                                } 
} else echo 
"Данные не верны! 
             <br><br> 
             
$admin_login_form"

include(
"design/foot.inc.php"); // подвальчик 
?> 


Дамп таблицы:

INSERT INTO `admin` VALUES (1, 'admin', '21232f297a57a5a743894a0e4a801fc3');


Никак не могу найти ошибку. Постоянно выводит - Данные не верны!
Прошу меня "тыкнуть носом".
Еще раз прошу простить за постинг кода...
Заранее спасибо...

   
 
 автор: kod   (14.01.2007 в 03:49)   письмо автору
 
   для: provodnik   (10.01.2007 в 01:12)
 

Господа кодеры - подскажите автору. Просто сам ищу повозможности готовый код авторизации. И в этой теме как нельзя подробно всё расписано, за исключением сообщения выше.
Хотелось бы "доработать" данный код, для дальнейшего использования его на сайте. Может в нем есть еще какие нибудь уязвимые места?

   
 
 автор: cheops   (14.01.2007 в 13:16)   письмо автору
 
   для: kod   (14.01.2007 в 03:49)
 

Возможно вам будут интересны статьи
http://www.softtime.ru/info/articlephp.php?id_article=34
http://www.softtime.ru/info/articlephp.php?id_article=27
темы форума
http://www.softtime.ru/forum/read.php?id_forum=1&id_theme=8481
http://www.softtime.ru/forum/read.php?id_forum=1&id_theme=80
и приложение
http://www.softtime.ru/info/authorization.php

   
 
 автор: Sergey89   (14.01.2007 в 13:58)   письмо автору
 
   для: provodnik   (10.01.2007 в 01:12)
 

$login = htmlspecialchars(stripslashes($_POST['login']), ENT_QUOTES);  
$password = md5(htmlspecialchars(stripslashes($_POST['password']), ENT_QUOTES));

Зачем так длинно? Достаточно:
$login = addslashes($_POST['login']);  
$password = md5($_POST['password']);

   
 
 автор: provodnik   (14.01.2007 в 15:58)   письмо автору
 
   для: Sergey89   (14.01.2007 в 13:58)
 

>Зачем так длинно? Достаточно:

>
$login = addslashes($_POST['login']);  
>$password = md5($_POST['password']);


А это делать, при вводе админом данных в базу? или когда проверяешь переменные , которые пришли из формы ? Или в обоих случаях?

   
 
 автор: Sergey89   (14.01.2007 в 16:08)   письмо автору
 
   для: provodnik   (14.01.2007 в 15:58)
 

$admins = mysql_query("SELECT * FROM admin WHERE login = '". addslashes($_SESSION['login'])."' AND password = '".md5($_SESSION['password'])."'");  

   
Rambler's Top100
вверх

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