csrf_12

Çapraz Site İstek (CSRF) Açıklarının Önüne Geçmek

Çapraz site istek açıkları (Cross Site Request Forgery) web uygulamalarında en sık karşılaşılan açıklardan biridir. Saldırganlar bu türdeki açıklardan faydalanırken saldırı yaptıkları siteyi istekler sanki kullanıcı tarafından yapılıyormuş gibi kandırmaya çalışırlar. Örneğin kullanıcı  her gun gezip tozduğu x.com adresli siteye giriş yaptıktan sonra tamamen farklı bir domain üzerinde çalışan y.com/link.html üzerindeki saldırı linkine tıkladığında farkına […]

Çapraz site istek açıkları (Cross Site Request Forgery) web uygulamalarında en sık karşılaşılan açıklardan biridir. Saldırganlar bu türdeki açıklardan faydalanırken saldırı yaptıkları siteyi istekler sanki kullanıcı tarafından yapılıyormuş gibi kandırmaya çalışırlar. Örneğin kullanıcı  her gun gezip tozduğu x.com adresli siteye giriş yaptıktan sonra tamamen farklı bir domain üzerinde çalışan y.com/link.html üzerindeki saldırı linkine tıkladığında farkına bile varmadan üye girişi yaptığı x.com adresli sitedeki kayıt olduğail bilgileri değiştirilebilir. Böylece saldırganlar bir kullanıcının şifre bilgilerini şifremi unuttum sayfaları aracılığı ile ellerine geçirebilirler. Saldırganlar bir kullanıcının site üzerindeki yetkisi dahilindeki her işlemi yapabileceklerinden istedikleri takdirde siz yapıyormuşsunuz gibi forumlara yazı yazabilir veya alışveriş sepetinize ürünler ekleyebilirler.

Nasıl yapılır ?

CSRF açıklarının nasıl çalıştığını anlayabilmenin en iyi yolu bu açıkları uygulama sırasında gözlemlemektir. Atağın nasıl yapıldığını anlatabilmek için aşağıda basit bir uygulama yapacağım. Aşağıdaki örnek önceden giriş yapılmış bir sayfadan csrf atağı yaparak çıkış yapmanızı sağlayacaktır. Öncelikle ihtiyacımız olan bir adet giriş sayfası (login.php), giriş ve çıkış işlemlerini işleyen script (process.php) ve son olarak da atağın geleceği dosya (attack.html).

Öncelikle, giriş sayfası dosyamız için hazırlanan kod (login.php):

<?php session_start(); // oturum başlatılıyor

if (isset($_SESSION["user"])) { // eğer oturum açıksa kullanıcıya çıkış linki gösteriliyor
 echo "Hoşgeldiniz, " . $_SESSION["user"] . "!";
 echo '<a href="process.php?action=logout">Çıkış Yap</a> ';
 }
 else {
 ?></pre>
<form action="process.php?action=login" method="post">
Kullanıcı adı : admin

 <input type="text" name="user" size="20" />

Şifre: test

 <input type="password" name="pass" size="20" />
 <input type="submit" value="Giriş" /></form>
 <?php  }  ?>

login.php dosyası oturum açma işlemi ile başlıyor, devamında $_SESSION[“user”] değişkeninin tanımlı olup olmadığını kontrol ederek kullanıcının giriş yapıp yapmadığını anlıyoruz ardından son olarak da kullanıcı giriş yaptı ise çıkış yap linkini gösteriyoruz. Eğer kullanıcı giriş yapmadı ise sadece giriş formu görüntülenecektir.

Giriş ve çıkış işlemlerinin işleneceği process.php dosyası :

