cvs: phpdoc-ru /chapters security.xml
| From: | Alexey Asemov | Date: | Sat, 18 Jan 2003 19:57:17 +0000 |
| Subject: | cvs: phpdoc-ru /chapters security.xml | ||
| Groups: | php.doc.ru | ||
| Request: | Send a blank email to doc-ru+get-72@lists.php.net to get a copy of this message | ||
alexws Sat Jan 18 14:57:17 2003 EDT
Modified files:
/phpdoc-ru/chapters security.xml
Log:
Translated this large file (security.xml) fully. Status - ready. Phew...
Index: phpdoc-ru/chapters/security.xml diff -u phpdoc-ru/chapters/security.xml:1.1 phpdoc-ru/chapters/security.xml:1.2 --- phpdoc-ru/chapters/security.xml:1.1 Wed Dec 25 11:40:35 2002 +++ phpdoc-ru/chapters/security.xml Sat Jan 18 14:57:17 2003 @@ -1,6 +1,6 @@ -<?xml version="1.0" encoding="iso-8859-1"?> -<!-- EN-Revision: 1.49 Maintainer: alexws Status: in-progress --> -<!-- $Revision: 1.1 $ --> +<?xml version="1.0" encoding="windows-1251"?> +<!-- EN-Revision: 1.50 Maintainer: alexws Status: ready --> +<!-- $Revision: 1.2 $ --> <chapter id="security"> <title>Áåçîïàñíîñòü</title> @@ -217,71 +217,68 @@ <sect2 id="security.cgi-bin.doc-root"> <title>Âàðèàíò 3: óñòàíîâêà doc_root èëè user_dir</title> <simpara> - To include active content, like scripts and executables, in the - web server document directories is sometimes consider an insecure - practice. If, because of some configuration mistake, the scripts - are not executed but displayed as regular HTML documents, this - may result in leakage of intellectual property or security - information like passwords. Therefore many sysadmins will prefer - setting up another directory structure for scripts that are - accessible only through the PHP CGI, and therefore always - interpreted and not displayed as such. + Ïîìåùåíèå àêòèâíîãî ñîäåðæèìîãî (âðîäå ïðîãðàìì è èñïîëíÿåìûõ ôàéëîâ) + â äèðåêòîðèè äîêóìåíòîâ Web-ñåðâåðà ñ÷èòàåòñÿ íåáåçîïàñíûì. Åñëè + â ñëó÷àå êàêîé-ëèáî îøèáêè â êîíôèãóðèðîâàíèè ïðîãðàììû íå âûïîëíÿòñÿ, + à îòîáðàçÿòñÿ êàê îáû÷íûå HTML-äîêóìåíòû, ýòî ïðèâåäåò ê óòå÷êå + èíòåëëåêòóàëüíîé ñîáñòâåííîñòè èëè ñêðûòîé èíôîðìàöèè âðîäå ïàðîëåé. + Ïîýòîìó ìíîãèå ñèñòåìíûå àäìèíèñòðàòîðû ïðåäïî÷èòàþò ñîçäàâàòü + îòäåëüíóþ ñòðóêòóðó äèðåêòîðèé äëÿ ïðîãðàìì, äîñòóïíûõ òîëüêî ÷åðåç + PHP CGI, à ïîýòîìó âñåãäà èíòåïðåòèðóåìûõ è îòîáðàæàåìûõ âåðíî. </simpara> <simpara> - Also if the method for making sure the requests are not - redirected, as described in the previous section, is not - available, it is necessary to set up a script doc_root that is - different from web document root. + Ê òîìó æå, åñëè íåäîñòóïåí ìåòîä áåçîïàñíîãî ïåðåíàïðàâëåíèÿ çàïðîñîâ, + îïèñàííûé â ïðåäûäóùåé ÷àñòè, íåîáõîäèìî óñòàíîâèòü doc_root äëÿ + ïðîãðàìì, îòëè÷íûé îò êîðíåâîãî êàòàëîãà äîêóìåíòîâ Web-ñåðâåðà. </simpara> <simpara> - You can set the PHP script document root by the configuration - directive <link linkend="ini.doc-root">doc_root</link> in the - <link linkend="configuration.file">configuration file</link>, or - you can set the environment variable - <envar>PHP_DOCUMENT_ROOT</envar>. If it is set, the CGI version - of PHP will always construct the file name to open with this - <parameter>doc_root</parameter> and the path information in the - request, so you can be sure no script is executed outside this - directory (except for <parameter>user_dir</parameter> - below). + Êîðíåâîé êàòàëîã äîêóìåíòîâ äëÿ ïðîãðàìì PHP ìîæíî óñòàíîâèòü + ñ ïîìîùüþ äèðåêòèâû <link linkend="ini.doc-root">doc_root</link> + â <link linkend="configuration.file">ôàéëå êîíôèãóðàöèè</link> èëè + ñ ïîìîùüþ ïåðåìåííîé îêðóæåíèÿ <envar>PHP_DOCUMENT_ROOT</envar>. + Åñëè òàêàÿ óñòàíîâêà ñäåëàíà, òî CGI-âåðñèÿ PHP âñåãäà áóäåò äîáàâëÿòü + ê èíôîðìàöèè ïóòè â çàïðîñå çíà÷åíèå ïàðàìåòðà + <parameter>doc_root</parameter>, òàê ÷òî â ýòîì ñëó÷àå âû ìîæåòå áûòü + óâåðåíû, ÷òî íè îäíà ïðîãðàììà íå âûïîëíèòñÿ çà ïðåäåëàìè ýòîé + äèðåêòîðèè (èñêëþ÷åíèå ñîñòàâëÿåò ëèøü ñëó÷àé ñ èñïîëüçîâàíèåì + ïàðàìåòðà <parameter>user_dir</parameter>, îïèñàííûé íèæå). </simpara> <simpara> - Another option usable here is <link - linkend="ini.user-dir">user_dir</link>. When user_dir is unset, - only thing controlling the opened file name is - <parameter>doc_root</parameter>. Opening an url like <filename - role="url">http://my.host/~user/doc.php</filename> does not - result in opening a file under users home directory, but a file - called <filename role="uri">~user/doc.php</filename> under - doc_root (yes, a directory name starting with a tilde - [<literal>~</literal>]). + Åùå îäíîé ïîëåçíîé îïöèåé ÿâëÿåòñÿ <link linkend="ini.user-dir">user_dir</link>. + Åñëè user_dir íå çàäàíà, òî åäèíñòâåííûì ôàêòîðîì, âëèÿþùèì íà èìÿ + îòêðûâàåìîãî ôàéëà ÿâëÿåòñÿ <parameter>doc_root</parameter>. Îòêðûòèå + ULR âðîäå <filename role="url">http://my.host/~user/doc.php</filename> + íå ïðèâåäåò â ýòîì ñëó÷àå ê îòêðûòèþ ôàéëà âíóòðè äîìàøíåãî êàòàëîãà + ïîëüçîâàòåëÿ.  ýòîì ñëó÷àå áóäåò îòêðûò ôàéë + <filename role="uri">~user/doc.php</filename> â êàòàëîãå, çàäàííîì â + doc_root. </simpara> <simpara> - If user_dir is set to for example <filename - role="dir">public_php</filename>, a request like <filename - role="url">http://my.host/~user/doc.php</filename> will open a - file called <filename>doc.php</filename> under the directory - named <filename role="dir">public_php</filename> under the home - directory of the user. If the home of the user is <filename - role="dir">/home/user</filename>, the file executed is - <filename>/home/user/public_php/doc.php</filename>. + Åñëè user_dir óñòàíîâëåíà, ê ïðèìåðó, â <filename + role="dir">public_php</filename>, òî çàïðîñ <filename + role="url">http://my.host/~user/doc.php</filename> îòêðîåò ôàéë + <filename>doc.php</filename> â êàòàëîãå <filename + role="dir">public_php</filename>, íàõîäÿùåìñÿ â äîìàøíåì êàòàëîãå + ïîëüçîâàòåëÿ. Åñëè äîìàøíèé êàòàëîã ïîëüçîâàòåëÿ - <filename + role="dir">/home/user</filename>, òî â ýòîì ñëó÷àå áóäåò îòêðûò + ôàéë <filename>/home/user/public_php/doc.php</filename>. </simpara> <simpara> - <parameter>user_dir</parameter> expansion happens regardless of - the <parameter>doc_root</parameter> setting, so you can control - the document root and user directory access - separately. + <parameter>user_dir</parameter> èñïîëüçóåòñÿ íåçàâèñèìî îò + <parameter>doc_root</parameter>, ÷òî äàåò âîçìîæíîñòü çàäàâàòü + êîðíåâóþ äèðåêòîðèþ äîêóìåíòîâ è ïîëüçîâàòåëüñêèå äèðåêòîðèè + íåçàâèñèìî äðóã îò äðóãà. </simpara> </sect2> <sect2 id="security.cgi-bin.shell"> - <title>Case 4: PHP parser outside of web tree</title> + <title>Âàðèàíò 4: òðàíñëÿòîð PHP âíå äåðåâà äîêóìåíòîâ Web</title> <para> - A very secure option is to put the PHP parser binary somewhere - outside of the web tree of files. In <filename - role="dir">/usr/local/bin</filename>, for example. The only real - downside to this option is that you will now have to put a line - similar to: + Âåñüìà áåçîïàñíûì ÿâëÿåòñÿ ïîìåùåíèå ïðîãðàììû-òðàíñëÿòîðà PHP + çà ïðåäåëàìè äåðåâà äîêóìåíòîâ Web-ñåðâåðà. Ê ïðèìåðó, â <filename + role="dir">/usr/local/bin</filename>. Ó ýòîãî âàðèàíòà åñòü ëèøü + îäèí íåäîñòàòîê - òî, ÷òî â íà÷àëî êàæäîãî ôàéëà ñ òýãàìè PHP ïðèäåòñÿ + ïîìåùàòü ñëåäóþùóþ ñòðîêó: <informalexample> <programlisting> <![CDATA[ @@ -289,333 +286,332 @@ ]]> </programlisting> </informalexample> - as the first line of any file containing PHP tags. You will also - need to make the file executable. That is, treat it exactly as - you would treat any other CGI script written in Perl or sh or any - other common scripting language which uses the - <literal>#!</literal> shell-escape mechanism for launching - itself. + . Òàêæå ïîòðåáóåòñÿ ñäåëàòü äàííûå ôàéëû èñïîëíÿåìûìè, ò.å. ïðèäåòñÿ + îáðàùàòüñÿ ñ íèìè òàê æå, êàê è ñ ëþáûìè äðóãèìè CGI-ïðîãðàììàìè íà + Perl, sh èëè íà äðóãèõ èçâåñòíûõ ÿçûêàõ, èñïîëüçóþùèõ êîíñòðóêöèþ + <literal>#!</literal> äëÿ çàïóñêà. </para> <para> - To get PHP to handle <envar>PATH_INFO</envar> and - <envar>PATH_TRANSLATED</envar> information correctly with this - setup, the php parser should be compiled with the <link - linkend="install.configure.enable-discard-path">--enable-discard-path</link> - configure option. + Äëÿ òîãî, ÷òîáû PHP íà÷àë â äàííîì ñëó÷àå êîððåêòíî îáðàáàòûâàòü + <envar>PATH_INFO</envar> è <envar>PATH_TRANSLATED</envar>, òðàíñëÿòîð + PHP äîëæåí áûòü ñêîìïèëèðîâàí ñ îïöèåé êîíôèãóðàöèè <link + linkend="install.configure.enable-discard-path">--enable-discard-path</link>. </para> </sect2> </sect1> <sect1 id="security.apache"> - <title>Installed as an Apache module</title> + <title>Ïðè èíñòàëëÿöèè â âèäå ìîäóëÿ Apache</title> <simpara> - When PHP is used as an Apache module it inherits Apache's user - permissions (typically those of the "nobody" user). This has several - impacts on security and authorization. For example, if you are using - PHP to access a database, unless that database has built-in access - control, you will have to make the database accessable to the - "nobody" user. This means a malicious script could access and modify - the database, even without a username and password. It's entirely - possible that a web spider could stumble across a database - administrator's web page, and drop all of your databases. You can - protect against this with Apache authorization, or you can design - your own access model using LDAP, .htaccess files, etc. and include - that code as part of your PHP scripts. + Ïðè èñïîëüçîâàíèè PHP, êàê Apache-ìîäóëü, äàííûé ìîäóëü ïîëó÷àåò + âñå ïðàâà è ðàçðåøåíèÿ Apache (îáû÷íî, ïðàâà ïîëüçîâàòåëÿ "nobody", + ò.å. "îòñóòñòâóþùåãî" ïîëüçîâàòåëÿ). Ýòî âíîñèò íåêîòîðûå ñëîæíîñòè + â ñèñòåìó áåçîïàñíîñòè è àâòîðèçàöèè. Ê ïðèìåðó, åñëè PHP èñïîëüçóåòñÿ + äëÿ îáðàùåíèÿ ê áàçå äàííûõ, òî â ñëó÷àå îòñóòñòâèÿ âñòðîåííîãî êîíòðîëÿ + äîñòóïà â áàçå äàííûõ åå ïðèäåòñÿ ñäåëàòü äîñòóïíîé äëÿ ïîëüçîâàòåëÿ + "nobody".  ýòîì ñëó÷àå ïðîãðàììà çëîóìûøëåííèêà ìîæåò ïîëó÷èòü äîñòóï + íà ÷òåíèå è èçìåíåíèå áàçû äàííûõ äàæå áåç óêàçàíèÿ èìåíè ïîëüçîâàòåëÿ + è ïàðîëÿ. Òàêæå âîçìîæíî, ÷òî ñåòåâîé ÷åðâü ïðîíèêíåò íà ñòðàíèöó + àäìèíèñòðàòîðà è óíè÷òîæèò âñå âàøè áàçû äàííûõ. Ìîæíî çàùèòèòüñÿ îò + ýòîãî ïóòåì ââåäåíèÿ àâòîðèçàöèè â Apache, èëè ðàçðàáîòàâ ñîáñòâåííóþ + ìîäåëü äîñòóïà ñ èñïîëüçîâàíèåì LDAP, ôàéëîâ .htaccess (è äð.) è + èñïîëüçîâàòü ýòîò êîä, êàê ÷àñòü âàøèõ ïðîãðàìì íà PHP. </simpara> <simpara> - Often, once security is established to the point where the PHP user - (in this case, the apache user) has very little risk attached to it, - it is discovered that PHP is now prevented from writing any files - to user directories. Or perhaps it has been prevented from accessing - or changing databases. It has equally been secured from writing - good and bad files, or entering good and bad database transactions. + ×àñòî ñëó÷àåòñÿ òàê, ÷òî êîãäà áåçîïàñíîñòü äîñòèãàåò óðîâíÿ, ãäå + PHP (à â äàííîì ñëó÷àå, Apache) ïðàêòè÷åñêè íå ïðåäñòàâëÿåò + ïðîáëåìû áåçîïàñíîñòè, îêàçûâàåòñÿ, ÷òî PHP íå ìîæåò çàïèñàòü íè + îäíîãî ôàéëà â ïîëüçîâàòåëüñêèå êàòàëîãè. Èëè, äîïóñòèì, íå èìååò + äîñòóïà ê áàçàì äàííûõ. PHP îêàçûâàåòñÿ îäèíàêîãî çàùèùåííûì îò + çàïèñè äîçâîëåííûõ è íåäîçâîëåííûõ ôàëîâ, èëè îò ïðîèçâåäåíèÿ + äîçâîëåííûõ èëè íåäîçâîëåííûõ îïåðàöèé ñ áàçàìè äàííûõ. </simpara> <simpara> - A frequent security mistake made at this point is to allow apache - root permissions, or to escalate apache's abilitites in some other - way. + Î÷åíü ÷àñòàÿ îøèáêà íà ýòîì ýòàïå - äàòü PHP ïðàâà "root", èëè + àäìèíèñòðàòîðà èëè êàêèì-ëèáî îáðàçîì óâåëè÷èòü ðàçðåøåíèÿ äëÿ + Apache. </simpara> <simpara> - Escalating the Apache user's permissions to root is extremely - dangerous and may compromise the entire system, so sudo'ing, - chroot'ing, or otherwise running as root should not be considered by - those who are not security professionals. + Óñòàíîâêà äëÿ Apache ðàçðåøåíèé àäìèíèñòðàòîðà (root) î÷åíü îïàñíà + äëÿ ñèñòåìû â öåëîì. Òå, êòî íå ÿâëÿåòñÿ ñïåöèàëèñòàìè ïî áåçîïàñíîñòè, + â äàííîì ñëó÷àå äîëæíû èçáåãàòü ëþáûõ îïåðàöèé âðîäå "sudo" èëè "chroot". </simpara> <simpara> - There are some simpler solutions. By using - <link linkend="ini.open-basedir">open_basedir</link> you can control and restrict what - directories are allowed to be used for PHP. You can also set up - apache-only areas, to restrict all web based activity to non-user, - or non-system, files. + Åñòü áîëåå ïðîñòûå ðåøåíèÿ. Èñïîëüçóÿ + <link linkend="ini.open-basedir">open_basedir</link>, ìîæíî + êîíòðîëèðîâàòü è îãðàíè÷èâàòü èñïîëüçîâàíèå PHP äèðåêòîðèé. Òàêæå + ìîæíî ñîçäàòü îáëàñòè "òîëüêî äëÿ Apache", îãðàíè÷èâ âåñü äîñòóï + íå-ïîëüçîâàòåëüñêèìè èëè íå-ñèñòåìíûìè ôàéëàìè. </simpara> </sect1> <sect1 id="security.filesystem"> - <title>Filesystem Security</title> + <title>Áåçîïàñíîñòü ôàéëîâîé ñèñòåìû</title> <simpara> - PHP is subject to the security built into most server systems with - respect to permissions on a file and directory basis. This allows - you to control which files in the filesystem may be read. Care - should be taken with any files which are world readable to ensure - that they are safe for reading by all users who have access to that - filesystem. + PHP ïîä÷èíÿåòñÿ óñòàíîâêàì áåçîïàñíîñòè íà óðîâíå ôàéëîâ è êàòàëîãîâ, + êîòîðûå âñòðîåíû â áîëüøèíñòâî ñåðâåðíûõ ñèñòåì. Ýòî ïîçâîëÿåò + êîíòðîëèðîâàòü, êàêèå ôàéëû ìîãóò áûòü ïðî÷èòàíû. Ñ îñîáîé àêêóðàòíîñòüþ + íóæíî îòíîñèòüñÿ ê ôàéëàì ñ ïðàâîì ÷òåíèÿ "äëÿ âñåõ" - íóæíî ïîìíèòü + î òîì, îíè ìîãóò áûòü ñ÷èòàíû ëþáûì ïîëüçîâàòåëåì, èìåþùèì äîñòóï ê + äàííîé ôàéëîâîé ñèñòåìå. </simpara> <simpara> - Since PHP was designed to allow user level access to the filesystem, - it's entirely possible to write a PHP script that will allow you - to read system files such as /etc/passwd, modify your ethernet - connections, send massive printer jobs out, etc. This has some - obvious implications, in that you need to ensure that the files - that you read from and write to are the appropriate ones. + Ïîñêîëüêó PHP ðàçðàáàòûâàëñÿ äëÿ ïðåäîñòàâëåíèÿ ïîëüçîâàòåëüñêèõ + ïðàâ äîñòóïà ê ñèñòåìå, âîçìîæíî ñîçäàòü ïðîãðàììó íà PHP, êîòîðàÿ + ïîçâîëèò âàì ÷èòàòü ñèñòåìíûå ôàéëû, òàêèå, êàê /etc/passwd, èçìåíÿòü + ïàðàìåòðû âàøèõ ñåòåâûõ ñîåäèíåíèé, ñîçäàâàòü áîëüøèå çàäàíèÿ äëÿ ïå÷àòè + è ò.ï. Ýòî ñîçäàåò ðÿä ïðîáëåì - íóæíî áûòü óâåðåííûì â òîì, ÷òî èìåííî + íåîáõîäèìûå ôàéëû ðàçðåøåíû äëÿ ÷òåíèÿ è çàïèñè. </simpara> <simpara> - Consider the following script, where a user indicates that they'd - like to delete a file in their home directory. This assumes a - situation where a PHP web interface is regularly used for file - management, so the Apache user is allowed to delete files in - the user home directories. + Ïðèâåäåì ñëåäóþùóþ ïðîãðàììó, ãäå ïîëüçîâàòåëü õî÷åò ñòåðåòü + ôàéë â ñâîåì äîìàøíåì êàòàëîãå. Ýòî òèïè÷íàÿ ñèòóàöèÿ, êîãäà + Web-èíòåðôåéñ PHP èñïîëüçóåòñÿ äëÿ óïðàâëåíèÿ ôàéëàìè, ò.å. + ïîëüçîâàòåëè Apache èìåþò âîçìîæíîñòü óäàëÿòü ôàéëû â ñâîèõ + äîìàøíèõ êàòàëîãàõ. </simpara> <para> <example> - <title>Poor variable checking leads to....</title> + <title>Íåäîñòàòî÷íàÿ ïðîâåðêà ïåðåìåííûõ - ïîñëåäñòâèÿ...</title> <programlisting role="php"> <![CDATA[ <?php -// remove a file from the user's home directory +// óäàëÿåì ôàéë èç ïîëüçîâàòåëüñêîãî äîìàøíåãî êàòàëîãà $username = $_POST['user_submitted_name']; $homedir = "/home/$username"; $file_to_delete = "$userfile"; unlink ($homedir/$userfile); -echo "$file_to_delete has been deleted!"; +echo "$file_to_delete óäàëåí!"; ?> ]]> </programlisting> </example> - Since the username is postable from a user form, they can submit - a username and file belonging to someone else, and delete files. - In this case, you'd want to use some other form of authentication. - Consider what could happen if the variables submitted were - "../etc/" and "passwd". The code would then effectively read: + Ïîñêîëüêó èìÿ ïîëüçîâàòåëÿ ïðåäîñòàâëÿåòñÿ ïîëüçîâàòåëüñêîé ôîðìîé + ââîäà, ìîæíî ïîäñòàâèòü ëþáûå èìåíà ïîëüçîâàòåëÿ è ôàéëà, äàæå åñëè + ýòîò ôàéë ïðèíàäëåæèò êîìó-òî äðóãîìó.  ýòîì ñëó÷àå íåîáõîäèìî + èñïîëüçîâàòü ñõåìó àóòåíòèôèêàöèè ïîëüçîâàòåëåé. Êðîìå òîãî, + ïðåäñòàâüòå, ÷òî ñëó÷èòüñÿ, åñëè ïåðåäàííûå ïåðåìåííûå áóäóò + ñîîòâåòñòâåííî "../etc/" è "passwd". Òîãäà ïðîãðàììà áóäåò âûãëÿäåòü + òàê: <example> - <title>... A filesystem attack</title> + <title>... Àòàêà íà ôàéëîâóþ ñèñòåìó</title> <programlisting role="php"> <![CDATA[ <?php -// removes a file from anywhere on the hard drive that -// the PHP user has access to. If PHP has root access: +// óäàëÿåò ëþáîé ôàéë â çîíå äåéñòâèÿ ïðàâ ïîëüçîâàòåëÿ +// Åñëè PHP èìååò ïðàâà àäìèíèñòðàòîðà: $username = "../etc/"; $homedir = "/home/../etc/"; $file_to_delete = "passwd"; unlink ("/home/../etc/passwd"); -echo "/home/../etc/passwd has been deleted!"; +echo "/home/../etc/passwd óäàëåí!"; ?> ]]> </programlisting> </example> - There are two important measures you should take to prevent these - issues. +  áîðüáå ñ ïîäîáíûìè ñëó÷àÿìè åñòü äâà êëþ÷åâûõ ìîìåíòà. <itemizedlist> <listitem> <simpara> - Only allow limited permissions to the PHP web user binary. + Íàçíà÷åíèå èíòåðïðåòàòîðó PHP îãðàíè÷åííûõ ïðàâ. </simpara> </listitem> <listitem> <simpara> - Check all variables which are submitted. + Ïðîâåðêà âñåõ ïåðåäàííûõ ïåðåìåííûõ. </simpara> </listitem> </itemizedlist> - Here is an improved script: + Âîò óëó÷øåííàÿ ïðîãðàììà: <example> - <title>More secure file name checking</title> + <title>Áîëåå áåçîïàñíàÿ ïðîâåðêà èìåíè ôàéëà</title> <programlisting role="php"> <![CDATA[ <?php -// removes a file from the hard drive that -// the PHP user has access to. -$username = $_SERVER['REMOTE_USER']; // using an authentication mechanisim +// óäàëÿåò ëþáîé ôàéë â çîíå äåéñòâèÿ ïðàâ ïîëüçîâàòåëÿ +// Åñëè PHP èìååò ïðàâà àäìèíèñòðàòîðà: +$username = $_SERVER['REMOTE_USER']; // èñïîëüçóåì ìåõàíèçì àóòåíòèôèêàöèè $homedir = "/home/$username"; -$file_to_delete = basename("$userfile"); // strip paths -unlink ($homedir/$file_to_delete); +$file_to_delete = basename("$userfile"); // îòðåçàòü ïóòè +unlink ("$homedir/$file_to_delete"); -$fp = fopen("/home/logging/filedelete.log","+a"); //log the deletion +$fp = fopen("/home/logging/filedelete.log","+a"); // îò÷èòàòüñÿ îá óäàëåíèè $logstring = "$username $homedir $file_to_delete"; fputs ($fp, $logstring); fclose($fp); -echo "$file_to_delete has been deleted!"; +echo "$file_to_delete óäàëåí!"; ?> ]]> </programlisting> </example> - However, even this is not without it's flaws. If your authentication - system allowed users to create their own user logins, and a user - chose the login "../etc/", the system is once again exposed. For - this reason, you may prefer to write a more customized check: + Îäíàêî è â ýòîì ñëó÷àå èìåþòñÿ "äûðêè". Åñëè âàøà ñèñòåìà àóòåíòèôèêàöèè + ïîçâîëÿåò ïîëüçîâàòåëÿì âûáèðàòü ñîáñòâåííûå èìåíà, è ïîëüçîâàòåëü + çàäàñò èìÿ "../etc/", ñèñòåìà îïÿòü ïîïàäàåò ïîä àòàêó.  ýòîì ñëó÷àå + ìîæíî ñäåëàòü áîëåå ñïåöèôè÷åñêóþ ïðîâåðêó: <example> - <title>More secure file name checking</title> + <title>Åùå áîëåå áåçîïàñíàÿ ïðîâåðêà èìåíè ôàéëà</title> <programlisting role="php"> <![CDATA[ <?php -$username = $_SERVER['REMOTE_USER']; // using an authentication mechanisim +$username = $_SERVER['REMOTE_USER']; // èñïîëüçóåì ìåõàíèçì àóòåíòèôèêàöèè $homedir = "/home/$username"; if (!ereg('^[^./][^/]*$', $userfile)) - die('bad filename'); //die, do not process + die('ïëîõîå èìÿ ôàéëà'); // âûõîä áåç îáðàáîòêè if (!ereg('^[^./][^/]*$', $username)) - die('bad username'); //die, do not process -//etc... + die('ïëîõîå èìÿ ïîëüçîâàòåëÿ'); // âûõîä áåç îáðàáîòêè +//è ò.ä. ?> ]]> </programlisting> </example> </para> <para> - Depending on your operating system, there are a wide variety of files - which you should be concerned about, including device entries (/dev/ - or COM1), configuration files (/etc/ files and the .ini files), - well known file storage areas (/home/, My Documents), etc. For this - reason, it's usually easier to create a policy where you forbid - everything except for what you explicitly allow. +  çàâèñèìîñòè îò âàøåé îïåðàöèîííîé ñèñòåìû, ñóùåñòâóþò ôàéëû, î + áåçîïàñíîñòè êîòîðûõ íàäî ïîçàáîòèòüñÿ - äðàéâåðû óñòðîéñòâ (/dev/ + èëè COM1), ôàéëû êîíôèãóðàöèè (ôàéëû /etc/ èëè ôàéëû .ini), + èçâåñòíûå îáëàñòè õðàíåíèÿ äàííûõ (/home/, Mîè äîêóìåíòû), è ò.ä. +  ñâÿçè ñ ýòèì, îáû÷íî ïðîùå ñîçäàòü ïîëèòèêó â êîòîðîé çàïðåùåíî âñå, + êðîìå òîãî, ÷òî ðàçðåøåíî, êàê ãîâîðèòñÿ, "âðó÷íóþ". </para> </sect1> <sect1 id="security.database"> - <title>Database Security</title> + <title>Áåçîïàñíîñòü áàç äàííûõ</title> <simpara> - Nowadays, databases are cardinal components of any web based application by - enabling websites to provide varying dynamic content. Since very sensitive - or secret informations can be stored in such database, you should strongly - consider to protect them somehow. + Ñåãîäíÿ áàçû äàííûõ - îñíîâíàÿ ñîñòàâëÿþùàÿ ïðàêòè÷åñêè ëþáûõ ïðèëîæåíèé, + îñíîâàííûõ íà Web, êîòîðàÿ äàåò âîçìîæíîñòü ïðåäîñòàâëåíèÿ ðàçíîîáðàçíîãî + äèíàìè÷åñêîãî ñîäåðæèìîãî. Ïîñêîëüêó â òàêèõ áàçàõ äàííûì ìîæåò õðàíèòüñÿ + âåñüìà âàæíàÿ è ñåêðåòíàÿ èíôîðìàöèÿ, íóæíî ïîçàáîòèòüñÿ è îá èõ çàùèòå. </simpara> <simpara> - To retrieve or to store any information you need to connect to the database, - send a legitimate query, fetch the result, and close the connecion. - Nowadays, the commonly used query language in this interaction is the - Structured Query Language (SQL). See how an attacker can <link - linkend="security.database.sql-injection">tamper with an SQL query</link>. + Äëÿ ïîëó÷åíèÿ èëè ñîõðàíåíèÿ èíôîðìàöèè â áàçå äàííûõ, ê íåé íóæíî + ïîäêëþ÷èòüñÿ, ïîñëàòü çàïðîñ, îáðàáîòàòü îòâåò è çàêðûòü ïîäêëþ÷åíèå. + Ñåãîäíÿ äëÿ âñåãî ýòîãî îáû÷íî èñïîëüçóåòñÿ ñòðóêòóðèðîâàííûé ÿçûê + çàïðîñîâ (Structured Query Language, SQL). Äàâàéòå ïîñìîòðèì, êàê + çëîóìûøëåííèê ìîæåò <link linkend="security.database.sql-injection">ïîñòóïèòü + ñ SQL-çàïðîñîì</link>. </simpara> <simpara> - As you can realize, PHP cannot protect your database by itself. The - following sections aim to be an introduction into the very basics of how to - access and manipulate databases within PHP scripts. + Êàê èçâåñòíî, PHP íå ìîæåò ñàì çàùèòèòü áàçó äàííûõ. Ñëåäóþùèå ðàçäåëû + ÿâëÿþòñÿ ââåäåíèåì â îñíîâû äîñòóïà è èñïîëüçîâàíèÿ áàç äàííûõ â + ïðîãðàììàõ PHP. </simpara> <simpara> - Keep in mind this simple rule: defence in depth. In the more place you - take the more action to increase the protection of your database, the less - probability of that an attacker succeeds, and exposes or abuse any stored - secret information. Good design of the database schema and the application - deals with your greatest fears. + Ïîìíèòå ïðîñòîå ïðàâèëî: çàùèòà ñòðîèòñÿ "âãëóáü". ×åì áîëüøå ìåñò + âû çàùèòèòå è ÷åì áîëüøå äåéñòâèé ïðåäïðèìåòå äëÿ çàùèòû áàçû äàííûõ, + òåì ìåíüøå âåðîÿòíîñòü óñïåõà ó çëîóìûøëåííèêà íà èçâëå÷åíèå è + èñïîëüçîâàíèå õðàíèìîé â íåé ñåêðåòíîé èíôîðìàöèè. Âñå îïàñíûå ìåñòà + óñòðàíÿþòñÿ ïðàâèëüíîé ðàçðàáîòêîé ñòðóêòóðû áàçû äàííûõ è èñïîëüçóþùåãî + åå ïðèëîæåíèÿ. </simpara> <sect2 id="security.database.design"> - <title>Designing Databases</title> + <title>Ïëàíèðîâàíèå áàç äàííûõ</title> <simpara> - The first step is always to create the database, unless you want to use - an existing third party's one. When a database is created, it is - assigned to an owner, who executed the creation statement. Usually, only - the owner (or a superuser) can do anything with the objects in that - database, and in order to allow other users to use it, privileges must be - granted. + Ïåðâûé øàã âñåãäà - ñîáñòâåííî ñîçäàíèå áàçû äàííûõ, çà èñêëþ÷åíèåì + ñëó÷àåâ èñïîëüçîâàíèÿ ÷óæèõ áàç. Êîãäà ñîçäàåòñÿ áàçà äàííûõ, åé + íàçíà÷àåòñÿ âëàäåëåö, êîòîðûé è âûçâàë êîìàíäó ñîçäàíèÿ. Îáû÷íî + òîëüêî îäèí âëàäåëåö ("ñóïåðïîëüçîâàòåëü") ìîæåò äåëàòü ÷òî óãîäíî + ñ îáúåêòàìè âíóòðè ýòîé áàçû äàííûõ è äëÿ òîãî, ÷òîáû ïîçâîëèòü + äðóãèì ïîëüçîâàòåëÿì èñïîëüçîâàòü åå, èì äîëæíû áûòü íàçíà÷åíû ïðàâà + äîñòóïà. </simpara> <simpara> - Applications should never connect to the database as its owner or a - superuser, because these users can execute any query at will, for - example, modifying the schema (e.g. dropping tables) or deleting its - entire content. + Ïðèëîæåíèÿ íèêîãäà íå äîëæíû ïîäêëþ÷àòüñÿ ê áàçå äàííûõ â ðîëè + åå âëàäåëüöà èëè "ñóïåðïîëüçîâàòåëÿ", ïîñêîëüêó â ýòîì ñëó÷àå + ïîëüçîâàòåëè ìîãóò ïðîèçâåñòè ëþáûå äåéñòâèÿ âðîäå ìîäèôèêàöèè + ñõåìû (ê ïðèìåðó, óäàëåíèÿ òàáëèö) èëè óäàëåíèÿ âñåãî åå ñîäåðæèìîãî. </simpara> <simpara> - You may create different database users for every aspect of your - application with very limited rights to database objects. The most - required privileges should be granted only, and avoid that the same user - can interact with the database in different use cases. This means that if - intruders gain access to your database using one of these credentials, - they can only effect as many changes as your application can. + Ìîæíî ñîçäàòü ðàçëè÷íûõ ïîëüçîâàòåëåé áàç äàííûõ äëÿ êàæäîãî íåîáõîäèìîãî + äåéñòâèÿ ïðèëîæåíèé, î÷åíü ñèëüíî îãðàíè÷èâàÿ äîñòóï ïîñëåäíèõ ê îáúåêòàì + áàçû äàííûõ. Òðåáóåìûå ïðàâà äîëæíû íàçíà÷àòüñÿ îäíîêðàòíî, èõ + èñïîëüçîâàíèÿ â äðóãèõ ìåñòàõ ïðèëîæåíèÿ íóæíî èçáåãàòü. Ýòî çíà÷èò, + ÷òî åñëè çëîóìûøëåííèê ïîëó÷èò äîñòóï ñ èñïîëüçîâàíèåì òîé èëè èíîé + ó÷åòíîé çàïèñè, îí ñìîæåò ïîëó÷èòü ëèøü òîò äîñòóï, êîòîðûì îáëàäàëà + èñïîëüçîâàííàÿ ÷àñòü ïðîãðàììû. </simpara> <simpara> - You are encouraged not to implement all the business logic in the web - application (i.e. your script), instead to do it in the database schema - using views, triggers or rules. If the system evolves, new ports will be - intended to open to the database, and you have to reimplement the logic - in each separate database client. Over and above, triggers can be used - to transparently and automatically handle fields, which often provides - insight when debugging problems with your application or tracing back - transactions. +  ïðèëîæåíèÿ ëó÷øå íå ââîäèòü âñþ ëîãèêó ðàáîòû ñ áàçàìè äàííûõ. Ýòî + ìîæíî ñäåëàòü è â ñàìîé áàçå äàííûõ ñ èñïîëüçîâàíèåì ôëàãîâ, + ïðåäñòàâëåíèé, ïðàâèë è âñòðîåííûõ ïðîöåäóð.  ñëó÷àå ðàçâèòèÿ è + ðàñøèðåíèÿ ñèñòåìû âñòðîåííûå ïðîöåäóðû ìîãóò áûòü èçìåíåíû äëÿ + àâòîìàòè÷åñêîé îáðàáîòêè íîâûõ ïîëåé, à ôëàãè ïðåäîñòàâÿò äîïîëíèòåëüíûå + âîçìîæíîñòè äëÿ îòëàäêè òðàíçàêöèé. </simpara> </sect2> <sect2 id="security.database.connection"> - <title>Connecting to Database</title> + <title>Ïîäêëþ÷åíèå ê áàçå äàííûõ</title> <simpara> - You may want to estabilish the connections over SSL to encrypt - client/server communications for increased security, or you can use ssh - to encrypt the network connection between clients and the database server. - If either of them is done, then monitoring your traffic and gaining - informations in this way will be a hard work. + Ìîæíî óñòàíàâëèâàòü ïîäêëþ÷åíèÿ ñ ïîìîùüþ SSL äëÿ øèôðîâàíèÿ ñîåäèíåíèé + êëèåíò-ñåðâåð, ÷òî äàåò ïîâûøåííóþ áåçîïàñíîñòü. À ìîæíî èñïîëüçîâàòü + ssh äëÿ øèôðîâàíèÿ ñåòåâûõ ñîåäèíåíèé ìåæäó êëèåíòàìè è ñåðâåðîì + áàç äàííûõ. Ëþáîé èç ýòèõ ñïîñîáîâ ñèëüíî óñëîæíÿåò îòñëåæèâàíèå + è ïîëó÷åíèå èíôîðìàöèè èç ñåòåâîãî òðàôôèêà. </simpara> <!--simpara> - If your database server native SSL support, consider to use <link - linkend="ref.openssl">OpenSSL functions</link> in communication between - PHP and database via SSL. + Åñëè âàø ñåðâåð áàç äàííûõ èìååò âñòðîåííóþ ïîääåðæêó SSL, ëó÷øå + èñïîëüçîâàòü <link linkend="ref.openssl">ôóíêöèè OpenSSL</link> äëÿ + ñâÿçè ìåæäó PHP è áàçîé äàííûõ ñ ïîìîùüþ SSL. </simpara--> </sect2> <sect2 id="security.database.storage"> - <title>Encrypted Storage Model</title> + <title>Õðàíåíèå çàøèôðîâàííûõ äàííûõ</title> <simpara> - SSL/SSH protects data travelling from the client to the server, SSL/SSH - does not protect the persistent data stored in a database. SSL is an - on-the-wire protocol. + SSL/SSH çàùèùàåò äàííûå òîëüêî ïî ïóòè îò êëèåíòà ê ñåðâåðó, íî íå + äàííûå, õðàíèìûå â áàçå äàííûõ. SSL - ëèøü ñåòåâîé ïðîòîêîë. </simpara> <simpara> - Once an attacker gains access to your database directly (bypassing the - webserver), the stored sensitive data may be exposed or misused, unless - the information is protected by the database itself. Encrypting the data - is a good way to mitigate this threat, but very few databases offer this - type of data encryption. + Êîãäà çëîóìûøëåííèê ïîëó÷àåò äîñòóï ê âàøåé áàçå äàííûõ â îáõîä + Web-ñåðâåðà, õðàíèìûå âàæíûå äàííûå ìîãóò áûòü ïîëó÷åíû è èñïîëüçîâàíû, + çà èñêëþ÷åíèåì ñëó÷àÿ, êîãäà èíôîðìàöèÿ çàùèùåíà â ñàìîé áàçå äàííûõ. + Øèôðîâàíèå - âåñüìà õîðîøèé ïðèåì â ýòîì ñëó÷àå, íî òàêîé ñïîñîá + ïîääåðæèâàþò íûíå ëèøü î÷åíü íåìíîãèå ñèñòåìû óïðàâëåíèÿ áàçàìè äàííûõ. </simpara> <simpara> - The easiest way to work around this problem is to first create your own - encryption package, and then use it from within your PHP scripts. PHP - can assist you in this case with its several extensions, such as <link - linkend="ref.mcrypt">Mcrypt</link> and <link - linkend="ref.mhash">Mhash</link>, covering a wide variety of encryption - algorithms. The script encrypts the data be stored first, and decrypts - it when retrieving. See the references for further examples how - encryption works. + Ñàìûé ëåãêèé ïóòü â ýòîì ñëó÷àå - ñîçäàòü ñâîþ ñîáñòâåííóþ ñèñòåìó + øèôðîâàíèÿ, à çàòåì èñïîëüçîâàòü åå â ïðîãðàììàõ PHP. PHP ñïîñîáñòâóåò + òàêîìó ïîäõîäó áëàãîäàðÿ íàëè÷èþ ñïåöèôè÷íûõ ðàøèðåíèé, òàêèõ, êàê <link + linkend="ref.mcrypt">Mcrypt</link> è <link linkend="ref.mhash">Mhash</link>, + îõâàòûâàþùèõ áîëüøîé ðÿä àëãîðèòìîâ øèôðîâàíèÿ. Ïðîãðàììà øèôðóåò + ñîõðàíÿåìûå äàííûå è ðàñøèôðîâûâàåò ïîëó÷àåìûå. Äëÿ äåòàëüíîãî îïèñàíèÿ + ñõåì øèôðîâàíèÿ ñìîòðèòå ññûëêè. </simpara> <simpara> - In case of truly hidden data, if its raw representation is not needed - (i.e. not be displayed), hashing may be also taken into consideration. - The well-known example for the hashing is storing the MD5 hash of a - password in a database, instead of the password itself. See also - <function>crypt</function> and <function>md5</function>. +  ñëó÷àå ñêðûòûõ äàííûõ, ãäå íå òðåáóåòñÿ èõ èñõîäíûé âèä (ê ïðèìåðó, + äëÿ îòîáðàæåíèÿ), ìîæíî èñïîëüçîâàòü õåøèðîâàíèå. Èçâåñòíûì ïðèìåðîì + õåøèðîâàíèÿ ÿâëÿåòñÿ ñîõðàíåíèå â áàçå äàííûõ õåøà MD5 îò ïàðîëÿ + âìåñòî ñàìîãî ïàðîëÿ. Äëÿ ïîäðîáíîãî îïèñàíèÿ ñìîòðèòå + <function>crypt</function> è <function>md5</function>. </simpara> <example> - <title>Using hashed password field</title> + <title>Èñïîëüçîâàíèå õåøèðîâàííûõ ïàðîëåé</title> <programlisting role="php"> <![CDATA[ -// storing password hash +// ñîõðàíÿåì õåø îò ïàðîëÿ $query = sprintf("INSERT INTO users(name,pwd) VALUES('%s','%s');", addslashes($username), md5($password)); $result = pg_exec($connection, $query); -// querying if user submitted the right password +// ïðîâåðÿåì êîððåêòíîñòü ââåäåííîãî ïîëüçîâàòåëåì ïàðîëÿ $query = sprintf("SELECT 1 FROM users WHERE name='%s' AND pwd='%s';", addslashes($username), md5($password)); $result = pg_exec($connection, $query); if (pg_numrows($result) > 0) { - echo "Welcome, $username!"; + echo "Äîáðî ïîæàëîâàòü, $username!"; } else { - echo "Authentication failed for $username."; + echo "Ââåäåí íåâåðíûé ïàðîëü äëÿ $username."; } ]]> </programlisting> @@ -623,88 +619,89 @@ </sect2> <sect2 id="security.database.sql-injection"> - <title>SQL Injection</title> + <title>Âíåäðåíèå â SQL</title> <simpara> - Many web developers are unaware of how SQL queries can be tampered with, - and assume that an SQL query is a trusted command. It means that SQL - queries are able to circumvent access controls, thereby bypassing standard - authentication and authorization checks, and sometimes SQL queries even - may allow access to host operating system level commands. + Ìíîãèå ðàçðàáîò÷èêè Web-ïðèëîæåíèé ñ÷èòàþò çàïðîñû SQL íå ñòîÿùèìè, + âíèìàíèÿ íå çíàÿ î òîì, ÷òî èõ ìîæåò èñïîëüçîâàòü çëîóìûøëåííèê. Ýòî + îçíà÷àåò, ÷òî çàïðîñû SQL ìîãóò áûòü èñïîëüçîâàíû äëÿ îáõîäà ñèñòåì + çàùèòû, àóòåíòèôèêàöèè è àâòîðèçàöèè, à òàêæå èíîãäà ìîãóò áûòü + èñïîëüçîâàíû äëÿ ïîëó÷åíèÿ äîñòóïà ê êîìàíäàì óðîâíÿ îïåðàöèîííîé + ñèñòåìû. </simpara> <simpara> - Direct SQL Command Injection is a technique where an attacker creates or - alters existing SQL commands to expose hidden data, or to override valuable - ones, or even to execute dangerous system level commands on the database - host. This is accomplished by the application taking user input and - combining it with static parameters to build a SQL query. The following - examples are based on true stories, unfortunately. + Âíåäðåíèå â êîìàíäû SQL - òåõíèêà, ïðè êîòîðîé çëîóìûøëåííèê ñîçäàåò + èëè èçìåíÿåò êîìàíäû SQL äëÿ ïîëó÷åíèÿ äîñòóïà ê ñêðûòûì äàííûì, äëÿ + èçìåíåíèÿ ñóùåñòâóþùèõ è äàæå äëÿ âûïîëíåíèÿ êîìàíä óðîâíÿ îïåðàöèîííîé + ñèñòåìû. Ýòî äîñòèãàåòñÿ â òîì ñëó÷àå, åñëè ïðîãðàììà èñïîëüçóåò + ââåäåííûå äàííûå â êîìáèíàöèè ñî ñòàòè÷åñêèìè ïàðàìåòðàìè äëÿ ñîçäàíèÿ + çàïðîñà SQL. Ñëåäóþùèå ïðèìåðû, ê ñîæàëåíèþ, îñíîâàíû íà ðåàëüíî + ïðîèçîøåäøèõ ñëó÷àÿõ: </simpara> <para> - Owing to the lack of input validation and connecting to the database on - behalf of a superuser or the one who can create users, the attacker - may create a superuser in your database. + Ïðè íåäîñòàòî÷íîé ïðîâåðêå ââîäèìûõ äàííûõ è ñîåäèíåíèè ñ áàçîé äàííûõ + íà ïðàâàõ ñóïåðïîëüçîâàòåëÿ çëîóìûøëåííèê ìîæåò ñîçäàòü íîâîãî + ñóïåðïîëüçîâàòåëÿ â áàçå äàííûõ. <example> <title> - Splitting the result set into pages ... and making superusers - (PostgreSQL and MySQL) + Ðàçäåëåíèå ðåçóëüòàòà çàïðîñà ïî ñòðàíèöàì è... ñîçäàíèå ñóïåðïîëüçîâàòåëåé + (PostgreSQL è MySQL) </title> <programlisting role="php"> <![CDATA[ -$offset = argv[0]; // beware, no input validation! +$offset = argv[0]; // âíèìàíèå! íåò ïðîâåðêè äàííûõ! $query = "SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET $offset;"; -// with PostgreSQL +// â PostgreSQL $result = pg_exec($conn, $query); -// with MySQL +// â MySQL $result = mysql_query($query); ]]> </programlisting> </example> - Normal users click on the 'next', 'prev' links where the <varname>$offset</varname> - is encoded into the URL. The script expects that the incoming - <varname>$offset</varname> is decimal number. However, someone tries to - break in with appending <function>urlencode</function>'d form of the - following to the URL + Îáû÷íî ïîëüçîâàòåëè èñïîëüçóþò êíîïî÷êè "ñëåäóþùàÿ" è "ïðåäûäóùàÿ", + ãäå <varname>$offset</varname> âíåäðåí â URL. Ïðîãðàììà ñ÷èòàåò, ÷òî + <varname>$offset</varname> - ÷èñëî. Îäíàêî, êòî-íèáóäü ìîæåò + ïîïûòàòüñÿ âíåäðèòüñÿ ïóòåì äîáàâëåíèÿ <function>urlencode</function>-êîäèðîâàííûõ + äàííûõ â URL <informalexample> <programlisting> <![CDATA[ -// in case of PostgreSQL +// â ñëó÷àå PostgreSQL 0; insert into pg_shadow(usename,usesysid,usesuper,usecatupd,passwd) select 'crack', usesysid, 't','t','crack' from pg_shadow where usename='postgres'; -- -// in case of MySQL +// â ñëó÷àå MySQL 0; UPDATE user SET Password=PASSWORD('crack') WHERE user='root'; FLUSH PRIVILEGES; ]]> </programlisting> </informalexample> - If it happened, then the script would present a superuser access to him. - Note that <literal>0;</literal> is to supply a valid offset to the - original query and to terminate it. + Åñëè ýòî ñëó÷èòñÿ, ïðîãðàììà ïðåäîñòàâèò åìó äîñòóï ñóïåðïîëüçîâàòåëÿ. + Çàìåòèì, ÷òî <literal>0;</literal> ñëóæèò äëÿ òîãî, ÷òîáû çàäàòü + êîððåêòíîå ñìåùåíèå äëÿ èñõîäíîãî çàïðîñà è çàâåðøèòü åãî. </para> <note> <para> - It is common technique to force the SQL parser to ignore the rest of the - query written by the developer with <literal>--</literal> which is the - comment sign in SQL. + Îáû÷íàÿ ïðàêòèêà - çàñòàâèòü òðàíñëÿòîð SQL ïðîèãíîðèðîâàòü îñòàòîê + çàïðîñà ðàçðàáîò÷èêà ñ ïîìîùüþ îáîçíà÷åíèÿ íà÷àëà êîìåíòàðèÿ SQL + <literal>--</literal>. </para> </note> <para> - A feasible way to gain passwords is to circumvent your search result pages. - What the attacker needs only is to try if there is any submitted variable - used in SQL statement which is not handled properly. These filters can be set - commonly in a preceding form to customize <literal>WHERE, ORDER BY, - LIMIT</literal> and <literal>OFFSET</literal> clauses in <literal>SELECT</literal> - statements. If your database supports the <literal>UNION</literal> construct, - the attacker may try to append an entire query to the original one to list - passwords from an arbitrary table. Using encrypted password fields is - strongly encouraged. + Ñóùåñòâóåò ïóòü ïîëó÷åíèÿ ïàðîëåé ÷åðåç âàøè ñòðàíèöû ïîèñêà. Âñå, ÷òî + íóæíî çëîóìûøëåííèêó - ýòî îäíà íå îáðàáîòàííàÿ äîëæíûì îáðàçîì + ïåðåìåííàÿ, èñïîëüçóåìàÿ â SQL-çàïðîñå. Èñïîëüçîâàòüñÿ ìîãóò êîìàíäû + <literal>WHERE, ORDER BY, LIMIT</literal> è <literal>OFFSET</literal> + çàïðîñà <literal>SELECT</literal>. + Åñëè âàøà áàçà äàííûõ ïîääåðæèâàåò êîíñòðóêöèþ <literal>UNION</literal>, + çëîóìûøëåííèê ìîæåò äîáàâèòü ê èñõîäíîìó çàïðîñó åùå îäèí - äëÿ ïîëó÷åíèÿ + ïàðîëåé.  ýòîì ñëó÷àå ïîìîæåò õðàíåíèå çàøèôðîâàííûõ ïàðîëåé. <example> <title> - Listing out articles ... and some passwords (any database server) + Âûâîä ñòàòåé... è ïàðîëåé (ëþáîé ñåðâåð áàç äàííûõ) </title> <programlisting role="php"> <![CDATA[ @@ -715,8 +712,8 @@ ]]> </programlisting> </example> - The static part of the query can be combined with another - <literal>SELECT</literal> statement which reveals all passwords: + Ñòàòè÷åñêàÿ ÷àñòü çàïðîñà ìîæåò áûòü ñîâìåùåíà ñ äðóãèì çàïðîñîì + <literal>SELECT</literal>, êîòîðûé âûâåäåò âñå ïàðîëè: <informalexample> <programlisting> <![CDATA[ @@ -726,21 +723,22 @@ ]]> </programlisting> </informalexample> - If this query (playing with the <literal>'</literal> and - <literal>--</literal>) were assigned to one of the variables used in - <varname>$query</varname>, the query beast awakened. + Åñëè ïîäîáíûé çàïðîñ (èñïîëüçóþùèé <literal>'</literal> è + <literal>--</literal>) áóäåò çàäàí â îäíîé èç ïåðåìåííûõ, èñïîëüçóåìûõ + <varname>$query</varname>, òî àòàêà áóäåò óñïåøíîé. </para> <para> - SQL UPDATEs are also subject to attacking your database. These queries are - also threatened by chopping and appending an entirely new query to it. But - the attacker might fiddle with the <literal>SET</literal> clause. In this - case some schema information must be possessed to manipulate the query - successfully. This can be acquired by examing the form variable names, or - just simply brute forcing. There are not so many naming convention for - fields storing passwords or usernames. + Çàïðîñû SQL "UPDATE" òàêæå ìîãóò áûòü èñïîëüçîâàíû äëÿ àòàêè íà áàçó + äàííûõ. Ýòè çàïðîñû òàêæå ïîäâåðæåíû îïàñíîñòè "îáðåçêè" è äîáàâëåíèÿ + íîâûõ çàïðîñîâ. Íî çäåñü çëîóìûøëåííèê ðàáîòàåò ñ êîìàíäîé + <literal>SET</literal>.  ýòîì ñëó÷àå íåîáõîäèìî çíàíèå íåêîòîðîé + èíôîðìàöèè î ñòðóêòóðå áàçû äàííûõ äëÿ óäà÷íîé ìîäèôèêàöèè çàïðîñà. + Òàêàÿ èíôîðìàöèÿ ìîæåò áûòü ïîëó÷åíà ïóòåì èçó÷åíèÿ íàçâàíèé ïåðåìåííûõ + ôîðì èëè ïðîñòî ïîäáîðîì.  êîíöå êîíöîâ, íå òàê óæ è ìíîãî èìåí ïðèäóìàíî + äëÿ ïîëåé ïîëüçîâàòåëåé è ïàðîëåé. <example> <title> - From resetting a password ... to gaining more privileges (any database server) + Îò ñáðîñà ïàðîëÿ äî ïîëó÷åíèÿ ïðèâèëåãèé... (ëþáîé ñåðâåð áàç äàííûõ) </title> <programlisting role="php"> <![CDATA[ @@ -748,11 +746,11 @@ ]]> </programlisting> </example> - But a malicious user sumbits the value - <literal>' or uid like'%admin%'; --</literal> to <varname>$uid</varname> to - change the admin's password, or simply sets <varname>$pwd</varname> to - <literal>"hehehe', admin='yes', trusted=100 "</literal> (with a trailing - space) to gain more privileges. Then, the query will be twisted: + Çëîóìûøëåííèê ïîñûëàåò çíà÷åíèå <literal>' or uid like'%admin%'; --</literal>, + â ïåðåìåííóþ <varname>$uid</varname> äëÿ èçìåíåíèÿ ïàðîëÿ àäìèíèñòðàòîðà + èëè ïðîñòî óñòàíàâëèâàåò <varname>$pwd</varname> â + <literal>"hehehe', admin='yes', trusted=100 "</literal> (ñ çàâåðøàþùèì + ïðîáåëîì) äëÿ ïîëó÷åíèÿ ïðàâ. Çàïðîñ áóäåò èñêàæåí òàê: <informalexample> <programlisting role="php"> <![CDATA[ @@ -766,10 +764,10 @@ </informalexample> </para> <para> - A frightening example how operating system level commands can be accessed - on some database hosts. + À âîò ïóãàþùèé ïðèìåð òîãî, êàê íà íåêîòîðûõ ñåðâåðàõ áàç äàííûõ + ìîãóò áûòü âûïîëíåíû êîìàíäû óðîâíÿ îïåðàöèîííîé ñèñòåìû: <example> - <title>Attacking the database host's operating system (MSSQL Server)</title> + <title>Àòàêà íà îïåðàöèîííóþ ñèñòåìó ñåðâåðà áàç äàííûõ (ñåðâåð MSSQL)</title> <programlisting role="php"> <![CDATA[ $query = "SELECT * FROM products WHERE id LIKE '%$prod%'"; @@ -777,9 +775,10 @@ ]]> </programlisting> </example> - If attacker submits the value + Åñëè çëîóìûøëåííèê ïîøëåò çíà÷åíèå <literal>a%' exec master..xp_cmdshell 'net user test testpass /ADD' --</literal> - to <varname>$prod</varname>, then the <varname>$query</varname> will be: + â <varname>$prod</varname>, òî <varname>$query</varname> áóäåò âûãëÿäåòü + òàê: <informalexample> <programlisting role="php"> <![CDATA[ @@ -790,73 +789,74 @@ ]]> </programlisting> </informalexample> - MSSQL Server executes the SQL statements in the batch including a command - to add a new user to the local accounts database. If this application - were running as <literal>sa</literal> and the MSSQLSERVER service is - running with sufficient privileges, the attacker would now have an - account with which to access this machine. + Ñåðâåð MSSQL âûïîëíÿåò âñå êîìàíäû SQL, âêëþ÷àÿ êîìàíäó äîáàâëåíèÿ + íîâîãî ïîëüçîâàòåëÿ â ëîêàëüíóþ áàçó äàííûõ ïîëüçîâàòåëåé. Åñëè + ýòî ïðèëîæåíèå áûëî çàïóùåíî, êàê <literal>sa</literal> è ñëóæáà + MSSQLSERVER èìååò äîñòàòî÷íî ïðàâ, çëîóìûøëåííèê áóäåò èìåòü ó÷åòíóþ + çàïèñü äëÿ äîñòóïà ê ýòîé ìàøèíå. </para> <note> <para> - Some of the examples above is tied to a specific database server. This - does not mean that a similar attack is impossible against other products. - Your database server may be so vulnerable in other manner. + Íåêîòîðûå èç âûøåïåðå÷èñëåííûõ ïðèìåðîâ ïðèâÿçàíû ê êîíêðåòíîìó + ñåðâåðó áàç äàííûõ. Íî ýòî âîâñå íå îçíà÷àåò, ÷òî ïîäîáíàÿ àòàêà + íåâîçìîæíà ñ äðóãèìè ïðîãðàììàìè. Âàø ñåðâåð áàç äàííûõ òîæå òàê èëè + èíà÷å áóäåò óÿçâèì äëÿ íåïðåäâèäåííûõ àòàê. </para> </note> <sect3 id="security.database.avoiding"> - <title>Avoiding techniques</title> + <title>Òåõíèêà çàùèòû</title> <simpara> - You may plead that the attacker must possess a piece of information - about the database schema in most examples. You are right, but you - never know when and how it can be taken out, and if it happens, - your database may be exposed. If you are using an open source, or - publicly available database handling package, which may belong to a - content management system or forum, the intruders easily produce - a copy of a piece of your code. It may be also a security risk if it - is a poorly designed one. +  áîëüøèíñòâå ïðèìåðîâ âèäíî, ÷òî äëÿ àòàêè çëîóìûøëåííèê äîëæåí + îáëàäàòü íåêîòîðîé èíôîðìàöèåé. Âñå âåðíî, íî íèêîãäà çàðàíåå íå + èçâåñòíî, êàêèìè ïóòÿìè óéäåò äàííàÿ èíôîðìàöèÿ. Åñëè ýòî âñå-òàêè + ñëó÷èòñÿ, áàçà äàííûõ ñòàíîâèòñÿ íåçàùèùåííîé. Åñëè âû èñïîëüçóåòå + ñâîáîäíî ðàñïðîñòðàíÿåìûé ïàêåò óïðàâëåíèÿ áàçàìè äàííûõ, êîòîðûé + ïðèíàäëåæèò êàêîé-íèáóäü ñèñòåìå óïðàâëåíèÿ ñîäåðæèìûì èëè ôîðóìó, + çëîóìûøëåííèê ëåãêî ïîëó÷èò êîïèþ äàííîé ÷àñòè âàøåé ïðîãðàììû. + Ýòî òàêæå ìîæåò ïðåäñòàâëÿòü "äûðó" â áåçîïàñíîñòè. </simpara> <simpara> - These attacks are mainly based on exploiting the code not being written - with security in mind. Never trust on any kind of input, especially - which comes from the client side, even though it comes from a select box, - a hidden input field or a cookie. The first example shows that such a - blameless query can cause disasters. + Áîëüøèíñòâî àòàê ïîñòðîåíû íà èñïîëüçîâàíèè êîäà, êîòîðûé ïèñàëñÿ áåç + ó÷åòà ñîîáðàæåíèé áåçîïàñíîñòè. Íèêîãäà íå äîâåðÿéòå ââåäåííûì äàííûì, + îñîáåííî åñëè îíè èäóò ñ êëèåíòñêîé ñòîðîíû, ïóñòü äàæå è èç ïîëÿ + îòìåòêè, ñêðûòîãî ïîëÿ èëè çàïèñè cookie. Ïåðâûé ïðèìåð ïîêàçûâàåò, + ê ÷åìó ìîæåò ïðèâåñòè ïîäìåíà ýòèõ äàííûõ. </simpara> <itemizedlist> <listitem> <simpara> - Never connect to the database as a superuser or as the database owner. - Use always customized users with very limited privileges. + Íèêîãäà íå ñîåäèíÿéòåñü ñ áàçîé äàííûõ â ðîëè ñóïåðïîëüçîâàòåëÿ èëè + âëàäåëüöà. Âñåãäà èñïîëüçóéòå ñïåöèàëüíûõ ïîëüçîâàòåëåé ñ ìèíèìóìîì + ïðàâ. </simpara> </listitem> <listitem> <simpara> - Check if the given input has the expected data type. PHP has - a wide range of input validating functions, from the simplest ones - found in <link linkend="ref.variables">Variable Functions</link> and - in <link linkend="ref.ctype">Character Type Functions</link> - (e.g. <function>is_numeric</function>, <function>ctype_digit</function> - respectively) onwards the - <link linkend="ref.pcre">Perl compatible Regular Expressions</link> - support. + Ïðîâåðÿéòå ââîä íà ñîâïàäåíèå òèïà äàííûõ ñ òðåáóåìûì. PHP âêëþ÷àåò + â ñåáÿ áîëüøîå êîëè÷åñòâî ïðîâåðî÷íûõ ôóíêöèé, îò ñàìûõ ïðîñòåéøèõ + èç ðàçäåëîâ <link linkend="ref.variables">Variable Functions</link> è + <link linkend="ref.ctype">Character Type Functions</link>, + (ê ïðèìåðó <function>is_numeric</function> è <function>ctype_digit</function> + ñîîòâåòñòâåííî) äî ðåãóëÿðíûõ âûðàæåíèé Perl + (<link linkend="ref.pcre">Perl compatible Regular Expressions</link>). </simpara> </listitem> <listitem> <para> - If the application waits for numerical input, consider to verify data - with <function>is_numeric</function>, or silently change its type - using <function>settype</function>, or use its numeric representation - by <function>sprintf</function>. + Åñëè ïðîãðàììà îæèäàåò ÷èñëî, ïðîâåðÿéòå äàííûå ñ ïîìîùüþ + <function>is_numeric</function>, èëè ïðîñòî èçìåíÿéòå òèï ñ ïîìîùüþ + <function>settype</function>, èëè äàæå èñïîëüçóéòå ÷èñëåííîå + ïðåäñòàâëåíèå, âûäàííîå <function>sprintf</function>. <example> - <title>A more secure way to compose a query for paging</title> + <title>Áîëåå áåçîïàñíàÿ ðàçáèâêà íà ñòðàíèöû</title> <programlisting role="php"> <![CDATA[ settype($offset, 'integer'); $query = "SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET $offset;"; -// please note %d in the format string, using %s would be meaningless +// îòìåòèì %d â ñòðîêå ôîðìàòèðîâàíèÿ, èñïîëüçîâàíèå %s áåñïîëåçíî $query = sprintf("SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET %d;", $offset); ]]> @@ -866,57 +866,58 @@ </listitem> <listitem> <simpara> - Quote each non numeric user input which is passed to the database with - <function>addslashes</function> or <function>addcslashes</function>. - See <link linkend="security.database.storage">the first example</link>. - As the examples shows, quotes burnt into the static part of the query - is not enough, and can be easily hacked. + Ïðåäâàðÿéòå ëþáîé íå÷èñëîâîé ââîä, ïåðåäàâàåìûé â áàçó äàííûõ, + ôóíêöèÿìè <function>addslashes</function> èëè + <function>addcslashes</function>.  + <link linkend="security.database.storage">ïåðâîì ïðèìåðå</link> + ïîêàçàíî, ÷òî êàâû÷åê â ñòàòè÷åñêîé ÷àñòè çàïðîñà íåäîñòàòî÷íî. </simpara> </listitem> <listitem> <simpara> - Do not print out any database specific information, especially - about the schema, by fair means or foul. See also <link - linkend="security.errors">Error Reporting</link> and <link + Íå âûâîäèòå íèêàêîé èíôîðìàöèè î ñòðóêòóðå áàçû äàííûõ íè êîèì + îáðàçîì. Äëÿ îïèñàíèÿ ïîäðîáíîñòåé ñìîòðèòå ðàçäåë <link + linkend="security.errors">îò÷åòû îá îøèáêàõ</link> è <link linkend="ref.errorfunc">Error Handling and Logging Functions</link>. </simpara> </listitem> <listitem> <simpara> - You may use stored procedures and previously defined cursors to abstract - data access so that users do not directly access tables or views, but - this solution has another impacts. + Ìîæíî èñïîëüçîâàòü õðàíèìûå ïðîöåäóðû è çàäàííûå ðàñïîëîæåíèÿ äëÿ òîãî, + ÷òîáû îòâÿçàòü îáðàùåíèå ê äàííûì îò ïðîãðàììû òàê, ÷òîáû ïîëüçîâàòåëè + íå èìåëè ïðÿìîãî äîñòóïà ê òàáëèöàì è ïðåäñòàâëåíèÿì, íî ýòîò âàðèàíò + èìååò ñîáñòâåííûå ïðîáëåìû. </simpara> </listitem> </itemizedlist> <simpara> - Besides these, you benefit from logging queries either within your script - or by the database itself, if it supports. Obviously, the logging is unable - to prevent any harmful attempt, but it can be helpful to trace back which - application has been circumvented. The log is not useful by itself, but - through the information it contains. The more detail is generally better. + Êðîìå òîãî, âåäèòå æóðíàë îïåðàöèé â ïðîãðàììå èëè ñîáñòâåííî â áàçå + äàííûõ, åñëè ýòî ïîääåðæèâàåòñÿ. Âåäåíèå æóðíàëà íå ïðåäîòâðàòèò + âíåäðåíèÿ, íî îíî ïîìîæåò îïðåäåëèòü, êàêàÿ ÷àñòü ïðîãðàììû áûëà + ïîñòàâëåíà ïîä óäàð. Ñàì æóðíàë áåñïîëåçåí - ïîëåçíà õðàíèìàÿ â íåì + èíôîðìàöèÿ. ×åì åå áîëüøå - òåì ëó÷øå. </simpara> </sect3> </sect2> </sect1> <sect1 id="security.errors"> - <title>Error Reporting</title> + <title>Îò÷åòû îá îøèáêàõ</title> <para> - With PHP security, there are two sides to error reporting. One is - beneficial to increasing security, the other is detrimental. +  ñëó÷àå íàñòðîéêè áåçîïàñíîñòè PHP ó îò÷åòà îá îøèáêàõ åñòü äâå + ñòîðîíû. Îäíà - ïëþñ â ñòîðîíó áåçîïàñíîñòè, äðóãàÿ - íàîáîðîò. </para> <para> - A standard attack tactic involves profiling a system by feeding - it improper data, and checking for the kinds, and contexts, of the - errors which are returned. This allows the system cracker to probe - for information about the server, to determine possible weaknesses. - For example, if an attacker had gleaned information about a page - based on a prior form submission, they may attempt to override - variables, or modify them: + Ñòàíäàðòíàÿ òåõíèêà àòàêè âêëþ÷àåò â ñåáÿ òåñòèðîâàíèå ñèñòåìû + ïóòåì óêàçàíèÿ çàâåäîìî íåâåðíûõ äàííûõ è ïîëó÷åíèÿ äåòàëåé + âñåõ âîçâðàùåííûõ îøèáîê. Ýòî ïîçâîëÿåò âçëîìùèêó ïîëó÷èòü èíôîðìàöèþ + î ñåðâåðå, î âîçìîæíûõ ñëàáîñòÿõ ñèñòåìû çàùèòû. Ê ïðèìåðó, åñëè + çëîóìûøëåííèêó äîñòóïíà èíôîðìàöèÿ î ñòðàíèöå, èñïîëüçóþùåé ïðåäâàðèòåëüíûé + ââîä äàííûõ â ôîðìó, òî îí ìîæåò ïîïûòàòüñÿ èçìåíèòü ïåðåäàâàåìûå + ïåðåìåííûå: <example> - <title>Attacking Variables with a custom HTML page</title> + <title>Àòàêà íà ïåðåìåííûå ñ ïîìîùüþ ñîáñòâåííîé ñòðàíèöû HTML</title> <programlisting role="php"> <![CDATA[ <form method="post" action="attacktarget?username=badfoo&password=badfoo"> @@ -928,22 +929,19 @@ </example> </para> <para> - The PHP errors which are normally returned can be quite helpful to a - developer who is trying to debug a script, indicating such things - as the function or file that failed, the PHP file it failed in, - and the line number which the failure occured in. This is all - information that can be exploited. It is not uncommon for a php - developer to use <function>show_source</function>, - <function>highlight_string</function>, or - <function>highlight_file</function> as a debugging measure, but in - a live site, this can expose hidden variables, unchecked syntax, - and other dangerous information. Especially dangerous is running - code from known sources with built-in debugging handlers, or using - common debugging techniques. If the attacker can determine what - general technique you are using, they may try to brute-force a page, - by sending various common debugging strings: + Îøèáêè, êîòîðûå îáû÷íî âîçâðàùàþòñÿ PHP, î÷åíü ïîìîãàþò â îòëàäêå ïðîãðàìì, + óêàçûâàÿ íà ôàéë èëè ôóíêöèþ, à òàêæå íîìåð ñòðîêè ãäå ïðîèçîøëà îøèáêà. + Îäíàêî, âñÿ ýòà èíôîðìàöèÿ ìîæåò áûòü èñïîëüçîâàíà. Î÷åíü ÷àñòî + ðàçðàáîò÷èêè èñïîëüçóþò ôóíêöèè <function>show_source</function>, + <function>highlight_string</function> + èëè <function>highlight_file</function>, êàê îòëàäî÷íûå, íî â ðåàëüíîì + ñëó÷àå îíè ìîãóò ïîêàçàòü ñêðûòûå ïåðåìåííûå, íåîòëàæåííûå ó÷àñòêè êîäà + è äðóãóþ îïàñíóþ èíôîðìàöèþ. Îñîáåííî îïàñåí çàïóñê êîäà ñ âñòðîåííûìè + îòëàäî÷íûìè ÷àñòÿìè èëè ñ èñïîëüçîâàíèåì òåõíîëîãèé îòëàäêè. Åñëè + çëîóìûøëåííèê îïðåäåëèò âàøó ñõåìó îòëàäêè, îí ìîæåò ïðîñòî ïîñëàòü + âàøåìó êîäó îòëàäî÷íûå êîìàíäû äëÿ ïðîèçâåäåíèÿ ñâîèõ äåéñòâèé. <example> - <title>Exploiting common debugging variables</title> + <title>Èñïîëüçîâàíèå îòëàäî÷íûõ ïåðåìåííûõ</title> <programlisting role="php"> <![CDATA[ <form method="post" action="attacktarget?errors=Y&showerrors=1"&debug=1"> @@ -956,60 +954,54 @@ </example> </para> <para> - Regardless of the method of error handling, the ability to probe a - system for errors leads to providing an attacker with more - information. + Íåçàâèñèìî îò ñïîñîáà îáðàáîòêè îøèáîê, âîçìîæíîñòü òåñòèðîâàíèÿ + ñèñòåìû ïðèâîäèò ê ïîëó÷åíèþ âçëîìùèêîì äîïîëíèòåëüíîé èíôîðìàöèè. </para> <para> - For example, the very style of a generic PHP error indicates a system - is running PHP. If the attacker was looking at an .html page, and - wanted to probe for the back-end (to look for known weaknesses in - the system), by feeding it the wrong data they may be able to - determine that a system was built with PHP. + Ê ïðèìåðó, ñàì ñòèëü îòîáðàæåíèÿ îøèáîê PHP îáîçíà÷àåò, ÷òî â ñèñòåìå + çàïóùåí PHP. Åñëè çëîóìûøëåííèê, âèäÿùèé .html ñòðàíèöó çàõî÷åò ïðîâåðèòü + ñåðâåð íà ñëàáûå ìåñòà â áåçîïàñíîñòè ïóòåì ââîäà íåâåðíûõ äàííûõ, îí, + òàêèì îáðàçîì, óçíàåò, ÷òî ñèñòåìà ïîñòðîåíà ñ èñïîëüçîâàíèåì PHP. </para> <para> - A function error can indicate whether a system may be running a - specific database engine, or give clues as to how a web page or - programmed or designed. This allows for deeper investigation into - open database ports, or to look for specific bugs or weaknesses - in a web page. By feeding different pieces of bad data, for example, - an attacker can determine the order of authentication in a script, - (from the line number errors) as well as probe for exploits that - may be exploited in different locations in the script. + Îøèáêè ôóíêöèé ìîãóò óêàçàòü íà çàïóùåííûé â ñèñòåìå ñåðâåð áàç + äàííûõ èëè äàòü èíôîðìàöèþ î òîì, êàê íàïèñàíà ýòà Web-ñòðàíèöà. + Ýòî ïîçâîëÿåò âåñòè äàëüíåéøåå èññëåäîâàíèå îòêðûòûõ ìåñò â áàçå + äàííûõ èëè èñêàòü îøèáêè è ñëàáûå ìåñòà â Web-ñòðàíèöå. + Ïóòåì ïîñûëêè ðàçëè÷íûõ íåêîððåêòíûõ äàííûõ çëîóìûøëåííèê ìîæåò, + íàïðèìåð, óçíàòü ïîñëåäîâàòåëüíîñòü àóòåíòèôèêàöèè (èç íîìåðîâ ñòðîê), + à òàêæå ìîæåò ïîïûòàòüñÿ îáíàðóæèòü "äûðû" â ðàçëè÷íûõ ìåñòàõ + ïðîãðàììû. </para> <para> - A filesystem or general PHP error can indicate what permissions - the webserver has, as well as the structure and organization of - files on the web server. Developer written error code can aggravate - this problem, leading to easy exploitation of formerly "hidden" - information. + Îøèáêè ôàéëîâîé ñèñòåìû èëè îáùèå îøèáêè PHP ìîãóò îòêðûòü + çàäàííûå Web-ñåðâåðó ðàçðåøåíèÿ, à òàêæå ñòðóêòóðó ôàéëîâ ñåðâåðà. + Êîäû îøèáîê ðàçðàáîò÷èêà óõóäøàþò ñèòóàöèþ, ïðèâîäÿ ê âåñüìà + ïðèìèòèâíîìó èñïîëüçîâàíèþ "îôèöèàëüíî ñêðûòîé" èíôîðìàöèè. </para> <para> - There are three major solutions to this issue. The first is to - scrutinize all functions, and attempt to compensate for the bulk - of the errors. The second is to disable error reporting entirely - on the running code. The third is to use PHP's custom error - handling functions to create your own error handler. Depending - on your security policy, you may find all three to be applicable - to your situation. + Åñòü òðè îñíîâíûõ ïóòè ðåøåíèÿ ïðîáëåìû. Ïåðâûé - îòëàäèòü âñå + ôóíêöèè è ïîïûòàòüñÿ êîìïåíñèðîâàòü íàëè÷èå îøèáîê. Âòîðîé - + ïîëíîñòüþ îòêëþ÷èòü îò÷åò îá îøèáêàõ. Òðåòèé - èñïîëüçîâàòü + ñîáñòâåííûé îáðàáîò÷èê îøèáîê PHP. Âûáîð çàâèñèò îò âàøåãî æåëàíèÿ è + ñòðóêòóðû âàøåé ñèñòåìû áåçîïàñíîñòè. </para> <para> - One way of catching this issue ahead of time is to make use of - PHP's own <function>error_reporting</function>, to help you - secure your code and find variable usage that may be dangerous. - By testing your code, prior to deployment, with E_ALL, you can - quickly find areas where your variables may be open to poisoning - or modification in other ways. Once you are ready for deployment, - by using E_NONE, you insulate your code from probing. + Åùå îäèí ñïîñîá ðåøåíèÿ ïðîáëåìû "äîñðî÷íî" - èñïîëüçîâàíèå âñòðîåííîé + îïöèè PHP <function>error_reporting</function>, äëÿ òîãî, ÷òîáû + îáåçîïàñèòü ïðîãðàììó è íàéòè óÿçâèìûå ïåðåìåííûå. Òåñòèðóÿ ïðîãðàììó äî + ðàçâåðòûâàíèÿ ñ E_ALL ìîæíî áûñòðî íàéòè ìåñòà, ãäå ïåðåìåííûå + ìîãóò áûòü îòêðûòû äëÿ ìîäèôèêàöèè. Êàê òîëüêî ïðîãðàììà ãîòîâà ê + ðàçâåðòûâàíèþ, E_NONE ïðåäîòâðàùàåò èññëåäîâàíèå. <example> - <title>Finding dangerous variables with E_ALL</title> + <title>Íàõîæäåíèå íåáåçîïàñíûõ ïåðåìåííûõ ñ ïîìîùüþ E_ALL</title> <programlisting role="php"> <![CDATA[ <?php -if ($username) { // Not initialized or checked before usage +if ($username) { // íå èíèöèàëèçèðîâàíà è íå ïðîâåðÿåòñÿ ïåðåä èñïîëüçîâàíèåì $good_login = 1; } -if ($good_login == 1) { // If above test fails, not initialized or checked before usage +if ($good_login == 1) { // åñëè ïðåäûäóùèé òåñò íå ïðîøåë, çíà÷èò $username íå èíèöèàëèçèðîâàíà fpassthru ("/highly/sensitive/data/index.html"); } ?> @@ -1020,31 +1012,30 @@ </sect1> <sect1 id="security.registerglobals"> - <title>Using Register Globals</title> + <title>Èñïîëüçîâàíèå îïöèè register-globals</title> <para> - One feature of PHP that can be used to enhance security is configuring PHP with + Åùå îäíî ñðåäñòâî PHP äëÿ ïîâûøåíèÿ áåçîïàñíîñòè - êîíôèãóðàöèÿ ñ + èñïîëüçîâàíèåì <link linkend="ini.register-globals">register_globals</link> = off. - By turning off the ability for any user-submitted variable to be injected - into PHP code, you can reduce the amount of variable - poisoning a potential attacker may inflict. They will have - to take the additional time to forge submissions, and your - internal variables are effectively isolated from user - submitted data. + Ýòî îòêëþ÷àåò âíåäðåíèå ïîëüçîâàòåëüñêèõ ïåðåìåííûõ â ñðåäó ïåðåìåííûõ + ïðîãðàììû íà PHP, ñâîäÿ ïîïûòêè âíåäðåíèÿ çëîóìûøëåííèêîì íóæíûõ åìó + çíà÷åíèé íà íåò. Îïöèÿ ïîëíîñòüþ èçîëèðóåò âíóòðåííèå ïåðåìåííûå îò + ïðåäîñòàâëÿåìûõ ïîëüçîâàòåëåì äàííûõ. </para> <para> - While it does slightly increase the amount of effort required - to work with PHP, it has been argued that the benefits far - outweigh the effort. + Êîíå÷íî, ýòî íåìíîãî óâåëè÷èâàåò êîëè÷åñòâî óñèëèé, íåîáõîäèìûõ äëÿ + îáðàáîòêè ïîëüçîâàòåëüñêîãî ââîäà. Íî âñå-òàêè èãðà ñòîèò ñâå÷, è + ïëþñû òàêîãî ïîäõîäà ãîðàçäî áîëåå ñóùåñòâåííû, íåæåëè ìèíóñû. <example> - <title>Working with register_globals=on</title> + <title>Ïðîãðàììà ñ register_globals=on</title> <programlisting role="php"> <![CDATA[ <?php -if ($username) { // can be forged by a user in get/post/cookies +if ($username) { // ìîæåò áûòü ïîäìåíåíà ïîëüçîâàòåëåì â get/post/cookies $good_login = 1; } -if ($good_login == 1) { // can be forged by a user in get/post/cookies, +if ($good_login == 1) { // òàêæå ìîæåò áûòü ïîäìåíåíà ïîëüçîâàòåëåì â get/post/cookies fpassthru ("/highly/sensitive/data/index.html"); } ?> @@ -1052,12 +1043,12 @@ </programlisting> </example> <example> - <title>Working with register_globals = off</title> + <title>Ïðîãðàììà ñ register_globals = off</title> <programlisting role="php"> <![CDATA[ <?php if($_COOKIE['username']){ - // can only come from a cookie, forged or otherwise + // ìîæåò ïðèéòè òîëüêî èç çàïèñè cookie, íîðìàëüíîé èëè ïîääåëüíîé $good_login = 1; fpassthru ("/highly/sensitive/data/index.html"); } @@ -1065,61 +1056,57 @@ ]]> </programlisting> </example> - By using this wisely, it's even possible to take preventative - measures to warn when forging is being attempted. If you know - ahead of time exactly where a variable should be coming from, - you can check to see if submitted data is coming from an - inappropriate kind of submission. While it doesn't guarantee - that data has not been forged, it does require an attacker - to guess the right kind of forging. + Ðàçóìíî èñïîëüçóÿ äàííûé ìåòîä, ìîæíî äàæå ïðèíÿò ìåðû ïðåäîòâðàùåíèÿ + ïîäìåíû äàííûõ, ïðåäóïðåæäàÿ, êîãäà òàêîâàÿ ïðåäïðèíèìàåòñÿ. Åñëè + èçâåñòíî, ãäå äîëæíà áûòü íåîáõîäèìàÿ ïåðåìåííàÿ, ìîæíî ïðîâåðèòü, íå + èäåò ëè îíà îò íåäîïóñòèìîãî èñòî÷íèêà. Ýòî íå ãàðàíòèðóåò îòñóòñòâèå + ïîäìåíû äàííûõ, íî çëîóìûøëåííèêó ïðèäåòñÿ èñêàòü ïðàâèëüíûé ïóòü ïîäìåíû. <example> - <title>Detecting simple variable poisoning</title> + <title>Ïðîñòåéøàÿ ïðîâåðêà íà ïîäìåíó äàííûõ</title> <programlisting role="php"> <![CDATA[ <?php if ($_COOKIE['username'] && !$_POST['username'] && !$_GET['username'] ) { - // Perform other checks to validate the user name... + // ïðîèçâåñòè ïðîâåðêó èìåíè ïîëüçîâàòåëÿ $good_login = 1; fpassthru ("/highly/sensitive/data/index.html"); } else { - mail("admin@example.com", "Possible breakin attempt", $_SERVER['REMOTE_ADDR']); - echo "Security violation, admin has been alerted."; + mail("admin@example.com", "Âîçìîæíà ïîäìåíà äàííûõ ", $_SERVER['REMOTE_ADDR']); + echo "Îøèáêà áåçîïàñíîñòè. Ïðîèçâåäåíî îïîâåùåíèå àäìèíèñòðàòîðà."; exit; } ?> ]]> </programlisting> </example> - Of course, simply turning off register_globals does not mean code - is secure. For every piece of data that is submitted, it - should also be checked in other ways. + Êîíå÷íî, âûêëþ÷åíèå register_globals íå îçíà÷àåò, ÷òî ïðîãðàììà + áåçîïàñíà. Âñå âõîäíûå äàííûå âñå ðàâíî òðåáóþò äîïîëíèòåëüíîé ïðîâåðêè. </para> </sect1> <sect1 id="security.variables"> - <title>User Submitted Data</title> + <title>Äàííûå, îòïðàâëåííûå ïîëüçîâàòåëåì</title> <para> - The greatest weakness in many PHP programs is not inherent in the - language itself, but merely an issue of code not being written with - security in mind. For this reason, you should always take the time - to consider the implications of a given piece of code, to ascertain - the possible damage if an unexpected variable is submitted to it. + Ñàìûå ñëàáûå ìåñòà â áîëüøèíñòâå ïðîãðàìì íà PHP íå ÿâëÿþòñÿ ñëåäñòâèåì + ïðîáëåì ñàìîãî ÿçûêà, íàïðîòèâ, îíè ÿâëÿþòñÿ ñëåäñòâèåì íàïèñàíèÿ ýòèõ + ïðîãðàìì áåç ó÷åòà ñîîáðàæåíèé áåçîïàñíîñòè. Ïîýòîìó âû âñåãäà äîëæíû + òðàòèòü íåêîòîðîå âðåìÿ íà ïðîäóìûâàíèå îãðàíè÷åíèé òåõ èëè èíûõ + ó÷àñòêîâ êîäà äëÿ ñíèæåíèÿ ðèñêà îò íåêîððåêòíî çàäàííûõ ïåðåìåííûõ. <example> - <title>Dangerous Variable Usage</title> + <title>Íåáåçîïàñíîå èñïîëüçîâàíèå ïåðåìåííîé</title> <programlisting role="php"> <![CDATA[ <?php -// remove a file from the user's home directory... or maybe -// somebody else's? +// óäàëåíèå ôàéëà èç ïîëüçîâàòåëüñêîãî äîìàøíåãî êàòàëîãà... èëè èç ÷üåãî-òî åùå? unlink ($evil_var); -// Write logging of their access... or maybe an /etc/passwd entry? +// çàïèñü æóðíàëà äîñòóïà... èëè çàïèñü â /etc/passwd? fputs ($fp, $evil_var); -// Execute something trivial.. or rm -rf *? +// èñïîëíåíèå ÷åãî-íèáóäü ïðîñòåíüêîãî.. èëè rm -rf *? system ($evil_var); exec ($evil_var); @@ -1127,120 +1114,118 @@ ]]> </programlisting> </example> - You should always carefully examine your code to make sure that any - variables being submitted from a web browser are being properly - checked, and ask yourself the following questions: + Âñåãäà íóæíî àêêóðàòíî èññëåäîâàòü ïðîãðàììó, ÷òîáû óáåäèòüñÿ, ÷òî + âñå ïåðåìåííûå, ïåðåäàâàåìûå ïîëüçîâàòåëåì, ïðîâåðÿþòñÿ. Ìîæíî äàæå + çàäàâàòü ñåáå ñëåäóþùèå âîïðîñû: <itemizedlist> <listitem> <simpara> - Will this script only affect the intended files? + Áóäåò ëè ýòà ïðîãðàììà èñïîëüçîâàòü èìåííî íåîáõîäèìûå ôàéëû? </simpara> </listitem> <listitem> <simpara> - Can unusual or undesirable data be acted upon? + Ìîãóò ëè áûòü îáðàáîòàíû íåîáû÷íûå èëè íåæåëàòåëüíûå äàííûå? </simpara> </listitem> <listitem> <simpara> - Can this script be used in unintended ways? + Ìîæåò ëè ýòà ïðîãðàììà èñïîëüçîâàòüñÿ íåæåëàòåëüíûì îáðàçîì? </simpara> </listitem> <listitem> <simpara> - Can this be used in conjunction with other scripts in a negative - manner? + Ìîæåò ëè îíà èñïîëüçîâàòüñÿ â ñîâîêóïíîñòè ñ äðóãèìè ïðîãðàììàìè äëÿ + ðåàëèçàöèè çëîãî óìûñëà? </simpara> </listitem> <listitem> <simpara> - Will any transactions be adequately logged? + Áóäóò ëè äîëæíûì îáðàçîì çàïèñàíû â æóðíàë îïåðàöèè? </simpara> </listitem> </itemizedlist> - By adequately asking these questions while writing the script, - rather than later, you prevent an unfortunate re-write when you - need to increase your security. By starting out with this mindset, - you won't guarantee the security of your system, but you can help - improve it. + Çàäàâàÿ ñåáå ýòè âîïðîñû âî âðåìÿ íàïèñàíèÿ ïðîãðàììû, ìîæíî + ïðåäîòâðàòèòü ïåðåïèñûâàíèå åå "ñ íóëÿ" â ñâÿçè ñ ïðîáëåìàìè + áåçîïàñíîñòè. Ïåðåíÿâ ïîäîáíûé îáðàç ìûøëåíèÿ, âû íå ãàðàíòèðóåòå + áåçîïàñíîñòè ñèñòåìû, íî óâåëè÷èòå ýòó áåçîïàñíîñòü. </para> <para> - You may also want to consider turning off register_globals, - magic_quotes, or other convenience settings which may confuse - you as to the validity, source, or value of a given variable. - Working with PHP in error_reporting(E_ALL) mode can also help warn - you about variables being used before they are checked or - initialized (so you can prevent unusual data from being - operated upon). + Òàêæå ñëåäóåò ïîäóìàòü îá îòêëþ÷åíèè register_globals, + magic_quotes, è äðóãèõ îïöèé, êîòîðûå ñòàâÿò ïîä ñîìíåíèå êîððåêòíîñòü, + èñòî÷íèê è çíà÷åíèÿ îòäåëüíî âçÿòûõ ïåðåìåííûõ. Ðàáîòà â ðåæèìå îòîáðàæåíèÿ + âñåõ îøèáîê (error_reporting=E_ALL) òàêæå ïðåäóïðåäèò îá èñïîëüçîâàíèè + ïåðåìåííûõ áåç ïðåäâàðèòåëüíîé ïðîâåðêè è èíèöèàëèçàöèè. </para> </sect1> <sect1 id="security.hiding"> - <title>Hiding PHP</title> + <title>Ñêðûòèå PHP</title> <para> - In general, security by obscurity is one of the weakest forms of security. - But in some cases, every little bit of extra security is desirable. +  îáùåì ñëó÷àå, ñêðûòèå - ñàìàÿ ñëàáàÿ ôîðìà ñèñòåìû áåçîïàñíîñòè. Íî â + íåêîòîðûõ ñëó÷àÿõ íåîáõîäèìà ëþáàÿ ìàëîñòü. </para> <para> - A few simple techniques can help to hide PHP, possibly slowing - down an attacker who is attempting to discover weaknesses in your - system. By setting expose_php = off in your &php.ini; file, you - reduce the amount of information available to them. + Åñòü íåñêîëüêî ïðèåìîâ, ïîçâîëÿþùèõ ñêðûòü PHP, ÷òî çàìåäëèò äåéñòâèÿ + çëîóìûøëåííèêà, ïûòàþùåãîñÿ îáíàðóæèòü ñëàáîñòè â âàøåé ñèñòåìå. + Óñòàíîâêà â ôàéëå &php.ini; îïöèè expose_php = off óìåíüøèò êîëè÷åñòâî + äîñòóïíîé èíôîðìàöèè. </para> <para> - Another tactic is to configure web servers such as apache to - parse different filetypes through PHP, either with an .htaccess - directive, or in the apache configuration file itself. You can - then use misleading file extensions: + Äðóãàÿ òàêòèêà - íàñòðîéêà ñåðâåðà Web (âðîäå Apache) äëÿ îáðàáîòêè + ðàçëè÷íûõ òèïîâ ôàéëîâ ñ ïîìîùüþ PHP. Ýòî äåëàåòñÿ ÷åðåç äèðåêòèâû + .htaccess èëè ÷åðåç ôàéë êîíôèãóðàöèè Apache. Çàòåì ìîæíî èñïîëüçîâàòü + "îòâëåêàþùèå" ðàñøèðåíèÿ ôàéëîâ: <example> - <title>Hiding PHP as another language</title> + <title>Ñêðûòèå PHP ïîä âèäîì äðóãîãî ÿçûêà</title> <programlisting role="apache-conf"> <![CDATA[ -# Make PHP code look like other code types +# Äåëàåì êîä PHP ïîõîæèì íà êîä äðóãèõ ÿçûêîâ AddType application/x-httpd-php .asp .py .pl ]]> </programlisting> </example> - Or obscure it completely: + Èëè âíîñèì ïóòàíèöó: <example> - <title>Using unknown types for PHP extensions</title> + <title>Èñïîëüçîâàíèå íåèçâåñòíûõ ðàñøèðåíèé äëÿ PHP</title> <programlisting role="apache-conf"> <![CDATA[ -# Make PHP code look like unknown types +# Äåëàåì PHP íè íà ÷òî íå ïîõîæèì AddType application/x-httpd-php .bop .foo .133t ]]> </programlisting> </example> - Or hide it as html code, which has a slight performance hit because - all html will be parsed through the PHP engine: + Èëè äàæå ìîæíî ñêðûòü PHP ïîä âèäîì html, ÷òî ïðèâåäåò ê íåáîëüøîé + ïîòåðå ïðîèçâîäèòåëüíîñòè, ïîñêîëüêó âñå .html-ôàéëû áóäóò îáðàáàòûâàòüñÿ + èíòåðïðåòàòîðîì PHP. <example> - <title>Using html types for PHP extensions</title> + <title>Èñïîëüçîâàíèå ðàñøèðåíèé html äëÿ PHP</title> <programlisting role="apache-conf"> <![CDATA[ -# Make all PHP code look like html +# Äåëàåì PHP ïîõîæèì íà html AddType application/x-httpd-php .htm .html ]]> </programlisting> </example> - For this to work effectively, you must rename your PHP files with - the above extensions. While it is a form of security through - obscurity, it's a minor preventative measure with few drawbacks. + ×òîáû âñå ýòî ðàáîòàëî, íàäî ïåðåèìåíîâàòü ôàéëû PHP â ôàéëû ñ + âûøåïåðå÷èñëåííûìè ðàñøèðåíèÿìè. Õîòÿ ýòî è ïîäâèä áåçîïàñíîñòè ÷åðåç + ñêðûòèå, ýòî îäíà èç ìåð ïðåäîòâðàùåíèÿ àòàê ñ ìèíèìóìîì èçâåñòíûõ ìèíóñîâ. </para> </sect1> <sect1 id="security.current"> - <title>Keeping Current</title> + <title> íîãó ñî âðåìåíåì</title> <simpara> - PHP, like any other large system, is under constant scrutiny and - improvement. Each new version will often include both major and - minor changes to enhance and repair security flaws, configuration - mishaps, and other issues that will affect the overall security - and stability of your system. + PHP, êàê è ëþáàÿ äðóãàÿ áîëüøàÿ ñèñòåìà, ïîñòîÿííî èçìåíÿåòñÿ è + äîðàáàòûâàåòñÿ. Êàæäàÿ íîâàÿ âåðñèÿ îáû÷íî âêëþ÷àåò êàê ñåðüåçíûå, + òàê è íåáîëüøèå èçìåíåíèÿ äëÿ óñòðàíåíèÿ ïðîáëåì áåçîïàñíîñòè, + êîíôèãóðàöèè, à òàêæå âñåãî, ÷òî âëèÿåò íà îáùóþ áåçîïàñíîñòü è + ñòàáèëüíîñòü ñèñòåìû. </simpara> <simpara> - Like other system-level scripting languages and programs, the best - approach is to update often, and maintain awareness of the latest - versions and their changes. + Êàê è â ñëó÷àå ñ äðóãèìè ïðîãðàììàìè, ëó÷øèé âàðèàíò - ýòî âûïîëíÿòü + îáíîâëåíèå êàê ìîæíî ÷àùå, à òàêæå ñëåäèòü çà ïîñëåäíèìè âåðñèÿìè + è ñäåëàííûìè â íèõ èçìåíåíèÿìè. </simpara> </sect1> </chapter>
Index: phpdoc-ru/chapters/security.xml diff -u phpdoc-ru/chapters/security.xml:1.1 phpdoc-ru/chapters/security.xml:1.2 --- phpdoc-ru/chapters/security.xml:1.1 Wed Dec 25 11:40:35 2002 +++ phpdoc-ru/chapters/security.xml Sat Jan 18 14:57:17 2003 @@ -1,6 +1,6 @@ -<?xml version="1.0" encoding="iso-8859-1"?> -<!-- EN-Revision: 1.49 Maintainer: alexws Status: in-progress --> -<!-- $Revision: 1.1 $ --> +<?xml version="1.0" encoding="windows-1251"?> +<!-- EN-Revision: 1.50 Maintainer: alexws Status: ready --> +<!-- $Revision: 1.2 $ --> <chapter id="security"> <title>Áåçîïàñíîñòü</title> @@ -217,71 +217,68 @@ <sect2 id="security.cgi-bin.doc-root"> <title>Âàðèàíò 3: óñòàíîâêà doc_root èëè user_dir</title> <simpara> - To include active content, like scripts and executables, in the - web server document directories is sometimes consider an insecure - practice. If, because of some configuration mistake, the scripts - are not executed but displayed as regular HTML documents, this - may result in leakage of intellectual property or security - information like passwords. Therefore many sysadmins will prefer - setting up another directory structure for scripts that are - accessible only through the PHP CGI, and therefore always - interpreted and not displayed as such. + Ïîìåùåíèå àêòèâíîãî ñîäåðæèìîãî (âðîäå ïðîãðàìì è èñïîëíÿåìûõ ôàéëîâ) + â äèðåêòîðèè äîêóìåíòîâ Web-ñåðâåðà ñ÷èòàåòñÿ íåáåçîïàñíûì. Åñëè + â ñëó÷àå êàêîé-ëèáî îøèáêè â êîíôèãóðèðîâàíèè ïðîãðàììû íå âûïîëíÿòñÿ, + à îòîáðàçÿòñÿ êàê îáû÷íûå HTML-äîêóìåíòû, ýòî ïðèâåäåò ê óòå÷êå + èíòåëëåêòóàëüíîé ñîáñòâåííîñòè èëè ñêðûòîé èíôîðìàöèè âðîäå ïàðîëåé. + Ïîýòîìó ìíîãèå ñèñòåìíûå àäìèíèñòðàòîðû ïðåäïî÷èòàþò ñîçäàâàòü + îòäåëüíóþ ñòðóêòóðó äèðåêòîðèé äëÿ ïðîãðàìì, äîñòóïíûõ òîëüêî ÷åðåç + PHP CGI, à ïîýòîìó âñåãäà èíòåïðåòèðóåìûõ è îòîáðàæàåìûõ âåðíî. </simpara> <simpara> - Also if the method for making sure the requests are not - redirected, as described in the previous section, is not - available, it is necessary to set up a script doc_root that is - different from web document root. + Ê òîìó æå, åñëè íåäîñòóïåí ìåòîä áåçîïàñíîãî ïåðåíàïðàâëåíèÿ çàïðîñîâ, + îïèñàííûé â ïðåäûäóùåé ÷àñòè, íåîáõîäèìî óñòàíîâèòü doc_root äëÿ + ïðîãðàìì, îòëè÷íûé îò êîðíåâîãî êàòàëîãà äîêóìåíòîâ Web-ñåðâåðà. </simpara> <simpara> - You can set the PHP script document root by the configuration - directive <link linkend="ini.doc-root">doc_root</link> in the - <link linkend="configuration.file">configuration file</link>, or - you can set the environment variable - <envar>PHP_DOCUMENT_ROOT</envar>. If it is set, the CGI version - of PHP will always construct the file name to open with this - <parameter>doc_root</parameter> and the path information in the - request, so you can be sure no script is executed outside this - directory (except for <parameter>user_dir</parameter> - below). + Êîðíåâîé êàòàëîã äîêóìåíòîâ äëÿ ïðîãðàìì PHP ìîæíî óñòàíîâèòü + ñ ïîìîùüþ äèðåêòèâû <link linkend="ini.doc-root">doc_root</link> + â <link linkend="configuration.file">ôàéëå êîíôèãóðàöèè</link> èëè + ñ ïîìîùüþ ïåðåìåííîé îêðóæåíèÿ <envar>PHP_DOCUMENT_ROOT</envar>. + Åñëè òàêàÿ óñòàíîâêà ñäåëàíà, òî CGI-âåðñèÿ PHP âñåãäà áóäåò äîáàâëÿòü + ê èíôîðìàöèè ïóòè â çàïðîñå çíà÷åíèå ïàðàìåòðà + <parameter>doc_root</parameter>, òàê ÷òî â ýòîì ñëó÷àå âû ìîæåòå áûòü + óâåðåíû, ÷òî íè îäíà ïðîãðàììà íå âûïîëíèòñÿ çà ïðåäåëàìè ýòîé + äèðåêòîðèè (èñêëþ÷åíèå ñîñòàâëÿåò ëèøü ñëó÷àé ñ èñïîëüçîâàíèåì + ïàðàìåòðà <parameter>user_dir</parameter>, îïèñàííûé íèæå). </simpara> <simpara> - Another option usable here is <link - linkend="ini.user-dir">user_dir</link>. When user_dir is unset, - only thing controlling the opened file name is - <parameter>doc_root</parameter>. Opening an url like <filename - role="url">http://my.host/~user/doc.php</filename> does not - result in opening a file under users home directory, but a file - called <filename role="uri">~user/doc.php</filename> under - doc_root (yes, a directory name starting with a tilde - [<literal>~</literal>]). + Åùå îäíîé ïîëåçíîé îïöèåé ÿâëÿåòñÿ <link linkend="ini.user-dir">user_dir</link>. + Åñëè user_dir íå çàäàíà, òî åäèíñòâåííûì ôàêòîðîì, âëèÿþùèì íà èìÿ + îòêðûâàåìîãî ôàéëà ÿâëÿåòñÿ <parameter>doc_root</parameter>. Îòêðûòèå + ULR âðîäå <filename role="url">http://my.host/~user/doc.php</filename> + íå ïðèâåäåò â ýòîì ñëó÷àå ê îòêðûòèþ ôàéëà âíóòðè äîìàøíåãî êàòàëîãà + ïîëüçîâàòåëÿ.  ýòîì ñëó÷àå áóäåò îòêðûò ôàéë + <filename role="uri">~user/doc.php</filename> â êàòàëîãå, çàäàííîì â + doc_root. </simpara> <simpara> - If user_dir is set to for example <filename - role="dir">public_php</filename>, a request like <filename - role="url">http://my.host/~user/doc.php</filename> will open a - file called <filename>doc.php</filename> under the directory - named <filename role="dir">public_php</filename> under the home - directory of the user. If the home of the user is <filename - role="dir">/home/user</filename>, the file executed is - <filename>/home/user/public_php/doc.php</filename>. + Åñëè user_dir óñòàíîâëåíà, ê ïðèìåðó, â <filename + role="dir">public_php</filename>, òî çàïðîñ <filename + role="url">http://my.host/~user/doc.php</filename> îòêðîåò ôàéë + <filename>doc.php</filename> â êàòàëîãå <filename + role="dir">public_php</filename>, íàõîäÿùåìñÿ â äîìàøíåì êàòàëîãå + ïîëüçîâàòåëÿ. Åñëè äîìàøíèé êàòàëîã ïîëüçîâàòåëÿ - <filename + role="dir">/home/user</filename>, òî â ýòîì ñëó÷àå áóäåò îòêðûò + ôàéë <filename>/home/user/public_php/doc.php</filename>. </simpara> <simpara> - <parameter>user_dir</parameter> expansion happens regardless of - the <parameter>doc_root</parameter> setting, so you can control - the document root and user directory access - separately. + <parameter>user_dir</parameter> èñïîëüçóåòñÿ íåçàâèñèìî îò + <parameter>doc_root</parameter>, ÷òî äàåò âîçìîæíîñòü çàäàâàòü + êîðíåâóþ äèðåêòîðèþ äîêóìåíòîâ è ïîëüçîâàòåëüñêèå äèðåêòîðèè + íåçàâèñèìî äðóã îò äðóãà. </simpara> </sect2> <sect2 id="security.cgi-bin.shell"> - <title>Case 4: PHP parser outside of web tree</title> + <title>Âàðèàíò 4: òðàíñëÿòîð PHP âíå äåðåâà äîêóìåíòîâ Web</title> <para> - A very secure option is to put the PHP parser binary somewhere - outside of the web tree of files. In <filename - role="dir">/usr/local/bin</filename>, for example. The only real - downside to this option is that you will now have to put a line - similar to: + Âåñüìà áåçîïàñíûì ÿâëÿåòñÿ ïîìåùåíèå ïðîãðàììû-òðàíñëÿòîðà PHP + çà ïðåäåëàìè äåðåâà äîêóìåíòîâ Web-ñåðâåðà. Ê ïðèìåðó, â <filename + role="dir">/usr/local/bin</filename>. Ó ýòîãî âàðèàíòà åñòü ëèøü + îäèí íåäîñòàòîê - òî, ÷òî â íà÷àëî êàæäîãî ôàéëà ñ òýãàìè PHP ïðèäåòñÿ + ïîìåùàòü ñëåäóþùóþ ñòðîêó: <informalexample> <programlisting> <![CDATA[ @@ -289,333 +286,332 @@ ]]> </programlisting> </informalexample> - as the first line of any file containing PHP tags. You will also - need to make the file executable. That is, treat it exactly as - you would treat any other CGI script written in Perl or sh or any - other common scripting language which uses the - <literal>#!</literal> shell-escape mechanism for launching - itself. + . Òàêæå ïîòðåáóåòñÿ ñäåëàòü äàííûå ôàéëû èñïîëíÿåìûìè, ò.å. ïðèäåòñÿ + îáðàùàòüñÿ ñ íèìè òàê æå, êàê è ñ ëþáûìè äðóãèìè CGI-ïðîãðàììàìè íà + Perl, sh èëè íà äðóãèõ èçâåñòíûõ ÿçûêàõ, èñïîëüçóþùèõ êîíñòðóêöèþ + <literal>#!</literal> äëÿ çàïóñêà. </para> <para> - To get PHP to handle <envar>PATH_INFO</envar> and - <envar>PATH_TRANSLATED</envar> information correctly with this - setup, the php parser should be compiled with the <link - linkend="install.configure.enable-discard-path">--enable-discard-path</link> - configure option. + Äëÿ òîãî, ÷òîáû PHP íà÷àë â äàííîì ñëó÷àå êîððåêòíî îáðàáàòûâàòü + <envar>PATH_INFO</envar> è <envar>PATH_TRANSLATED</envar>, òðàíñëÿòîð + PHP äîëæåí áûòü ñêîìïèëèðîâàí ñ îïöèåé êîíôèãóðàöèè <link + linkend="install.configure.enable-discard-path">--enable-discard-path</link>. </para> </sect2> </sect1> <sect1 id="security.apache"> - <title>Installed as an Apache module</title> + <title>Ïðè èíñòàëëÿöèè â âèäå ìîäóëÿ Apache</title> <simpara> - When PHP is used as an Apache module it inherits Apache's user - permissions (typically those of the "nobody" user). This has several - impacts on security and authorization. For example, if you are using - PHP to access a database, unless that database has built-in access - control, you will have to make the database accessable to the - "nobody" user. This means a malicious script could access and modify - the database, even without a username and password. It's entirely - possible that a web spider could stumble across a database - administrator's web page, and drop all of your databases. You can - protect against this with Apache authorization, or you can design - your own access model using LDAP, .htaccess files, etc. and include - that code as part of your PHP scripts. + Ïðè èñïîëüçîâàíèè PHP, êàê Apache-ìîäóëü, äàííûé ìîäóëü ïîëó÷àåò + âñå ïðàâà è ðàçðåøåíèÿ Apache (îáû÷íî, ïðàâà ïîëüçîâàòåëÿ "nobody", + ò.å. "îòñóòñòâóþùåãî" ïîëüçîâàòåëÿ). Ýòî âíîñèò íåêîòîðûå ñëîæíîñòè + â ñèñòåìó áåçîïàñíîñòè è àâòîðèçàöèè. Ê ïðèìåðó, åñëè PHP èñïîëüçóåòñÿ + äëÿ îáðàùåíèÿ ê áàçå äàííûõ, òî â ñëó÷àå îòñóòñòâèÿ âñòðîåííîãî êîíòðîëÿ + äîñòóïà â áàçå äàííûõ åå ïðèäåòñÿ ñäåëàòü äîñòóïíîé äëÿ ïîëüçîâàòåëÿ + "nobody".  ýòîì ñëó÷àå ïðîãðàììà çëîóìûøëåííèêà ìîæåò ïîëó÷èòü äîñòóï + íà ÷òåíèå è èçìåíåíèå áàçû äàííûõ äàæå áåç óêàçàíèÿ èìåíè ïîëüçîâàòåëÿ + è ïàðîëÿ. Òàêæå âîçìîæíî, ÷òî ñåòåâîé ÷åðâü ïðîíèêíåò íà ñòðàíèöó + àäìèíèñòðàòîðà è óíè÷òîæèò âñå âàøè áàçû äàííûõ. Ìîæíî çàùèòèòüñÿ îò + ýòîãî ïóòåì ââåäåíèÿ àâòîðèçàöèè â Apache, èëè ðàçðàáîòàâ ñîáñòâåííóþ + ìîäåëü äîñòóïà ñ èñïîëüçîâàíèåì LDAP, ôàéëîâ .htaccess (è äð.) è + èñïîëüçîâàòü ýòîò êîä, êàê ÷àñòü âàøèõ ïðîãðàìì íà PHP. </simpara> <simpara> - Often, once security is established to the point where the PHP user - (in this case, the apache user) has very little risk attached to it, - it is discovered that PHP is now prevented from writing any files - to user directories. Or perhaps it has been prevented from accessing - or changing databases. It has equally been secured from writing - good and bad files, or entering good and bad database transactions. + ×àñòî ñëó÷àåòñÿ òàê, ÷òî êîãäà áåçîïàñíîñòü äîñòèãàåò óðîâíÿ, ãäå + PHP (à â äàííîì ñëó÷àå, Apache) ïðàêòè÷åñêè íå ïðåäñòàâëÿåò + ïðîáëåìû áåçîïàñíîñòè, îêàçûâàåòñÿ, ÷òî PHP íå ìîæåò çàïèñàòü íè + îäíîãî ôàéëà â ïîëüçîâàòåëüñêèå êàòàëîãè. Èëè, äîïóñòèì, íå èìååò + äîñòóïà ê áàçàì äàííûõ. PHP îêàçûâàåòñÿ îäèíàêîãî çàùèùåííûì îò + çàïèñè äîçâîëåííûõ è íåäîçâîëåííûõ ôàëîâ, èëè îò ïðîèçâåäåíèÿ + äîçâîëåííûõ èëè íåäîçâîëåííûõ îïåðàöèé ñ áàçàìè äàííûõ. </simpara> <simpara> - A frequent security mistake made at this point is to allow apache - root permissions, or to escalate apache's abilitites in some other - way. + Î÷åíü ÷àñòàÿ îøèáêà íà ýòîì ýòàïå - äàòü PHP ïðàâà "root", èëè + àäìèíèñòðàòîðà èëè êàêèì-ëèáî îáðàçîì óâåëè÷èòü ðàçðåøåíèÿ äëÿ + Apache. </simpara> <simpara> - Escalating the Apache user's permissions to root is extremely - dangerous and may compromise the entire system, so sudo'ing, - chroot'ing, or otherwise running as root should not be considered by - those who are not security professionals. + Óñòàíîâêà äëÿ Apache ðàçðåøåíèé àäìèíèñòðàòîðà (root) î÷åíü îïàñíà + äëÿ ñèñòåìû â öåëîì. Òå, êòî íå ÿâëÿåòñÿ ñïåöèàëèñòàìè ïî áåçîïàñíîñòè, + â äàííîì ñëó÷àå äîëæíû èçáåãàòü ëþáûõ îïåðàöèé âðîäå "sudo" èëè "chroot". </simpara> <simpara> - There are some simpler solutions. By using - <link linkend="ini.open-basedir">open_basedir</link> you can control and restrict what - directories are allowed to be used for PHP. You can also set up - apache-only areas, to restrict all web based activity to non-user, - or non-system, files. + Åñòü áîëåå ïðîñòûå ðåøåíèÿ. Èñïîëüçóÿ + <link linkend="ini.open-basedir">open_basedir</link>, ìîæíî + êîíòðîëèðîâàòü è îãðàíè÷èâàòü èñïîëüçîâàíèå PHP äèðåêòîðèé. Òàêæå + ìîæíî ñîçäàòü îáëàñòè "òîëüêî äëÿ Apache", îãðàíè÷èâ âåñü äîñòóï + íå-ïîëüçîâàòåëüñêèìè èëè íå-ñèñòåìíûìè ôàéëàìè. </simpara> </sect1> <sect1 id="security.filesystem"> - <title>Filesystem Security</title> + <title>Áåçîïàñíîñòü ôàéëîâîé ñèñòåìû</title> <simpara> - PHP is subject to the security built into most server systems with - respect to permissions on a file and directory basis. This allows - you to control which files in the filesystem may be read. Care - should be taken with any files which are world readable to ensure - that they are safe for reading by all users who have access to that - filesystem. + PHP ïîä÷èíÿåòñÿ óñòàíîâêàì áåçîïàñíîñòè íà óðîâíå ôàéëîâ è êàòàëîãîâ, + êîòîðûå âñòðîåíû â áîëüøèíñòâî ñåðâåðíûõ ñèñòåì. Ýòî ïîçâîëÿåò + êîíòðîëèðîâàòü, êàêèå ôàéëû ìîãóò áûòü ïðî÷èòàíû. Ñ îñîáîé àêêóðàòíîñòüþ + íóæíî îòíîñèòüñÿ ê ôàéëàì ñ ïðàâîì ÷òåíèÿ "äëÿ âñåõ" - íóæíî ïîìíèòü + î òîì, îíè ìîãóò áûòü ñ÷èòàíû ëþáûì ïîëüçîâàòåëåì, èìåþùèì äîñòóï ê + äàííîé ôàéëîâîé ñèñòåìå. </simpara> <simpara> - Since PHP was designed to allow user level access to the filesystem, - it's entirely possible to write a PHP script that will allow you - to read system files such as /etc/passwd, modify your ethernet - connections, send massive printer jobs out, etc. This has some - obvious implications, in that you need to ensure that the files - that you read from and write to are the appropriate ones. + Ïîñêîëüêó PHP ðàçðàáàòûâàëñÿ äëÿ ïðåäîñòàâëåíèÿ ïîëüçîâàòåëüñêèõ + ïðàâ äîñòóïà ê ñèñòåìå, âîçìîæíî ñîçäàòü ïðîãðàììó íà PHP, êîòîðàÿ + ïîçâîëèò âàì ÷èòàòü ñèñòåìíûå ôàéëû, òàêèå, êàê /etc/passwd, èçìåíÿòü + ïàðàìåòðû âàøèõ ñåòåâûõ ñîåäèíåíèé, ñîçäàâàòü áîëüøèå çàäàíèÿ äëÿ ïå÷àòè + è ò.ï. Ýòî ñîçäàåò ðÿä ïðîáëåì - íóæíî áûòü óâåðåííûì â òîì, ÷òî èìåííî + íåîáõîäèìûå ôàéëû ðàçðåøåíû äëÿ ÷òåíèÿ è çàïèñè. </simpara> <simpara> - Consider the following script, where a user indicates that they'd - like to delete a file in their home directory. This assumes a - situation where a PHP web interface is regularly used for file - management, so the Apache user is allowed to delete files in - the user home directories. + Ïðèâåäåì ñëåäóþùóþ ïðîãðàììó, ãäå ïîëüçîâàòåëü õî÷åò ñòåðåòü + ôàéë â ñâîåì äîìàøíåì êàòàëîãå. Ýòî òèïè÷íàÿ ñèòóàöèÿ, êîãäà + Web-èíòåðôåéñ PHP èñïîëüçóåòñÿ äëÿ óïðàâëåíèÿ ôàéëàìè, ò.å. + ïîëüçîâàòåëè Apache èìåþò âîçìîæíîñòü óäàëÿòü ôàéëû â ñâîèõ + äîìàøíèõ êàòàëîãàõ. </simpara> <para> <example> - <title>Poor variable checking leads to....</title> + <title>Íåäîñòàòî÷íàÿ ïðîâåðêà ïåðåìåííûõ - ïîñëåäñòâèÿ...</title> <programlisting role="php"> <![CDATA[ <?php -// remove a file from the user's home directory +// óäàëÿåì ôàéë èç ïîëüçîâàòåëüñêîãî äîìàøíåãî êàòàëîãà $username = $_POST['user_submitted_name']; $homedir = "/home/$username"; $file_to_delete = "$userfile"; unlink ($homedir/$userfile); -echo "$file_to_delete has been deleted!"; +echo "$file_to_delete óäàëåí!"; ?> ]]> </programlisting> </example> - Since the username is postable from a user form, they can submit - a username and file belonging to someone else, and delete files. - In this case, you'd want to use some other form of authentication. - Consider what could happen if the variables submitted were - "../etc/" and "passwd". The code would then effectively read: + Ïîñêîëüêó èìÿ ïîëüçîâàòåëÿ ïðåäîñòàâëÿåòñÿ ïîëüçîâàòåëüñêîé ôîðìîé + ââîäà, ìîæíî ïîäñòàâèòü ëþáûå èìåíà ïîëüçîâàòåëÿ è ôàéëà, äàæå åñëè + ýòîò ôàéë ïðèíàäëåæèò êîìó-òî äðóãîìó.  ýòîì ñëó÷àå íåîáõîäèìî + èñïîëüçîâàòü ñõåìó àóòåíòèôèêàöèè ïîëüçîâàòåëåé. Êðîìå òîãî, + ïðåäñòàâüòå, ÷òî ñëó÷èòüñÿ, åñëè ïåðåäàííûå ïåðåìåííûå áóäóò + ñîîòâåòñòâåííî "../etc/" è "passwd". Òîãäà ïðîãðàììà áóäåò âûãëÿäåòü + òàê: <example> - <title>... A filesystem attack</title> + <title>... Àòàêà íà ôàéëîâóþ ñèñòåìó</title> <programlisting role="php"> <![CDATA[ <?php -// removes a file from anywhere on the hard drive that -// the PHP user has access to. If PHP has root access: +// óäàëÿåò ëþáîé ôàéë â çîíå äåéñòâèÿ ïðàâ ïîëüçîâàòåëÿ +// Åñëè PHP èìååò ïðàâà àäìèíèñòðàòîðà: $username = "../etc/"; $homedir = "/home/../etc/"; $file_to_delete = "passwd"; unlink ("/home/../etc/passwd"); -echo "/home/../etc/passwd has been deleted!"; +echo "/home/../etc/passwd óäàëåí!"; ?> ]]> </programlisting> </example> - There are two important measures you should take to prevent these - issues. +  áîðüáå ñ ïîäîáíûìè ñëó÷àÿìè åñòü äâà êëþ÷åâûõ ìîìåíòà. <itemizedlist> <listitem> <simpara> - Only allow limited permissions to the PHP web user binary. + Íàçíà÷åíèå èíòåðïðåòàòîðó PHP îãðàíè÷åííûõ ïðàâ. </simpara> </listitem> <listitem> <simpara> - Check all variables which are submitted. + Ïðîâåðêà âñåõ ïåðåäàííûõ ïåðåìåííûõ. </simpara> </listitem> </itemizedlist> - Here is an improved script: + Âîò óëó÷øåííàÿ ïðîãðàììà: <example> - <title>More secure file name checking</title> + <title>Áîëåå áåçîïàñíàÿ ïðîâåðêà èìåíè ôàéëà</title> <programlisting role="php"> <![CDATA[ <?php -// removes a file from the hard drive that -// the PHP user has access to. -$username = $_SERVER['REMOTE_USER']; // using an authentication mechanisim +// óäàëÿåò ëþáîé ôàéë â çîíå äåéñòâèÿ ïðàâ ïîëüçîâàòåëÿ +// Åñëè PHP èìååò ïðàâà àäìèíèñòðàòîðà: +$username = $_SERVER['REMOTE_USER']; // èñïîëüçóåì ìåõàíèçì àóòåíòèôèêàöèè $homedir = "/home/$username"; -$file_to_delete = basename("$userfile"); // strip paths -unlink ($homedir/$file_to_delete); +$file_to_delete = basename("$userfile"); // îòðåçàòü ïóòè +unlink ("$homedir/$file_to_delete"); -$fp = fopen("/home/logging/filedelete.log","+a"); //log the deletion +$fp = fopen("/home/logging/filedelete.log","+a"); // îò÷èòàòüñÿ îá óäàëåíèè $logstring = "$username $homedir $file_to_delete"; fputs ($fp, $logstring); fclose($fp); -echo "$file_to_delete has been deleted!"; +echo "$file_to_delete óäàëåí!"; ?> ]]> </programlisting> </example> - However, even this is not without it's flaws. If your authentication - system allowed users to create their own user logins, and a user - chose the login "../etc/", the system is once again exposed. For - this reason, you may prefer to write a more customized check: + Îäíàêî è â ýòîì ñëó÷àå èìåþòñÿ "äûðêè". Åñëè âàøà ñèñòåìà àóòåíòèôèêàöèè + ïîçâîëÿåò ïîëüçîâàòåëÿì âûáèðàòü ñîáñòâåííûå èìåíà, è ïîëüçîâàòåëü + çàäàñò èìÿ "../etc/", ñèñòåìà îïÿòü ïîïàäàåò ïîä àòàêó.  ýòîì ñëó÷àå + ìîæíî ñäåëàòü áîëåå ñïåöèôè÷åñêóþ ïðîâåðêó: <example> - <title>More secure file name checking</title> + <title>Åùå áîëåå áåçîïàñíàÿ ïðîâåðêà èìåíè ôàéëà</title> <programlisting role="php"> <![CDATA[ <?php -$username = $_SERVER['REMOTE_USER']; // using an authentication mechanisim +$username = $_SERVER['REMOTE_USER']; // èñïîëüçóåì ìåõàíèçì àóòåíòèôèêàöèè $homedir = "/home/$username"; if (!ereg('^[^./][^/]*$', $userfile)) - die('bad filename'); //die, do not process + die('ïëîõîå èìÿ ôàéëà'); // âûõîä áåç îáðàáîòêè if (!ereg('^[^./][^/]*$', $username)) - die('bad username'); //die, do not process -//etc... + die('ïëîõîå èìÿ ïîëüçîâàòåëÿ'); // âûõîä áåç îáðàáîòêè +//è ò.ä. ?> ]]> </programlisting> </example> </para> <para> - Depending on your operating system, there are a wide variety of files - which you should be concerned about, including device entries (/dev/ - or COM1), configuration files (/etc/ files and the .ini files), - well known file storage areas (/home/, My Documents), etc. For this - reason, it's usually easier to create a policy where you forbid - everything except for what you explicitly allow. +  çàâèñèìîñòè îò âàøåé îïåðàöèîííîé ñèñòåìû, ñóùåñòâóþò ôàéëû, î + áåçîïàñíîñòè êîòîðûõ íàäî ïîçàáîòèòüñÿ - äðàéâåðû óñòðîéñòâ (/dev/ + èëè COM1), ôàéëû êîíôèãóðàöèè (ôàéëû /etc/ èëè ôàéëû .ini), + èçâåñòíûå îáëàñòè õðàíåíèÿ äàííûõ (/home/, Mîè äîêóìåíòû), è ò.ä. +  ñâÿçè ñ ýòèì, îáû÷íî ïðîùå ñîçäàòü ïîëèòèêó â êîòîðîé çàïðåùåíî âñå, + êðîìå òîãî, ÷òî ðàçðåøåíî, êàê ãîâîðèòñÿ, "âðó÷íóþ". </para> </sect1> <sect1 id="security.database"> - <title>Database Security</title> + <title>Áåçîïàñíîñòü áàç äàííûõ</title> <simpara> - Nowadays, databases are cardinal components of any web based application by - enabling websites to provide varying dynamic content. Since very sensitive - or secret informations can be stored in such database, you should strongly - consider to protect them somehow. + Ñåãîäíÿ áàçû äàííûõ - îñíîâíàÿ ñîñòàâëÿþùàÿ ïðàêòè÷åñêè ëþáûõ ïðèëîæåíèé, + îñíîâàííûõ íà Web, êîòîðàÿ äàåò âîçìîæíîñòü ïðåäîñòàâëåíèÿ ðàçíîîáðàçíîãî + äèíàìè÷åñêîãî ñîäåðæèìîãî. Ïîñêîëüêó â òàêèõ áàçàõ äàííûì ìîæåò õðàíèòüñÿ + âåñüìà âàæíàÿ è ñåêðåòíàÿ èíôîðìàöèÿ, íóæíî ïîçàáîòèòüñÿ è îá èõ çàùèòå. </simpara> <simpara> - To retrieve or to store any information you need to connect to the database, - send a legitimate query, fetch the result, and close the connecion. - Nowadays, the commonly used query language in this interaction is the - Structured Query Language (SQL). See how an attacker can <link - linkend="security.database.sql-injection">tamper with an SQL query</link>. + Äëÿ ïîëó÷åíèÿ èëè ñîõðàíåíèÿ èíôîðìàöèè â áàçå äàííûõ, ê íåé íóæíî + ïîäêëþ÷èòüñÿ, ïîñëàòü çàïðîñ, îáðàáîòàòü îòâåò è çàêðûòü ïîäêëþ÷åíèå. + Ñåãîäíÿ äëÿ âñåãî ýòîãî îáû÷íî èñïîëüçóåòñÿ ñòðóêòóðèðîâàííûé ÿçûê + çàïðîñîâ (Structured Query Language, SQL). Äàâàéòå ïîñìîòðèì, êàê + çëîóìûøëåííèê ìîæåò <link linkend="security.database.sql-injection">ïîñòóïèòü + ñ SQL-çàïðîñîì</link>. </simpara> <simpara> - As you can realize, PHP cannot protect your database by itself. The - following sections aim to be an introduction into the very basics of how to - access and manipulate databases within PHP scripts. + Êàê èçâåñòíî, PHP íå ìîæåò ñàì çàùèòèòü áàçó äàííûõ. Ñëåäóþùèå ðàçäåëû + ÿâëÿþòñÿ ââåäåíèåì â îñíîâû äîñòóïà è èñïîëüçîâàíèÿ áàç äàííûõ â + ïðîãðàììàõ PHP. </simpara> <simpara> - Keep in mind this simple rule: defence in depth. In the more place you - take the more action to increase the protection of your database, the less - probability of that an attacker succeeds, and exposes or abuse any stored - secret information. Good design of the database schema and the application - deals with your greatest fears. + Ïîìíèòå ïðîñòîå ïðàâèëî: çàùèòà ñòðîèòñÿ "âãëóáü". ×åì áîëüøå ìåñò + âû çàùèòèòå è ÷åì áîëüøå äåéñòâèé ïðåäïðèìåòå äëÿ çàùèòû áàçû äàííûõ, + òåì ìåíüøå âåðîÿòíîñòü óñïåõà ó çëîóìûøëåííèêà íà èçâëå÷åíèå è + èñïîëüçîâàíèå õðàíèìîé â íåé ñåêðåòíîé èíôîðìàöèè. Âñå îïàñíûå ìåñòà + óñòðàíÿþòñÿ ïðàâèëüíîé ðàçðàáîòêîé ñòðóêòóðû áàçû äàííûõ è èñïîëüçóþùåãî + åå ïðèëîæåíèÿ. </simpara> <sect2 id="security.database.design"> - <title>Designing Databases</title> + <title>Ïëàíèðîâàíèå áàç äàííûõ</title> <simpara> - The first step is always to create the database, unless you want to use - an existing third party's one. When a database is created, it is - assigned to an owner, who executed the creation statement. Usually, only - the owner (or a superuser) can do anything with the objects in that - database, and in order to allow other users to use it, privileges must be - granted. + Ïåðâûé øàã âñåãäà - ñîáñòâåííî ñîçäàíèå áàçû äàííûõ, çà èñêëþ÷åíèåì + ñëó÷àåâ èñïîëüçîâàíèÿ ÷óæèõ áàç. Êîãäà ñîçäàåòñÿ áàçà äàííûõ, åé + íàçíà÷àåòñÿ âëàäåëåö, êîòîðûé è âûçâàë êîìàíäó ñîçäàíèÿ. Îáû÷íî + òîëüêî îäèí âëàäåëåö ("ñóïåðïîëüçîâàòåëü") ìîæåò äåëàòü ÷òî óãîäíî + ñ îáúåêòàìè âíóòðè ýòîé áàçû äàííûõ è äëÿ òîãî, ÷òîáû ïîçâîëèòü + äðóãèì ïîëüçîâàòåëÿì èñïîëüçîâàòü åå, èì äîëæíû áûòü íàçíà÷åíû ïðàâà + äîñòóïà. </simpara> <simpara> - Applications should never connect to the database as its owner or a - superuser, because these users can execute any query at will, for - example, modifying the schema (e.g. dropping tables) or deleting its - entire content. + Ïðèëîæåíèÿ íèêîãäà íå äîëæíû ïîäêëþ÷àòüñÿ ê áàçå äàííûõ â ðîëè + åå âëàäåëüöà èëè "ñóïåðïîëüçîâàòåëÿ", ïîñêîëüêó â ýòîì ñëó÷àå + ïîëüçîâàòåëè ìîãóò ïðîèçâåñòè ëþáûå äåéñòâèÿ âðîäå ìîäèôèêàöèè + ñõåìû (ê ïðèìåðó, óäàëåíèÿ òàáëèö) èëè óäàëåíèÿ âñåãî åå ñîäåðæèìîãî. </simpara> <simpara> - You may create different database users for every aspect of your - application with very limited rights to database objects. The most - required privileges should be granted only, and avoid that the same user - can interact with the database in different use cases. This means that if - intruders gain access to your database using one of these credentials, - they can only effect as many changes as your application can. + Ìîæíî ñîçäàòü ðàçëè÷íûõ ïîëüçîâàòåëåé áàç äàííûõ äëÿ êàæäîãî íåîáõîäèìîãî + äåéñòâèÿ ïðèëîæåíèé, î÷åíü ñèëüíî îãðàíè÷èâàÿ äîñòóï ïîñëåäíèõ ê îáúåêòàì + áàçû äàííûõ. Òðåáóåìûå ïðàâà äîëæíû íàçíà÷àòüñÿ îäíîêðàòíî, èõ + èñïîëüçîâàíèÿ â äðóãèõ ìåñòàõ ïðèëîæåíèÿ íóæíî èçáåãàòü. Ýòî çíà÷èò, + ÷òî åñëè çëîóìûøëåííèê ïîëó÷èò äîñòóï ñ èñïîëüçîâàíèåì òîé èëè èíîé + ó÷åòíîé çàïèñè, îí ñìîæåò ïîëó÷èòü ëèøü òîò äîñòóï, êîòîðûì îáëàäàëà + èñïîëüçîâàííàÿ ÷àñòü ïðîãðàììû. </simpara> <simpara> - You are encouraged not to implement all the business logic in the web - application (i.e. your script), instead to do it in the database schema - using views, triggers or rules. If the system evolves, new ports will be - intended to open to the database, and you have to reimplement the logic - in each separate database client. Over and above, triggers can be used - to transparently and automatically handle fields, which often provides - insight when debugging problems with your application or tracing back - transactions. +  ïðèëîæåíèÿ ëó÷øå íå ââîäèòü âñþ ëîãèêó ðàáîòû ñ áàçàìè äàííûõ. Ýòî + ìîæíî ñäåëàòü è â ñàìîé áàçå äàííûõ ñ èñïîëüçîâàíèåì ôëàãîâ, + ïðåäñòàâëåíèé, ïðàâèë è âñòðîåííûõ ïðîöåäóð.  ñëó÷àå ðàçâèòèÿ è + ðàñøèðåíèÿ ñèñòåìû âñòðîåííûå ïðîöåäóðû ìîãóò áûòü èçìåíåíû äëÿ + àâòîìàòè÷åñêîé îáðàáîòêè íîâûõ ïîëåé, à ôëàãè ïðåäîñòàâÿò äîïîëíèòåëüíûå + âîçìîæíîñòè äëÿ îòëàäêè òðàíçàêöèé. </simpara> </sect2> <sect2 id="security.database.connection"> - <title>Connecting to Database</title> + <title>Ïîäêëþ÷åíèå ê áàçå äàííûõ</title> <simpara> - You may want to estabilish the connections over SSL to encrypt - client/server communications for increased security, or you can use ssh - to encrypt the network connection between clients and the database server. - If either of them is done, then monitoring your traffic and gaining - informations in this way will be a hard work. + Ìîæíî óñòàíàâëèâàòü ïîäêëþ÷åíèÿ ñ ïîìîùüþ SSL äëÿ øèôðîâàíèÿ ñîåäèíåíèé + êëèåíò-ñåðâåð, ÷òî äàåò ïîâûøåííóþ áåçîïàñíîñòü. À ìîæíî èñïîëüçîâàòü + ssh äëÿ øèôðîâàíèÿ ñåòåâûõ ñîåäèíåíèé ìåæäó êëèåíòàìè è ñåðâåðîì + áàç äàííûõ. Ëþáîé èç ýòèõ ñïîñîáîâ ñèëüíî óñëîæíÿåò îòñëåæèâàíèå + è ïîëó÷åíèå èíôîðìàöèè èç ñåòåâîãî òðàôôèêà. </simpara> <!--simpara> - If your database server native SSL support, consider to use <link - linkend="ref.openssl">OpenSSL functions</link> in communication between - PHP and database via SSL. + Åñëè âàø ñåðâåð áàç äàííûõ èìååò âñòðîåííóþ ïîääåðæêó SSL, ëó÷øå + èñïîëüçîâàòü <link linkend="ref.openssl">ôóíêöèè OpenSSL</link> äëÿ + ñâÿçè ìåæäó PHP è áàçîé äàííûõ ñ ïîìîùüþ SSL. </simpara--> </sect2> <sect2 id="security.database.storage"> - <title>Encrypted Storage Model</title> + <title>Õðàíåíèå çàøèôðîâàííûõ äàííûõ</title> <simpara> - SSL/SSH protects data travelling from the client to the server, SSL/SSH - does not protect the persistent data stored in a database. SSL is an - on-the-wire protocol. + SSL/SSH çàùèùàåò äàííûå òîëüêî ïî ïóòè îò êëèåíòà ê ñåðâåðó, íî íå + äàííûå, õðàíèìûå â áàçå äàííûõ. SSL - ëèøü ñåòåâîé ïðîòîêîë. </simpara> <simpara> - Once an attacker gains access to your database directly (bypassing the - webserver), the stored sensitive data may be exposed or misused, unless - the information is protected by the database itself. Encrypting the data - is a good way to mitigate this threat, but very few databases offer this - type of data encryption. + Êîãäà çëîóìûøëåííèê ïîëó÷àåò äîñòóï ê âàøåé áàçå äàííûõ â îáõîä + Web-ñåðâåðà, õðàíèìûå âàæíûå äàííûå ìîãóò áûòü ïîëó÷åíû è èñïîëüçîâàíû, + çà èñêëþ÷åíèåì ñëó÷àÿ, êîãäà èíôîðìàöèÿ çàùèùåíà â ñàìîé áàçå äàííûõ. + Øèôðîâàíèå - âåñüìà õîðîøèé ïðèåì â ýòîì ñëó÷àå, íî òàêîé ñïîñîá + ïîääåðæèâàþò íûíå ëèøü î÷åíü íåìíîãèå ñèñòåìû óïðàâëåíèÿ áàçàìè äàííûõ. </simpara> <simpara> - The easiest way to work around this problem is to first create your own - encryption package, and then use it from within your PHP scripts. PHP - can assist you in this case with its several extensions, such as <link - linkend="ref.mcrypt">Mcrypt</link> and <link - linkend="ref.mhash">Mhash</link>, covering a wide variety of encryption - algorithms. The script encrypts the data be stored first, and decrypts - it when retrieving. See the references for further examples how - encryption works. + Ñàìûé ëåãêèé ïóòü â ýòîì ñëó÷àå - ñîçäàòü ñâîþ ñîáñòâåííóþ ñèñòåìó + øèôðîâàíèÿ, à çàòåì èñïîëüçîâàòü åå â ïðîãðàììàõ PHP. PHP ñïîñîáñòâóåò + òàêîìó ïîäõîäó áëàãîäàðÿ íàëè÷èþ ñïåöèôè÷íûõ ðàøèðåíèé, òàêèõ, êàê <link + linkend="ref.mcrypt">Mcrypt</link> è <link linkend="ref.mhash">Mhash</link>, + îõâàòûâàþùèõ áîëüøîé ðÿä àëãîðèòìîâ øèôðîâàíèÿ. Ïðîãðàììà øèôðóåò + ñîõðàíÿåìûå äàííûå è ðàñøèôðîâûâàåò ïîëó÷àåìûå. Äëÿ äåòàëüíîãî îïèñàíèÿ + ñõåì øèôðîâàíèÿ ñìîòðèòå ññûëêè. </simpara> <simpara> - In case of truly hidden data, if its raw representation is not needed - (i.e. not be displayed), hashing may be also taken into consideration. - The well-known example for the hashing is storing the MD5 hash of a - password in a database, instead of the password itself. See also - <function>crypt</function> and <function>md5</function>. +  ñëó÷àå ñêðûòûõ äàííûõ, ãäå íå òðåáóåòñÿ èõ èñõîäíûé âèä (ê ïðèìåðó, + äëÿ îòîáðàæåíèÿ), ìîæíî èñïîëüçîâàòü õåøèðîâàíèå. Èçâåñòíûì ïðèìåðîì + õåøèðîâàíèÿ ÿâëÿåòñÿ ñîõðàíåíèå â áàçå äàííûõ õåøà MD5 îò ïàðîëÿ + âìåñòî ñàìîãî ïàðîëÿ. Äëÿ ïîäðîáíîãî îïèñàíèÿ ñìîòðèòå + <function>crypt</function> è <function>md5</function>. </simpara> <example> - <title>Using hashed password field</title> + <title>Èñïîëüçîâàíèå õåøèðîâàííûõ ïàðîëåé</title> <programlisting role="php"> <![CDATA[ -// storing password hash +// ñîõðàíÿåì õåø îò ïàðîëÿ $query = sprintf("INSERT INTO users(name,pwd) VALUES('%s','%s');", addslashes($username), md5($password)); $result = pg_exec($connection, $query); -// querying if user submitted the right password +// ïðîâåðÿåì êîððåêòíîñòü ââåäåííîãî ïîëüçîâàòåëåì ïàðîëÿ $query = sprintf("SELECT 1 FROM users WHERE name='%s' AND pwd='%s';", addslashes($username), md5($password)); $result = pg_exec($connection, $query); if (pg_numrows($result) > 0) { - echo "Welcome, $username!"; + echo "Äîáðî ïîæàëîâàòü, $username!"; } else { - echo "Authentication failed for $username."; + echo "Ââåäåí íåâåðíûé ïàðîëü äëÿ $username."; } ]]> </programlisting> @@ -623,88 +619,89 @@ </sect2> <sect2 id="security.database.sql-injection"> - <title>SQL Injection</title> + <title>Âíåäðåíèå â SQL</title> <simpara> - Many web developers are unaware of how SQL queries can be tampered with, - and assume that an SQL query is a trusted command. It means that SQL - queries are able to circumvent access controls, thereby bypassing standard - authentication and authorization checks, and sometimes SQL queries even - may allow access to host operating system level commands. + Ìíîãèå ðàçðàáîò÷èêè Web-ïðèëîæåíèé ñ÷èòàþò çàïðîñû SQL íå ñòîÿùèìè, + âíèìàíèÿ íå çíàÿ î òîì, ÷òî èõ ìîæåò èñïîëüçîâàòü çëîóìûøëåííèê. Ýòî + îçíà÷àåò, ÷òî çàïðîñû SQL ìîãóò áûòü èñïîëüçîâàíû äëÿ îáõîäà ñèñòåì + çàùèòû, àóòåíòèôèêàöèè è àâòîðèçàöèè, à òàêæå èíîãäà ìîãóò áûòü + èñïîëüçîâàíû äëÿ ïîëó÷åíèÿ äîñòóïà ê êîìàíäàì óðîâíÿ îïåðàöèîííîé + ñèñòåìû. </simpara> <simpara> - Direct SQL Command Injection is a technique where an attacker creates or - alters existing SQL commands to expose hidden data, or to override valuable - ones, or even to execute dangerous system level commands on the database - host. This is accomplished by the application taking user input and - combining it with static parameters to build a SQL query. The following - examples are based on true stories, unfortunately. + Âíåäðåíèå â êîìàíäû SQL - òåõíèêà, ïðè êîòîðîé çëîóìûøëåííèê ñîçäàåò + èëè èçìåíÿåò êîìàíäû SQL äëÿ ïîëó÷åíèÿ äîñòóïà ê ñêðûòûì äàííûì, äëÿ + èçìåíåíèÿ ñóùåñòâóþùèõ è äàæå äëÿ âûïîëíåíèÿ êîìàíä óðîâíÿ îïåðàöèîííîé + ñèñòåìû. Ýòî äîñòèãàåòñÿ â òîì ñëó÷àå, åñëè ïðîãðàììà èñïîëüçóåò + ââåäåííûå äàííûå â êîìáèíàöèè ñî ñòàòè÷åñêèìè ïàðàìåòðàìè äëÿ ñîçäàíèÿ + çàïðîñà SQL. Ñëåäóþùèå ïðèìåðû, ê ñîæàëåíèþ, îñíîâàíû íà ðåàëüíî + ïðîèçîøåäøèõ ñëó÷àÿõ: </simpara> <para> - Owing to the lack of input validation and connecting to the database on - behalf of a superuser or the one who can create users, the attacker - may create a superuser in your database. + Ïðè íåäîñòàòî÷íîé ïðîâåðêå ââîäèìûõ äàííûõ è ñîåäèíåíèè ñ áàçîé äàííûõ + íà ïðàâàõ ñóïåðïîëüçîâàòåëÿ çëîóìûøëåííèê ìîæåò ñîçäàòü íîâîãî + ñóïåðïîëüçîâàòåëÿ â áàçå äàííûõ. <example> <title> - Splitting the result set into pages ... and making superusers - (PostgreSQL and MySQL) + Ðàçäåëåíèå ðåçóëüòàòà çàïðîñà ïî ñòðàíèöàì è... ñîçäàíèå ñóïåðïîëüçîâàòåëåé + (PostgreSQL è MySQL) </title> <programlisting role="php"> <![CDATA[ -$offset = argv[0]; // beware, no input validation! +$offset = argv[0]; // âíèìàíèå! íåò ïðîâåðêè äàííûõ! $query = "SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET $offset;"; -// with PostgreSQL +// â PostgreSQL $result = pg_exec($conn, $query); -// with MySQL +// â MySQL $result = mysql_query($query); ]]> </programlisting> </example> - Normal users click on the 'next', 'prev' links where the <varname>$offset</varname> - is encoded into the URL. The script expects that the incoming - <varname>$offset</varname> is decimal number. However, someone tries to - break in with appending <function>urlencode</function>'d form of the - following to the URL + Îáû÷íî ïîëüçîâàòåëè èñïîëüçóþò êíîïî÷êè "ñëåäóþùàÿ" è "ïðåäûäóùàÿ", + ãäå <varname>$offset</varname> âíåäðåí â URL. Ïðîãðàììà ñ÷èòàåò, ÷òî + <varname>$offset</varname> - ÷èñëî. Îäíàêî, êòî-íèáóäü ìîæåò + ïîïûòàòüñÿ âíåäðèòüñÿ ïóòåì äîáàâëåíèÿ <function>urlencode</function>-êîäèðîâàííûõ + äàííûõ â URL <informalexample> <programlisting> <![CDATA[ -// in case of PostgreSQL +// â ñëó÷àå PostgreSQL 0; insert into pg_shadow(usename,usesysid,usesuper,usecatupd,passwd) select 'crack', usesysid, 't','t','crack' from pg_shadow where usename='postgres'; -- -// in case of MySQL +// â ñëó÷àå MySQL 0; UPDATE user SET Password=PASSWORD('crack') WHERE user='root'; FLUSH PRIVILEGES; ]]> </programlisting> </informalexample> - If it happened, then the script would present a superuser access to him. - Note that <literal>0;</literal> is to supply a valid offset to the - original query and to terminate it. + Åñëè ýòî ñëó÷èòñÿ, ïðîãðàììà ïðåäîñòàâèò åìó äîñòóï ñóïåðïîëüçîâàòåëÿ. + Çàìåòèì, ÷òî <literal>0;</literal> ñëóæèò äëÿ òîãî, ÷òîáû çàäàòü + êîððåêòíîå ñìåùåíèå äëÿ èñõîäíîãî çàïðîñà è çàâåðøèòü åãî. </para> <note> <para> - It is common technique to force the SQL parser to ignore the rest of the - query written by the developer with <literal>--</literal> which is the - comment sign in SQL. + Îáû÷íàÿ ïðàêòèêà - çàñòàâèòü òðàíñëÿòîð SQL ïðîèãíîðèðîâàòü îñòàòîê + çàïðîñà ðàçðàáîò÷èêà ñ ïîìîùüþ îáîçíà÷åíèÿ íà÷àëà êîìåíòàðèÿ SQL + <literal>--</literal>. </para> </note> <para> - A feasible way to gain passwords is to circumvent your search result pages. - What the attacker needs only is to try if there is any submitted variable - used in SQL statement which is not handled properly. These filters can be set - commonly in a preceding form to customize <literal>WHERE, ORDER BY, - LIMIT</literal> and <literal>OFFSET</literal> clauses in <literal>SELECT</literal> - statements. If your database supports the <literal>UNION</literal> construct, - the attacker may try to append an entire query to the original one to list - passwords from an arbitrary table. Using encrypted password fields is - strongly encouraged. + Ñóùåñòâóåò ïóòü ïîëó÷åíèÿ ïàðîëåé ÷åðåç âàøè ñòðàíèöû ïîèñêà. Âñå, ÷òî + íóæíî çëîóìûøëåííèêó - ýòî îäíà íå îáðàáîòàííàÿ äîëæíûì îáðàçîì + ïåðåìåííàÿ, èñïîëüçóåìàÿ â SQL-çàïðîñå. Èñïîëüçîâàòüñÿ ìîãóò êîìàíäû + <literal>WHERE, ORDER BY, LIMIT</literal> è <literal>OFFSET</literal> + çàïðîñà <literal>SELECT</literal>. + Åñëè âàøà áàçà äàííûõ ïîääåðæèâàåò êîíñòðóêöèþ <literal>UNION</literal>, + çëîóìûøëåííèê ìîæåò äîáàâèòü ê èñõîäíîìó çàïðîñó åùå îäèí - äëÿ ïîëó÷åíèÿ + ïàðîëåé.  ýòîì ñëó÷àå ïîìîæåò õðàíåíèå çàøèôðîâàííûõ ïàðîëåé. <example> <title> - Listing out articles ... and some passwords (any database server) + Âûâîä ñòàòåé... è ïàðîëåé (ëþáîé ñåðâåð áàç äàííûõ) </title> <programlisting role="php"> <![CDATA[ @@ -715,8 +712,8 @@ ]]> </programlisting> </example> - The static part of the query can be combined with another - <literal>SELECT</literal> statement which reveals all passwords: + Ñòàòè÷åñêàÿ ÷àñòü çàïðîñà ìîæåò áûòü ñîâìåùåíà ñ äðóãèì çàïðîñîì + <literal>SELECT</literal>, êîòîðûé âûâåäåò âñå ïàðîëè: <informalexample> <programlisting> <![CDATA[ @@ -726,21 +723,22 @@ ]]> </programlisting> </informalexample> - If this query (playing with the <literal>'</literal> and - <literal>--</literal>) were assigned to one of the variables used in - <varname>$query</varname>, the query beast awakened. + Åñëè ïîäîáíûé çàïðîñ (èñïîëüçóþùèé <literal>'</literal> è + <literal>--</literal>) áóäåò çàäàí â îäíîé èç ïåðåìåííûõ, èñïîëüçóåìûõ + <varname>$query</varname>, òî àòàêà áóäåò óñïåøíîé. </para> <para> - SQL UPDATEs are also subject to attacking your database. These queries are - also threatened by chopping and appending an entirely new query to it. But - the attacker might fiddle with the <literal>SET</literal> clause. In this - case some schema information must be possessed to manipulate the query - successfully. This can be acquired by examing the form variable names, or - just simply brute forcing. There are not so many naming convention for - fields storing passwords or usernames. + Çàïðîñû SQL "UPDATE" òàêæå ìîãóò áûòü èñïîëüçîâàíû äëÿ àòàêè íà áàçó + äàííûõ. Ýòè çàïðîñû òàêæå ïîäâåðæåíû îïàñíîñòè "îáðåçêè" è äîáàâëåíèÿ + íîâûõ çàïðîñîâ. Íî çäåñü çëîóìûøëåííèê ðàáîòàåò ñ êîìàíäîé + <literal>SET</literal>.  ýòîì ñëó÷àå íåîáõîäèìî çíàíèå íåêîòîðîé + èíôîðìàöèè î ñòðóêòóðå áàçû äàííûõ äëÿ óäà÷íîé ìîäèôèêàöèè çàïðîñà. + Òàêàÿ èíôîðìàöèÿ ìîæåò áûòü ïîëó÷åíà ïóòåì èçó÷åíèÿ íàçâàíèé ïåðåìåííûõ + ôîðì èëè ïðîñòî ïîäáîðîì.  êîíöå êîíöîâ, íå òàê óæ è ìíîãî èìåí ïðèäóìàíî + äëÿ ïîëåé ïîëüçîâàòåëåé è ïàðîëåé. <example> <title> - From resetting a password ... to gaining more privileges (any database server) + Îò ñáðîñà ïàðîëÿ äî ïîëó÷åíèÿ ïðèâèëåãèé... (ëþáîé ñåðâåð áàç äàííûõ) </title> <programlisting role="php"> <![CDATA[ @@ -748,11 +746,11 @@ ]]> </programlisting> </example> - But a malicious user sumbits the value - <literal>' or uid like'%admin%'; --</literal> to <varname>$uid</varname> to - change the admin's password, or simply sets <varname>$pwd</varname> to - <literal>"hehehe', admin='yes', trusted=100 "</literal> (with a trailing - space) to gain more privileges. Then, the query will be twisted: + Çëîóìûøëåííèê ïîñûëàåò çíà÷åíèå <literal>' or uid like'%admin%'; --</literal>, + â ïåðåìåííóþ <varname>$uid</varname> äëÿ èçìåíåíèÿ ïàðîëÿ àäìèíèñòðàòîðà + èëè ïðîñòî óñòàíàâëèâàåò <varname>$pwd</varname> â + <literal>"hehehe', admin='yes', trusted=100 "</literal> (ñ çàâåðøàþùèì + ïðîáåëîì) äëÿ ïîëó÷åíèÿ ïðàâ. Çàïðîñ áóäåò èñêàæåí òàê: <informalexample> <programlisting role="php"> <![CDATA[ @@ -766,10 +764,10 @@ </informalexample> </para> <para> - A frightening example how operating system level commands can be accessed - on some database hosts. + À âîò ïóãàþùèé ïðèìåð òîãî, êàê íà íåêîòîðûõ ñåðâåðàõ áàç äàííûõ + ìîãóò áûòü âûïîëíåíû êîìàíäû óðîâíÿ îïåðàöèîííîé ñèñòåìû: <example> - <title>Attacking the database host's operating system (MSSQL Server)</title> + <title>Àòàêà íà îïåðàöèîííóþ ñèñòåìó ñåðâåðà áàç äàííûõ (ñåðâåð MSSQL)</title> <programlisting role="php"> <![CDATA[ $query = "SELECT * FROM products WHERE id LIKE '%$prod%'"; @@ -777,9 +775,10 @@ ]]> </programlisting> </example> - If attacker submits the value + Åñëè çëîóìûøëåííèê ïîøëåò çíà÷åíèå <literal>a%' exec master..xp_cmdshell 'net user test testpass /ADD' --</literal> - to <varname>$prod</varname>, then the <varname>$query</varname> will be: + â <varname>$prod</varname>, òî <varname>$query</varname> áóäåò âûãëÿäåòü + òàê: <informalexample> <programlisting role="php"> <![CDATA[ @@ -790,73 +789,74 @@ ]]> </programlisting> </informalexample> - MSSQL Server executes the SQL statements in the batch including a command - to add a new user to the local accounts database. If this application - were running as <literal>sa</literal> and the MSSQLSERVER service is - running with sufficient privileges, the attacker would now have an - account with which to access this machine. + Ñåðâåð MSSQL âûïîëíÿåò âñå êîìàíäû SQL, âêëþ÷àÿ êîìàíäó äîáàâëåíèÿ + íîâîãî ïîëüçîâàòåëÿ â ëîêàëüíóþ áàçó äàííûõ ïîëüçîâàòåëåé. Åñëè + ýòî ïðèëîæåíèå áûëî çàïóùåíî, êàê <literal>sa</literal> è ñëóæáà + MSSQLSERVER èìååò äîñòàòî÷íî ïðàâ, çëîóìûøëåííèê áóäåò èìåòü ó÷åòíóþ + çàïèñü äëÿ äîñòóïà ê ýòîé ìàøèíå. </para> <note> <para> - Some of the examples above is tied to a specific database server. This - does not mean that a similar attack is impossible against other products. - Your database server may be so vulnerable in other manner. + Íåêîòîðûå èç âûøåïåðå÷èñëåííûõ ïðèìåðîâ ïðèâÿçàíû ê êîíêðåòíîìó + ñåðâåðó áàç äàííûõ. Íî ýòî âîâñå íå îçíà÷àåò, ÷òî ïîäîáíàÿ àòàêà + íåâîçìîæíà ñ äðóãèìè ïðîãðàììàìè. Âàø ñåðâåð áàç äàííûõ òîæå òàê èëè + èíà÷å áóäåò óÿçâèì äëÿ íåïðåäâèäåííûõ àòàê. </para> </note> <sect3 id="security.database.avoiding"> - <title>Avoiding techniques</title> + <title>Òåõíèêà çàùèòû</title> <simpara> - You may plead that the attacker must possess a piece of information - about the database schema in most examples. You are right, but you - never know when and how it can be taken out, and if it happens, - your database may be exposed. If you are using an open source, or - publicly available database handling package, which may belong to a - content management system or forum, the intruders easily produce - a copy of a piece of your code. It may be also a security risk if it - is a poorly designed one. +  áîëüøèíñòâå ïðèìåðîâ âèäíî, ÷òî äëÿ àòàêè çëîóìûøëåííèê äîëæåí + îáëàäàòü íåêîòîðîé èíôîðìàöèåé. Âñå âåðíî, íî íèêîãäà çàðàíåå íå + èçâåñòíî, êàêèìè ïóòÿìè óéäåò äàííàÿ èíôîðìàöèÿ. Åñëè ýòî âñå-òàêè + ñëó÷èòñÿ, áàçà äàííûõ ñòàíîâèòñÿ íåçàùèùåííîé. Åñëè âû èñïîëüçóåòå + ñâîáîäíî ðàñïðîñòðàíÿåìûé ïàêåò óïðàâëåíèÿ áàçàìè äàííûõ, êîòîðûé + ïðèíàäëåæèò êàêîé-íèáóäü ñèñòåìå óïðàâëåíèÿ ñîäåðæèìûì èëè ôîðóìó, + çëîóìûøëåííèê ëåãêî ïîëó÷èò êîïèþ äàííîé ÷àñòè âàøåé ïðîãðàììû. + Ýòî òàêæå ìîæåò ïðåäñòàâëÿòü "äûðó" â áåçîïàñíîñòè. </simpara> <simpara> - These attacks are mainly based on exploiting the code not being written - with security in mind. Never trust on any kind of input, especially - which comes from the client side, even though it comes from a select box, - a hidden input field or a cookie. The first example shows that such a - blameless query can cause disasters. + Áîëüøèíñòâî àòàê ïîñòðîåíû íà èñïîëüçîâàíèè êîäà, êîòîðûé ïèñàëñÿ áåç + ó÷åòà ñîîáðàæåíèé áåçîïàñíîñòè. Íèêîãäà íå äîâåðÿéòå ââåäåííûì äàííûì, + îñîáåííî åñëè îíè èäóò ñ êëèåíòñêîé ñòîðîíû, ïóñòü äàæå è èç ïîëÿ + îòìåòêè, ñêðûòîãî ïîëÿ èëè çàïèñè cookie. Ïåðâûé ïðèìåð ïîêàçûâàåò, + ê ÷åìó ìîæåò ïðèâåñòè ïîäìåíà ýòèõ äàííûõ. </simpara> <itemizedlist> <listitem> <simpara> - Never connect to the database as a superuser or as the database owner. - Use always customized users with very limited privileges. + Íèêîãäà íå ñîåäèíÿéòåñü ñ áàçîé äàííûõ â ðîëè ñóïåðïîëüçîâàòåëÿ èëè + âëàäåëüöà. Âñåãäà èñïîëüçóéòå ñïåöèàëüíûõ ïîëüçîâàòåëåé ñ ìèíèìóìîì + ïðàâ. </simpara> </listitem> <listitem> <simpara> - Check if the given input has the expected data type. PHP has - a wide range of input validating functions, from the simplest ones - found in <link linkend="ref.variables">Variable Functions</link> and - in <link linkend="ref.ctype">Character Type Functions</link> - (e.g. <function>is_numeric</function>, <function>ctype_digit</function> - respectively) onwards the - <link linkend="ref.pcre">Perl compatible Regular Expressions</link> - support. + Ïðîâåðÿéòå ââîä íà ñîâïàäåíèå òèïà äàííûõ ñ òðåáóåìûì. PHP âêëþ÷àåò + â ñåáÿ áîëüøîå êîëè÷åñòâî ïðîâåðî÷íûõ ôóíêöèé, îò ñàìûõ ïðîñòåéøèõ + èç ðàçäåëîâ <link linkend="ref.variables">Variable Functions</link> è + <link linkend="ref.ctype">Character Type Functions</link>, + (ê ïðèìåðó <function>is_numeric</function> è <function>ctype_digit</function> + ñîîòâåòñòâåííî) äî ðåãóëÿðíûõ âûðàæåíèé Perl + (<link linkend="ref.pcre">Perl compatible Regular Expressions</link>). </simpara> </listitem> <listitem> <para> - If the application waits for numerical input, consider to verify data - with <function>is_numeric</function>, or silently change its type - using <function>settype</function>, or use its numeric representation - by <function>sprintf</function>. + Åñëè ïðîãðàììà îæèäàåò ÷èñëî, ïðîâåðÿéòå äàííûå ñ ïîìîùüþ + <function>is_numeric</function>, èëè ïðîñòî èçìåíÿéòå òèï ñ ïîìîùüþ + <function>settype</function>, èëè äàæå èñïîëüçóéòå ÷èñëåííîå + ïðåäñòàâëåíèå, âûäàííîå <function>sprintf</function>. <example> - <title>A more secure way to compose a query for paging</title> + <title>Áîëåå áåçîïàñíàÿ ðàçáèâêà íà ñòðàíèöû</title> <programlisting role="php"> <![CDATA[ settype($offset, 'integer'); $query = "SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET $offset;"; -// please note %d in the format string, using %s would be meaningless +// îòìåòèì %d â ñòðîêå ôîðìàòèðîâàíèÿ, èñïîëüçîâàíèå %s áåñïîëåçíî $query = sprintf("SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET %d;", $offset); ]]> @@ -866,57 +866,58 @@ </listitem> <listitem> <simpara> - Quote each non numeric user input which is passed to the database with - <function>addslashes</function> or <function>addcslashes</function>. - See <link linkend="security.database.storage">the first example</link>. - As the examples shows, quotes burnt into the static part of the query - is not enough, and can be easily hacked. + Ïðåäâàðÿéòå ëþáîé íå÷èñëîâîé ââîä, ïåðåäàâàåìûé â áàçó äàííûõ, + ôóíêöèÿìè <function>addslashes</function> èëè + <function>addcslashes</function>.  + <link linkend="security.database.storage">ïåðâîì ïðèìåðå</link> + ïîêàçàíî, ÷òî êàâû÷åê â ñòàòè÷åñêîé ÷àñòè çàïðîñà íåäîñòàòî÷íî. </simpara> </listitem> <listitem> <simpara> - Do not print out any database specific information, especially - about the schema, by fair means or foul. See also <link - linkend="security.errors">Error Reporting</link> and <link + Íå âûâîäèòå íèêàêîé èíôîðìàöèè î ñòðóêòóðå áàçû äàííûõ íè êîèì + îáðàçîì. Äëÿ îïèñàíèÿ ïîäðîáíîñòåé ñìîòðèòå ðàçäåë <link + linkend="security.errors">îò÷åòû îá îøèáêàõ</link> è <link linkend="ref.errorfunc">Error Handling and Logging Functions</link>. </simpara> </listitem> <listitem> <simpara> - You may use stored procedures and previously defined cursors to abstract - data access so that users do not directly access tables or views, but - this solution has another impacts. + Ìîæíî èñïîëüçîâàòü õðàíèìûå ïðîöåäóðû è çàäàííûå ðàñïîëîæåíèÿ äëÿ òîãî, + ÷òîáû îòâÿçàòü îáðàùåíèå ê äàííûì îò ïðîãðàììû òàê, ÷òîáû ïîëüçîâàòåëè + íå èìåëè ïðÿìîãî äîñòóïà ê òàáëèöàì è ïðåäñòàâëåíèÿì, íî ýòîò âàðèàíò + èìååò ñîáñòâåííûå ïðîáëåìû. </simpara> </listitem> </itemizedlist> <simpara> - Besides these, you benefit from logging queries either within your script - or by the database itself, if it supports. Obviously, the logging is unable - to prevent any harmful attempt, but it can be helpful to trace back which - application has been circumvented. The log is not useful by itself, but - through the information it contains. The more detail is generally better. + Êðîìå òîãî, âåäèòå æóðíàë îïåðàöèé â ïðîãðàììå èëè ñîáñòâåííî â áàçå + äàííûõ, åñëè ýòî ïîääåðæèâàåòñÿ. Âåäåíèå æóðíàëà íå ïðåäîòâðàòèò + âíåäðåíèÿ, íî îíî ïîìîæåò îïðåäåëèòü, êàêàÿ ÷àñòü ïðîãðàììû áûëà + ïîñòàâëåíà ïîä óäàð. Ñàì æóðíàë áåñïîëåçåí - ïîëåçíà õðàíèìàÿ â íåì + èíôîðìàöèÿ. ×åì åå áîëüøå - òåì ëó÷øå. </simpara> </sect3> </sect2> </sect1> <sect1 id="security.errors"> - <title>Error Reporting</title> + <title>Îò÷åòû îá îøèáêàõ</title> <para> - With PHP security, there are two sides to error reporting. One is - beneficial to increasing security, the other is detrimental. +  ñëó÷àå íàñòðîéêè áåçîïàñíîñòè PHP ó îò÷åòà îá îøèáêàõ åñòü äâå + ñòîðîíû. Îäíà - ïëþñ â ñòîðîíó áåçîïàñíîñòè, äðóãàÿ - íàîáîðîò. </para> <para> - A standard attack tactic involves profiling a system by feeding - it improper data, and checking for the kinds, and contexts, of the - errors which are returned. This allows the system cracker to probe - for information about the server, to determine possible weaknesses. - For example, if an attacker had gleaned information about a page - based on a prior form submission, they may attempt to override - variables, or modify them: + Ñòàíäàðòíàÿ òåõíèêà àòàêè âêëþ÷àåò â ñåáÿ òåñòèðîâàíèå ñèñòåìû + ïóòåì óêàçàíèÿ çàâåäîìî íåâåðíûõ äàííûõ è ïîëó÷åíèÿ äåòàëåé + âñåõ âîçâðàùåííûõ îøèáîê. Ýòî ïîçâîëÿåò âçëîìùèêó ïîëó÷èòü èíôîðìàöèþ + î ñåðâåðå, î âîçìîæíûõ ñëàáîñòÿõ ñèñòåìû çàùèòû. Ê ïðèìåðó, åñëè + çëîóìûøëåííèêó äîñòóïíà èíôîðìàöèÿ î ñòðàíèöå, èñïîëüçóþùåé ïðåäâàðèòåëüíûé + ââîä äàííûõ â ôîðìó, òî îí ìîæåò ïîïûòàòüñÿ èçìåíèòü ïåðåäàâàåìûå + ïåðåìåííûå: <example> - <title>Attacking Variables with a custom HTML page</title> + <title>Àòàêà íà ïåðåìåííûå ñ ïîìîùüþ ñîáñòâåííîé ñòðàíèöû HTML</title> <programlisting role="php"> <![CDATA[ <form method="post" action="attacktarget?username=badfoo&password=badfoo"> @@ -928,22 +929,19 @@ </example> </para> <para> - The PHP errors which are normally returned can be quite helpful to a - developer who is trying to debug a script, indicating such things - as the function or file that failed, the PHP file it failed in, - and the line number which the failure occured in. This is all - information that can be exploited. It is not uncommon for a php - developer to use <function>show_source</function>, - <function>highlight_string</function>, or - <function>highlight_file</function> as a debugging measure, but in - a live site, this can expose hidden variables, unchecked syntax, - and other dangerous information. Especially dangerous is running - code from known sources with built-in debugging handlers, or using - common debugging techniques. If the attacker can determine what - general technique you are using, they may try to brute-force a page, - by sending various common debugging strings: + Îøèáêè, êîòîðûå îáû÷íî âîçâðàùàþòñÿ PHP, î÷åíü ïîìîãàþò â îòëàäêå ïðîãðàìì, + óêàçûâàÿ íà ôàéë èëè ôóíêöèþ, à òàêæå íîìåð ñòðîêè ãäå ïðîèçîøëà îøèáêà. + Îäíàêî, âñÿ ýòà èíôîðìàöèÿ ìîæåò áûòü èñïîëüçîâàíà. Î÷åíü ÷àñòî + ðàçðàáîò÷èêè èñïîëüçóþò ôóíêöèè <function>show_source</function>, + <function>highlight_string</function> + èëè <function>highlight_file</function>, êàê îòëàäî÷íûå, íî â ðåàëüíîì + ñëó÷àå îíè ìîãóò ïîêàçàòü ñêðûòûå ïåðåìåííûå, íåîòëàæåííûå ó÷àñòêè êîäà + è äðóãóþ îïàñíóþ èíôîðìàöèþ. Îñîáåííî îïàñåí çàïóñê êîäà ñ âñòðîåííûìè + îòëàäî÷íûìè ÷àñòÿìè èëè ñ èñïîëüçîâàíèåì òåõíîëîãèé îòëàäêè. Åñëè + çëîóìûøëåííèê îïðåäåëèò âàøó ñõåìó îòëàäêè, îí ìîæåò ïðîñòî ïîñëàòü + âàøåìó êîäó îòëàäî÷íûå êîìàíäû äëÿ ïðîèçâåäåíèÿ ñâîèõ äåéñòâèé. <example> - <title>Exploiting common debugging variables</title> + <title>Èñïîëüçîâàíèå îòëàäî÷íûõ ïåðåìåííûõ</title> <programlisting role="php"> <![CDATA[ <form method="post" action="attacktarget?errors=Y&showerrors=1"&debug=1"> @@ -956,60 +954,54 @@ </example> </para> <para> - Regardless of the method of error handling, the ability to probe a - system for errors leads to providing an attacker with more - information. + Íåçàâèñèìî îò ñïîñîáà îáðàáîòêè îøèáîê, âîçìîæíîñòü òåñòèðîâàíèÿ + ñèñòåìû ïðèâîäèò ê ïîëó÷åíèþ âçëîìùèêîì äîïîëíèòåëüíîé èíôîðìàöèè. </para> <para> - For example, the very style of a generic PHP error indicates a system - is running PHP. If the attacker was looking at an .html page, and - wanted to probe for the back-end (to look for known weaknesses in - the system), by feeding it the wrong data they may be able to - determine that a system was built with PHP. + Ê ïðèìåðó, ñàì ñòèëü îòîáðàæåíèÿ îøèáîê PHP îáîçíà÷àåò, ÷òî â ñèñòåìå + çàïóùåí PHP. Åñëè çëîóìûøëåííèê, âèäÿùèé .html ñòðàíèöó çàõî÷åò ïðîâåðèòü + ñåðâåð íà ñëàáûå ìåñòà â áåçîïàñíîñòè ïóòåì ââîäà íåâåðíûõ äàííûõ, îí, + òàêèì îáðàçîì, óçíàåò, ÷òî ñèñòåìà ïîñòðîåíà ñ èñïîëüçîâàíèåì PHP. </para> <para> - A function error can indicate whether a system may be running a - specific database engine, or give clues as to how a web page or - programmed or designed. This allows for deeper investigation into - open database ports, or to look for specific bugs or weaknesses - in a web page. By feeding different pieces of bad data, for example, - an attacker can determine the order of authentication in a script, - (from the line number errors) as well as probe for exploits that - may be exploited in different locations in the script. + Îøèáêè ôóíêöèé ìîãóò óêàçàòü íà çàïóùåííûé â ñèñòåìå ñåðâåð áàç + äàííûõ èëè äàòü èíôîðìàöèþ î òîì, êàê íàïèñàíà ýòà Web-ñòðàíèöà. + Ýòî ïîçâîëÿåò âåñòè äàëüíåéøåå èññëåäîâàíèå îòêðûòûõ ìåñò â áàçå + äàííûõ èëè èñêàòü îøèáêè è ñëàáûå ìåñòà â Web-ñòðàíèöå. + Ïóòåì ïîñûëêè ðàçëè÷íûõ íåêîððåêòíûõ äàííûõ çëîóìûøëåííèê ìîæåò, + íàïðèìåð, óçíàòü ïîñëåäîâàòåëüíîñòü àóòåíòèôèêàöèè (èç íîìåðîâ ñòðîê), + à òàêæå ìîæåò ïîïûòàòüñÿ îáíàðóæèòü "äûðû" â ðàçëè÷íûõ ìåñòàõ + ïðîãðàììû. </para> <para> - A filesystem or general PHP error can indicate what permissions - the webserver has, as well as the structure and organization of - files on the web server. Developer written error code can aggravate - this problem, leading to easy exploitation of formerly "hidden" - information. + Îøèáêè ôàéëîâîé ñèñòåìû èëè îáùèå îøèáêè PHP ìîãóò îòêðûòü + çàäàííûå Web-ñåðâåðó ðàçðåøåíèÿ, à òàêæå ñòðóêòóðó ôàéëîâ ñåðâåðà. + Êîäû îøèáîê ðàçðàáîò÷èêà óõóäøàþò ñèòóàöèþ, ïðèâîäÿ ê âåñüìà + ïðèìèòèâíîìó èñïîëüçîâàíèþ "îôèöèàëüíî ñêðûòîé" èíôîðìàöèè. </para> <para> - There are three major solutions to this issue. The first is to - scrutinize all functions, and attempt to compensate for the bulk - of the errors. The second is to disable error reporting entirely - on the running code. The third is to use PHP's custom error - handling functions to create your own error handler. Depending - on your security policy, you may find all three to be applicable - to your situation. + Åñòü òðè îñíîâíûõ ïóòè ðåøåíèÿ ïðîáëåìû. Ïåðâûé - îòëàäèòü âñå + ôóíêöèè è ïîïûòàòüñÿ êîìïåíñèðîâàòü íàëè÷èå îøèáîê. Âòîðîé - + ïîëíîñòüþ îòêëþ÷èòü îò÷åò îá îøèáêàõ. Òðåòèé - èñïîëüçîâàòü + ñîáñòâåííûé îáðàáîò÷èê îøèáîê PHP. Âûáîð çàâèñèò îò âàøåãî æåëàíèÿ è + ñòðóêòóðû âàøåé ñèñòåìû áåçîïàñíîñòè. </para> <para> - One way of catching this issue ahead of time is to make use of - PHP's own <function>error_reporting</function>, to help you - secure your code and find variable usage that may be dangerous. - By testing your code, prior to deployment, with E_ALL, you can - quickly find areas where your variables may be open to poisoning - or modification in other ways. Once you are ready for deployment, - by using E_NONE, you insulate your code from probing. + Åùå îäèí ñïîñîá ðåøåíèÿ ïðîáëåìû "äîñðî÷íî" - èñïîëüçîâàíèå âñòðîåííîé + îïöèè PHP <function>error_reporting</function>, äëÿ òîãî, ÷òîáû + îáåçîïàñèòü ïðîãðàììó è íàéòè óÿçâèìûå ïåðåìåííûå. Òåñòèðóÿ ïðîãðàììó äî + ðàçâåðòûâàíèÿ ñ E_ALL ìîæíî áûñòðî íàéòè ìåñòà, ãäå ïåðåìåííûå + ìîãóò áûòü îòêðûòû äëÿ ìîäèôèêàöèè. Êàê òîëüêî ïðîãðàììà ãîòîâà ê + ðàçâåðòûâàíèþ, E_NONE ïðåäîòâðàùàåò èññëåäîâàíèå. <example> - <title>Finding dangerous variables with E_ALL</title> + <title>Íàõîæäåíèå íåáåçîïàñíûõ ïåðåìåííûõ ñ ïîìîùüþ E_ALL</title> <programlisting role="php"> <![CDATA[ <?php -if ($username) { // Not initialized or checked before usage +if ($username) { // íå èíèöèàëèçèðîâàíà è íå ïðîâåðÿåòñÿ ïåðåä èñïîëüçîâàíèåì $good_login = 1; } -if ($good_login == 1) { // If above test fails, not initialized or checked before usage +if ($good_login == 1) { // åñëè ïðåäûäóùèé òåñò íå ïðîøåë, çíà÷èò $username íå èíèöèàëèçèðîâàíà fpassthru ("/highly/sensitive/data/index.html"); } ?> @@ -1020,31 +1012,30 @@ </sect1> <sect1 id="security.registerglobals"> - <title>Using Register Globals</title> + <title>Èñïîëüçîâàíèå îïöèè register-globals</title> <para> - One feature of PHP that can be used to enhance security is configuring PHP with + Åùå îäíî ñðåäñòâî PHP äëÿ ïîâûøåíèÿ áåçîïàñíîñòè - êîíôèãóðàöèÿ ñ + èñïîëüçîâàíèåì <link linkend="ini.register-globals">register_globals</link> = off. - By turning off the ability for any user-submitted variable to be injected - into PHP code, you can reduce the amount of variable - poisoning a potential attacker may inflict. They will have - to take the additional time to forge submissions, and your - internal variables are effectively isolated from user - submitted data. + Ýòî îòêëþ÷àåò âíåäðåíèå ïîëüçîâàòåëüñêèõ ïåðåìåííûõ â ñðåäó ïåðåìåííûõ + ïðîãðàììû íà PHP, ñâîäÿ ïîïûòêè âíåäðåíèÿ çëîóìûøëåííèêîì íóæíûõ åìó + çíà÷åíèé íà íåò. Îïöèÿ ïîëíîñòüþ èçîëèðóåò âíóòðåííèå ïåðåìåííûå îò + ïðåäîñòàâëÿåìûõ ïîëüçîâàòåëåì äàííûõ. </para> <para> - While it does slightly increase the amount of effort required - to work with PHP, it has been argued that the benefits far - outweigh the effort. + Êîíå÷íî, ýòî íåìíîãî óâåëè÷èâàåò êîëè÷åñòâî óñèëèé, íåîáõîäèìûõ äëÿ + îáðàáîòêè ïîëüçîâàòåëüñêîãî ââîäà. Íî âñå-òàêè èãðà ñòîèò ñâå÷, è + ïëþñû òàêîãî ïîäõîäà ãîðàçäî áîëåå ñóùåñòâåííû, íåæåëè ìèíóñû. <example> - <title>Working with register_globals=on</title> + <title>Ïðîãðàììà ñ register_globals=on</title> <programlisting role="php"> <![CDATA[ <?php -if ($username) { // can be forged by a user in get/post/cookies +if ($username) { // ìîæåò áûòü ïîäìåíåíà ïîëüçîâàòåëåì â get/post/cookies $good_login = 1; } -if ($good_login == 1) { // can be forged by a user in get/post/cookies, +if ($good_login == 1) { // òàêæå ìîæåò áûòü ïîäìåíåíà ïîëüçîâàòåëåì â get/post/cookies fpassthru ("/highly/sensitive/data/index.html"); } ?> @@ -1052,12 +1043,12 @@ </programlisting> </example> <example> - <title>Working with register_globals = off</title> + <title>Ïðîãðàììà ñ register_globals = off</title> <programlisting role="php"> <![CDATA[ <?php if($_COOKIE['username']){ - // can only come from a cookie, forged or otherwise + // ìîæåò ïðèéòè òîëüêî èç çàïèñè cookie, íîðìàëüíîé èëè ïîääåëüíîé $good_login = 1; fpassthru ("/highly/sensitive/data/index.html"); } @@ -1065,61 +1056,57 @@ ]]> </programlisting> </example> - By using this wisely, it's even possible to take preventative - measures to warn when forging is being attempted. If you know - ahead of time exactly where a variable should be coming from, - you can check to see if submitted data is coming from an - inappropriate kind of submission. While it doesn't guarantee - that data has not been forged, it does require an attacker - to guess the right kind of forging. + Ðàçóìíî èñïîëüçóÿ äàííûé ìåòîä, ìîæíî äàæå ïðèíÿò ìåðû ïðåäîòâðàùåíèÿ + ïîäìåíû äàííûõ, ïðåäóïðåæäàÿ, êîãäà òàêîâàÿ ïðåäïðèíèìàåòñÿ. Åñëè + èçâåñòíî, ãäå äîëæíà áûòü íåîáõîäèìàÿ ïåðåìåííàÿ, ìîæíî ïðîâåðèòü, íå + èäåò ëè îíà îò íåäîïóñòèìîãî èñòî÷íèêà. Ýòî íå ãàðàíòèðóåò îòñóòñòâèå + ïîäìåíû äàííûõ, íî çëîóìûøëåííèêó ïðèäåòñÿ èñêàòü ïðàâèëüíûé ïóòü ïîäìåíû. <example> - <title>Detecting simple variable poisoning</title> + <title>Ïðîñòåéøàÿ ïðîâåðêà íà ïîäìåíó äàííûõ</title> <programlisting role="php"> <![CDATA[ <?php if ($_COOKIE['username'] && !$_POST['username'] && !$_GET['username'] ) { - // Perform other checks to validate the user name... + // ïðîèçâåñòè ïðîâåðêó èìåíè ïîëüçîâàòåëÿ $good_login = 1; fpassthru ("/highly/sensitive/data/index.html"); } else { - mail("admin@example.com", "Possible breakin attempt", $_SERVER['REMOTE_ADDR']); - echo "Security violation, admin has been alerted."; + mail("admin@example.com", "Âîçìîæíà ïîäìåíà äàííûõ ", $_SERVER['REMOTE_ADDR']); + echo "Îøèáêà áåçîïàñíîñòè. Ïðîèçâåäåíî îïîâåùåíèå àäìèíèñòðàòîðà."; exit; } ?> ]]> </programlisting> </example> - Of course, simply turning off register_globals does not mean code - is secure. For every piece of data that is submitted, it - should also be checked in other ways. + Êîíå÷íî, âûêëþ÷åíèå register_globals íå îçíà÷àåò, ÷òî ïðîãðàììà + áåçîïàñíà. Âñå âõîäíûå äàííûå âñå ðàâíî òðåáóþò äîïîëíèòåëüíîé ïðîâåðêè. </para> </sect1> <sect1 id="security.variables"> - <title>User Submitted Data</title> + <title>Äàííûå, îòïðàâëåííûå ïîëüçîâàòåëåì</title> <para> - The greatest weakness in many PHP programs is not inherent in the - language itself, but merely an issue of code not being written with - security in mind. For this reason, you should always take the time - to consider the implications of a given piece of code, to ascertain - the possible damage if an unexpected variable is submitted to it. + Ñàìûå ñëàáûå ìåñòà â áîëüøèíñòâå ïðîãðàìì íà PHP íå ÿâëÿþòñÿ ñëåäñòâèåì + ïðîáëåì ñàìîãî ÿçûêà, íàïðîòèâ, îíè ÿâëÿþòñÿ ñëåäñòâèåì íàïèñàíèÿ ýòèõ + ïðîãðàìì áåç ó÷åòà ñîîáðàæåíèé áåçîïàñíîñòè. Ïîýòîìó âû âñåãäà äîëæíû + òðàòèòü íåêîòîðîå âðåìÿ íà ïðîäóìûâàíèå îãðàíè÷åíèé òåõ èëè èíûõ + ó÷àñòêîâ êîäà äëÿ ñíèæåíèÿ ðèñêà îò íåêîððåêòíî çàäàííûõ ïåðåìåííûõ. <example> - <title>Dangerous Variable Usage</title> + <title>Íåáåçîïàñíîå èñïîëüçîâàíèå ïåðåìåííîé</title> <programlisting role="php"> <![CDATA[ <?php -// remove a file from the user's home directory... or maybe -// somebody else's? +// óäàëåíèå ôàéëà èç ïîëüçîâàòåëüñêîãî äîìàøíåãî êàòàëîãà... èëè èç ÷üåãî-òî åùå? unlink ($evil_var); -// Write logging of their access... or maybe an /etc/passwd entry? +// çàïèñü æóðíàëà äîñòóïà... èëè çàïèñü â /etc/passwd? fputs ($fp, $evil_var); -// Execute something trivial.. or rm -rf *? +// èñïîëíåíèå ÷åãî-íèáóäü ïðîñòåíüêîãî.. èëè rm -rf *? system ($evil_var); exec ($evil_var); @@ -1127,120 +1114,118 @@ ]]> </programlisting> </example> - You should always carefully examine your code to make sure that any - variables being submitted from a web browser are being properly - checked, and ask yourself the following questions: + Âñåãäà íóæíî àêêóðàòíî èññëåäîâàòü ïðîãðàììó, ÷òîáû óáåäèòüñÿ, ÷òî + âñå ïåðåìåííûå, ïåðåäàâàåìûå ïîëüçîâàòåëåì, ïðîâåðÿþòñÿ. Ìîæíî äàæå + çàäàâàòü ñåáå ñëåäóþùèå âîïðîñû: <itemizedlist> <listitem> <simpara> - Will this script only affect the intended files? + Áóäåò ëè ýòà ïðîãðàììà èñïîëüçîâàòü èìåííî íåîáõîäèìûå ôàéëû? </simpara> </listitem> <listitem> <simpara> - Can unusual or undesirable data be acted upon? + Ìîãóò ëè áûòü îáðàáîòàíû íåîáû÷íûå èëè íåæåëàòåëüíûå äàííûå? </simpara> </listitem> <listitem> <simpara> - Can this script be used in unintended ways? + Ìîæåò ëè ýòà ïðîãðàììà èñïîëüçîâàòüñÿ íåæåëàòåëüíûì îáðàçîì? </simpara> </listitem> <listitem> <simpara> - Can this be used in conjunction with other scripts in a negative - manner? + Ìîæåò ëè îíà èñïîëüçîâàòüñÿ â ñîâîêóïíîñòè ñ äðóãèìè ïðîãðàììàìè äëÿ + ðåàëèçàöèè çëîãî óìûñëà? </simpara> </listitem> <listitem> <simpara> - Will any transactions be adequately logged? + Áóäóò ëè äîëæíûì îáðàçîì çàïèñàíû â æóðíàë îïåðàöèè? </simpara> </listitem> </itemizedlist> - By adequately asking these questions while writing the script, - rather than later, you prevent an unfortunate re-write when you - need to increase your security. By starting out with this mindset, - you won't guarantee the security of your system, but you can help - improve it. + Çàäàâàÿ ñåáå ýòè âîïðîñû âî âðåìÿ íàïèñàíèÿ ïðîãðàììû, ìîæíî + ïðåäîòâðàòèòü ïåðåïèñûâàíèå åå "ñ íóëÿ" â ñâÿçè ñ ïðîáëåìàìè + áåçîïàñíîñòè. Ïåðåíÿâ ïîäîáíûé îáðàç ìûøëåíèÿ, âû íå ãàðàíòèðóåòå + áåçîïàñíîñòè ñèñòåìû, íî óâåëè÷èòå ýòó áåçîïàñíîñòü. </para> <para> - You may also want to consider turning off register_globals, - magic_quotes, or other convenience settings which may confuse - you as to the validity, source, or value of a given variable. - Working with PHP in error_reporting(E_ALL) mode can also help warn - you about variables being used before they are checked or - initialized (so you can prevent unusual data from being - operated upon). + Òàêæå ñëåäóåò ïîäóìàòü îá îòêëþ÷åíèè register_globals, + magic_quotes, è äðóãèõ îïöèé, êîòîðûå ñòàâÿò ïîä ñîìíåíèå êîððåêòíîñòü, + èñòî÷íèê è çíà÷åíèÿ îòäåëüíî âçÿòûõ ïåðåìåííûõ. Ðàáîòà â ðåæèìå îòîáðàæåíèÿ + âñåõ îøèáîê (error_reporting=E_ALL) òàêæå ïðåäóïðåäèò îá èñïîëüçîâàíèè + ïåðåìåííûõ áåç ïðåäâàðèòåëüíîé ïðîâåðêè è èíèöèàëèçàöèè. </para> </sect1> <sect1 id="security.hiding"> - <title>Hiding PHP</title> + <title>Ñêðûòèå PHP</title> <para> - In general, security by obscurity is one of the weakest forms of security. - But in some cases, every little bit of extra security is desirable. +  îáùåì ñëó÷àå, ñêðûòèå - ñàìàÿ ñëàáàÿ ôîðìà ñèñòåìû áåçîïàñíîñòè. Íî â + íåêîòîðûõ ñëó÷àÿõ íåîáõîäèìà ëþáàÿ ìàëîñòü. </para> <para> - A few simple techniques can help to hide PHP, possibly slowing - down an attacker who is attempting to discover weaknesses in your - system. By setting expose_php = off in your &php.ini; file, you - reduce the amount of information available to them. + Åñòü íåñêîëüêî ïðèåìîâ, ïîçâîëÿþùèõ ñêðûòü PHP, ÷òî çàìåäëèò äåéñòâèÿ + çëîóìûøëåííèêà, ïûòàþùåãîñÿ îáíàðóæèòü ñëàáîñòè â âàøåé ñèñòåìå. + Óñòàíîâêà â ôàéëå &php.ini; îïöèè expose_php = off óìåíüøèò êîëè÷åñòâî + äîñòóïíîé èíôîðìàöèè. </para> <para> - Another tactic is to configure web servers such as apache to - parse different filetypes through PHP, either with an .htaccess - directive, or in the apache configuration file itself. You can - then use misleading file extensions: + Äðóãàÿ òàêòèêà - íàñòðîéêà ñåðâåðà Web (âðîäå Apache) äëÿ îáðàáîòêè + ðàçëè÷íûõ òèïîâ ôàéëîâ ñ ïîìîùüþ PHP. Ýòî äåëàåòñÿ ÷åðåç äèðåêòèâû + .htaccess èëè ÷åðåç ôàéë êîíôèãóðàöèè Apache. Çàòåì ìîæíî èñïîëüçîâàòü + "îòâëåêàþùèå" ðàñøèðåíèÿ ôàéëîâ: <example> - <title>Hiding PHP as another language</title> + <title>Ñêðûòèå PHP ïîä âèäîì äðóãîãî ÿçûêà</title> <programlisting role="apache-conf"> <![CDATA[ -# Make PHP code look like other code types +# Äåëàåì êîä PHP ïîõîæèì íà êîä äðóãèõ ÿçûêîâ AddType application/x-httpd-php .asp .py .pl ]]> </programlisting> </example> - Or obscure it completely: + Èëè âíîñèì ïóòàíèöó: <example> - <title>Using unknown types for PHP extensions</title> + <title>Èñïîëüçîâàíèå íåèçâåñòíûõ ðàñøèðåíèé äëÿ PHP</title> <programlisting role="apache-conf"> <![CDATA[ -# Make PHP code look like unknown types +# Äåëàåì PHP íè íà ÷òî íå ïîõîæèì AddType application/x-httpd-php .bop .foo .133t ]]> </programlisting> </example> - Or hide it as html code, which has a slight performance hit because - all html will be parsed through the PHP engine: + Èëè äàæå ìîæíî ñêðûòü PHP ïîä âèäîì html, ÷òî ïðèâåäåò ê íåáîëüøîé + ïîòåðå ïðîèçâîäèòåëüíîñòè, ïîñêîëüêó âñå .html-ôàéëû áóäóò îáðàáàòûâàòüñÿ + èíòåðïðåòàòîðîì PHP. <example> - <title>Using html types for PHP extensions</title> + <title>Èñïîëüçîâàíèå ðàñøèðåíèé html äëÿ PHP</title> <programlisting role="apache-conf"> <![CDATA[ -# Make all PHP code look like html +# Äåëàåì PHP ïîõîæèì íà html AddType application/x-httpd-php .htm .html ]]> </programlisting> </example> - For this to work effectively, you must rename your PHP files with - the above extensions. While it is a form of security through - obscurity, it's a minor preventative measure with few drawbacks. + ×òîáû âñå ýòî ðàáîòàëî, íàäî ïåðåèìåíîâàòü ôàéëû PHP â ôàéëû ñ + âûøåïåðå÷èñëåííûìè ðàñøèðåíèÿìè. Õîòÿ ýòî è ïîäâèä áåçîïàñíîñòè ÷åðåç + ñêðûòèå, ýòî îäíà èç ìåð ïðåäîòâðàùåíèÿ àòàê ñ ìèíèìóìîì èçâåñòíûõ ìèíóñîâ. </para> </sect1> <sect1 id="security.current"> - <title>Keeping Current</title> + <title> íîãó ñî âðåìåíåì</title> <simpara> - PHP, like any other large system, is under constant scrutiny and - improvement. Each new version will often include both major and - minor changes to enhance and repair security flaws, configuration - mishaps, and other issues that will affect the overall security - and stability of your system. + PHP, êàê è ëþáàÿ äðóãàÿ áîëüøàÿ ñèñòåìà, ïîñòîÿííî èçìåíÿåòñÿ è + äîðàáàòûâàåòñÿ. Êàæäàÿ íîâàÿ âåðñèÿ îáû÷íî âêëþ÷àåò êàê ñåðüåçíûå, + òàê è íåáîëüøèå èçìåíåíèÿ äëÿ óñòðàíåíèÿ ïðîáëåì áåçîïàñíîñòè, + êîíôèãóðàöèè, à òàêæå âñåãî, ÷òî âëèÿåò íà îáùóþ áåçîïàñíîñòü è + ñòàáèëüíîñòü ñèñòåìû. </simpara> <simpara> - Like other system-level scripting languages and programs, the best - approach is to update often, and maintain awareness of the latest - versions and their changes. + Êàê è â ñëó÷àå ñ äðóãèìè ïðîãðàììàìè, ëó÷øèé âàðèàíò - ýòî âûïîëíÿòü + îáíîâëåíèå êàê ìîæíî ÷àùå, à òàêæå ñëåäèòü çà ïîñëåäíèìè âåðñèÿìè + è ñäåëàííûìè â íèõ èçìåíåíèÿìè. </simpara> </sect1> </chapter>