WordPress nonce sanitize escape: Pratik Senaryo: Güvensiz Bir Eklenti Formu

// KOTU ORNEK - kullanmayin
if (isset($_POST['aciklama'])) {
update_option('site_aciklama', $_POST['aciklama']);
}
echo '<p>Mevcut acıklama: ' . get_option('site_aciklama') . '</p>';
Bu dört satırlık kod üç farklı saldırı vektörüne açıktır:
- CSRF (Cross-Site Request Forgery): Saldırgan, oturumu açık bir adminin tarayıcısına gizli bir form çalıştırarak site açıklamasını değiştirebilir.
- Stored XSS: POST verisinde gönderilen
<script>etiketi veritabanına yazılır ve her sayfa yüklendiğinde çalışır. - Veri bütünlüğü kaybı: Beklenmedik karakterler, satır sonları veya kontrol dizileri filtrelenmeden veritabanına sızar.
Nonce Kullanımı: CSRF Koruması
Nonce Nedir?
Nonce kelimesi “number used once” ifadesinin kısaltmasıdır. WordPress’te nonce, belirli bir kullanıcı, belirli bir eylem ve sınırlı bir zaman aralığı için üretilen tek kullanımlık benzeri bir token’dır. Varsayılan ömrü 24 saattir ve eylem (action) adına göre üretilir. Nonce’un işlevi tek bir cümleyle özetlenebilir: bir isteğin gerçekten o kullanıcının kendi sitesinden bilinçli olarak gönderildiğini doğrulamak. Nonce yetkilendirme için değildir; sadece isteğin kaynağını doğrular.Nonce Üretme ve Doğrulama
Form içinde nonce alanı oluşturmak içinwp_nonce_field() kullanılır:
// Formda nonce alani olustur
wp_nonce_field('ob_site_aciklama_guncelle', 'ob_site_aciklama_nonce');
İlk parametre eylem (action) adıdır, ikincisi form alanının adıdır. Bu fonksiyon iki gizli alan üretir: nonce token ve referer URL.
İşleme tarafında doğrulama:
if (
! isset($_POST['ob_site_aciklama_nonce']) ||
! wp_verify_nonce(
sanitize_text_field(wp_unslash($_POST['ob_site_aciklama_nonce'])),
'ob_site_aciklama_guncelle'
)
) {
wp_die('Guvenlik dogrulamasi basarisiz.');
}
Eylem bir admin sayfası içindeyse daha kısa yol check_admin_referer()‘dır:
check_admin_referer('ob_site_aciklama_guncelle', 'ob_site_aciklama_nonce');
Bu fonksiyon doğrulama başarısız olursa otomatik olarak wp_die() ile durur.
AJAX İstekleri İçin Nonce
AJAX işlemlerinde nonce farklı yerleştirilir. Önce localize edilir:wp_localize_script('ob-admin-js', 'obAdmin', [
'ajaxUrl' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('ob_ajax_islem'),
]);
Sunucu tarafında doğrulama:
add_action('wp_ajax_ob_islem', function () {
check_ajax_referer('ob_ajax_islem', 'security');
// islem...
});
JavaScript tarafında security parametresine obAdmin.nonce değeri gönderilir. wp_ajax_nopriv_ ile giriş yapmamış kullanıcılara da açık endpoint’ler tanımlanıyorsa nonce burada özellikle önemlidir.
Girdi Sanitize Etme: Veri Temizleme

