Genel

HTTP Güvenlik Başlıkları: HSTS ve CSP Rehberi

Bir güvenlik başlığı değişikliğinden sonra script’ler yüklenmiyor, bir sayfa iframe içinde açılmıyor veya tarayıcı HTTPS bağlantısını reddediyorsa önce hangi kuralın etkili olduğunu belirleyin. HTTP güvenlik başlıkları, tarayıcının bağlantı ve içerik davranışını yönlendirir; yanlış kapsam veya eksik uygulama desteği işlev kaybına yol açabilir.

Bu rehber; HSTS, CSP, X-Frame-Options ve X-Content-Type-Options başlıklarının görevlerini ve aşamalı kurulumunu anlatır. Nginx ve Apache örneklerinde kısa HSTS süresi, gözlem amaçlı CSP ve açık sunucu koşulları kullanılır. Örnek alan adlarını ve rapor hedeflerini kendi ortamınıza uyarlayıp temel kullanıcı akışlarını test edin.

HTTP güvenlik başlıkları ne yapar?

HTTP yanıt başlıkları, sunucunun içerikle birlikte istemciye gönderdiği bilgilerdir. Güvenlik başlıkları; tarayıcının HTTPS tercihini, kaynak yükleme kurallarını, sayfanın başka bir sayfaya gömülmesini ve içerik türünü nasıl değerlendireceğini etkiler. Her başlığın kapsamı ve tarayıcı desteği ayrı değerlendirilmelidir.

HSTS bir hostname için süreli HTTPS politikası tanımlar. CSP kaynakları ve belirli belge davranışlarını sınırlar. X-Frame-Options, belgenin hangi çerçevelere gömülebileceğini belirler; modern ve daha esnek karşılığı CSP frame-ancestors direktifidir. X-Content-Type-Options: nosniff ise MIME türü denetimini güçlendirir. Bu başlıklar uygulama kimlik doğrulamasının, çıktı kaçışının veya yazılım güncellemelerinin yerine geçmez.

Önce mevcut başlıkları ve uygulamanın ihtiyaçlarını kaydedin. Her değişiklik için kapsam, test ve geri alma yöntemini belirleyin; özellikle HSTS tarayıcıda saklandığı için başlığı kaldırmak hemen eski davranışa dönüş sağlamaz.

HSTS: Süreli HTTPS politikası

HSTS, HTTP Strict Transport Security mekanizmasıdır ve Strict-Transport-Security yanıt başlığıyla duyurulur. Destekleyen tarayıcı, hatasız HTTPS bağlantısından aldığı politikayı max-age süresince uygular ve ilgili HTTP isteklerini HTTPS’e yükseltir. Politika öğrenilmeden önceki ilk bağlantı farklıdır; HSTS bütün harici kaynakların mixed content sorununu düzeltmez ve proxy ile origin arasındaki bağlantıyı şifrelemez.

max-age saniye cinsinden süreyi belirler. Çalışan HTTPS ve sertifika yenilemesi doğrulandıktan sonra kısa süreyle başlayın. includeSubDomains, iç veya test amaçlı olanlar dahil alt alanlara da uygulanır; bunlar hazır değilse eklemeyin. Politika etkinken sertifika hatası bağlantıyı durdurur. Yeni geçerli başlık süreyi yeniler; başlığı göndermeyi bırakmak mevcut kayıtlı süreyi hemen silmez.

HSTS nasıl eklenir?

Nginx: Bu satırı HTTPS sunucu bloğuna ekleyin. 300 saniyelik örnek yalnızca mevcut hostname içindir; alt alanları veya preload’u kapsamaz. always, hata yanıtları dahil başlığın eklenmesini sağlar.

add_header Strict-Transport-Security "max-age=300" always;

