İnternet ve GüvenlikWordPress

Content Security Policy Nedir? WordPress CSP Kurulum Rehberi

Content security policy nedir? Content Security Policy (CSP), tarayıcıya bir web sayfasının hangi kaynaklardan script, stil, görsel veya iframe yükleyebileceğini bildiren bir HTTP güvenlik başlığıdır. Basitçe söylemek gerekirse CSP, sitenize “yalnızca bu adreslerden gelen kodları çalıştır, gerisini reddet” talimatını veren bir güvenlik duvarı gibi çalışır. WordPress siteleri için özellikle önemli, çünkü çoğu site onlarca eklenti, tema ve üçüncü taraf script’e (analitik araçları, sohbet widget’ları, reklam kodları) bağımlı; bu bağımlılıkların her biri potansiyel bir saldırı yüzeyi oluşturuyor.

Bu rehberde CSP’nin nasıl çalıştığını, WordPress’te üç farklı yöntemle nasıl kurulacağını, hangi direktiflerin ne işe yaradığını ve kurulum sırasında sitenizi kilitlememek için nelere dikkat etmeniz gerektiğini adım adım, kod örnekleriyle anlatıyoruz.

Content Security Policy Nedir? Temel Çalışma Mantığı

CSP, sunucunuzun tarayıcıya gönderdiği bir HTTP yanıt başlığıdır (Content-Security-Policy). Tarayıcı bu başlığı aldığında, sayfadaki her kaynağı (script, stil dosyası, görsel, font, iframe) yüklemeden önce başlıkta tanımlanan kurallarla karşılaştırır. Kural dışı bir kaynak varsa tarayıcı o kaynağı yüklemeyi reddeder ve isteğe bağlı olarak bir ihlal raporu gönderir.

Tarayıcı CSP’yi Nasıl Uygular?

Süreç şu şekilde işler: sunucu HTML sayfasıyla birlikte CSP başlığını gönderir, tarayıcı sayfayı ayrıştırmaya başlar ve her kaynak isteğinde CSP kurallarını kontrol eder. İzin verilmeyen bir script çalıştırılmaya çalışılırsa (örneğin sayfaya sonradan enjekte edilen kötü amaçlı bir <script> etiketi), tarayıcı bu isteği tamamen engeller ve konsola bir hata yazar. Bu, özellikle XSS (Cross-Site Scripting) saldırılarına karşı çok güçlü bir savunma katmanı oluşturur; çünkü saldırgan sayfaya kod enjekte etse bile, o kod CSP’nin izin verdiği kaynak listesinde değilse çalıştırılamaz.

CSP Neden Önemli? Güncel Tehdit Ortamı

CSP beklenmeyen kaynaklardan script yüklenmesini sınırlandırabilir. Fakat izin listesindeki bir CDN’nin scripti ele geçirilirse, aynı adresten gelen zararlı içerik de izinli olabilir. Bu nedenle CSP, üçüncü taraf kod bütünlüğü ve tedarikçi denetiminin yerini almaz.

WordPress özelinde bu risk daha da belirgin, çünkü tipik bir kurulum onlarca farklı kaynaktan kod çalıştırıyor: tema dosyaları, eklenti script’leri, reklam ağları, analitik araçları, sosyal medya gömme kodları ve ödeme sağlayıcı widget’ları. Bu kaynaklardan yalnızca biri güvenliği ihlal edilse (tıpkı Brevo örneğinde olduğu gibi), sitenizin kendi kodu hiç değişmeden ziyaretçileriniz risk altında kalabilir. CSP, bu noktada “varsayılan olarak güvenmeme” ilkesini uygulayan bir ek güvenlik katmanı sunuyor: açıkça izin vermediğiniz hiçbir kaynak çalışmıyor.