<?php session_start(); switch($_GET["action"]) {  case "login":  if ($_SERVER["REQUEST_METHOD"] == "POST") {  $user = (isset($_POST["user"]) &&  ctype_alnum($_POST["user"]) ? $_POST["user"] : null;  $pass = (isset($_POST["pass"])) ? $_POST["pass"] : null;  $salt = '$2a$07$h3ll0.k1tty$'; if (isset($user, $pass) && (crypt($user . $pass, $salt) ==  crypt("admintest", $salt))) {  $_SESSION["user"] = $_POST["user"];  }  }  break; case "logout":  $_SESSION = array();  session_destroy();  break;  } header("Location: login.php");  ?>

process.php dosyası oturum verisinin başlatılması ile başlar, ardından gelen parametrelere göre yapılacak herhangi bir işlem olup olmadığını kontrol eder.

Son olarak atağın geleceği attack.html dosyası :


Bu site zararlıdır ! 

<!-- Hedef siteyi adresler -->
<img style="display: none;" src="process.php?action=logout" alt="" />

Eğer login.php dosyasını ziyaret edip hesabınıza giriş yapmışsanız attack.html dosyasını açtığınızda çıkış işleminiz sanki logout butonuna tıklamışsınız gibi yapılacaktır. Bunun yapılmasının temel sebebi img tagının src tanımında process.php ‘nin verilmiş olmasıdır. Bu sayede kullanıcı tarafından sunucuya sıradan bir resim isteği yapılmış gibi davranılarak process.php ye istek gönderilmek istenmektedir. process.php uzerinde isteklerin kullanıcı tarafından çıkış linkine tıklanarak yapılıp yapılmadığını kontrol eden herhangi bir mekanizma bulunmadığından işlem geçerli sayılarak çıkış işlemi yapılacaktır.

attack.html dosyası tamamen farklı bir sunucuda host edilebileceğinden siz siteye giriş yaptıktan sonra arka planda halen daha siteye bağlı durumda olduğunuzdan dolayı sanki istek sizin tarafınızdan yapılıyormuş gibi işleme alınacaktır. Bu gibi durumlarda isteğin kaynağının nereden geldiğini anlayabilmenin herhangi bir yolu yoktur.
Sanırım bu noktada CSRF ataklarının nasıl yapıldığı konusunda kısa bir bilgi sahibi olmuşsunuzdur.
Kullanıcıları Ataklardan Korumak
Bir isteğin kullanıcı tarafından mı yoksa üçüncü parti bir uygulama tarafından yapılıp yapılmadığını anlayabilmek için, sizin uygulama üzerinde bazı özel tanımlamalar yapmanız gerekmektedir. Bu tanımlamalardan bazıları için login.php dosyasında aşağıdaki değişiklikleri yapmak gerekmektedir.

<?php <br ?--> // özel bir id oluştur.
 $_SESSION["token"] = md5(uniqid(mt_rand(), true));
 echo '<a href="process.php?action=logout&csrf=' . $_SESSION[">Çıkış yap</a>';

Ardından bu özel tanımlamayı process.php üzerinden onaylayabilmek için process.php dosyası üzerinde aşağıdaki değişiklikleri yapmak gerekmektedir  :

case "logout":
 if (isset($_GET["csrf"]) && $_GET["csrf"] == $_SESSION["token"]) {
 $_SESSION = array();
 session_destroy();
 }
 break;

Yapılan bu basit eklemelerle attack.html dosyası artık çalışmayacaktır. Bunun sebebi attack.html dosyasını hazırlayan kişinin oluşturduğumuz özel id yi tahmin edemeyecek olmasındandır.
Oluşturduğunuz formları CSRF ataklarından korumak için aşağıdaki kodu form tagının içerisine yerleştirmeniz gerekiyor.

<input type="hidden" name="csrf" value="<?php echo $_SESSION[" />

Sonuç
Şu an itibari ile kısaca CSRF atakları hakkında bilgi sahibi oldunuz. Eminim hepimiz sonradan çıkacak ataklar ve sonucunda yaşayacağımız baş ağrılarından korunmak için daha işin başındayken güvenli kodlar yazmak isteriz. Bu anlamda projelerinizde tedbiri elden bırakmamanız gerektiğini birkez daha hatırlatmak isterim.