Apache 2.4: mod_headers etkin olmalıdır. Aşağıdaki koşul, TLS doğrudan Apache’de sonlandığında HSTS’i yalnızca HTTPS yanıtına ekler. Sanal sunucu yapılandırmasında veya izin verilen .htaccess bağlamında kullanılabilir. TLS başka bir proxy’de sonlanıyorsa başlığı HTTPS’i gören güvenilen katmanda yönetin; istemcinin gönderdiği bir şema başlığına doğrudan güvenmeyin.

Header always set Strict-Transport-Security "max-age=300" "expr=%{HTTPS} == 'on'"

Preload, tarayıcıya önceden dağıtılan HSTS listesine katılmayı amaçlayan ayrı bir adımdır; başlığa preload yazmak tek başına listeye kayıt yapmaz. HSTS preload hizmetinin güncel koşullarını, tüm alt alanların HTTPS hazırlığını ve geri çıkarılma sürecini değerlendirin. Yeni kurulum için yukarıdaki kısa, hostname ile sınırlı örnekten başlayın.

HSTS tarayıcının bağlantı tercihiyle ilgilidir. Ağ erişim kuralları için güvenlik duvarı rehberine başvurabilirsiniz. TLS yapılandırması, sertifika yenilemesi ve ağ erişimi ayrı kontroller gerektirir.

CSP: Kaynak ve belge davranışını sınırlamak

Content-Security-Policy, script, stil, görsel, font ve bağlantı kaynaklarına ayrı kurallar koyabilir. Yanlış bir kural gerekli bir kaynağı engelleyebilir. Önce gerçek kaynakları ve kullanıcı akışlarını çıkarın; analitik, ödeme, kimlik doğrulama ve yönetim ekranlarını da denemeye dahil edin.

Content-Security-Policy-Report-Only, politikayı uygulamadan ihlalleri gözlemlemek için kullanılır. Raporların sunucuya ulaşması için çalışan bir toplama uç noktası ve ona bağlı raporlama direktifleri gerekir; normal erişim günlükleri CSP ihlallerini kendiliğinden içermez. Mevcut bir zorlayıcı CSP varsa Report-Only eklemek onu devre dışı bırakmaz.

Eksiksiz bir Report-Only örneği

Aşağıdakiler iki ayrı HTTP yanıt başlığıdır; Nginx veya .htaccess direktifi değildir. Örnek politika aynı origin kaynaklarını izler, inline script veya stil izni vermez. example.com ve /csp-report yerine yapılandırdığınız rapor adresini kullanın. Reporting-Endpoints ile report-to aynı adı eşleştirir; report-uri eski istemciler için geçiş desteğidir. Toplama uç noktası iki rapor biçimini de işleyebilmelidir.

Reporting-Endpoints: csp-endpoint="https://example.com/csp-report"
Content-Security-Policy-Report-Only: default-src 'self'; base-uri 'self'; object-src 'none'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-ancestors 'self'; report-to csp-endpoint; report-uri /csp-report

Inline script gerekiyorsa sabit bir nonce kopyalamayın. Her HTML yanıtında kriptografik rastgele en az 128 bitlik bir değer üretin; PHP’de örnek üretim ifadesi $nonce = base64_encode(random_bytes(16)); olabilir. Aynı değeri CSP’nin script-src nonce ifadesine ve yalnızca uygulamanın güvendiği script etiketlerinin nonce niteliğine yerleştirin. Yukarıdaki statik politikada nonce bulunmaz; bunu dinamik şablon akışıyla ayrıca tasarlamalısınız. Nonce içeren HTML ile başlık aynı yanıta ait olmalı; eski HTML’yi ortak önbellekten tekrar sunmak nonce tasarımını bozabilir.

Reporting-Endpoints: csp-endpoint="https://example.com/csp-report"
Content-Security-Policy: default-src 'self'; base-uri 'self'; object-src 'none'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-ancestors 'self'; report-to csp-endpoint; report-uri /csp-report

