Ïàðîëüíàÿ çàùèòà
Àâòîð: | Àðòåìüåâ Ñåðãåé Èãîðåâè÷ |
ICQ: | 438856621 |
email: | _spin_@bk.ru |
Îäíà èç îñíîâíûõ àêñèîì çàùèòû èíôîðìàöèè ãëàñèò - "êîìôîðòíîñòü ñèñòåìû îáðàòíî ïðîïîðöèîíàëüíà å¸ çàùèù¸ííîñòè". Ýòî çíà÷èò, ÷òî ïðè âûáîðå ñèñòåìû çàùèòû íåîáõîäèìî íàéòè îïòèìàëüíîå ñîîòíîøåíèå ñëîæíîñòè çàùèòû è óäîáñòâà ðàáîòû ïîëüçîâàòåëåé.
Ñ äðóãîé ñòîðîíû, ðàçðàáîòêà è âíåäðåíèå çàùèòû òðåáóåò îïðåäåë¸ííûõ çàòðàò ñèë è ñðåäñòâ. Ñëåäîâàòåëüíî, íàäî ðàçóìíî ïîäõîäèòü ê ïðîåêòèðîâàíèþ çàùèòû. Ïðîùå ãîâîðÿ, íå íàäî äåëàòü ñëîæíóþ è äîðîãîñòîÿùóþ ñèñòåìó çàùèòû, åñëè íà ñàéòå íå õðàíèòñÿ íè÷åãî öåííîãî. Íè îäèí çëîóìûøëåííèê íå ïîëåçåò ëîìàòü âàøó äîìàøíþþ ñòðàíè÷êó, ñàéò-âèçèòêó íåáîëüøîé êîìïàíèè èëè ñàéò äåòñêîãî ñàäà.
 ïðåäûäóùåì óðîêå ìû ðàññìàòðèâàëè àâòîðèçàöèþ ñðåäñòâàìè Web-ñåðâåðà (Basic-àâòîðèçàöèÿ). Íàâåðíîå, ýòî ñàìûé ë¸ãêèé è ñàìûé áåçîïàñíûé ñïîñîá îãðàíè÷åíèÿ äîñòóïà ê ðåñóðñàì. Îäíàêî, ñîïðîâîæäåíèå òàêîãî ìåõàíèçìà äîñòàòî÷íî òðóäî¸ìêî, îñîáåííî ïðè áîëüøîì êîëè÷åñòâå ïîëüçîâàòåëåé ñ ðàçëè÷íûìè ïðàâàìè. Êðîìå òîãî, íå âñå ñåðâåðà ïîçâîëÿþò èñïîëüçîâàòü HTTP-àâòîðèçàöèþ.
