mirror of
https://github.com/php/doc-pl.git
synced 2026-03-24 07:02:07 +01:00
237 lines
7.7 KiB
XML
237 lines
7.7 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<!-- EN-Revision: 91570644fbbe4d23e79908e1a04c4c4d003fe587 Maintainer: sobak Status: ready -->
|
|
<!-- splitted from ./index.xml, last change in rev 1.66 -->
|
|
<chapter xml:id="security.filesystem" xmlns="http://docbook.org/ns/docbook">
|
|
<title>Bezpieczeństwo systemu plików</title>
|
|
<simpara>
|
|
<acronym>PHP</acronym> podlega zabezpieczeniom wbudowanym w większość systemów serwerowych,
|
|
jeśli chodzi o uprawnienia do plików i katalogów. To pozwala
|
|
na kontrolę, które pliki w systemie plików mogą być odczytywane. Powinno
|
|
się zwracać uwagę na wszelkie pliki odczytywalne dla wszystkich, aby upewnić się,
|
|
że mogą one być bezpiecznie odczytane przez wszystkich użytkowników, którzy mają dostęp do tego
|
|
systemu plików.
|
|
</simpara>
|
|
<simpara>
|
|
Jako iż <acronym>PHP</acronym> został zaprojektowany, aby pozwolić na dostęp na poziomie użytkownika do systemu plików,
|
|
jest absolutnie możliwe, by napisać skrypt <acronym>PHP</acronym>, który pozwoli Ci na
|
|
odczytanie plików systemowych takich jak <filename>/etc/passwd</filename>, modyfikację połączeń
|
|
ethernet, wysłanie zadań do drukarki itd. Ma to pewne
|
|
oczywiste implikacje — musisz się upewnić, że pozwalasz
|
|
na odczyt i zapis właściwych plików.
|
|
</simpara>
|
|
<simpara>
|
|
Przeanalizuj poniższy skrypt, w którym użytkownik decyduje, że chciałby
|
|
usunąć plik w swoim katalogu domowym. Zakłada on
|
|
sytuację, w której interfejs webowy <acronym>PHP</acronym> jest często używany do
|
|
zarządzania plikami, więc użytkownik Apache ma uprawnienia do usuwania plików
|
|
w katalogu domowym użytkownika.
|
|
</simpara>
|
|
<para>
|
|
<example>
|
|
<title>Złe sprawdzanie zmiennych prowadzi do...</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
// Usuń plik z katalogu domowego użytkownika
|
|
$username = $_POST['user_submitted_name'];
|
|
$userfile = $_POST['user_submitted_filename'];
|
|
$homedir = "/home/$username";
|
|
|
|
unlink("$homedir/$userfile");
|
|
|
|
echo "Plik został usunięty!";
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
Ponieważ nazwa użytkownika i nazwa pliku pochodzą z formularza,
|
|
użytkownik może wysłać nazwę użytkownika i pliku należące do kogoś innego,
|
|
i skasować ich pliki nawet jeśli nie powinni mieć do tego uprawnień.
|
|
W tym wypadku powinno się użyć jakiejś innej formy autentykacji.
|
|
Zastanów się, co mogłoby się wydarzyć, jeśli przekazano by zmienne
|
|
<literal>"../etc/"</literal> i <literal>"passwd"</literal>.
|
|
Kod mówiłby wtedy:
|
|
<example>
|
|
<title>...ataku na system plików</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
// Usuwa plik z dowolnego miejsca na dysku, do którego
|
|
// ma dostęp użytkownik PHP. Jeśli PHP ma dostęp roota:
|
|
$username = $_POST['user_submitted_name']; // "../etc"
|
|
$userfile = $_POST['user_submitted_filename']; // "passwd"
|
|
$homedir = "/home/$username"; // "/home/../etc"
|
|
|
|
unlink("$homedir/$userfile"); // "/home/../etc/passwd"
|
|
|
|
echo "Plik został usunięty!";
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
Istnieją dwie konkretne akcje, które powinieneś podjąć aby zapobiec
|
|
tym problemom.
|
|
<itemizedlist>
|
|
<listitem>
|
|
<simpara>
|
|
Plik binarny <acronym>PHP</acronym> wykorzystywany przez strony internetowe powinien mieć ogranicozne uprawnienia,
|
|
</simpara>
|
|
</listitem>
|
|
<listitem>
|
|
<simpara>
|
|
Sprawdzaj wszystkie przesyłane zmienne.
|
|
</simpara>
|
|
</listitem>
|
|
</itemizedlist>
|
|
Oto poprawiony skrypt:
|
|
<example>
|
|
<title>Bardziej bezpieczne sprawdzanie nazwy pliku</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
// Usuwa z dysku plik, do którego
|
|
// ma dostęp użytkownik PHP
|
|
$username = $_SERVER['REMOTE_USER']; // użycie mechanizmu autoryzacji
|
|
$userfile = basename($_POST['user_submitted_filename']);
|
|
$homedir = "/home/$username";
|
|
|
|
$filepath = "$homedir/$userfile";
|
|
|
|
if (file_exists($filepath) && unlink($filepath)) {
|
|
$logstring = "Usunięto $filepath\n";
|
|
} else {
|
|
$logstring = "Nie udało się usunąć $filepath\n";
|
|
}
|
|
|
|
$fp = fopen("/home/logging/filedelete.log", "a");
|
|
fwrite($fp, $logstring);
|
|
fclose($fp);
|
|
|
|
echo htmlentities($logstring, ENT_QUOTES);
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
Jednakże nawet ten skrypt nie jest pozbawiony wad. Jeżeli Twój system
|
|
autentykacji pozwala użytkownikom stworzyć ich własne loginy i użytkownik
|
|
wybrał login <literal>"../etc/"</literal>, to system jest ponownie w niebezpieczeństwie. Z
|
|
tego powodu możesz preferować bardziej dostosowane sprawdzenie:
|
|
<example>
|
|
<title>Bardziej bezpieczne sprawdzanie nazwy pliku</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
$username = $_SERVER['REMOTE_USER']; // użycie mechanizmu autoryzacji
|
|
$userfile = $_POST['user_submitted_filename'];
|
|
$homedir = "/home/$username";
|
|
|
|
$filepath = "$homedir/$userfile";
|
|
|
|
if (!ctype_alnum($username) || !preg_match('/^(?:[a-z0-9_-]|\.(?!\.))+$/iD', $userfile)) {
|
|
die("Bad username/filename");
|
|
}
|
|
|
|
// etc.
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
W zależności od systemu operacyjnego, istnieją różne pliki, o których
|
|
ochronę powinieneś się zatroszczyć, w tym wpisy urządzeń (<filename>/dev/</filename>
|
|
lub <filename>COM1</filename>), pliki konfiguracyjne (pliki w <filename>/etc/</filename> oraz
|
|
pliki <literal>.ini</literal>), powszechnie znane miejsca przechowywania plików (<filename>/home/</filename>,
|
|
<filename>Moje Dokumenty</filename>) itd. Z tego
|
|
powodu zazwyczaj łatwiej jest stworzyć politykę, w której zabraniasz
|
|
wszystko poza wprost dozwolonymi plikami.
|
|
</para>
|
|
<sect1 xml:id="security.filesystem.nullbytes">
|
|
<title>Problemy związane z pustym bajtem</title>
|
|
<simpara>
|
|
Jako iż <acronym>PHP</acronym> wykorzystuje pod maską funkcje C do obsługi operacji na
|
|
systemie plików, puste bajty mogą być obsługiwane w nieco zaskakujący sposób.
|
|
Jako że puste bajty oznaczają koniec ciągu znaków w C, ciągi znaków zawierające je
|
|
nie będą interpretowane w całości a jedynie do wystąpienia pustego bajtu.
|
|
|
|
Następujący przykład pokazuje podatny kod, który demonstruje ten problem:
|
|
</simpara>
|
|
<example>
|
|
<title>Skrypt podatny na puste bajty</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
$file = $_GET['file']; // "../../etc/passwd\0"
|
|
|
|
if (file_exists('/home/wwwrun/' . $file . '.php')) {
|
|
// file_exists zwróci true, ponieważ plik /home/wwwrun/../../etc/passwd istnieje
|
|
include '/home/wwwrun/' . $file . '.php';
|
|
|
|
// Plik /etc/passwd zostanie dołączony
|
|
}
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
<para>
|
|
Z tego powodu każdy skrypt, który wykonuje operacje na systemie plików powinien być zawsze
|
|
dokładnie sprawdzony. Oto lepsza wersja poprzedniego przykładu:
|
|
</para>
|
|
<example>
|
|
<title>Poprawne sprawdzanie danych wejściowych</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
$file = $_GET['file'];
|
|
|
|
// Biała lista dozwolonych wartości
|
|
switch ($file) {
|
|
case 'main':
|
|
case 'foo':
|
|
case 'bar':
|
|
include '/home/wwwrun/include/' . $file . '.php';
|
|
break;
|
|
default:
|
|
include '/home/wwwrun/include/main.php';
|
|
}
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</sect1>
|
|
|
|
</chapter>
|
|
|
|
<!-- Keep this comment at the end of the file
|
|
Local variables:
|
|
mode: sgml
|
|
sgml-omittag:t
|
|
sgml-shorttag:t
|
|
sgml-minimize-attributes:nil
|
|
sgml-always-quote-attributes:t
|
|
sgml-indent-step:1
|
|
sgml-indent-data:t
|
|
indent-tabs-mode:nil
|
|
sgml-parent-document:nil
|
|
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
|
|
sgml-exposed-tags:nil
|
|
sgml-local-catalogs:nil
|
|
sgml-local-ecat-files:nil
|
|
End:
|
|
vim600: syn=xml fen fdm=syntax fdl=2 si
|
|
vim: et tw=78 syn=sgml
|
|
vi: ts=1 sw=1
|
|
-->
|