Üstteki ikinci örnek, kontroller tamamlandığında aynı politikanın zorlayıcı başlık adıyla gönderilmesini gösterir; ilk kurulumda bunu etkinleştirmeyin. Kaynak ve inline kod ihtiyaçlarını giderdikten sonra geçiş yapın. Ayrıntılar için MDN CSP kılavuzunu inceleyin. İkinci bir zorlayıcı CSP, ilk politikadaki yasağı gevşetmez; bütün etkin politikaların koşulları birlikte uygulanır.

Mixed content geçişi için kullanılan upgrade-insecure-requests, kapsadığı kaynakları HTTPS’e yükseltir; HTTPS başarısızsa HTTP’ye dönmez. Bunu sıradan bir Report-Only politikasının kaynakları gerçekten yükselttiği varsayımıyla kullanmayın. Eski block-all-mixed-content direktifine yeni örneklerde ihtiyaç yoktur. Protokol performansını ayrıca değerlendirmek için HTTP/3 rehberine bakabilirsiniz.

X-Frame-Options ve frame-ancestors

Clickjacking, kullanıcının başka bir sayfaya gömülen arayüzde yanıltılarak işlem yapmasına dayanabilir. X-Frame-Options ve CSP frame-ancestors, belgenizin hangi üst çerçeveler içinde açılabileceğini sınırlar. Bu kontrol, sayfanızın içine yüklediğiniz üçüncü taraf iframe’lere izin veren frame-src ile aynı değildir.

DENY her türlü çerçevelemeyi, SAMEORIGIN ise aynı origin dışındaki üst çerçeveleri engeller. Origin; şema, hostname ve port birleşimidir, yalnızca alan adı değildir. Belirli bir dış origin’e gömme izni için CSP frame-ancestors kullanın; eski ALLOW-FROM değerini kullanmayın.

Hızlı uygulama

Nginx:

add_header X-Frame-Options "SAMEORIGIN" always;

Apache / .htaccess:

Header always set X-Frame-Options "SAMEORIGIN"

Bir sayfanın harici bir uygulamaya gömülmesi gerekiyorsa o sayfanın yanıtındaki frame-ancestors kapsamını belirleyin. Destekleyen tarayıcıda zorlayıcı frame-ancestors, X-Frame-Options’ın önüne geçer; Report-Only bunu yapmaz. SAMEORIGIN başlığını korumak, eski istemcilerde dış gömmeyi engelleyebilir. Tüm üst çerçeveleri, desteklenen tarayıcıları ve o URL’ye gelen diğer CSP başlıklarını test edin; yalnızca bir istisna başlığı eklemenin yeterli olduğunu varsaymayın.

X-Content-Type-Options ve MIME türleri

X-Content-Type-Options: nosniff, tarayıcının gönderilen Content-Type değerini esas almasını sağlar. Script ve stil isteklerinde MIME türü uygun değilse kaynak engellenir. Bu başlık, bütün dosya türlerini tarayan bir güvenlik filtresi veya hatalı MIME ayarlarını düzelten bir mekanizma değildir.

Nginx için:

add_header X-Content-Type-Options "nosniff" always;

Apache / .htaccess için:

Header always set X-Content-Type-Options "nosniff"

Kaynakların doğru Content-Type ile sunulduğunu kontrol edin: CSS için text/css, JavaScript için uygun bir JavaScript MIME türü gerekir; mevcut application/javascript değeri de tanınan türlerdendir. Bir JS isteğinin aslında HTML hata sayfası veya text/plain yanıtı alması yüklemeyi bozabilir. Font sorunlarını otomatik olarak nosniff’e bağlamadan gerçek MIME, CORS ve ağ yanıtını inceleyin.

Nginx, Apache ve CDN üzerinde uygulamak

Aşağıdaki Nginx HTTPS server bloğu örneği kısa HSTS, SAMEORIGIN, nosniff ve gözlem amaçlı CSP içerir. Rapor toplama servisi ayrıca kurulmuş olmalıdır; example.com adresini değiştirin. Statik politika inline script/stil çalıştırmaya izin veren bir nonce üretmez. Varsayılan Nginx mirasında alt location kendi add_header satırını tanımlarsa üst seviyedeki başlıklar miras alınmaz; ilgili yanıtları ve varsa sürüme özgü miras ayarlarını kontrol edin.

