HTTP güvenlik başlıkları neden bu kadar konuşuluyor?
Son birkaç yılda yaptığım güvenlik denetimlerinin neredeyse tamamında aynı tabloyla karşılaştım: SSL sertifikası var, temel güncellemeler yapılmış, ama HTTP güvenlik başlıkları tamamen yok sayılmış durumda. Özellikle WordPress, WooCommerce veya özel yazılım projelerinde, uygulama tarafında güvenliğe epey emek verilirken, tarayıcıya gönderilen güvenlik talimatları atlanıyor. Sonuç: XSS, clickjacking, veri sızıntısı gibi birçok saldırı için kapı aralık kalıyor.
HTTP güvenlik başlıkları (HTTP Security Headers), tarayıcıya “Bu siteyle nasıl davranman gerektiğini” anlatan ek kurallar seti gibi düşünebilirsiniz. Basit birkaç satır konfigürasyonla, saldırganın işini ciddi anlamda zorlaştırabiliyorsunuz. Güzel tarafı, bu başlıklar uygulama koduna dokunmadan, sadece web sunucusu (cPanel/Apache, Nginx vb.) üzerinden yönetilebiliyor.
Bu yazıda, hem teorik tarafı netleştireceğim hem de pratik olarak cPanel (Apache/LiteSpeed) ve Nginx üzerinde adım adım nasıl uygulayabileceğinizi göstereceğim. Eğer sitenizde zaten HTTPS kullanıyorsanız ve örneğin HTTP’den HTTPS’ye geçiş rehberindeki adımları uyguladıysanız, bu yazı o çalışmanın güvenlik tarafını tamamlayıcı bir adım olacak.
HTTP güvenlik başlıkları nedir?
HTTP güvenlik başlıkları, HTTP cevabında (response) yer alan ve tarayıcıya ek güvenlik politikaları bildiren özel header alanlarıdır. Örneğin bir sayfa çağırdığınızda tarayıcı şu tür yanıtlar alır:
HTTP/2 200 OK
content-type: text/html; charset=UTF-8
server: nginx
...
Biz bu cevaba şu tip ekstra satırlar ekliyoruz:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Content-Security-Policy: default-src 'self';
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: geolocation=(), camera=()
Bu başlıklar sayesinde tarayıcı:
- Sadece HTTPS üzerinden bağlanmasına (HSTS) zorlanıyor,
- Sayfanın başka sitelerde iframe ile gömülmesini engelliyor (clickjacking koruması),
- Yanlış içerik tipini tahmin etmeye çalışmıyor (MIME sniffing engeli),
- Hangi dış kaynaklardan JS, CSS, font, görsel yüklenebileceğini biliyor (CSP),
- Konum, kamera, mikrofon gibi izinlerin kimlere verileceğini biliyor (Permissions-Policy).
Yani tek tek uygulama tarafında kontrol etmeniz gereken bir sürü senaryoyu, tarayıcıya merkezi bir politika olarak tanımlamış oluyorsunuz.
En kritik HTTP güvenlik başlıkları ve ne işe yaradıkları
Strict-Transport-Security (HSTS)
Strict-Transport-Security, sitenize sadece HTTPS üzerinden erişilmesini zorlayan başlıktır. Tarayıcıya şu mesajı verir: “Bu alan adını şu süre boyunca sadece HTTPS ile ziyaret et, HTTP istekleri gelirse otomatik olarak HTTPS’e çevir.”
Örnek:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
- max-age: Saniye cinsinden süre (31536000 ≈ 1 yıl).
- includeSubDomains: Tüm alt alan adlarını da kapsa.
- preload: Tarayıcıların HSTS preload listesine alınmak için kullanılır (daha ileri seviye).
Bu başlık, HTTP → HTTPS yönlendirmelerinde ortadaki adam (MITM) saldırılarını zorlaştırdığı için özellikle önemli. Zaten HTTP/HTTPS geçişine odaklandıysanız, yukarıda link verdiğim SEO kaybı olmadan HTTPS’e geçiş rehberi ile birlikte mutlaka kullanmanızı öneririm.
Content-Security-Policy (CSP)
Content-Security-Policy, XSS (Cross-Site Scripting) ve veri enjeksiyonu saldırılarına karşı en güçlü araçlardan biri. Temel mantığı şu: “Bu sayfa sadece şu kaynaklardan JS, CSS, resim, font, iframe vb. yükleyebilir.”
Basit bir örnek politika:
Content-Security-Policy: default-src 'self'; img-src 'self' https: data:; script-src 'self'; style-src 'self' 'unsafe-inline';
- default-src ‘self’: Varsayılan olarak sadece kendi alan adından kaynaklara izin ver.
- img-src: Görseller için kendi alan adın + tüm HTTPS kaynakları + data URI’leri.
- script-src: Sadece kendi alan adından JS.
- style-src: Kendi alan adından CSS, ayrıca inline stil (mecbur kaldığımız senaryolarda).
CSP, yanlış yazıldığında siteyi kırabilecek kadar güçlü; bu yüzden önce report-only modda test etmenizi tavsiye ederim. Aşağıda konfigürasyonda nasıl yapacağımızı göstereceğim.
X-Frame-Options
X-Frame-Options, sitenizin başka sitelere iframe ile gömülmesini sınırlar. Clickjacking saldırılarına karşı temel savunmalardan biridir.
En yaygın iki kullanım:
X-Frame-Options: SAMEORIGIN
X-Frame-Options: DENY
- SAMEORIGIN: Sadece aynı alan adı iframe ile gömebilir.
- DENY: Hiçbir şekilde iframe ile gömülmesin.
Eğer ödeme sayfası gibi kritik bir alanınız varsa, en azından bu sayfalar için DENY kullanmak mantıklı olabilir.
X-Content-Type-Options
X-Content-Type-Options: nosniff, tarayıcının içerik tipini “tahmin etmeye” çalışmasını engeller. Örneğin bir JS dosyası yanlışlıkla text/plain ile gönderilirse, tarayıcı bunu JS olarak çalıştırmaya zorlamaz. Bu da bazı saldırı senaryolarını engeller.
X-Content-Type-Options: nosniff
Bu başlık basit, risksiz ve neredeyse tüm projelerde varsayılan olarak açılması gereken bir ayar.
Referrer-Policy
Referrer-Policy, kullanıcı başka bir siteye geçtiğinde, gönderilecek referer bilgisinin ne kadar detaylı olacağını kontrol eder. Varsayılan davranış çoğu zaman gereksiz veri sızıntısına yol açabilir.
Referrer-Policy: strict-origin-when-cross-origin
Bu değerle:
- Aynı origin içindeki isteklerde tam URL paylaşılır,
- Farklı domainlere giderken sadece origin (örn: https://site.com) gönderilir, tam path gizlenir.
Özellikle e-ticaret, üyelik sistemleri, ödeme sayfaları gibi hassas URL’ler kullanan projelerde önemli.
Permissions-Policy (eski adıyla Feature-Policy)
Permissions-Policy, tarayıcının kamera, mikrofon, geolocation, payment API gibi gelişmiş özellikleri hangi siteler için açıp açmayacağını belirler.
Permissions-Policy: geolocation=(), camera=(), microphone=()
Bu örnekte tüm domainler için konum, kamera ve mikrofon tamamen kapatılmış olur. Eğer özel bir alt alanda (örneğin video konferans uygulaması) gerekiyorsa, sadece o origin’e açabilirsiniz.
X-XSS-Protection (artık önerilmez ama hâlâ karşımıza çıkıyor)
X-XSS-Protection, eski tarayıcılardaki dahili XSS filtrelerini açıp kapatmaya yarıyordu. Modern tarayıcıların çoğu bu başlığı görmezden geliyor veya zaten kendi korumalarını kullanıyor. Yeni projelerde zorunlu değil; esas odaklanmanız gereken başlık CSP olmalı. Yine de eski uygulamalarla uyum için şu şekilde görebilirsiniz:
X-XSS-Protection: 1; mode=block
HTTP güvenlik başlıklarını nasıl test edersiniz?
Konfigürasyona geçmeden önce mevcut durumunuzu görmek iyi bir fikir. En pratik yöntemler:
- Tarayıcı geliştirici araçları (Network sekmesi → Response Headers),
curl -I https://alanadiniz.comkomutuyla header’ları görmek,- Online test araçları (HTTP security headers checker vb.; marka vermeden aratabilirsiniz).
Zaten güvenlik tarafına ilginiz varsa, mutlaka bir göz atmanızı tavsiye ettiğim web hosting güvenliği için öneriler yazısındaki kontrollerle birlikte bu testleri rutin hale getirebilirsiniz.
cPanel (Apache / LiteSpeed) üzerinde HTTP güvenlik başlıkları konfigürasyonu
cPanel kullanan çoğu hosting ortamında web sunucusu olarak Apache veya LiteSpeed bulunur. İkisi de .htaccess dosyası üzerinden header yönetimine izin verir. Aşağıdaki adımlar Paylaşımlı hosting, reseller veya DCHost gibi bir sağlayıcı üzerinde kendi VPS’inizi yönetirken benzer şekilde geçerli olacaktır.
.htaccess ile güvenlik başlıkları ekleme
1. cPanel’e giriş yapın.
2. File Manager (Dosya Yöneticisi) bölümüne gidin.
3. Web sitenizin kök dizinine (genelde public_html) girin.
4. .htaccess dosyasını bulun. Yoksa oluşturun.
5. Dosyanın en üstüne veya uygun bir yerine aşağıdaki satırları ekleyin:
<IfModule mod_headers.c> Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" Header set X-Content-Type-Options "nosniff" Header set X-Frame-Options "SAMEORIGIN" Header set Referrer-Policy "strict-origin-when-cross-origin" Header set Permissions-Policy "geolocation=(), camera=(), microphone=()" # Basit bir CSP örneği (önce test edin!) Header set Content-Security-Policy "default-src 'self'; img-src 'self' https: data:; script-src 'self'; style-src 'self' 'unsafe-inline'; font-src 'self' data:; frame-ancestors 'self';"
</IfModule>
6. Dosyayı kaydedin ve sitenizi yenileyin.
7. curl -I veya tarayıcı geliştirici araçlarından başlıkların gelip gelmediğini kontrol edin.
Eğer sitenizde çok sayıda üçüncü parti JS (analitik, reklam, CDN, chatbot vb.) kullanıyorsanız, CSP’yi muhtemelen özelleştirmeniz gerekecek. Özellikle WooCommerce veya yoğun JS kullanan siteler için daha önce paylaştığım WooCommerce için sunucu ayarları rehberi ile beraber bu konfigurasyonu gözden geçirebilirsiniz.
cPanel arayüzü üzerinden Apache Global konfigürasyonu (root yetkisi olanlar için)
Eğer kendi VPS veya Dedicated Sunucunuzu yönetiyorsanız ve WHM/cPanel root erişiminiz varsa, bu başlıkları global seviyede de uygulayabilirsiniz:
- WHM → Service Configuration → Apache Configuration → Global Configuration altında ek parametreler,
- Veya
httpd.conf/includesdosyalarınaHeader setdirektifleri ekleyerek.
Ancak bu yöntem tüm siteleri etkiler. Farklı projelerin farklı CSP gereksinimleri olabileceği için, genelde sadece temel başlıkları (HSTS, X-Content-Type-Options, X-Frame-Options, Referrer-Policy) globalde; CSP’yi ise site bazlı .htaccess ile yönetmeyi tercih ediyorum.
Nginx üzerinde HTTP güvenlik başlıkları konfigürasyonu
Nginx tarafında yapı Apache’den biraz farklı. .htaccess yok; ayarları doğrudan site konfigürasyon dosyanıza ekliyorsunuz. Genelde şu yollar altında olur:
/etc/nginx/sites-available/alanadiniz.conf- Veya bazı panellerde (örn. kendi geliştirilmiş paneller) özel yollar.
Örnek bir Nginx sanal host (server block) içinde güvenlik başlıkları şu şekilde tanımlanabilir:
server { listen 443 ssl http2; server_name alanadiniz.com www.alanadiniz.com; # SSL ayarları burada... add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; add_header X-Content-Type-Options "nosniff" always; add_header X-Frame-Options "SAMEORIGIN" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; add_header Permissions-Policy "geolocation=(), camera=(), microphone=()" always; # CSP - önce report-only ile test etmeniz tavsiye edilir add_header Content-Security-Policy "default-src 'self'; img-src 'self' https: data:; script-src 'self'; style-src 'self' 'unsafe-inline'; font-src 'self' data:; frame-ancestors 'self';" always; root /var/www/alanadiniz.com/public; index index.php index.html index.htm; # Diğer Nginx / PHP-FPM ayarları...
}
Değişiklik sonrası:
nginx -t
systemctl reload nginx
komutlarıyla konfigürasyonu test edip Nginx’i yeniden yüklemeyi unutmayın.
CSP’yi Nginx’te güvenli şekilde test etmek
CSP en çok sorun çıkaran başlık olduğu için, gerçek ortamda genelde şu yaklaşımı kullanıyorum:
- Önce Content-Security-Policy-Report-Only başlığını ekliyorum.
- Tarayıcı konsolunda ve loglarda nelerin engelleneceğini gözlüyorum.
- Gerekli domain ve kaynak tiplerini whitelist’leyip, sorun kalmayınca gerçek CSP’ye geçiyorum.
Örnek report-only kullanım:
add_header Content-Security-Policy-Report-Only "default-src 'self'; img-src 'self' https: data:; script-src 'self'; style-src 'self' 'unsafe-inline';" always;
Bir süre bu modda çalıştırıp, beklenmeyen engellemeleri çözdükten sonra Content-Security-Policy başlığına geçmek, canlı sitede “tema bozuldu, script çalışmıyor” sürprizlerini büyük ölçüde engelliyor.
Performans, SEO ve uyumluluk açısından dikkat edilmesi gerekenler
HTTP güvenlik başlıkları doğrudan performansı artırmaz; ancak dolaylı olarak birkaç faydası var:
- HSTS ile tarayıcı doğrudan HTTPS’e gittiği için, HTTP → HTTPS yönlendirme turu azalır.
- Güvenlik skorunuz yükseldiği için, özellikle e-ticaret projelerinde kullanıcı güveni artar.
- Arama motorları güvenli siteleri tercih etme eğiliminde; SSL, HSTS, güvenlik pratikleri uzun vadede SEO’ya pozitif etki eder.
SEO tarafında, özellikle HTTPS ve SSL konularına meraklıysanız, ücretsiz Let’s Encrypt mi, ücretli SSL mi? yazısında bu konunun arka planını detaylı anlatmıştım. Oradaki yaklaşımı, bu güvenlik başlıklarıyla birlikte düşünmek çok mantıklı.
Uyumluluk tarafında ise:
- Eski tarayıcılar bazı başlıkları (özellikle CSP, Permissions-Policy) yok sayabilir; bu genelde sorun değildir.
- CSP’de üçüncü parti script/font/CDN kullanan sitelerde mutlaka kademeli ilerleyin.
- HSTS preload özelliğini açmadan önce tüm alt alan adlarınızın sorunsuz HTTPS verdiğinden emin olun; aksi halde kendinizi kilitleyebilirsiniz.
Gerçek senaryolar: Neyi, nereden başlatmalı?
Benim pratikte izlediğim yol genelde şöyle oluyor:
- Önce sitenin genel bir güvenlik durumunu çıkarıyorum (açık portlar, güncellemeler, SSH, panel erişimleri, SSL durumu). Bu kısım için VPS sunucu güvenliği rehberinde adım adım bir çerçeve paylaştım.
- HTTPS zorunlu hale getirilmemişse, SSL + HTTP → HTTPS yönlendirmelerini yapıyorum. Gerekirse Let’s Encrypt ile SSL kurulum rehberindeki adımları uyguluyorum.
- Temel HTTP güvenlik başlıklarını (HSTS, X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy) ekliyorum.
- Son aşamada CSP’yi report-only ile sahaya sürüp, birkaç gün/hafta gözlemledikten sonra gerçek moda alıyorum.
Eğer kendi altyapınızı kendiniz yönetmek istiyorsanız ve tam kontrol istiyorsanız, DCHost gibi size root erişimli VPS veya Fiziksel Sunucu veren sağlayıcılar üzerinde bu adımları çok daha esnek şekilde uygulayabilirsiniz. Panel sınırlamalarına takılmadan Nginx/Apache konfigürasyon dosyalarına doğrudan erişebilmek, özellikle CSP gibi hassas ayarları yönetirken büyük rahatlık sağlıyor.
Sonuç ve sonraki adımlar
HTTP güvenlik başlıkları, çoğu zaman birkaç satır konfigürasyonla ciddi güvenlik kazanımı sağlayan, ama maalesef hala birçok projede atlanan bir konu. Özellikle “zaten SSL’imiz var” noktasında durup kalan projeler, tarayıcıya nasıl davranması gerektiğini söylemediği için gereksiz riskleri üzerinde taşımaya devam ediyor.
Bu yazıda hem en kritik başlıkları (HSTS, CSP, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy) özetledim hem de cPanel/.htaccess ve Nginx üzerinde adım adım nasıl uygulayabileceğinizi anlattım. Buradan sonrası biraz proje bağımlı: Eğer çok sayıda üçüncü parti servis kullanıyorsanız, özellikle CSP kısmını dikkatle test ederek ilerlemeniz gerekiyor. Ama temel başlıkları bugün bile devreye almanız, saldırganların işini ciddi anlamda zorlaştıracaktır.
Benim önerim, bu çalışmayı tek seferlik bir “güvenlik görevi” olarak değil, genel güvenlik stratejinizin parçası olarak görmeniz. Zaten ransomware ve benzeri saldırıların arttığı bir dönemdeyiz; daha önce yazdığım ransomware ve siber güvenlik tehditleri yazısındaki tabloyu düşününce, uygulama + sunucu + tarayıcı üçlüsünü birlikte güçlendirmek zorunlu hale geliyor.
Eğer kendi projeniz için hangi başlıklarla başlamanız gerektiğinden emin değilseniz, elinizdeki hosting/sunucu yapısını (paylaşımlı, VPS, fiziksel, DCHost vb.) ve kullandığınız yazılımı (WordPress, özel yazılım, WooCommerce, Laravel vs.) not edin; buna göre adım adım bir güvenlik checklist’i oluşturmak çok daha kolay olacaktır. İlerleyen yazılarda, farklı platformlar ve hazır script’ler için örnek CSP şablonları ve gelişmiş politika kombinasyonlarını da paylaşmayı planlıyorum.