Php Güvenlik - En Yaygın Açıklar ve Güvenlik Önlemleri

Php Güvenlik - En Yaygın Açıklar ve Güvenlik Önlemleri

Php, bilişim dünyasının en popüler dili olarak karşımıza çıkıyor şu günlerde. Programlama dillerinin en popüleri olan bu dilin arkasındaki güç elbette kullanım kolaylığı, birçok programlama dili ile kolayca ilişkilendirilebilmesi ve daha birçok şey. Tanımını yapmak gerekirse, internet için yaratılmış, server yönlü, kullanım ağı epey geniş, html dili içerisine gömülebilen bir betik yahut programlama dilidir demek mümkün. Ocak 2013 yılından itibaren 244 milyondan fazla web sitesinin PHP dili ile yazıldığı ve yürütüldüğü doğrulanmış. Çoğu dil ile ilişkilendirilebildiğini söylemiştik ancak Linux ve MySQL ile çok daha iyi performans verdiğini söylersek de yalan olmayacak bir cümle ortaya koyarız. Peki, Rasmus Lerdorf’un mucidi olduğu bu dilin oluşturduğu web sitelerine sızılabilir mi? Sorumuz biraz çetrefilli, bir o kadar da eğlenceli bir soru. Son kullanıcı dediğimiz, olayın arka tarafı ile ilgili olmayan birçok insanın bugün Windows kullandığını, Linux ve diğer işletim sistemlerinin adını bile duymadığını bilmekteyiz. PHP’nin protokolü de bu şekilde işliyor aslında. Bugüne kadar Windows için üretilen kaç virüs var bir düşünelim. Ardından, bu soruyu “Windows” yerine “Linux” ekleyerek düşünelim. Sonuç, Windows için belki de on binler, milyonlar; Linux için ise çok fazla olmayacaktır, belki binler.

Peki neden? Çünkü, Windows işletim sistemi popüler. Bilgisayar korsanları, az sayıdaki kullanıcıyı değil; her zaman çok sayıdaki kullanıcıyı hedeflerler. Onlar için insanların nitelikleri değil, ne kadar insanın, neyi; ne kadar kullandığı önem arz eder. Bu sebepten sabahtan akşama dek Windows işletim sistemine sızmaya çalışırlar. Anti-Virüs programları saat başı güncellemeler alır; vesaire. Php’de de durum böyledir. Bugün, doğrulanan veri ile 244 milyondan fazla web sitesinin PHP kullanıyor olması, bilgisayar korsanları için yeterince ilgi çekici, tatmin edici bir olgu. Bu dile sızmanın en önemli yollarını bilmek demek, öncelikle dile hakim olmaktan geçer, unutmayın. Dile tamamı ile hakim olmayan bir “hacker” ya da “coder”, buzdağının sadece görünen tarafı ile ilgilenebilir ve bir şeyleri yaptığını, yapabildiğini zanneder. Yeni, hevesli, PHP öğrenmeye çalışan pek çok insan; üç, beş komutu html ve css çalışmasının içerisine gömerek, bir şeyler üretmeye çalışır. Ne PHP’nin güvenlik zafiyetlerinden haberdardır, ne de olacaklardan. Sadece yapar. Bu onun için çok heyecan verici bir deneyimdir çünkü öğrendiklerini pratik yaparak uygulamasının yanında; gövde gösterisi de yapacaktır. İşte tam burada bu dile hakim, kötü niyetli “hacker”lar devreye girer. Sisteme, basit, zafiyetlerle dolu betikten içeriye anahtarı varmışçasına, kolayca erişebilir. Bunu bir de, alanında profesyonel olmayan web tasarımcı ve programlamacıların; birçok siteye uyguladığını tasavvur ederek düşünün; ufak bir ilan, yarı yarıya fiyat ve küçük bir çevre ile bunu yapıp geçimini sağlamasa da küçük paralar kazanmaya çalışan birçok sözüm ona uzman tasarımcı var etrafta ve referansları güvenlik zafiyetinden geçilmiyor. Bu tür yeni “coder”lar öğrenebildiği ölçüde yapabildiği sitelerle, “hacker”ın ekmeğine yağ sürmekten başka bir şey yapmaz.