CSP’nin sağladığı başlıca korumalar şunlar:

  • XSS saldırılarını sınırlama: Enjekte edilen kötü amaçlı script’lerin çalışmasını engeller.
  • Veri sızıntısı (exfiltration) önleme: Sayfanın izinsiz harici adreslere veri göndermesini kısıtlar.
  • Clickjacking koruması: frame-ancestors direktifiyle sitenizin başka sitelerde iframe içinde açılmasını engelleyebilirsiniz.
  • Tedarik zinciri saldırılarına karşı ek katman: Beklenmeyen bir üçüncü taraf kaynaktan kod yüklenmesi durumunda son bir güvenlik ağı işlevi görür.

CSP Direktifleri: Bilmeniz Gereken Temel Kavramlar

CSP, tek bir kural değil; farklı kaynak türlerini ayrı ayrı kontrol eden “direktifler” bütünüdür. En sık kullanılan direktifler aşağıdaki tabloda özetlenmiştir:

Direktif Kontrol Ettiği Kaynak Örnek Kullanım
default-src Belirtilmeyen fetch direktifleri için varsayılan; frame-ancestors, base-uri ve form-action dahil değildir default-src 'self'
script-src JavaScript dosyaları script-src 'self' https://cdn.example.com
style-src CSS dosyaları style-src 'self' 'unsafe-inline'
img-src Görseller img-src 'self' data: https:
font-src Font dosyaları font-src 'self' https://fonts.gstatic.com
frame-ancestors Sitenizin hangi sitelerde iframe olarak açılabileceği frame-ancestors 'self'
connect-src AJAX, fetch, WebSocket bağlantıları connect-src 'self'

'self' değeri “aynı origin (şema, host ve port)” anlamına gelirken, 'unsafe-inline' sayfa içine gömülü script veya stillere izin verir (mümkünse kaçınılması önerilir, çünkü XSS korumasını zayıflatır). Resmi ve güncel direktif listesi için MDN’in CSP dokümantasyonuna başvurabilirsiniz.

WordPress’te CSP Nasıl Kurulur? Adım Adım Rehber

CSP kurulumuna başlamadan önce, sürecin tek seferlik bir “başlık ekle ve unut” işlemi olmadığını, siteniz büyüdükçe ve yeni entegrasyonlar eklendikçe düzenli bakım gerektiren bir güvenlik pratiği olduğunu baştan kabul etmek, ileride yaşanacak sürprizleri büyük ölçüde azaltır. Aşağıdaki adımlar bu süreci güvenli ve sürdürülebilir şekilde yönetmenize yardımcı olur.

  1. Mevcut kaynakları envanterleyin: Sitenizin hangi harici script, font ve stil kaynaklarını kullandığını belirleyin (Google Fonts, analitik araçları, ödeme sağlayıcıları, sohbet widget’ları vb.).
  2. Önce Report-Only modda başlayın: Politikayı doğrudan uygulamak yerine önce sadece ihlalleri raporlayan modda test edin.
  3. Bir hafta boyunca ihlal raporlarını izleyin: Meşru kaynakların yanlışlıkla engellenip engellenmediğini kontrol edin.
  4. Politikayı sıkılaştırıp enforce moduna geçin: Test sonuçlarına göre politikayı güncelleyip gerçek uygulamaya alın.
  5. Düzenli olarak gözden geçirin: Yeni bir eklenti veya entegrasyon eklediğinizde CSP politikasını güncellemeyi unutmayın.

Yöntem 1: .htaccess Üzerinden (Apache Sunucularda)

Paylaşımlı hosting kullanan çoğu WordPress sitesi Apache tabanlı çalışır. Bu durumda CSP başlığını .htaccess dosyasına ekleyebilirsiniz:

<IfModule mod_headers.c>
    Header always set Content-Security-Policy-Report-Only "default-src 'self'; \
    script-src 'self' https://www.google-analytics.com; \
    style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; \
    font-src 'self' https://fonts.gstatic.com; \
    img-src 'self' data: https:; \
    frame-ancestors 'self'"
</IfModule>

Bu yöntemin avantajı eklenti gerektirmemesi; dezavantajı ise her değişiklikte dosyaya doğrudan erişim gerektirmesi ve hatalı bir düzenlemenin siteyi geçici olarak bozabilmesi.

