Uygulamanızın güvenliğini artırmak için uygulamanızın kullanabileceği HTTP güvenlik başlıkları (ya da üstbilgileri hangisi daha Türkçe karar veremedim. İngilizcesi HTTP Security Headers) konusuna kısaca değinelim. Bunları pratik bir şekilde yaptıktan sonra, bu HTTP yanıtı üstbilgileri modern tarayıcıların kolayca önlenebilir güvenlik açıklarına girmesini engelleyebilir. Hiç bir şey olmasa da HTTP güvenlik üstbilgileri hakkında farkındalık ve kullanımı arttırır belki de. Ayrıca bu yazıda HTTP headers yerine bazen üstbilgi bazen de başlık sözcüğünü kullanılacağını belirtmem gerekiyor.
HTTP güvenlik üstbilgileri aslında Web sayfası hazırlayanlar tarafından da Web programcılığı yapan tayfa arasında da nerdeyse internetin (yani HTTP'nin) çıkışından beri iyi bilinir ve aynı derecede hor görülür. Kullanılabilirlik ve güvenlik geliştiricileri arasındaki dengeyi aramak daha makul gibi görünüyor ama uygulamanıza ekstra güvenlik sağlayabilen bu üstbilgiler sayesinde aslında web uygulamanıza işlevsellik de kazandırmış olursunuz. Ancak pratikte bu http güvenlik üstbilgileri nasıl uygulanıyor? Bunları en çok tıklanan siteler nasıl hallediyor? Büyük şirketler mi, küçükler mi kimler gibi pek çok sorunun yanıtını burada bulamayacaksınız çünkü bu başka yazı ya araştırmanın konusu.
Peki nedir bu HTTP başlıkları?
- Genel başlık: Bu başlık alanları, hem istek hem de yanıt mesajları için genel uygulanabilirliğe sahiptir.
- İstemci İsteği başlık: (Client Request-header) Bu başlık alanları yalnızca istek iletilerine uygulanabilir.
- Sunucu Yanıtı başlığı: (Server Response-header) Bu başlık alanları yalnızca yanıt mesajları için kullanılabilir.
- Varlık üstbilgisi: (Entity-header) Bu başlık alanları, varlık gövdesiyle ilgili meta bilgileri veya herhangi bir gövde yoksa, istek tarafından tanımlanan kaynak hakkında tanımlar.
Tüm HTTP başlık bilgilerini Wikipedia'dan bulabilirsiniz.
Ancak bizi ilgilendiren kısım sadece HTTP Güvenlik Başlıkları (HTTP Security Headers) kategorisinde olanlar.
HTTP Güvenlik Başlıkları derken?
Bir tarayıcı bir web sunucusundan bir sayfa istediğinde, sunucu HTTP Yanıt Başlıkları ile birlikte içerikle beraber yanıt verir. Bu başlıkların bazıları, içerik kodlama, önbellek kontrolü, durum hata kodları vb. içerik meta verileri içermektedir. Bunlarla birlikte, tarayıcınıza sitenizin içeriğiyle ilgili çalışırken nasıl davranacağını söyleyen HTTP güvenlik başlıkları da vardır. Örneğin, strict-transport-security başlığını kullanarak, tarayıcıyı yalnızca HTTPS üzerinden iletişim kurmaya zorlayabilirsiniz. Şimdi aşağıda bunları teker teker ele alalım:
X-XSS-Protection
# Apache
Header always append X-XSS-Protection 1
# Nginx
add_header X-Frame-X-XSS-Protection 1;
# IIS
<httpProtocol>
<customHeaders>
<add name="X-XSS-Protection" value="1" />
</customHeaders>
</httpProtocol>


X-Frame-Options
X-Frame-Options başlığı ile web sitenizi iframe içerisinde kimlerin çağırabileceğine izin vermek ve bunu tarayıcılara söyleyerek tıklama korumasını (clickjacking) sağlar. IE 8+, Chrome 4.1+, Firefox 3.6.9+, Opera 10.5+, Safari 4+ tarafından desteklenmektedir.
Geçerli parametreler, sitenizin herhangi bir frame içine alınamayacağı anlamına gelen DENY, sadece kendi alan adınızda (domain) sitenizi frame içine alınmasını sağlayan SAMEORIGIN veya kendi sitenizi frame içine alınmasına izin veren diğer siteleri belirtebildiğiniz ALLOW-FROM https://siteadi.com/ içerir.
# Apache
Header always append X-Frame-Options SAMEORIGIN
# Nginx
add_header X-Frame-Options SAMEORIGIN;
# IIS
<httpProtocol>
<customHeaders>
<add name="X-Frame-Options" value="SAMEORIGIN" />
</customHeaders>
</httpProtocol>
şeklindedir.
Bu düzenlemeyi IIS 7 ve sonraki sürümlerinde IIS Manager üzerinden HTTP Response Headers kısmından da yapabilirsiniz.
X-Content-Type-Options
# Apache
Header always X-Content-Type-Options nosniff
# Nginx
add_header X-Content-Type-Options nosniff;
# IIS
<httpProtocol>
<customHeaders>
<add name="X-Content-Type-Options" value="nosniff" />
</customHeaders>
</httpProtocol>
şeklindedir.
Bu düzenlemeyi IIS 7 ve sonraki sürümlerinde IIS Manager üzerinden HTTP Response Headers kısmından da yapabilirsiniz.
HTTP Strict Transport Security (HSTS)
HTTP Strict Transport Security başlığı, web tarayıcılarını yalnızca HTTPS üzerinden web sunucularına erişmeye zorlayan bir güvenlik geliştirmesidir. Bu web tarayıcılarının HTTPS olmayan bağlantılar üzerinden web sunucularına erişmesini önler (downgrade). Aynı zamanda tüm trafiği şifrelenmemiş HTTP olarak yeniden yönlendirmen MITM (Man-in-the-Middle) saldırılarının önlenmesine yardımcı olur (SSLStrip). Neredeyse tüm modern tarayıcılar -şimdiki Opera Mini ve Internet Explorer'ın önceki sürümleri dışında- HTTP Strict Transport Security desteklemektedir.
strict-transport-security: max-age=31536000; includeSubDomains; preload
HSTS'yi tüm alt etki alanlarınız için yani www.domain.com, sub.domain.com vb. gibi etkinleştirmek için IncludeSubDomains ekleyebilirsiniz.
HSTS önyüklemesini preload parametresiyle sitenizin yalnızca HTTPS olarak erişilebileceği bilgisinin bulunduğu listeye dahil etmek üzere yapılandırabilirsiniz. Düzenlemeyi yaptıktan sonra https://hstspreload.org adresinden web sitenizi girerek listeye ekletebilirsiniz.
# Apache HSTS
LoadModule headers_module modules/mod_headers.so
<VirtualHost *:443>
Header always set Strict-Transport-Security "max-age= 31536000; includeSubDomains"
</VirtualHost>
# Nginx
add_header Strict-Transport-Security max-age= 31536000; includeSubdomains
# IIS
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Strict-Transport-Security" value="max-age=31536000"/>
</customHeaders>
</httpProtocol>
</system.webServer>
şeklindedir.
HTTP Public Key Pinning (HPKP)
Public-Key-Pins başlığı, hangi sertifikaya güvendiğini tarayıcılara bildirir. Bir tarayıcı ilk defa bu başlık ile karşılaştığında, belirtilmiş olan sabitlenmiş (pinned) sertifikayı kaydeder. Bu başlık aynı zamanda , bir sertifika yetkilisinin tehlikeye girmesi durumunda sahte X.509 sertifikalarını ve MITM (Man-in-the-Middle) sahtekarlık saldırılarını önlemeye yardımcı olur.
Bu başlığı muhtemelen kullanmamalısınız (eğer yapmanız gerekiyorsa bunun için bir rehber burada). Bir çok şeyin yanlış gidebileceği riskli bir başlıktır kendileri. Biri yanlış sertifikayı işaretlerse, anahtarları kaybeder veya başka bir sorun ortaya çıkarsa, kullanıcıları bir sitenin dışından kolayca kilitleyebilir.
Mümkün olan diğer bir alternatif, sorunları bildiren ancak siteyi kilitlemeyen bir Public-Key-Pins-Report-Only başlığı olabilir. Bu şekilde sahte sertifika ihlallerinin tespit edilmesi daha kolaydır.
Bunu yapmak için report-uri (geçersiz girişimleri rapor etmek) parametresi kullanılmalıdır.
Public-Key-Pins başlığı neye benzer diyorsanız o da şöyle bir şey (değerler örnektir kullanmayın):
public-key-pins: pin-sha256="t/TMRSZLWdYUDmhOyUzS+ptUbrdVgb6Tv2R+EMLxJM="; pin-sha256="FgTGL6PvKOp6Nk3Y9B7npcpeL40twdPwZ4kA2IiixqA="; pin-sha256="De22XrPkTuoiLk/BR5FseiIV/diN3eWnSewbAIUMcn8="; pin-sha256="3dKINA/6eVxlkns5z2zWv2/vHhxGne/W0Sau/ypt3HY="; pin-sha256="MsTQT9vxVN4834AQmuFcGlSysT1ZJAxg+8N1NkNG/N8="; pin-sha256="dvti0+82AErp+MzGE7UliKxbmJ54lR/oFseQFZURy8="; max-age=518400; report-uri="https://report-uri.cloudflare.com/cdn-cgi"
Content-Security-Policy
Content-Security-Policy başlığı ek bir güvenlik katmanı sağlar. Siteniz için onaylanan içerik kaynaklarını tanımlayarak ve böylece tarayıcının bunları yüklemesine izin vererek Cross Site Scripting (XSS) ve diğer kod enjeksiyon saldırılarını önlemeye yardımcı olur.
Content-Security-Policy ile kullanabileceğiniz bir çok parametre vardır. Aşağıdaki örnek hem google-analytics.com hem de alan adınızdaki ("self" ile tanımlanmıştır) komut (script) dosyalarına izin vermektedir.
Content-Security-Policy: script-src 'self' https://www.google-analytics.com
Bir CSP'nin düzgün şekilde ayarlanması zor bir iştir. Başlangıçta yukarıdaki ya da aşağıdakiler gibi basit bir örnekle başlayabilirsiniz. İçerik politikanızı geliştirmek istediğinizde de başvuracağınız siteler:
- https://content-security-policy.com
- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
- https://developers.google.com/web/fundamentals/security/csp/
Unutmayınız ki bunlar CSP konusundaki ana referans sitelerinizdir.
# Apache
Header always set Content-Security-Policy "default-src https: data: 'unsafe-inline' 'unsafe-eval'"
# Nginx
add_header Content-Security-Policy "default-src https: data: 'unsafe-inline' 'unsafe-eval'" always;
Bu düzenlemeyi IIS 7 ve sonraki sürümlerinde IIS Manager üzerinden HTTP Response Headers kısmından yapabilirsiniz. Referrer-Policy
Bu başlığın kullanımı “isteğe bağlı” olarak kabul edilebilir, ancak tavsiye edilir.
Analiz için gayet iyidir ancak kullanıcı gizliliği için çok fazla değildir. Analitik verilerinizi özellikle rakiplerinizin gözlerinden uzak tutmak istiyorsanız uygulayın.
Örneğin no-referrer parametre değeri, tarayıcıya referrer (yönlendirici) başlığını asla sitenizden yapılan isteklerle göndermemesini bildirir. Bu, kendi sitenizdeki sayfalara bağlantılar da içerir.
Referrer-Policy: no-referrer
Referrer-Policy: için geçerli olan parametreler şunlardır:
"",
"no-referrer",
"no-referrer-when-downgrade",
"same-origin",
"origin",
"strict-origin",
"origin-when-cross-origin",
"strict-origin-when-cross-origin",
"unsafe-url"
Set-Cookie (Çerez Ayarları)
Set-Cookie ile yaptığınız çerez seçeneklerinin doğru ayarlanması, sitenizi güvenli hale getirmek açısından önemlidir. O yüzden bir güvenlik başlığı/üstbilgisi (http security header) olmamasına rağmen güvenlik kategorisinde burada bahsedilmesinde hiç bir sakınca göremiyorum.
Bilmeniz gereken üç farklı çerez (cookie) seçeneği var: Secure, HttpOnly ve SameSite.
- Secure (güvenli) çerezler yalnızca HTTPS üzerinden sunulur, böylece MITM (Man-in-the-Middle) tarayıcı yönlendirmelerinden kaçınılır.
- HttpOnly çerezlerine Javascript'ten erişilemez (XSS hatası durumunda, çerezlere saldırgan tarafından ulaşılamaz)
- SameSite çerezleri farklı bir siteye gönderilmeyecek. Bu, Cross-Origin Request Forgery (CSRF) saldırılarından korunmaya yardımcı olur (diğer siteler kullanıcıları sitenize yanlışlıkla bir istekte bulunmaya zorladıysa).
Hangi tarayıcı hangi HTTP başlığını tanır?
Yukarıda bahsedilen HTTP güvenlik başlıklarını maalesef tüm tarayıcılar özellikle eskiler başta olmak üzere desteklemiyor. Bazı başlıkların uygulaması da çok yeni olduğu için eski- bazı tarayıcılar tarafından desteklenmiyor. Peki ne yapacağım? Tüm tarayıcıların tüm sürümlerini bilgisayarıma kurup test mi edeceğim diyorsanız yanılıyorsunuz. Sizin için bunu yapan bir site var. Mesela HSTS başlığına hangi tarayıcılar destek atıyor, bunu öğrenmek için:
https://caniuse.com/#search=hsts
gidiyorsunuz ve size bir matris olarak gösteriyor (yatay hizada tarayıcılar ve dikey olarak sürümleri bulunmakta, yeşil alanlar evet biat ediyorum anlamında kırmızı alanlar ise hayır henüz değil).
Ayrıca site içinde arama yaparak her başlığı sorgulayabiliyorsunuz.
Düzenlediğimiz başlıkları nasıl test ediyoruz?
Şöyle. Bunu hakkını vererek yapan bir kaç site var. Bunlara gidip sitenizin URL adresini (https://siteadi.com) yazıyorsunuz ve onlar gerekenleri söylüyor. İşte sıralı liste
Bu kadarı kafidir.
Netice
HTTP güvenlik başlıkları/üstbilgileri, web sitenizin güvenliğini sıkılaştırmanın ucuz ve pratik bir yoludur. Bunları kullanmamanız için geçerli bir senaryonuz olamaz. Güvenlik başlıklarınızı doğru bir şekilde ayarlayarak, yalnızca sitenizi korumanıza değil, aynı zamanda kullanıcılarınızın da korunmasına yardımcı olursunuz. Bu ayrıca güvenlik hatalarını azaltmanıza ve bunları izlemenize ve sabitlemenize harcanan çalışma saatlerine yardımcı olacaktır.
Güvenlik başlıklarını doğru şekilde belirlemek ve güncel tutmak, gelecekte ihtiyaç duyulan risk azaltma işlerinizi de büyük ölçüde azaltacaktır. Umarım, bu yazı en azından bu konulara giriş babında size yardımcı olacaktır.