| Fonksiyon | Kullanım Yeri | Davranış |
|---|---|---|
sanitize_text_field() |
Tek satırlık metin alanları | HTML temizler, satır sonlarını ve fazla boşlukları kaldırır |
sanitize_textarea_field() |
Çok satırlı metin alanları | HTML temizler ama satır sonlarını korur |
sanitize_email() |
E-posta alanları | Geçersiz karakterleri kaldırır, geçerli değilse boş döner |
esc_url_raw() |
URL’nin veritabanına yazılması | URL’yi güvenli forma getirir, ekrana yazmaz |
absint() |
Pozitif tamsayılar (ID, sayfa numarası) | Mutlak değerli tamsayı döner |
sanitize_key() |
Slug, key, option name | Sadece küçük harf, rakam, alt çizgi ve tire bırakır |
wp_kses_post() |
Yazı içeriği | İzin verilen HTML etiketlerini korur |
$aciklama = isset($_POST['aciklama'])
? sanitize_textarea_field(wp_unslash($_POST['aciklama']))
: '';
update_option('site_aciklama', $aciklama);
wp_unslash() burada önemlidir. WordPress, magic quotes davranışını taklit ederek POST/GET verisindeki ters bölü işaretlerini otomatik ekler. Sanitize öncesinde bunlar temizlenmezse ters bölü işaretleri veritabanına sızar.
Çıktı Escape Etme: XSS Koruması
Sanitize, veritabanına yazılan veriyi temizler. Escape ise tam tersine, veriyi ekrana yazarken bağlama göre güvenli hale getirir. Sanitize girişte, escape çıkışta yapılır. İkisini karıştırmamak gerekir. Çekirdek mantık şudur: veriyi ne kadar temiz aldığınızdan emin olsanız bile, ekrana yazarken bağlama uygun escape uygulanmalıdır. Çünkü aynı veri farklı bağlamlarda farklı tehlikeler taşır.| Fonksiyon | Kullanım Bağlamı |
|---|---|
esc_html() |
HTML içinde metin: <p>...</p> |
esc_attr() |
HTML niteliği: value="...", title="..." |
esc_url() |
href, src gibi URL bağlamları |
esc_js() |
JavaScript dizesi içine değer gömme |
esc_textarea() |
<textarea> içinde varsayılan değer |
wp_kses_post() |
İzin verilen HTML ile içerik gösterimi |
esc_html() ile escape edilmiş bir değeri href niteliğinin içine koymak hâlâ javascript: şemalı saldırılara açıktır. URL bağlamında esc_url() tercih edilmelidir.
Tam Bir Güvenli Form Örneği