Yöntem 2: functions.php Üzerinden (PHP ile)

Tema veya bir site-özel eklenti üzerinden CSP başlığını PHP ile de gönderebilirsiniz:

<?php
add_action('send_headers', function () {
    if (!is_admin()) {
        header("Content-Security-Policy-Report-Only: default-src 'self'; " .
               "script-src 'self' https://www.google-analytics.com; " .
               "style-src 'self' 'unsafe-inline'; " .
               "img-src 'self' data: https:; " .
               "frame-ancestors 'self'");
    }
});

Bu yaklaşım, politikayı koşullu olarak (örneğin yalnızca belirli sayfa türlerinde) uygulamak isteyenler için daha esnek bir kontrol sağlar. is_admin() kontrolü, yönetim panelinin farklı script ihtiyaçları nedeniyle kısıtlanmasını önlemek için ekleniyor; admin paneli için ayrı ve daha gevşek bir politika düşünebilirsiniz.

Yöntem 3: Güvenlik Eklentisi Üzerinden

Kod ile uğraşmak istemiyorsanız, CSP başlığı yönetimini açıkça destekleyen bir eklenti seçin; her güvenlik eklentisi bu özelliği sunmaz. Bu yöntem teknik bilgi gerektirmez ama genelde daha az granüler kontrol sağlar; büyük ölçekli veya çok sayıda üçüncü taraf entegrasyonu olan siteler için manuel yapılandırma genellikle daha sürdürülebilir sonuç verir.

Yöntem 4: CDN veya Reverse Proxy Seviyesinde

Cloudflare gibi bir CDN/reverse proxy kullanıyorsanız, CSP başlığını sunucunuza hiç dokunmadan CDN katmanında da ekleyebilirsiniz. Bu yaklaşım, özellikle birden fazla sunucuya veya mikroservise sahip kurumsal kurulumlarda, politikayı tek bir merkezi noktadan yönetmeyi sağlar. Örneğin bir kenar (edge) fonksiyonu üzerinden şu şekilde bir yapılandırma tanımlanabilir:

addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request));
});

async function handleRequest(request) {
  const response = await fetch(request);
  const newHeaders = new Headers(response.headers);
  newHeaders.set(
    'Content-Security-Policy-Report-Only',
    "default-src 'self'; script-src 'self' https://www.google-analytics.com; " +
    "style-src 'self' 'unsafe-inline'; frame-ancestors 'self'"
  );
  return new Response(response.body, {
    status: response.status,
    headers: newHeaders,
  });
}

Bu yöntemin avantajı, WordPress kurulumunuzdan tamamen bağımsız çalışması ve birden fazla origin sunucusu için tek bir noktadan yönetilebilmesi; dezavantajı ise CDN/edge fonksiyon yazımı konusunda ek teknik bilgi gerektirmesi.

CSP İhlal Raporlarını Nasıl Okumalı?

Report-Only modunda topladığınız ihlal raporları, tarayıcı geliştirici konsolunda veya report-uri/report-to direktifiyle belirttiğiniz uç noktada JSON formatında görünür. Tipik bir rapor, engellenen kaynağın adresini (blocked-uri), hangi direktifin ihlal edildiğini (violated-directive) ve ihlalin gerçekleştiği sayfayı (document-uri) içerir. Bu bilgiler, politikanızı iyileştirirken hangi alan adını ekleyip eklemeyeceğinize karar vermenizde doğrudan yol gösterici olur. Pratikte raporları birkaç gün topladıktan sonra, sık tekrar eden ve gerçekten meşru olan alan adlarını politikanıza ekleyip, tanımadığınız veya şüpheli adresleri ise kasıtlı olarak dışarıda bırakmanız öneriliyor; ikinci grup genellikle tarayıcı eklentileri veya (daha nadiren) kötü amaçlı enjeksiyon girişimleri kaynaklı çıkıyor.

Report-Only Modu ile Güvenli Test Etme