Áîëåå ïîïóëÿðíàÿ àëüòåðíàòèâà - ïàðîëüíàÿ çàùèòà. Ñìûñë å¸ â òîì, ÷òî íà ñåðâåðå õðàíÿòñÿ ñïèñêè ïîëüçîâàòåëåé è ñîîòâåòñòâóþùèå èì ëîãèíû, ïàðîëè è ïðàâà äîñòóïà. Ïðè ïåðâîì îáðàùåíèè ê ñàéòó ïîëüçîâàòåëü ââîäèò ëîãèí/ïàðîëü è ïîëó÷àåò äîñòóï ê ðåñóðñàì. Ñåðâåð "çàïîìèíàåò" ïîëüçîâàòåëÿ è íå ñïðàøèâàåò ïàðîëü äî ñëåäóþùåãî îòêðûòèÿ ñåññèè (ïåðåçàïóñêà áðàóçåðà).
Îðãàíèçàöèÿ ïàðîëüíîé çàùèòû öåëèêîì è ïîëíîñòüþ ëîæèòñÿ íà ïëå÷è ïðîãðàììèñòà. Ðàçðàáîò÷èê äîëæåí ñàì îáåñïå÷èòü áåçîïàñíîñòü õðàíåíèÿ ñïèñêîâ ïîëüçîâàòåëåé, ïðîâåðêó ëîãèíîâ/ïàðîëåé, ñîõðàíåíèå êîíòåêñòîâ áåçîïàñíîñòè è èõ ïîâòîðíîå èñïîëüçîâàíèå. Ïîä êîíòåêñòîì áåçîïàñíîñòè çäåñü ïîíèìàåòñÿ íàáîð ïàðàìåòðîâ, îäíîçíà÷íî îïðåäåëÿþùèõ ïîëüçîâàòåëÿ (êàê ìèíèìóì ýòî ëîãèí, ïàðîëü è èäåíòèôèêàòîð ñåññèè).
Ðàññìîòðè ïðèìåð ðåàëèçàöèè ïðîñòåéøåé ïàðîëüíîé çàùèòû. Ñîçäàäèì ôàéë logon.php
<div> <?php $login = isset($_GET['login'])?$_GET['login']:''; $passwd = isset($_GET['passwd'])?$_GET['passwd']:''; if($login != '' || $passwd != '') { if($login == 'admin' && $passwd == 'megaPass') echo 'Äîñòóï ðàçðåøåí'; else echo 'Äîñòóï çàïðåùåí!'; } else echo 'Ââåäèòå ëîãèí è ïàðîëü'; ?> </div> <form action="logon.php" method="get"> <input type="text" value="" name="login" /> <input type="password" value="" name="passwd" /> <input type="submit" value="âõîä" /> </form>
Ïðè íàæàòèè íà êíîïêó "âõîä" äàííûå ôîðìû áóäóò îòïðàâëåíû íà ñåðâåð, òàì ñêðèïò ïðîâåðèò ââåä¸ííûå ëîãèí è ïàðîëü è åñëè îíè ðàâíû "admin" è "megaPass" ñîîòâåòñòâåííî - îòîáðàçèò ñîîáùåíèå, ÷òî âõîä ðàçðåøåí. Åñëè ëîãèí èëè ïàðîëü íå âåðíû - ïîëüçîâàòåëü óâèäèò ïðåäóïðåæäàþùåå ñîîáùåíèå.
Ïåðâûé íåäîñòàòîê ýòîãî ñêðèïòà: ïåðåäà÷à äàííûõ ìåòîäîì GET. Ïðè èñïîëüçîâàíèè ýòîãî ìåòîäà äàííûå ïåðåäàþòñÿ íåïîñðåäñòâåííî â àäðåñå, à çíà÷èò âèäíû äàæå íåâîîðóæåííûì ãëàçîì. Íàïðèìåð, åñëè âû ââåëè ïðàâèëüíûå ëîãèí è ïàðîëü, òî â àäðåñíîé ñòðîêå óâèäèòå
http://localhost/logon.php?login=admin&passwd=megaPass
Âòîðîé íåäîñòàòîê: èìåíà ïîëüçîâàòåëåé è ïàðîëè çàøèòû ïðÿìî â êîä. Ýòî çíà÷èò, ÷òî äëÿ äîáàâëåíèÿ íîâûõ ïîëüçîâàòåëåé âàì íàäî áóäåò ïîñòîÿííî ìåíÿòü êîä ôàéëà. À ïðåäñòàâüòå ñåáå, êàêîãî ðàçìåðà áóäåò ôàéë, åñëè ó âàñ íà ñàéòå õîòÿ-áû òûñÿ÷à çàðåãèñòðèðîâàííûõ ïîëüçîâàòåëåé... Ñïèñêè ïîëüçîâàòåëåé ëó÷øå âñåãî õðàíèòü â îòäåëüíîì ôàéëå, à ëó÷øå â áàçå äàííûõ, ò.ê. çëîóìûøëåííèêó ôàéë óêðàñòü íàìíîãî ïðîùå, ÷åì äîáûâàòü ÷òî-òî èç áàçû äàííûõ.
Òðåòèé íåäîñòàòîê: ðåçóëüòàòû âõîäà ïîëüçîâàòåëÿ íå çàïîìèíàþòñÿ, ò.å. äîñòàòî÷íî îáíîâèòü ñòðàíèöó è âàñ ñíîâà ïîïðîñÿò ââåñòè ïàðîëü.
Èòàê, ðàññìîòðèì ñïîñîáû óñòðàíåíèÿ ýòèõ íåäîñòàòêîâ.
Ñêðûòü ïåðåäàâàåìûå äàííûå ïðîùå âñåãî èñïîëüçóÿ ìåòîä ïåðåäà÷è POST.  ýòîì ñëó÷àå áðàóçåð ñàì (ñêðûòíî îò ïîëüçîâàòåëÿ) ïåðåäàñò ñåðâåðó âñå íåîáõîäèìûå äàííûå è ïåðåõâàòèòü èõ ìîæíî áóäåò òîëüêî ñïåöèàëüíûìè ïðîãðàììàìè èç àðñåíàëà IT-ñïåöèàëèñòîâ, ïðîãðàììèñòîâ èëè õàêåðîâ.
Êàê ãîâîðèëîñü âûøå, ñïèñêè ïîëüçîâàòåëåé íàäî õðàíèòü îòäåëüíî. Ñîçäàäèì òàáëèöó â òåñòîâîé áàçå äàííûõ:
CREATE TABLE `smplusers` (
`user_id` int(11) NOT NULL auto_increment,
`user_name` varchar(50) NOT NULL,
`user_login` varchar(50) NOT NULL,
`user_password` varchar(50) NOT NULL,
`reg_date` datetime NOT NULL,
PRIMARY KEY (`user_id`)
)
è äîáàâèì â íå¸ íåñêîëüêî çàïèñåé ïîëüçîâàòåëåé:
INSERT INTO smplUsers
(user_name, user_login, user_password, reg_date)
values
('Èâàíîâ È.È.', 'ivanov-i-i', 'pass1', NOW()),
('Ïåòðîâ Ï.Ï.', 'petrovich', 'pass2', NOW()),
('Ñèäîðîâ Ñ.Ñ.', 'sidorov', 'pass3', NOW())
Îáðàòèòå âíèìàíèå, ÷òî îïåðàòîð INSERT äîïóñêàåò îäíîâðåìåííîå äîáàâëåíèå â òàáëèöó ñðàçó íåñêîëüêèõ çàïèñåé, ïðè ýòîì äàííûå ïåðå÷èñëÿþòñÿ áëîêàìè ÷åðåç çàïÿòóþ.
Òåïåðü èçìåíèì logon.php òàêèì îáðàçîì, ÷òîáû èìÿ ïîëüçîâàòåëÿ è ïàðîëü êîððåêòíî ïðîâåðÿëèñü íåïîñðåäñòâåííî â áàçå äàííûõ:
<?php
// çäåñü ïîäêëþ÷àåìñÿ ê áàçå äàííûõ
// $link - ññûëêà íà ïîäêëþ÷åíèå
$link = mysql_connect('localhost', 'db_user', 'db_passwd');
mysql_select_db('db_name', $link);
?>
<div> <?php
$login = isset($_POST['login'])?$_POST['login']:'';
$passwd = isset($_POST['passwd'])?$_POST['passwd']:'';
$login = mysql_real_escape_string($login);
$passwd = mysql_real_escape_string($passwd);
if($login != '' || $passwd != '')
{
$sql = "SELECT * FROM smplUsers
WHERE user_login = '$login'
AND user_password = '$passwd'
LIMIT 1";
$qry = mysql_query($sql, $link);
if($qry)
{
if(mysql_num_rows($qry) > 0)
{
echo 'Äîñòóï ðàçðåøåí<br />' . "\n";
$row = mysql_fetch_array($qry);
echo 'Ïîëüçîâàòåëü: ' . $row['user_name'];
}
else
echo 'Äîñòóï çàïðåùåí!';
}
}
else
echo 'Ââåäèòå ëîãèí è ïàðîëü';
?>
</div> <form action="passes.php" method="post" enctype="application/form-data">
<input type="text" value="" name="login" />
<input type="password" value="" name="passwd" />
<input type="submit" value="LogIn" />
</form>
Òåïåðü ëîãèí è ïàðîëü ïåðåäàþòñÿ ñêðûòíî, à ó÷¸òíûå äàííûå î÷åíü ïðîñòî èçìåíèòü, îòðåäàêòèðîâàâ òàáëèöó â áàçå äàííûõ. Îñòàëñÿ ïîñëåäíèé øòðèõ - íàó÷èòü ñåðâåð çàïîìèíàòü ôàêò ðåãèñòðàöèè. Ïðîùå âñåãî ñäåëàòü ýòî ïðè ïîìîùè ìåõàíèçìà ñåññèé. Âíåñ¸ì íåîáõîäèìûå èçìåíåíèÿ:
<?php // îòêðûâàåì ñåññèþ
session_start(); if(!$_SESSION['user_id']) $_SESSION['user_id'] = -1; // çäåñü ïîäêëþ÷àåìñÿ ê áàçå äàííûõ ...
?>
<div> <?php if($_SESSION['user_id'] == -1) {
$login = isset($_POST['login'])?$_POST['login']:'';
...
if(mysql_num_rows($qry) > 0)
{
echo 'Äîñòóï ðàçðåøåí<br />' . "\n";
$row = mysql_fetch_array($qry);
echo 'Ïîëüçîâàòåëü: ' . $row['user_name']; $_SESSION['user_id'] = $row['user_id']; $_SESSION['user_name'] = $row['user_name'];
}
... } else echo 'Çäðàâñòâóéòå, ' . $_SESSION['user_name'];
?>
</div> ...
Òåïåðü ñåðâåð áóäåò çàïîìèíàòü êàæäîãî ïîëüçîâàòåëÿ, óñïåøíî âîøåäøåãî â ñèñòåìó, à ïðè ñëåäóþùåì îáíîâëåíèè ñòðàíèöû áóäåò âûâîäèòüñÿ ïðèâåòñòâåííîå ñîîáùåíèå.
Ýòî ñêðèïò - ëèøü ïðèìåð îðãàíèçàöèè ïàðîëüíîé çàùèòû, ïóñòü è âïîëíå ôóíêöèîíàëüíûé. Ñäåëàòü èç íåãî ïðàêòè÷åñêè öåííûé îáðàçåö ìîæíî, äîáàâèâ ïðîâåðêó ââîäèìûõ äàííûõ, ôóíêöèè øèôðîâàíèÿ, âîññòàíîâåíèÿ ïàðîëÿ, çàâåðøåíèÿ ñåññèè è äð.