add_header Strict-Transport-Security "max-age=300" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Reporting-Endpoints 'csp-endpoint="https://example.com/csp-report"' always;
add_header Content-Security-Policy-Report-Only "default-src 'self'; base-uri 'self'; object-src 'none'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-ancestors 'self'; report-to csp-endpoint; report-uri /csp-report" always;

Apache 2.4/mod_headers karşılığı aşağıdadır. .htaccess kullanılacaksa sunucu bu direktiflere izin vermelidir. HSTS koşulu TLS’in Apache’de sonlandığını varsayar. onsuccess unset ile always set birlikte, Apache’nin ayrı başlık tablolarında tekrarı önlemeye yardımcı olur; uygulama ve CDN katmanında da aynı başlığın sahibini netleştirin. Ek Referrer-Policy satırı, farklı origin’e giderken gönderilen yönlendiren adres bilgisini sınırlar.

Header onsuccess unset Strict-Transport-Security
Header always set Strict-Transport-Security "max-age=300" "expr=%{HTTPS} == 'on'"
Header onsuccess unset X-Frame-Options
Header always set X-Frame-Options "SAMEORIGIN"
Header onsuccess unset X-Content-Type-Options
Header always set X-Content-Type-Options "nosniff"
Header onsuccess unset Referrer-Policy
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header onsuccess unset Reporting-Endpoints
Header onsuccess unset Content-Security-Policy-Report-Only
Header always set Reporting-Endpoints "csp-endpoint=\"https://example.com/csp-report\""
Header always set Content-Security-Policy-Report-Only "default-src 'self'; base-uri 'self'; object-src 'none'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-ancestors 'self'; report-to csp-endpoint; report-uri /csp-report"

cPanel’de .htaccess erişimi ve etkin web sunucusu yapılandırması hizmete göre değişebilir. Mevcut dosyayı yedekleyin, ilgili site kökünü ve izinleri doğrulayın; yapılandırma kontrolünden sonra gerçek yanıtı inceleyin. Daha geniş sunucu bakım adımları için VPS güvenliği rehberine başvurabilirsiniz.

Cloudflare gibi bir CDN’de Response Header Transform Rules ile uygun yanıt başlıkları düzenlenebilir; kullanılabilir kuralları ve URL kapsamını kontrol edin. Set işlemi mevcut değeri değiştirir, add ise aynı adlı ikinci başlık oluşturabilir. Özellikle CSP başlıklarını kökte ve kenarda gelişigüzel çoğaltmayın. Nonce’u yalnızca başlıkta değiştiren bir kenar kuralı, HTML’deki nonce ile eşleşmeyi sağlayamaz.

Kapsam ve önbellek kontrolleri

HSTS’i HTTPS ve yenileme hazırken kısa süreyle başlatın. CSP için rapor ile gerçek kullanıcı akışlarını birlikte değerlendirin; her ihlali otomatik izin listesine eklemeyin. Gömmeye izin verilen URL’lerde frame-ancestors, X-Frame-Options ve diğer CSP politikalarının aynı sonucu hedeflediğini kontrol edin. Nonce kullanılan dinamik HTML’de yanıt ve önbellek stratejisi birlikte tasarlanmalıdır.

HTTP başlıkları trafik hacmini sınırlamaz veya DDoS saldırısını tek başına durdurmaz. Ağ ve uygulama katmanındaki kapasite/erişim kontrolleri için DDoS korunma rehberini ayrı değerlendirin.

Gerçek yanıtı ve kullanıcı akışını test etmek

Önce gerçek bir GET yanıtının başlıklarını alın. Aşağıdaki komutta örnek alanı ve yolu değiştirin. curl -I ise HEAD isteği gönderir; sunucu HEAD için farklı davranabileceğinden tek başına yeterli olmayabilir.