CSP’yi doğrudan zorunlu kılmadan önce Content-Security-Policy-Report-Only başlığını kullanarak test etmeniz şiddetle öneriliyor. Bu modda tarayıcı hiçbir kaynağı engellemez, sadece ihlalleri konsola ve (yapılandırılmışsa) belirttiğiniz bir uç noktaya raporlar:

Header set Content-Security-Policy-Report-Only "default-src 'self'; report-uri /csp-report-endpoint/"

Bu sayede politikanızın sitenizi bozup bozmadığını, ziyaretçileri etkilemeden önceden görebilirsiniz. Özellikle WooCommerce gibi ödeme sağlayıcısı script’lerine bağımlı sitelerde bu test aşaması hayati önem taşıyor; daha önce yayınladığımız WooCommerce güvenliği rehberinde de üçüncü taraf ödeme entegrasyonlarının dikkatli yönetilmesi gerektiğine değinmiştik.

Kurulum Yöntemlerinin Karşılaştırması

Yöntem Teknik Bilgi Gereksinimi Esneklik Uygun Olduğu Durum
.htaccess Orta Orta Apache tabanlı paylaşımlı hosting
functions.php Orta-Yüksek Yüksek (koşullu politika mümkün) Özel gereksinimleri olan siteler
Güvenlik eklentisi Düşük Düşük-Orta Teknik bilgisi sınırlı site sahipleri
CDN/Reverse proxy seviyesi Yüksek Yüksek Yüksek trafikli, CDN kullanan kurumsal siteler

Sık Yapılan Hatalar ve Çözümleri

CSP kurulumu teoride basit görünse de, pratikte birçok WordPress sitesinde ilk denemede sorun çıkarıyor. Aşağıdaki hatalar, en sık karşılaşılan ve genellikle site sahiplerinin CSP’yi tamamen terk etmesine yol açan durumlar:

1. Politikayı doğrudan enforce modunda başlatmak

Sorun: Report-Only aşamasını atlayıp doğrudan zorunlu politikayı uygulamak, meşru script’lerin engellenmesine ve sitenin görsel olarak bozulmasına (stillerin yüklenmemesi, form gönderiminin çalışmaması gibi) yol açabilir.

Çözüm: Her zaman önce Report-Only modda en az birkaç gün test edin.

2. Ödeme ve form sağlayıcılarını unutmak

Sorun: WooCommerce ödeme sağlayıcıları, reCAPTCHA veya harita widget’ları gibi kritik üçüncü taraf script’ler CSP listesine eklenmezse, checkout süreci veya form gönderimi sessizce bozulabilir.

Çözüm: Kurulum öncesi sitenizdeki tüm form ve ödeme akışlarını uçtan uca test edip kullanılan tüm alan adlarını listeleyin.

3. ‘unsafe-inline’ ve ‘unsafe-eval’ değerlerini gerekli olmadan bırakmak

Sorun: Bu değerler CSP’nin XSS koruma gücünü büyük ölçüde zayıflatır; birçok WordPress teması ve eklentisi varsayılan olarak satır içi script veya stil kullandığı için bu değerler “kolay çözüm” olarak eklenip hiç kaldırılmıyor.

Çözüm: Mümkünse satır içi script ve stilleri harici dosyalara taşıyın; taşınamayan durumlarda nonce veya hash tabanlı CSP yaklaşımlarını değerlendirin.

4. CSP başlığını yalnızca ana sayfada test edip diğer sayfa türlerini atlamak

Sorun: Blog yazısı, ürün sayfası, sepet ve ödeme sayfası gibi farklı sayfa türleri farklı script’ler yükleyebilir; sadece ana sayfada test etmek eksik bir doğrulama sağlar. Özellikle WooCommerce mağazalarında ödeme sayfası, ana sayfadan tamamen farklı üçüncü taraf script’ler (ödeme sağlayıcı SDK’ları, dolandırıcılık tespit araçları) yükleyebiliyor.

Çözüm: Sitenizin farklı sayfa şablonlarının her birini Report-Only modunda ayrı ayrı test edin; özellikle ödeme ve form içeren sayfalara öncelik verin.