Peki, nedir bu betikte en sık karşılaşılan güvenlik zafiyetleri?

Birçok güvenlik zafiyeti mevcut ancak en sık karşılaşılan güvenlik zafiyetlerinden biri; Cross Site Scripting (XSS) olarak bilinir. Zafiyet JavaScript kodları aracılığı ile, web sitesinin html kodları içerisinde istemci tabanlı bir kod bulunması (searchbox, vs.) ve bu istemci koduna gömülen JavaScript kodunun çalıştırılabilmesi metoduna uygun olarak hareket eder. Bulunduğu tarihten bu yana erişim kontrolü tedbirleri geliştiriliyor ancak bu zafiyetin önüne geçmek maalesef dikkatsizlikten ötürü pek kolay değil. Açığın bulunmasından sonra saldırgan, başka bir alan adı aracılığı ile açığın bulunduğu alan adı ve sayfanın bilgilerini, açılan oturumların kişi bilgilerini çalabilmektedir. Bu açığın Cookie Sniffer denilen, cookie bilgilerinizi çalan yöntem ile birleşmesi, siteniz için çok kötü sonuçlar doğurabilir. Popüler bir online satış sitenize Sniffer yerleştirildiğini ve oturum açan her kullanıcının oturum bilgilerinin bu Sniffer’e düştüğünü tasavvur edin. Bu, site sahibi için kâbus, site korsanı için bayram olarak nitelendirilebilir.

Peki, Cross Site Scripting zafiyetinin kod tarafında önlemi nedir, nasıl alınmalıdır. Bunu kod üzerinden açıklayalım:

<?php

$mesajyazdir = $_GET['mesaj'];
print $mesajyazdir ;
?>

Yukarıda verdiğim kod, basit bir PHP betiği. Dolar işareti ile belirlenen bir değişken ve GET ile atanan bir değerimiz mevcut. Ardından, print komutu ile $mesajyazdir değişkeninin ekrana vurulmasını sağladık. Ekrana vurulmasından kastımız elbette site kullanıcılarına iletilmesi. Siteye iletilecek olan değeri ise 'mesaj' olarak belirledik. Kodda herhangi bir önlem görüyor musunuz? Ben görmüyorum. Bu dili yeni öğrenen arkadaşlar da göremezler, çünkü hatasız yazılmış ve çalışan bir koddur kendisi. Ancak, “hacker”lara kapı açması için verilen olanakların hepsini sonuna dek kullanır bu kod. Çünkü, herhangi bir önlem alınmamıştır. Bu kod, GET değerinde herhangi bir filtreleme işlemi yapılmaksızın oluşturulmuştur. Bizim sitemizin mesajyazdir değişkeni sitemizde, bu kodu “index.php” adlı dosyaya yazdığımızı varsayar isek, “index.php?mesajyazdir=” olarak belirecektir. Eşittir işaretinin ertesine herhangi bir filtreleme yapmadığımız için istediğimiz her şeyi yazabiliriz. Peki, “hacker” neden JavaScript kodları ile bilgilerimizi çalma yoluna gitmesin?

Gidecektir. ve “hacker”ın kodu aşağıdaki şekillerde oluşacaktır muhtemelen:

index.php?mesajyazdir= 

ve Senaryo, “hacker”a bütün cookie’ler, yani oturum çerezleri pop-up aracılığı ile düşmesi şeklinde ilerler. Yapılacak diğer her şey “hacker”ın zekâsına kalmıştır aslında. Oturum bilgilerini çözerek her şeyi yapabilir. Ya da bu zafiyeti Cookie Sniffer yöntemi ile birleştirip, ortaya koca bir tehdit çıkarabilir.

Peki, bu açığı nasıl önleyebiliriz?

Aslında çok basit. Karakterleri filtreleyerek bu açığın önlenmesi mümkündür. Sonuçta, yukarıda gördüğünüz kod, parantez ve taksim işaretleri ile dolu bir kod ve bunları filtreleyebilirsek; kötü sonucu önleyebiliriz. Bunun muadili PHP dilinde htmlspecialchars adlı komuttur. Temel olarak, bu zafiyetin bu şekilde önlenmesi mümkündür. Örnekleyecek olursak:

