22
2013
wpnonce Kullanarak WordPress Eklenti Güvenliğini Sağlama
WordPress eklentilerinde oluşabilecek en büyük güvenlik açıkları CRSF denilen bir saldırıya karşı gerekli önlemlerin alınmamasından kaynaklanmaktadır. Bu saldırıda, yönetici konumundaki bir kişiye özel bir link tıklatılarak, eklenti aracılığıyla site zarar verilir. Bunun temelinde de siteye gönderilen bilgilerin başka yerden mi yoksa site içinden mi geldiğinin kontrol edilmemesi yatar.
Halbuki WordPress bu problem için bir çözüm üretmiştir, eklenti ile bir form ya da link oluşturulduğunda, formun ya da linkin içerisine gizli bir kod eklenir. Linke tıklandığında ya da form gönderildiğinde bu bilgi de aktarılır. Bilgiler geldiğinde bu kod kontrol edilir, eğer kod doğruysa bu durum, bilgiler site içerisinden gelmiş, yönetici bilinçli olarak bu bilgiyi gönderiyor anlamına gelir, böylece önemli bir güvenlik problemi ortadan kaldırılmış olur.
Bu yöntem için WordPress bize nonce (tek seferlik) kod üretip, kontrol etme amaçlı birkaç basit fonksiyon sunuyor. Bize düşen bu fonksiyonlardan, yapacağımız işe uygun olan birkaç tanesini seçip, eklentimize entegre etmek.
Tek seferlik kod üretip, kontrol etme mekanizması üç adımda gerçekleşiyor. Bu adımlar;
- Tek seferlik bir kod üretip, bunu forma, işlem yapmak için kullanılan linke (örneğin; sil, düzenle, ekle vs.) ya da AJAX ile işlem yapılıyorsa, AJAX isteğinin içine eklemek
- Bu kodu form gönderildiğinde, linke tıklandığında, AJAX isteğinde bulunduğunda karşıya göndermek
- Eklentiye bilgiler geldiğinde bir şey yapmadan önce bu kodun doğruluğu kontrol edilir, eğer doğru ise işlemlere devam edilir, değilse bilgilerin başka bir siteden gönderildiği kabul edilip, script sonlandırılır.
Linkler'de Nonce Kullanarak Güvenlik Sağlama
Çoğu eklenti yazarı, ilk eklentilerini yazdıklarında, örneğin veritabanına kaydettikleri bir bilgi için Sil, Düzenle şeklinde linkler oluştururken genelde aşağıdaki şekilde linkler oluştururlar.
<a href=".../admin.php?page=eklenti-sayfam&islem=sil&id=5">Sil</a>
Linke baktığınızda gayet normal, gayet masum görünüyor öyle değil mi? Ancak bu eklentiyi kullanan bir siteye ben bir yorum yazsam, sitemde şöyle bir problemim var, kontrol eder misin deyip, yukarıdaki linkin aynısını oluştursam ve site yöneticisine tıklatsam ne olur? Tahmin ettiğiniz gibi 5 nolu kayıt silinmiş olur.
Sanırım problem daha açık görmüş oldunuz. Peki ne yapmak lazım? Yapacağımız şey basit, link içerisine, sadece o an için kullanılabilecek, tek kullanımlık bir kod ekleyeceğiz. Bunu da aşağıdaki fonksiyonu ve kodlamayı kullanarak yapabiliriz.
<a href="<?php wp_nonce_url ( admin_url('admin.php?page=eklenti-sayfam') . '&islem=sil&id='. $id, 'eklentim-sil-nonce');?>">Sil</a>
Bu kodu eklentiniz içindeki bir döngüde kullandığınızı, $id değişkeninin silinecek kaydın ID nosunu tutttuğunu farzedersek, kodun 5 kayıt için çıktısı aşağıdaki şekilde olacaktır.
<a href="http://www.siteadresi.com/wp-admin/admin.php?page=eklenti-sayfam&islem=sil&id=5&_wpnonce=c8c0a2a584">Sil</a> <a href="http://www.siteadresi.com/wp-admin/admin.php?page=eklenti-sayfam&islem=sil&id=7&_wpnonce=c8c0a2a584">Sil</a> <a href="http://www.siteadresi.com/wp-admin/admin.php?page=eklenti-sayfam&islem=sil&id=9&_wpnonce=c8c0a2a584">Sil</a> <a href="http://www.siteadresi.com/wp-admin/admin.php?page=eklenti-sayfam&islem=sil&id=15&_wpnonce=c8c0a2a584">Sil</a> <a href="http://www.siteadresi.com/wp-admin/admin.php?page=eklenti-sayfam&islem=sil&id=21&_wpnonce=c8c0a2a584">Sil</a>
Kod içindeki admin_url() fonksiyonu yönetim panelinin adresine, verdiğiniz parametredeki adresi ekler. Kod ile çıktıyı karşılaştırırsanız, ne işe yaradığını görebilirsiniz.
wp_nonce_url() fonksiyonu bizim esas oğlanımız, bu fonksiyon kendisine verilen adrese, _wpnonce=rastgelekod şeklinde bir parametre ekler. Fonksiyon iki parametre almaktadır, birinci parametre adresi ifade ederken, ikinci parametre eklentimize ait benzersiz bir isim olmalıdır. Bu nedenle ikinci parametre olarak eklenti isminizi vermeniz mantıklı olacaktır. Bu kodlama sistemi çoğu eklentide bu şekilde kullanılmaktadır. Ancak WordPress kendi içerisinde farklı bir sistem kullanmakta, her link için farklı kodlar üretmektedir.
Ekran çıktısından da görebileceğiniz üzere wp_nonce_url() fonksiyonu, bütün linkler için tek kod üretip, yazdırdı; bunun sebebi fonksiyona verdiğimiz ikinci parametrenin hep aynı kalmasıdır. O zaman 'eklentim-sil-nonce' ifadesini değişken hale getirirsek her link için farklı bir kod üretilmesini sağlayabiliriz. Aslında aynı kod ya da farklı kod kullanmanın bir fark yaratıp, yaratmadığını bilmiyorum. NextGen Gallery eklentisi buradaki kod yapısını kullanıyor, yani her link için aynı kodun oluşmasını sağlayıp, kullanıyor. Hangisini kullanacağınız size kalmış. Kodu aşağıdaki gibi kullanırsanız her link için farklı bir _wpnonce ifadesi oluşacaktır.
<a href="<?php wp_nonce_url ( admin_url('admin.php?page=eklenti-sayfam') . '&islem=sil&id='. $id, 'eklentim-sil-' . $id);?>">Sil</a>
Kodda yaptığımız tek değişiklik eklentim-sil-nonce ifadesi yerine eklentim-sil-$id ifadesini yazmak oldu, bu şekilde ikinci parametreyi değişken hale getirmiş olduk, böylece de her link için farklı bir kod üretmesini sağladık. Bu kodun ekran çıktısı aşağıdaki gibi olacaktır.
<a href="http://www.siteadresi.com/wp-admin/admin.php?page=eklenti-sayfam&islem=sil&id=5&_wpnonce=c8c0a2a584">Sil</a> <a href="http://www.siteadresi.com/wp-admin/admin.php?page=eklenti-sayfam&islem=sil&id=7&_wpnonce=ea22a58563">Sil</a> <a href="http://www.siteadresi.com/wp-admin/admin.php?page=eklenti-sayfam&islem=sil&id=9&_wpnonce=de48b8cea0">Sil</a> <a href="http://www.siteadresi.com/wp-admin/admin.php?page=eklenti-sayfam&islem=sil&id=15&_wpnonce=f87b8c749c">Sil</a> <a href="http://www.siteadresi.com/wp-admin/admin.php?page=eklenti-sayfam&islem=sil&id=21&_wpnonce=ab8a0c89ef">Sil</a>
Tek Kullanımlık Kodu Kontrol Etme
Yukarıdaki kodları kullanarak, linklerimizi oluşturduk. Şimdi sıra kullanıcı oluşturduğumuz Sil linkine tıkladığında, oluşturduğumuz bu tek kullanımlık kodu nasıl kullanacağımıza geldi. Eğer ilk kodu kullanıyorsanız, linke tıklandığında işlem yapan fonksiyonunuzun başına aşağıdaki kodu ekleyerek, linkle beraber tek kullanımlık kodu kontrol edip, eğer hatalı ise ya da bu bilgi yoksa scripti sonlandırabilirsiniz.
$nonce=$_REQUEST['_wpnonce']; if (! wp_verify_nonce($nonce, 'eklentim-sil-nonce') ) die("Bu İşlem İçin İzniniz yok");
Eğer her link için ayrı kod ürettiğimiz ikinci kod yapısını kullandıysanız da bu durumda aşağıdaki kodu kullanarak kontrol edebilirsiniz.
$id=$_GET['id']; if ($_GET['islem'] == 'sil') { if (! wp_verify_nonce($_REQUEST['_wpnonce'], 'eklentim-sil-' . $id) ) die("Bu İşlem İçin İzniniz yok"); } wp_verify_nonce() fonksiyonu kendisine verilen _wpnonce değerinin, ikinci parametre ile verilen ifadeye ait olup, olmadığını kontrol eder. Uyuyorsa true, uymuyorsa false değerini döndürür. Kodlarda da eğer true dönmemişse scripti sonlandır demiş oluyoruz. Eğer wp_nonce_url() fonksiyonunu kullanmak istemeyip, kendi linklerinizi oluşturmak, _wpnonce değerini kendiniz, linkinize eklemek isterseniz de aşağıdaki kodu kullanabilirsiniz. 1 $nonce= wp_create_nonce ('eklentim-sil-nonce'); echo '<a href="http://www.siteadresi.com/wp-admin/admin.php?page=eklenti-sayfam&islem=sil&id=5&_wpnonce=' . &nonce . '">Sil</a>';
Dikkat! : Her ne kadar verdiğim örnekler eklentilerimizin sadece yönetim paneli bölümü için olsa da, eğer eklentimizin ziyaretçi tarafında da linklerle işlem yapılacaksa örneğin bir linke tıklandığında yazıyı beğenmiş olacaksa, yine o linklere de nonce kodu eklemeniz ve kontrolünü yapmanız gerekmektedir. Aksi halde yine olumsuz durumlarla karşılaşabilirsiniz.
Verdiğim örnekler Sil linklerini oluşturmayla ilgiliydi, eklentinizde Düzenle ya da benzeri farklı linkler de oluşturacaksanız, aynı yöntemle linkleri oluşturmanız yerinde olacaktır.
Bir sonraki WordPress Eklentilerimizdeki Formların Güvenliğini Artırma başlıklı yazımda eklentimiz içerisinde form işlemleri yaparken, örneğin yeni bir kayıt eklerken, bir kaydı güncellerken, bir bilgiyi almak için bir değer gönderirken, wpnonce sistemini nasıl kullanabileceğimizi anlatacağım anlattım. Özellikle veritabanıyla ilgili işlem yaparken ya da yazılarınız için Özel Meta Kutuları hazırlarken güvenliği nasıl sağlayacağınızdan bahsedeceğim bahsettim. Serinin bir sonraki yazısını da okumanızı şiddetle tavsiye ederim.