5. CSP’yi bir kez kurup bir daha hiç güncellememek

Sorun: Yeni bir eklenti, analitik aracı veya widget eklendiğinde CSP politikası güncellenmezse, ya yeni özellik çalışmaz ya da site sahibi CSP’yi tamamen devre dışı bırakma yoluna gider.

Çözüm: Yeni bir üçüncü taraf entegrasyon eklediğinizde CSP politikasını gözden geçirmeyi standart yayın öncesi kontrol listenize dahil edin.

Nonce Tabanlı CSP: ‘unsafe-inline’ Olmadan Satır İçi Script Kullanmak

WordPress temalarının ve eklentilerinin büyük bölümü, sayfaya doğrudan satır içi (<script>...</script>) kod yerleştirir. Bu tür kodlar, 'unsafe-inline' değeri politikadan çıkarıldığında çalışmayı durdurur. Bu sorunu çözmenin daha güvenli yolu, her sayfa isteğinde benzersiz bir “nonce” (rastgele token) üretip hem CSP başlığına hem de ilgili script etiketine eklemektir:

<?php
add_action('send_headers', function () {
    if (!is_admin()) {
        $nonce = base64_encode(random_bytes(16));
        // Nonce degerini global olarak saklayip sablon icinde tekrar kullanabilirsiniz
        define('CSP_NONCE', $nonce);
        header("Content-Security-Policy-Report-Only: default-src 'self'; " .
               "script-src 'self' 'nonce-{$nonce}'; " .
               "style-src 'self' 'unsafe-inline'");
    }
});

// Sablon dosyasinda ilgili script etiketine ayni nonce degeri eklenir:
// <script nonce="<?php echo CSP_NONCE; ?>">...</script>

Nonce örneği başlangıç içindir; WordPress’in ürettiği bütün gerekli inline script etiketlerine aynı yanıtın nonce’u eklenmelidir. Başlık ve HTML birlikte güncellenmelidir. Tam sayfa önbelleğinde eski nonce’u tekrar sunmak güvenlik amacını zayıflatır; sonradan JavaScript ile rastgele nonce eklemek de başlıktaki değeri kendiliğinden değiştirmez. Önbellek uyumlu hash politikası veya yanıt anında eşleşen başlık/HTML üreten bir yaklaşım planlayın.

CSP Diğer Güvenlik Başlıklarıyla Nasıl Tamamlanır?

CSP tek başına yeterli bir güvenlik stratejisi değil; diğer HTTP güvenlik başlıklarıyla birlikte kullanıldığında daha güçlü bir savunma oluşturuyor. Strict-Transport-Security (HSTS) bağlantıların her zaman HTTPS üzerinden yapılmasını zorunlu kılar, X-Frame-Options clickjacking koruması için CSP’nin frame-ancestors direktifini tamamlar, X-Content-Type-Options: nosniff ise tarayıcının dosya türünü yanlış tahmin etmesini önler. Kapsamlı bir güvenlik sertleştirmesi için daha önce yayınladığımız WordPress güvenlik sertleştirme kontrol listesini de incelemenizi öneririz.

Sonuç: CSP Kimin İçin Uygun?

Content Security Policy, özellikle üçüncü taraf entegrasyonu yoğun olan WooCommerce mağazaları, kullanıcı içeriği kabul eden topluluk siteleri ve kurumsal WordPress kurulumları için önemli bir ek güvenlik katmanı sağlıyor. Basit bir blog işletiyorsanız ve az sayıda güvenilir eklenti kullanıyorsanız, CSP’nin getirisi daha sınırlı olabilir; yine de temel bir default-src 'self' politikası bile ek bir güvenlik ağı oluşturur. Kurulum sürecinin en kritik adımı, politikayı asla doğrudan enforce modunda başlatmamak ve Report-Only aşamasını atlamamaktır; bu adım atlanmadığı sürece CSP, sitenizi bozmadan güvenliğinizi artırabilecek pratik ve düşük maliyetli bir önlem olarak öne çıkıyor. Küçük bir blogdan büyük bir WooCommerce mağazasına kadar her ölçekteki site için, en azından temel bir default-src 'self' politikasıyla başlayıp zamanla daha sıkı hale getirmek, hem uygulanabilir hem de sürdürülebilir bir yol haritası sunuyor.

