A PHP tiszteli a rendszerbe épített biztonsági megoldásokat,
különös figyelemmel a fájlokra és könyvtárakra beállított
jogosultságokra. Ez lehetőséget ad arra, hogy megszabd,
mely fájlok olvashatóak a rendszerben. A mindenki számára
olvasható fájloknál ügyelni kell arra, hogy ne tartalmazzanak
olyan fontos adatot, amit nem szabad, hogy elolvasson
akármelyik user a rendszeren.
Mivel a PHP úgy készült, hogy felhasználói szintű fájlrendszer
hozzáférést ad, lehetséges olyan program készítése, ami a
rendszerfájlokat olvassa, pl. az /etc/password fájlt. Ez
maga után von egy nyilvánvaló következtetést, hogy meg kell
győződnöd a programjaidban, hogy a helyes fájlokat olvasod
illetve írod.
Nézzük a következő szkriptet, ahol a felhasználó megadja, hogy
le szeretne törölni egy fájlt a könyvtárában. Ez többnyire
egy webes felületet jelent, ahol egy PHP program használatos
fájlkezelésre, ezért az Apache usernek engedélyezni kell
a fájlok törlését a user felhasználó könyvtárában.
Példa 4-1. A helytelen változó használat ....
<?php
// egy fájl törlése a user könyvtárából
$usernev = $user_altal_beadott_nev;
$konyvtar = "/home/$usernev";
$torlendo_file = "$userfile";
unlink ($konyvtar/$torlendo_file);
echo "$torlendo_file törölve!";
?>
|
|
Mivel a usernév egy HTML űrlapból érkezik, a felhasználó beírhat
tetszőleges usernevet és fájlt, így akár más könyvtárát
is manipulálhatja. Ebben az esetben általában valamilyen
felhasználó-azonosítási eljárást kell alkalmaznod. Lássuk,
mi történik, ha a beadott változók a "../etc/" és a
"passwd". A kód akkor így alakulna (az adatokat
behelyettesítve):
Példa 4-2. ... fájlrendszer támadáshoz vezethet
<?php
// egy fájl törlése akárhonnan, ahol a PHP usernek
// joga van erre. Ha a PHP root userként fut:
$usernev = "../etc/"
$konyvtar = "/home/../etc/";
$torlendo_file = "passwd";
unlink ("/home/../etc/passwd");
echo "/home/../etc/passwd törölve!";
?>
|
|
Két fontos komponens van, amire oda kell figyelned, hogy
megelőzd az ilyen problémákat:
Egy fejlettebb szkript:
Példa 4-3. Biztonságosabb fájl ellenőrzés
<?php
// egy fájl törlése akárhonnan, ahol a PHP usernek
// joga van erre.
$usernev = $HTTP_REMOTE_USER; // ez a user azonosított neve
// (ha volt előtte azonosítás)
$konyvtar = "/home/$usernev";
$torlendo_file = basename("$userfile"); // elérési trükközés eldobása
unlink ($konyvtar/$torlendo_file);
$fp = fopen("/home/logging/filedelete.log","+a"); // törlés naplózása
$logstring = "$HTTP_REMOTE_USER $konyvtar $torlendo_file";
fputs ($fp, $logstring);
fclose($fp);
echo "$torlendo_file törölve!";
?>
|
|
Esetleg egy jobban testreszabott ellenőrzést is készíthetsz:
Példa 4-4. Biztonságosabb fájlnév-ellenőrzés
<?php
$username = getenv("REMOTE_USER");
$homedir = "/home/$username";
if (!ereg('^[^./][^/]*$', $userfile))
die('rossz fájlnév'); //nem hajtjuk végre a törlést
//etc...
?>
|
|
A használt operációs rendszertől függően széles a védeni kívánt
fájlok skálája, beleértve az eszköz hivatkozásokat (/dev/ vagy COM1),
konfigurációs fájlokat (/etc/ és az .ini fájlok), jól ismert
tárolóhelyek (/home/, My Documents), stb. Ezen okból könnyebb egy
olyan rendszert készíteni, ahol mindent megtiltasz azon kívül,
amit kifejezetten megengedsz.