<?php

$mesajyazdir = $_GET['mesaj'];
print htmlspecialchars($mesajyazdir);
?>

Yukarıdaki biçimde, bu zafiyetin engellenmesi mümkündür. Bu en kolay yoldan açığı defetme yöntemidir ancak daha gelişmiş yollar da mevcuttur, araştırdığınız takdirde bulabilirsiniz. Daha gelişmiş yolların sebebi, daha gelişmiş saldırı ataklarının icat edilmesi olabilir.

**

Gelelim bir diğer zafiyet türü olan SQL Injection adlı zafiyete. Bir önceki zafiyetimiz Javascript kodlarının istemciye karışması ile ilgiliydi. 98 yılından bu yana PHP dilinin en büyük tehdidi olarak karşımıza çıkar SQL Injection. Uygulama yazılımı içerisindeki zafiyetlerden yararlanarak tabanda çalışan SQL dilinden yararlanır ve uygulama alanındaki ilgili alana, SQL komutları girerek yapılan atak tekniklerinden biridir. Çoğunlukla web sitelerinde bu saldırı tipini görsek de tabanında SQL çalışan her uygulamanın tehdit edildiğini söyleyebiliriz. Bizim makalemiz PHP ile ilgili olduğundan sadece PHP ile çalışan bir sistemin nasıl SQL Injection saldırısı alabileceğinden bahsedeceğiz. Elbette bu zafiyette de sadece PHP değil, SQL bilgisinin de önemli olduğunu belirtmek gerekir zira girilen SQL komutlarının ne derece tehlikeli olduğu, SQL komutlarının ne derece bilindiğine bağlıdır. Bu zafiyeti de kodlar üzerinde, php ile çalışacak bir sistemde pratik olarak gösterelim:

<?php

$id= $_GET['id'];
$query= "SELECT * FROM kullanicilar WHERE id= ' “ .$id." ;"
?>

Yine bir değişken belirledik, ve GET ile o değişkeni ekrana ilettik. Ardından, query değişkeni ile SQL veritabanından veri çekmeye çalıştık. query değişkeninden sonraki komutu açıklamak gerekir ise, SELECT komutu, seçim yaptığımız komuttur. Elbette nereden seçeceğimizin komutu FROM komutudur. kullanicilar tablosundan seçeceğimizi belirtmişiz. WHERE ile bu tablonun id= değişkeninde olduğunu belirtmişiz. Burada, id= değişkeninde hiçbir şekilde filtreleme işlemi yapılmadığından, “hacker” bu değişkenden sonra dilediğince SQL komutu çalıştırabilecektir. İçeri girmek için belli işlemleri yaptıktan sonra “hacker” son komutunu yazacaktır:

index.php?id=1+UNION+SELECT+1,@@version,3,4,5+from+kullanicilar/*

Hacker, bu komuttan sonra tüm kullanıcı bilgilerini SQL veritabanından ortaya dökebilecektir. ve Bu bilgiler ile neler yapabileceği yine ona kalmıştır. Bu zafiyeti de önlemenin ana etmeni karakter filtrelemeden geçmektedir elbette. Gördüğünüz üzere yukarıdaki komutta da birçok özel karakter mevcut ve bunların engellenmesini bir diğer yöntem olan; php güvenlik fonksiyonlarını kullanarak, onların url’de etkisiz hale getirilmesi ile sağlayacağız.

Kod satırımız dosyaya şu şekilde eklenebilir:

<?php

$id = addslashes(strip_tags($_POST['id']));
$veri = addslashes(strip_tags($_POST['veri']));
?>

Bu sayede “hacker” yukarıdaki karakterlerden birini girdiğinde, url direkt yoldan onları etkisizleştirecektir. Fonksiyonları arttırabilirsiniz ve SQL Injection hakkında detaylı bilgi almak için internette araştırmalar yapabilirsiniz. Kısaca ve yüzeysel bir biçimde bu önlemlerin nasıl alabileceğini, en temel yöntemler ile anlatmaya çalıştık. Bunlar basit ancak etkili yöntemlerdir; daha yetkin yöntemlere de ulaşabileceğinizi unutmayın!

PHP güvenlik açıkları hakkında destek almak için bize ulaşın