Sık Sorulan Sorular

Content Security Policy WordPress sitemi yavaşlatır mı?

Hayır, CSP bir HTTP başlığı olduğu için sayfa performansına ölçülebilir bir yük getirmez. Tarayıcı, başlığı yalnızca kaynak yükleme kararlarında referans olarak kullanır; sayfa yükleme hızını veya sunucu tarafındaki işlem süresini pratik anlamda etkilemez.

CSP kurduktan sonra sitem bozulursa ne yapmalıyım?

Öncelikle tarayıcı konsolunu açıp hangi kaynağın engellendiğini görün, ardından ilgili alan adını politikanıza ekleyin. Bu nedenle kurulumu her zaman Report-Only modunda test etmeniz önerilir; böylece sorunları ziyaretçiler etkilenmeden tespit edebilirsiniz.

Ücretsiz bir güvenlik eklentisi CSP kurmak için yeterli mi?

Eklentinin CSP desteğini ve mevcut yanıt başlıklarıyla etkileşimini doğrulayın. Birden fazla zorunlu CSP politikası birbiriyle birleşerek kaynakları daha fazla kısıtlayabilir. Kurulum sonunda giriş, form, sepet ve ödeme akışlarını test edin.

CSP tüm güvenlik açıklarını kapatır mı?

Hayır. CSP, özellikle XSS ve bazı tedarik zinciri saldırı senaryolarına karşı güçlü bir ek katmandır, ancak SQL enjeksiyonu, zayıf parolalar veya güncel olmayan eklentiler gibi diğer güvenlik risklerine karşı tek başına koruma sağlamaz; kapsamlı bir güvenlik stratejisinin yalnızca bir parçası olarak değerlendirilmelidir. Düzenli eklenti güncellemeleri, güçlü parola politikaları ve yetkilendirme kontrolleri gibi diğer temel önlemlerle birlikte kullanıldığında en etkili sonucu verir.

nonce tabanlı CSP nedir, ne zaman kullanılır?

Nonce (number used once), her sayfa yüklemesinde rastgele üretilen ve yalnızca o istekte geçerli olan bir belirteçtir. Satır içi script kullanmak zorunda olduğunuz durumlarda, 'unsafe-inline' yerine nonce tabanlı bir yaklaşım kullanmak, güvenliği önemli ölçüde artırır; ancak bu yöntem sunucu tarafında her istekte dinamik başlık üretimi gerektirdiği için statik önbellekleme kullanan sitelerde ek yapılandırma gerektirebilir.

Örnekleri Uygulama Sırası

Yukarıdaki başlık örnekleri önce Report-Only olarak verilmiştir; bu mod engellemez. Konsolu izleyin ve rapor toplamak istiyorsanız gerçekten çalışan bir alıcı kurun; /csp-report-endpoint/ WordPress’in hazır bir uç noktası değildir. Raporlar URL ve kullanıcı bilgisi içerebilir. Politikayı doğruladıktan sonra başlık adını Content-Security-Policy yaparak zorunlu uygulamaya geçin. PHP başlıkları, PHP çalışmadan sunulan önbellek yanıtlarına eklenmeyebilir.

özgür BAYRAM

Özgür Bayram, WordPress, Laravel, yapay zekâ ve web performansı alanlarında çalışan bir yazılım geliştiricisidir. Bilim Meraklısı’nda teknoloji, yazılım, hosting, SEO ve dijital araçlar hakkında anlaşılır, uygulanabilir rehberler hazırlar. Amacı, teknik konuları sade bir dille anlatarak okuyucuların doğru kararlar vermesine ve sorunlarını güvenle çözmesine yardımcı olmaktır.

İlgili Makaleler

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Başa dön tuşu