| |
PHP scriptlerinizin güvenli oldugundan emin olmaniz için ilk olarak temel kurallari yerine getirmeniz gerekiyor: kullanici girdilerinin (input) filtrelenmesi ve çiktilarin (output) kontrolü. Eger bu ikisini dogru olarak yapmiyorsaniz scriptleriniz her zaman güvenlik problemleri ile karsi karsiya olacaktir. Bu makalede bu iki islem ile ilgili yapilmasi gerekenler anlatiliyor.
Bütün girdileri filtreleyin Scriptleriniz harici bir kaynaktan girdi okudugunda, bu verinin tehlikeli oldugu varsayilmali ve güvenilmemelidir. Güvenilmemesi gereken degiskenlerden bazilari: $_POST, $_GET, $_REQUEST ve hatta pek mümkün görünmese de önemli veriler içerebilecek olan $_SERVER .
Tehlikeli bir degiskenden gelen veriyi islemlere tabi tutmadan önce ilk olarak önce onaylanamaniz ve filtrelemeniz gerekmektedir. Onaylama islemi ile sadece sizin istediginiz verileri içerdiginden emin olabilirsiniz. Örnegin bir eposta adresi bilgisi bekliyorsaniz, onay fonksiyonunuz girilen verinin dogru bir eposta adresi olup olmadigini kontrol etmeli.
Hemen basit bir örnekle açiklayalim. Asagidaki kodda ilk olarak $_POST degiskeninden e-posta adresini aliyorum ve sonra veriyi onaylama islemine sokuyorum: <?php $eposta = $_POST[eposta]; # Burada veri hala TEHLIKELI durumda
// Validate e-mail if (valid_eposta($eposta) == false) { // Geçerli bir adres degil die(Geçerli bir eposta adresi degil!); } ?> Veriyi kontrol ederek scriptimize tehlikeli verilerin eklenmesi riski büyük ölçüde azaltilmis oldu. valid_eposta() fonksiyonu nda da bulunabilecek olan standar bir onay islemidir
Verimiz daha güvenli olsa da isimiz daha bitmedi çünkü hala veriyi MySQL veritabanina yerlestirmek istiyoruz ve bu islemden önce de bazi kontroller yapmamiz gerekiyor. PHP tüm önemli karakterlerin escape edildigi standart fonksiyonunu sunar. Diger bir yöntem ise SQL sorgusunda veriyi her zaman kesme imleri arasina yerlestirin.
Önceki örnegimize devam edelim: <?php $eposta = $_POST[eposta]; # Burada veri hala TEHLIKELI durumda
// Validate e-mail if (valid_eposta($eposta) == false) { // Geçerli bir adres degil die(Geçerli bir eposta adresi degil!); }
// eposta in veritabani için güvenli hale getirilmesi $eposta = mysql_real_escape_string($eposta);
// Artik güvenli! ?>
Artik elimizdeki eposta verisi veritabanina güvenli bir sekilde islenebilir. Hatalardan kaçinmak için tehlikeli degiskenlere bir ön ek verilebilir, örnegin: <?php $t_eposta = $_POST[eposta]; # Tehlikeli
// Onay islemi
$g_eposta = mysql_real_escape_string($d_eposta); ?>
Bu sekilde tehlikeli bir veriyi isleme sokarken ön tarafindaki t_ eklentisi ile hemen farkina varabilirsiniz.
Çiktilarin filtrelenmesi Girdilerde oldugu gibi disariya sunulan tüm verilerin de (güvenli olarak filtreleyip veritabanina islediginiz verilerin dahi) filtrelenmesi gerekmektedir.
Filtrelenmesi gereken en önemli sey probleme yol açabilecek olan HTML tagleridir. Bunu yapmanin en kolay yolu bütün HTMLi escape islemine sokan fonksiyonudur: <?php echo htmlentities($_GET[eposta]); ?>
Bu kod (saldirganin sayfalariniza JavaScript kodlari eklemesine ve diger kullanicilarin cookielerini çalmasini saglayan) muhtemel XSS (çapraz site betik çalistirma - cross site scripting) saldirilarini kaldirir. Eger mümkünse, htmlentities fonksiyonunun üçüncü argümani i (encoding/charset tipi) da kullanmalisiniz. Googleda HTMLi escape isleminde düzgün encoding ayari yapmadigi için . Google bu açigi 1 aralik a kapatti. Basitçe, her zaman encoding tipini belirlemelisiniz: <?php echo htmlentities($_GET[eposta], ENT_QUOTES, UTF-8); ?>
Eger bütün HTML taglerini filtrelemek istemiyorsaniz, bazi taglere izin vermek istiyorsaniz strip_tags() fonksiyonunu kullanabilirsiniz. Fakat bu, <script> taglerini filtreleseniz dahi Javascript ekleme açiklarina karsi bir güvenlik problemi içerebilir. ör ( <div onclick="alert(Hi!);"> .
Diger bir yöntem de sadece sizin istediklerinizi filtrelemenize yarayacak kendi fonksiyonunuzu yazmaniz (veya internet eki yüzlerce hazir fonksiyondan birini kullanmaniz). Bu bazen en iyi yöntem olabilir fakat herhangi bir seyi unutmaniz durumunda güvenlik problemlerine yol açabilir.
Son olarak, çiktiyi filtrelemenin en iyi yolu, üç argümani ile birlikte htmlentities() fonksiyonunun kullanimi fakat bununda islevi sinirli (ör: formatlama olmamasi) kalabilir. Buna çözüm olarak verileri formatlamanizda kullanilabilecek olan kendi HTML kodunuzu yaratabilirsiniz. Kendi HTML kodunuzu yaratma ile ilgili olarak dokümanina göz atabilirsiniz.
Sonuç Bu makalede PHP programlaminin iki temel ilkesi olan girdi filtreleme ve çikti filtrelemeden bahsettim. Eger bu ikisini dogru olarak yapabilirseniz çok güvenli bir PHP scriptine dogru yola çikmissiniz demektir.
Verdigim örnekler çok basit ve hantal. Escape islemini otomatiklestirmeniz iyi olabilir. Bunun için iyi bir yöntem gerekli islemleri yapan bir class veya fonksiyonlar yazmaniz.
PHP güvenligi ile ilgili daha fazla bilgiye ihtiyaç duyuyorsaniz asagidaki sitelerine göz atabilirsiniz:
- - Çok sayida bilgi içeren mükemmel bir güvenlik rehberi. Mutlaka okunmali. - - Chris Shiflettin Essential PHP Security kitabindan bilgiler. Kitabin bir kaç bölümü ücretsiz sunuluyor. - - Güvenlik bültenlerine yer veriliyor
|