curl -sS -D - -o /dev/null https://example.com/

Hedef URL’lerde başarı, yönlendirme ve hata yanıtlarını; CDN kullanılıyorsa halka açık yanıtı kontrol edin. Başlık sayısını ve değerini inceleyin. Ardından tarayıcı geliştirici araçlarında kaynak yüklemelerini, CSP ihlallerini ve iframe davranışını test edin. curl yalnızca yanıtı gösterir; CSP’yi bir tarayıcı gibi uygulamaz.

Security Headers gibi taramalar, eksik veya beklenmeyen başlıkları bulmaya yardımcı olabilir. Bir puan; nonce’un doğru üretildiğini, tüm akışların çalıştığını veya sitenin bütün güvenlik gereksinimlerini karşıladığını kanıtlamaz.

Çıktı kaçışı, oturum yönetimi, bağımlılık güncellemeleri ve erişim denetimi ayrı gereksinimlerdir. Ağ katmanı için güvenlik duvarının rolünü, performans çalışmaları için HTTP/3 notlarını inceleyebilirsiniz. Başlık değişikliklerinin hız veya uyumluluk sonucu, uygulama üzerinde ölçülmelidir.

Uygulama ve bakım sırası

Önce HTTPS’i ve sertifika yenilemeyi doğrulayın. HSTS süresini kontrollü artırın; CSP kaynaklarını ve inline kod ihtiyacını gözlemleyin. X-Frame-Options veya frame-ancestors ile belgenin gömülme kapsamını, nosniff ile doğru MIME davranışını kontrol edin.

Report-Only’den zorlayıcı CSP’ye geçişi, kritik akışlar doğrulandıktan sonra yapın. Gömmeye açık sayfalardaki frame-ancestors istisnalarını ayrıca test edin. Yeni eklenti, CDN özelliği, şablon veya önbellek ayarı eklendiğinde aynı testleri tekrarlayın; geçmişte alınmış iyi bir tarama sonucu yeni yanıtları doğrulamaz.

Başlıkların hangi katmanda yönetildiğini, raporları kimin izlediğini ve değişikliklerin nasıl geri alınacağını kaydedin. Sunucu tarafındaki ek bakım adımları için VPS güvenliği rehberinden yararlanabilirsiniz.

Sıkça Sorulan Sorular

HSTS etkinken HTTPS veya sertifika doğrulaması başarısızsa tarayıcı bağlantıyı durdurabilir. Önce HTTPS ve yenileme akışını doğrulayın; kısa max-age ile başlayın ve alt alanlar hazır değilse includeSubDomains eklemeyin. Başlığı kaldırmak saklanan politikayı hemen silmez. Preload ayrı hazırlık ve kayıt gerektirir; ilk kurulum örneği olarak kullanılmamalıdır.

Kaynakları, inline kodu ve kritik kullanıcı akışlarını çıkarın. Report-Only başlığıyla gözlem yapın; sunucu raporları için çalışan uç nokta ve doğru Reporting-Endpoints/report-to eşleşmesini kurun. Nonce gerekiyorsa her HTML yanıtında kriptografik rastgele değer üretip aynı değeri yalnızca güvenilen script etiketlerine ve CSP’ye yerleştirin. Raporlar ile tarayıcı testleri doğrulandıktan sonra zorlayıcı politikaya geçin.

Sayfanın hangi origin ve üst çerçeveler tarafından gömüleceğini belirleyin. SAMEORIGIN dış origin’leri engeller; harici gömme için ilgili sayfanın zorlayıcı CSP frame-ancestors kapsamını açıkça tanımlayın. Destekleyen tarayıcıda bu direktif X-Frame-Options’ın önüne geçer, Report-Only geçmez. Eski istemciler SAMEORIGIN nedeniyle engellemeyi sürdürebilir. Diğer CSP başlıklarını ve tüm gerekli tarayıcıları birlikte test edin.
↑