Merhaba
Daha önceki blog yazılarında ayrı ayrı ele aldığım HTTP Security Header’larına genel olarak tekrar değinip, bu header’ların neden ve nasıl kullanılması gerektiğine göz atacağız.
Günümüz internet tarayıcıları, düşük seviye zafiyetlere ( Use after free vb ) verdikleri önem kadar, daha üst seviye aşamalar içinde güvenliğe önem vermektedir. Örneğin; internet tarayıcıları, Reflected XSS zafiyetlerini sömüren saldırganları durdurmak adınaHTM içerik üzerinde filter gerçekleştirmektedir.
Modern tarayıcıların desteklediği HTTP Security Header’ları aşağıdaki gibidir.
1 – Strict-Transport-Security
HTTP Strict Transport Security, nâmı diğer HSTS, kullanıcıların internet tarayıcılarını her talep için HTTPS kullanmaya zorlayarak downgrade adı verilen saldırılara karşı çözüm üretmek ve tüm trafiğin güvenliğini sağlamak adına güzel bir çözümdür. ( Daha detaylı bilgi için; https://www.mehmetince.net/hsts-http-strict-transport-security-ile-https-trafik-guvenligi/ )
HSTS Konfigürasyonu
HSTS’i aktif etmek için aşağıdaki satırı HTTP cevabının başlık bilgisine eklenmelidir.
Strict-Transport-Security: max-age=16070400;
Bu sayede HSTS belirlenen domain veya subdomain için HTTPS everywhere aktif hale getirilmiş olacaktır. Bazı durumlarda “Ben www.domain.com için bu tanımlamayı yapayım. Tüm subdomainler dahil HSTS default olarak gelsin.” diyebilirsiniz. Bu durumda aşağıdaki eklemenin yapılması gereklidir.
Strict-Transport-Security: max-age=16070400; includeSubDomains
HSTS Preload
Eğer sertifikanızın Chrome, Firefox gibi tarayıcılar tarafından default olarak kontrol listesinde yer almasını istiyorsanız, aşağıdaki düzenlemeyi yaptıktan sonra https://hstspreload.appspot.com adresinden web sitenizi girerek başvurunuzu ücretsiz gerçekleştirebilirsiniz.
Strict-Transport-Security: max-age=10886400; includeSubDomains; preload
NOT: max-age değerinin 6 hafta olmasını önermekteyim.
Nerede, Nasıl Kullanmalıyım ?
Domain için HTTPS hizmet verecekseniz HSTS kullanmanızı şiddetle öneriyorum.
Tüm bu HTTP başlık bilgilerini kod katmanında yapmak yerine Apache/IIS/Nginx/Tomcat vb web sunucu uygulamaları üzerinde yapmanızı öneririm.
Apache’de HSTS aktifleştirmek için;
# Apache HSTS LoadModule headers_module modules/mod_headers.so <VirtualHost *:443> Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains" </VirtualHost>
Nginx’de HSTS aktifleştirmek için;
add_header Strict-Transport-Security max-age=63072000; includeSubdomains
IIS web.config ile HSTS aktifleştirmek için
<system.webServer> <httpProtocol> <customHeaders> <add name="Strict-Transport-Security" value="max-age=31536000"/> </customHeaders> </httpProtocol> </system.webServer>
Cloudflare Kullanıcıları
Cloudflare bildiğiniz üzere Keyless SSL hizmeti ile herkes için ücretsiz HTTPS hizmet vermektedir. Bu nedenle HSTS preload için başvuru yapmadan önce sertifikanızın size ait olmadığını belirtmek isterim.
Özellikle uzun süredir beklediğim HSTS özelliğine cloudflare destek vermeye yeni başladı. Web sunucu üzerinde ki konfigurasyonlar ile boğuşmadan Cloudflare web arayüzü üzerinden preload dahil tüm HSTS özelliklerini aktif edebilirsiniz. ( Bakınız : https://blog.cloudflare.com/enforce-web-policy-with-hypertext-strict-transport-security-hsts/ )
2 – X-Frame-Options
Web uygulama güvenliği konularından bir tanesi olan Clickjacking, X-Frame-Options başlık bilgisi ile doğrudan ilişkilidir. Saldırganın kendi kontrolü altında olan web sitesi içerisinde iframe çağrısı gerçekleştiren saldırganlar, kullanıcılara istemedikleri aksiyonları aldırmaya çalışırlar.
Bu nedenle web sitemizi iframe içerisinde kimlerin çağırabileceğine karar vermek ve bu kararımızı internet tarayıcılarına belirtmek gerekmektedir.
Neden ve Nasıl Kullanmalıyım ?
Belirtmekte fayda gördüğüm bir husus ise, bu kontrolü X-Frame-Options yerine javascript ile yapılmaya çalışıldığı noktalar. Malesef bu kontroller her zaman yeterli değildir. ( Bakınız; Stanford tarafından yapılan Frame Bust saldırılarının analizi http://seclab.stanford.edu/websec/framebusting/framebust.pdf ) . Bu nedenle işi X-Frame-Options ile doğrudan internet tarayıcısına bırakmak daha akıllıca olacaktır.
X-Frame-Options’ın 3 farklı parametresi bulunmaktadır.
Deny = Sayfanın herhangi bir frame içerisinde çağırılmasını tamamiyle engelle.
SAMEORIGIN = Kendi domain’imden başka herhangi bir domainin frame içerisinde çağırmasını engelle.
ALLOW-FROM uri = Parametre olarak verilen uri adresinin iframe çağrılarını kabul et. Haricindekileri engelle.
NOT: Allow-From özelliği tüm tarayıcılar tarafından henüz desteklenmemektedir.
Benin taysiyem ise SAMEORIGIN özelliği ile kullanmaktır. Böylece farklı subdomainlerinizdeki uygulamaları birbirleri içerisinde iframe ile çağırabilirken, saldırgan kontrolü altındaki domain üzerinden çağırılmasının önüne geçilmiş olacaktır.
# Nginx için add_header X-Frame-Options SAMEORIGIN; # Apache için Header always append X-Frame-Options SAMEORIGIN # IIS için <httpProtocol> <customHeaders> <add name="X-Frame-Options" value="SAMEORIGIN" /> </customHeaders> </httpProtocol>
3 – X-XSS-Protection
Yazının girişinde verdiğim örnek, yani kullanıcıları XSS saldırılarından korumak için X-XSS-Protection başlık bilgisi kullanılmalıdır. Tabi öncelik uygulama tarafında XSS zafiyetlerini gidermek olmalıdır. Kod bazlı güvenlik sağlandıktan sonra, korumayı bir kat arttırarak internet tarayıcılarında da XSS güvenliği aktifleştirilmelidir.
Neden ve Nasıl Kullanmalıyım ?
Modern tarayıcılar, uygulama tarafından oluşturulan içerik üzerinde filtreleme gerçekleştirerek potansiyel XSS payloadlarını tespit edebilirler. Bu özelliği aktifleştirmek içinse X-XSS-Protection başlık bilgisi kullanılır.
# Nginx için add_header X-Frame-X-XSS-Protection 1; # Apache için Header always append X-XSS-Protection 1 # IIS için <httpProtocol> <customHeaders> <add name="X-XSS-Protection" value="1" /> </customHeaders> </httpProtocol>
Mode Block
Default olarak XSS saldırısı olan kod blogunun çalıştırılmasını engellenmektedir. Eğer olası tehlike durumu varsa tüm içeriğin render edilmesini engellemek isterseniz aşağıdaki ufak değişikliğin yapılması gerekir.
X-XSS-Protection: 1; mode=block
4 – X-Content-Type-Options
Özellikle Internet Explorer başta olmak üzere internet tarayıcıları kendilerine web uygulaması tarafında sunulan içerik üzerinde MIME Type Sniffing adı verilen analizi gerçekleştirerek, içeriğin tipine karar vermeye çalışmaktadır. Örneğin bir PDF dosyası veya JPEG dosyasına erişim talebi olduysa, HTTP cevabı üzerinde analiz gerçekleştirerek dosya tipi tahmin edilmeye çalışılır.
Örneğin; Uzantısı jpeg olan ama içeriği text/html olan bir dosyayı düşündüğümüzde, upload modülünde ki korumalar uzantılı ile aşılarak dosyanın yüklenmesi başarıyla sağlanır. Yüklenen dosya URL üzerinden çağırıldığında MIME Type sniffing sonuç olarak text/html döndürecek ve içeriği HTML olarak render edecektir. En nihayetinde ise Stored XSS zafiyeti oluşacaktır.
Neden ve Nasıl Kullanmalıyım ?
X-Content-Type-Options: nosniff satırı HTTP başlık bilgisine eklenerek, internet tarayıcılarının MIME Type sniffing yaparak içerik üzerinde karar vermesi engellenmelidir.
# Nginx için add_header X-Content-Type-Options nosniff; # Apache için Header always X-Content-Type-Options nosniff # IIS için <httpProtocol> <customHeaders> <add name="X-Content-Type-Options" value="nosniff" /> </customHeaders> </httpProtocol>
5- Cookie HttpOnly ve Secure Bayrakları
Sevgili dostum Adil İlhan’ın hatırlatması üzerine, yazıyı hazırlarken unuttuğum bu bölümü eklemek istedim.
HttpOnly Bayrağı
Web uygulamaları kullanıcıların oturumlarını session ID üzerinden takip etmektedir. Bu değer kullanıcıya HTTp Set-Cookie başlık bilgisi ile iletilmektedir. İnternet tarayıcıları bu değeri saklayarak, Cookie’nin geçerli olduğu kapsam için oluşturulacak her HTTP talebinde bu değeri otomatik olarak talebe ekleyecektir.
Cookie’ler oturum anahtarının taşınmasının haricinde de başka amaçlar için kullanılabilir. Örneğin; resim galerisinde ki tıklanan son resim gibi.Bu sayede HTTP trafiği azaltılarak client-site scripting ile yükün bir kısmı kullanıcının internet tarayıcısı tarafından çözümlenebilir. Bu bize şu kararı vermemizi gerektirir. Hangi cookie değerleri güvenlik açısından önemli ?
Cevap genellikle kullanıcı kimlik numarasını ( session ID ) barındıran değerdir. Bu değer uç durumlar hariç, sadece ve sadece HTTP talebi içerisinde kullanılmalıdır. Bir diğer ifade ile;
Oturum anahtarı bilgisine Javascript vb client-site programming ile ulaşılmaması gerekir..!
HttpOnly tamda bu işe yaramaktadır. Bunu sağlamak için Cookie ataması aşağıdaki şekilde yapılmalıdır.
Set-Cookie: user=t=bfabf0b1c1133a822; path=/; HttpOnly
Cookie set işleminde gönderilen HttpOnly değerine dikkat ediniz. HttpOnly bayrağını gören internet tarayıcı document.cookie değişkeni üzerinden Cookie’e erişim yapıldığında HttpOnly bayrağı olan değerleri işleme almayacaktır.
Secure Flag
Set-Cookie işleminde Secure bayrağının kullanılması, bu Cookie değerinin sadece ve sadece HTTPS taleplerde header’a ekleneceğini ifade etmektedir.
Peki neden böyle bir özelliğe ihtiyaç duyulmuştur ?
Genellikle e-ticaret siteleri, network trafiğini azaltmak ve performası arttırmak adına HTTPS trafiği login işlemi ve ürün alımı esnasında kullanmaktadır. Bu sayede kullanıcıların username & password ikilileri ve kredi kartı vb kritik bilgileri “NSA” den gizlenmiş olacaktır. Buradaki problem ise; oturum açma işlemini başarıyla tamamlayan kullanıcılara Cookie değeri atamasının Secure bayrağı olmadan yapılması. Bu durumda, HTTPS olmayan linklere yapılan HTTP taleplerinde de oturum anahtarı gönderilmiş olacaktır.
Özetlemek gerekirse;
- Ürün gezmek, sepete ürün eklemek gibi işlemlerin hepsi HTTP üzerinden,
- Login, kredi kartı ile ödeme gibi işlemler ise HTTPS üzerinden.
Saldırı senaryosu ise;
- HTTPS üzerinde login işlemini gerçekleştirildi.
- Uygulama oturum anahtarı atamasını HTTPS üzerinden yaptı.
- Bir önceki adım da yapılan Set-Cookie işlemi Secure bayrağı olmadan yapıldı.
- Ürünleri tekrar gezmek isteyen kullanıcı tekrardan HTTP talep yaptı.
- 3. adımda oluşturulan ve kullanıcının kimliğini ifade eden oturum anahtarı Secure bayrağı olmadığı için HTTP 4. adımda oluşturulan HTTP talebine eklendi.
- Network sniffing yapan saldırgan oturum anahtarını ele geçirdi.
Secure bayrağını eklemek ise aşağıdaki örnekte ki gibi son derece kolay.
Set-Cookie: user=t=bfabf0b1c1133a822; path=/; Secure
Mevcut durum nedir ?
Chrome vb internet tarayıcılarının developer tool’ları ile bu analiz kolayca yapılabilir. Örneğin www.mehmetince.net için mevcut cookie’lerin durumu. NOT : Administrator yetkisinde ki kullancının cookie’leridir.
Görüldüğü üzere oturum anahtarları hem Secure hemde HttpOnly bayrakları ile işaretlenmiş durumda.
Sonuç
Çok basit düzenlemeler ile web uygulamalarının güvenliği, adeta uygulamanın 3th party parçası sayılan Internet Tarayıcı’lar ile üst seviyelere çıkartılabilir.
NOT: Content-Security-Policy yukarıda anlatılan header bilgilerinden çok daha farklı ve anlatımı uzun olacağı için ayrı bir blog yazısı olarak sunulacaktır.