Dosya Sistemi Güvenliği

PHP birçok sunucu sisteme kurulu güvenlik sisteminin dosya ve klasör izinlerine uyum gösterir. Bu, size dosya sistemindeki hangi dosyaların okunabileceğini kontrol etme imkanını verir. Herkes tarafından okunabilir dosyaların, dosya sistemine erişimi olan kullanıcılar tarafından güvenle okunabilir olması mutlaka dikkate alınmalıdır.

PHP dosya sistemine kullanıcı seviyesi tabanlı erişim sağlamak üzere tasarlandığından, PHP uygulamalarının /etc/password gibi sistem dosyalarını okumaları, ethernet bağlantıları üzerinde değişiklik yapmaları, yazıcıya ardı ardına görevler yüklemeleri ve benzeri birçok eylemi kolayca yapmaları mümkündür. Bu durum, sizi kullanıcıların hangi dosyalara okuma ve yazma hakları olduğunu denetlemeye zorunlu kılar.

Kullanıcının kendi ana klasöründeki bir dosyayı silmek istediği aşağıdaki uygulamayı ele alalım. PHP web arayüzünün dosya yönetimini sağlamak için kullanıldığını, ve Apache kullanıcısının kullanıcının ana klasöründeki dosyaları silme iznine sahip olduğunu kabul edelim.

Örnek 4-1. Yetersiz değişken kontrolünün yol açtığı....

<?php
// kullan&inodot;c&inodot;n&inodot;n ana klasöründen dosya silme
$username = $HTTP_POST_VARS['user_submitted_name'];
$homedir = "/home/$username";
$file_to_delete = "$userfile";
unlink ($homedir/$userfile);
echo "$file_to_delete silindi!";
?>
username bir kullanıcı formundan gönderilebilir olduğu için, başkasına ait bir kullanıcı adı ve dosya ismi ile, istediği dosyayı silebilir. Bu durumda, bir çeşit kullanıcı doğrulama sistemi kullanmanız gereklidir. Burada gönderilen değerlerin "../etc/" ve "passwd" olduğunda neler olabileceğini düşünün. Kodu bu şekilde okursak:

Örnek 4-2. ... Bir dosya sistemi saldırısı

<?php
// PHP kullan&inodot;c&inodot;s&inodot;n&inodot;n izniyle silinebilecek diskteki bütün dosyalari
// siler. PHP kullan&inodot;c&inodot;s&inodot; root eri&scedil;imine sahipse:
$username = "../etc/";
$homedir = "/home/../etc/";
$file_to_delete = "passwd";
unlink ("/home/../etc/passwd");
echo "/home/../etc/passwd silindi!";
?>
Bu durumu önlemenizi gerektiren iki önemli ölçü vardır.

İşte geliştirilmiş bir uygulama:

Örnek 4-3. Daha güvenli dosya ismi kontrolü

<?php
// Diskten PHP kullanicisinin silme izni varsa
// dosyay&inodot; siler. 
$username = $HTTP_SERVER_VARS['REMOTE_USER']; // dogrulama mekanizmasi

$homedir = "/home/$username";

$file_to_delete = basename("$userfile"); // yol ayristiriliyor
unlink ($homedir/$file_to_delete);

$fp = fopen("/home/logging/filedelete.log","+a"); // silme islemi kaydediliyor
$logstring = "$username $homedir $file_to_delete";
fputs ($fp, $logstring);
fclose($fp);

echo "$file_to_delete silindi!";
?>
Ancak bu bile istediğimizi tam olarak yapmaz. Doğrulama sisteminiz kullanıcıların kendilerine özel oturum açma hakkını tanıyorsa, ve bir bullanıcı "../etc" olarak login olmayı seçerse, sistem tekrar kırılabilir. Bu nedenle, daha özelleştirilmiş bir kontrol yazmayı tercih etmelisiniz:

Örnek 4-4. Daha güvenli dosya ismi kontrolü

<?php
$username = $HTTP_SERVER_VARS['REMOTE_USER']; // dogrulama mekanizmasi
$homedir = "/home/$username";

if (!ereg('^[^./][^/]*$', $userfile))
     die('bad filename'); //öl, islem yok
     
if (!ereg('^[^./][^/]*$', $username))
     die('bad username'); //öl, islem yok
//vb...
?>

İşletim sisteminize bağlı olarak, endişelenmenizi gerektirecek farklı dosyalar bulunur. Bunların arasında aygıt girişleri (/dev/ ya da COM1), konfigürasyon dosyaları (/etc/ dosyaları ve .ini dosyaları), herkesçe bilinen dosya saklama alanları (/home/, Belgelerim), vb. Bu nedenle, öncelikle her şeyi yasaklayıp daha sonra izin verilecek alanları belirlemek, kullanım açısından daha kolaydır.