// Admin sayfasini ekle
add_action('admin_menu', function () {
add_options_page(
'OB Site Aciklamasi',
'OB Site Aciklamasi',
'manage_options',
'ob-site-aciklama',
'ob_render_aciklama_sayfa'
);
});
function ob_render_aciklama_sayfa() {
if (! current_user_can('manage_options')) {
wp_die('Yetkisiz erisim.');
}
// Form gonderildi mi?
if (
isset($_POST['ob_aciklama_submit']) &&
check_admin_referer('ob_aciklama_action', 'ob_aciklama_nonce')
) {
$aciklama = isset($_POST['ob_aciklama'])
? sanitize_textarea_field(wp_unslash($_POST['ob_aciklama']))
: '';
update_option('ob_site_aciklama', $aciklama);
echo '<div class="notice notice-success"><p>Kaydedildi.</p></div>';
}
$mevcut = get_option('ob_site_aciklama', '');
?>
<div class="wrap">
<h1>OB Site Aciklamasi</h1>
<form method="post">
<?php wp_nonce_field('ob_aciklama_action', 'ob_aciklama_nonce'); ?>
<p>
<label for="ob_aciklama">Aciklama</label><br>
<textarea
id="ob_aciklama"
name="ob_aciklama"
rows="5"
cols="60"
><?php echo esc_textarea($mevcut); ?></textarea>
</p>
<p>
<button
type="submit"
name="ob_aciklama_submit"
class="button button-primary"
>Kaydet</button>
</p>
</form>
<h2>Onizleme</h2>
<p><?php echo esc_html($mevcut); ?></p>
</div>
<?php
}
Bu kodda dört katmanlı koruma vardır:
- Yetki kontrolü:
current_user_can('manage_options')ile sadece yöneticiler erişebilir. - Nonce doğrulama:
check_admin_referer()CSRF’yi kapatır. - Girdi sanitize:
sanitize_textarea_field()veritabanı için temizler. - Çıktı escape:
esc_textarea()veesc_html()XSS’i engeller.
Sık Yapılan Hatalar
Pratikte tekrar eden hata kalıpları:- Yetki kontrolünü atlamak. Nonce, yetkilendirme yerine geçmez. Nonce sadece isteğin meşru olduğunu doğrular; kullanıcının o işlemi yapmaya hakkı olup olmadığını
current_user_can()belirler. - Sanitize ve escape’i karıştırmak. Veritabanına yazarken sanitize, ekrana yazarken escape kullanılır.
esc_html()ile temizlenmiş bir değeri veritabanına yazmak veri kaybına yol açabilir. - Çıktıyı tek bir fonksiyonla escape etmek. Bağlama göre
esc_html(),esc_attr(),esc_url()ayrılmalıdır. Aksi halde bazı saldırı vektörleri açık kalabilir. wp_unslash()‘i unutmak. WordPress POST/GET verisini otomatik olarak slash ekleyerek alır; sanitize öncesinde temizlenmezse ters bölü işaretleri veritabanına sızar.- AJAX endpoint’lerini nonce’suz bırakmak.
admin-ajax.phpgiriş yapmamış kullanıcılar için de açık olabilir;wp_ajax_nopriv_kullanılıyorsa nonce doğrulaması özellikle önemlidir. - SQL sorgularında
$wpdb->prepare()kullanmamak. Bu rehberin doğrudan konusu değildir ancak sanitize ile birlikte düşünülmesi gereken bir katmandır.
Yayın Öncesi Kontrol Listesi
Eklentiyi depoya göndermeden veya canlıya almadan önce şu listeyi sırasıyla kontrol edin:- Tüm formlarda
wp_nonce_field()var mı? - Tüm POST işleyicilerde
wp_verify_nonce()veyacheck_admin_referer()çağrısı var mı? - Tüm AJAX endpoint’lerinde
check_ajax_referer()çağrılıyor mu? - Her işlem için
current_user_can()ile yetki kontrolü yapılıyor mu? - Tüm
$_POST,$_GET,$_REQUESTerişimleriwp_unslash()ile temizleniyor mu? - Veritabanına yazılan her değer veri türüne uygun sanitize fonksiyonundan geçiyor mu?
- Ekrana yazılan her değer bağlama uygun escape fonksiyonundan geçiyor mu?
- HTML niteliklerinde
esc_attr(), URL’lerdeesc_url()ayrımı yapıldı mı? - Kullanıcının HTML girebileceği alanlarda
wp_kses_post()veya benzer filtre kullanılıyor mu? - Doğrudan SQL sorgularında
$wpdb->prepare()kullanılıyor mu?
Sonuç
WordPress eklenti güvenliğinin temeli üç katmandan oluşur: nonce ile isteğin meşruluğunu doğrulamak, sanitize ile girdiyi temizlemek ve escape ile çıktıyı güvenli hale getirmek. Bu üç adım birbirinin yerine geçmez; bir formda hepsi birlikte uygulanmalıdır. Sonraki adım olarak kendi eklentinizdeki tüm form ve AJAX endpoint’lerini yukarıdaki kontrol listesine göre gözden geçirebilir, eksik kalan katmanları tek tek tamamlayabilirsiniz. WPCS (WordPress Coding Standards) PHP_CodeSniffer kurallarıyla yapılacak otomatik taramalar da bu kontrolleri büyük oranda destekler ve sizi tekil hataları teker teker kovalamaktan kurtarır.WordPress nonce sanitize escape için pratik kontrol listesi
WordPress nonce sanitize escape konusunda uygulamaya geçmeden önce mevcut yedeği doğrulayın, değişikliği küçük adımlarla test edin ve sonucu canlı sitede tekrar kontrol edin. Benzer konular için WordPress REST API ve WordPress güvenli giriş rehberlerine de bakabilirsiniz. Resmi kaynak olarak WordPress güvenlik dokümantasyonu sayfasını incelemek faydalı olur.
SSS: WordPress Eklentilerinde Nonce, Sanitize ve Escape Kullanımı
WordPress Eklentilerinde Nonce, Sanitize ve Escape Kullanımı için ilk kontrol ne olmalı?
Önce sorunun kapsamını belirleyin. Sadece tek sayfada mı, tüm sitede mi, yoksa belirli kullanıcı veya cihazlarda mı göründüğünü kontrol edin.
- WordPress nonce sanitize escape: Pratik Senaryo: Güvensiz Bir Eklenti Formu
- Nonce Kullanımı: CSRF Koruması
- Girdi Sanitize Etme: Veri Temizleme
- Çıktı Escape Etme: XSS Koruması
- Tam Bir Güvenli Form Örneği
- Sık Yapılan Hatalar
- Yayın Öncesi Kontrol Listesi
- Sonuç
- WordPress nonce sanitize escape için pratik kontrol listesi
- SSS: WordPress Eklentilerinde Nonce, Sanitize ve Escape Kullanımı
Bu işlem SEO performansını etkiler mi?
Evet, teknik sorunlar kullanıcı deneyimini ve tarama kalitesini etkileyebilir. Bu nedenle değişiklikten sonra Search Console verilerini takip etmek gerekir.
Canlı sitede işlem yapmadan önce yedek almak gerekir mi?
Kesinlikle gerekir. Dosya ve veritabanı yedeği olmadan yapılan canlı değişiklikler, küçük bir hatada geri dönüşü zorlaştırabilir.
Değişiklikten sonra cache temizlemek şart mı?
Çoğu durumda evet. WordPress cache eklentisi, CDN ve tarayıcı cache’i eski çıktıyı göstermeye devam edebilir.
Sorun devam ederse nasıl ilerlemeliyim?
Son yapılan değişikliği geri alın, hata loglarını kontrol edin ve eklenti/tema çakışmasını izole edin. Gerekirse küçük adımlarla yeniden test edin.
Bir Cevap Yaz
E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir.