1S1C: WWW Subdomainini Websitemde Kullanmalı mıyım?
WWW subdomaini herkes için geleneksel önem taşıyan bir subdomain gibi durur ancak işin iç yüzü öyle değil. Özellikle de birden çok kullanıcıya kendi etki alanında hizmet veren servisler için, Cookie'nin yani imparatorluğun anahtarlarının korunması için oldukça elzemdir.
Günümüzde internetin en popüler protokolü HTTP, nam-ı diğer web. Dolayısıyla internet deyince aklımıza web geliyor. Yıllar yıllar önce durum elbette ki böyle değildi. Dolayısıyla domainlerde o servisi işaret eden protokoller, bugün olduğu gibi ama daha sık bir biçimde, bir ön ek olarak kullanılıyordu. Örneğin ftp.example.com, gopher.example.com, mail.example.com gibi.
WWW subdomaininin gerekliliği konusunda pek çok şeyin yazılıp çizildiği bu hususta arama yapacak kişinin malumu olacak. Domain izolasyonu bunlardan biri. Biz WWW subdomainini kullanmanın domain izolasyonuna ek bir katkısı olacağını düşünmüyoruz. Zira domain izolasyonuna örnek verilen TLD'nin üçüncü kişilerle paylaşılması, yani ziyahan.example.com, mustafa.example.com WWW kullanılsın ya da kullanılmasın bu domainlerden, example.com'a ya da birbirlerine bir DOM erişimini zaten mümkün kılmıyor.
Her ne kadar mevzu bahis domainlerden (ziyahan.example.com ve mustafa.example.com) document.domain'i TLD'ye kadar esnetin. Example.com da document.domain komutu ile bu talimatı vermediği müddetçe böylesi bir erişim söz konusu zaten olmayacak.
Bugün biz WWW subdomaininin gerekliliğini başka bir açıdan, Cookie'lerin güvenliği açışından tartışıyor ve gerekliliği bu noktadan ötürü salık veriyor olacağız.
Ayrıntılarına Netsparker Türkiye Güvenlik Blogu'nda yayınlanan HTTP İşleyişi ve Güvenliği Açısından Cookie ve Session Yönetimi yazımızda temas ettiğimiz meseleyi özetle burada ele alalım.
1994 yılında web dünyasında kullanılmaya başlanan Cookie, kendisinden bir yıl sonra dizayn edilecek SOP'dan farklı bir orgin anlayışına sahip. Domain, path, expire, name attributeları ve httpOnly, secure gibi flagları olan Cookie'nin bu cevap kapsamında yalnızca domain attribute'ına temas edeceğiz.
domain: Cookie'nin browserda set edildikten sonra, hangi domain'e yapılan isteklerle birlikte gönderileceğini belirten seçenektir. Opsiyonel bir değerdir. Belirtilmediği takdirde browser, Cookie'yi set eden domain adını kullanacaktır. Siteye domain adı ile değil IP ile erişiyorsanız, domain attribute'ında bu IP'yi göreceksiniz.
X sitesi, Y sitesine ait bir Cookie'yi browserda set edemez. Güvenlik nedeniyle bu tür girişimler sunucu tarafında da, istemci tarafında da engellenmiştir. Fakat, Bir Cookie aynı domain'e ait birden fazla alt domain için kullanılabilir. Örneğin example.com için set edilmiş bir Cookie, mail.example.com, calendar.example.com, crm.example.com sitelerine yapılan isteklerle beraber gönderilebilir. Burada browserda kayıtlı Cookie'lerin domain değeri ile, istek yapılan URL'in hostname'i Tail Comparison olarak adlandırılan, sondan başa (sağdan sola) doğru yapılan bir karşılaştırma işlemi ile kontrol edilmekte, ve eşleşen Cookie'ler istekle beraber gönderilmektedir.
Set-Cookie: Scanner=Netsparker; domain=example.com
Kaynak: HTTP İşleyişi ve Güvenliği Açısından Cookie ve Session Yönetimi
Tablodan da görüleceği üzere domain Cookie'nin güvenliği açısından çok önemli bir özelliktir. Özellikle de subdomain desteği olan sitelerde büyük önem arz etmektedir.
Cookie istekle birlikte gönderilmeden önce, istek yapılan URL ile, browserın belleğindeki cookilerin domain alanlarında bir eşleştirme işlemi yapıldığından söz etmiş idik. Ancak Tail Comparison olarak bilinen bu eşleştirmede sonuç olumlu ise, diğer kriterlerin kontrolünün yapılacağını söylemiştik.
Tarayıcıların bu konudaki farklı davranışları, Cookie domain özelliğinin iyi anlaşılamamış olması ve giderek "www" kullanımının terkedilmesinin bir moda halini almasının yarattığı bazı güvenlik zafiyetlerini bir örnekle inceleyelim.
Ücretsiz web hizmeti veren badsites.local'de iki ayrı hesap açıldığını düşünelim:
victim.badsites.local
attacker.badsites.local
Bu adreslere girildiğinde kullanıcılara ait olan web siteleri görüntülenecek. Kullanıcı web içeriğinde bir değişiklik yapmak istediği takdirde badsites.local üzerinden login olup, kontrol panel üzerinden gerekli değişikleri yapabiliyor.
Victim kullanıcısı sisteme login oluyor. Login için HTTP isteği:
POST http://badsites.local/control.php HTTP/1.1
Host: badsites.local
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 35
username=victim&password=victim
Sunucudan dönen cevaptaki Cookie'nin domain değerine göre üç farklı durum mevcuttur. Bu üç farklı duruma tarayıcıların verdiği farklı tepkileri hep birlikte görelim:
Durum 1 : Cookie'nin domain değeri set edilmemiştir:
HTTP/1.1 200 OK
Date: Sat, 27 Feb 2016 20:59:42 GMT
Server: Apache/2.4.7 (Ubuntu)
X-Powered-By: PHP/5.5.9-1ubuntu4.14
Set-Cookie: PHPSESSID=ock3keuidn0t24vrf4hkvtopm0; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Görüldüğü gibi Cookie set edilirken domain bilgisi belirtilmemiş. Bu durumda üç majör tarayıcı da, farklı davranışlar sergilemekte ve ciddi bir güvenlik zafiyeti meydana gelmektedir.(Test edilen tarayıcılar: Chrome, 48.0.2564.116 m, Internet Explorer 11, Mozilla Firefox 44.0.2)
Eğer domain değeri belirtmemişse, IE 11'de badsites.local etki alanının tüm subdomainlerine yapılan isteklere Cookie eklenecek:
GET / HTTP/1.1
Accept: text/html, application/xhtml+xml, */*
Accept-Language: tr,en-US;q=0.7,en;q=0.3
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko
Proxy-Connection: Keep-Alive
Host: attacker.badsites.local
Pragma: no-cache
Cookie: PHPSESSID=ock3keuidn0t24vrf4hkvtopm0
Victim kullanıcısı ya da badsites.local'e login olmuş biri attacker.badsites.local 'e girdiğinde, attacker.badsites.local sitesi üzerinden badsites.local'e ait oturumu ele geçirilebilecektir.
Chrome ve Firefox tarayıcıları ise Cookie'yi, subdomainlere yapılan istekle birlikte göndermeyecektir.
Durum 2: Cookie domain bilgisi, badsites.local olarak edilmiştir:
HTTP/1.1 200 OK
Date: Sat, 27 Feb 2016 21:28:13 GMT
Server: Apache/2.4.7 (Ubuntu)
X-Powered-By: PHP/5.5.9-1ubuntu4.14
Set-Cookie: PHPSESSID=1fr54qg3j9rf77toohcpcsk8h0; path=/; domain=badsites.local
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-Length: 66
Content-Type: text/html
IE, Chrome ve Firefox, attacker.badsites.local 'e yapılan isteklere, badsites.local tarafından oluşturulan Cookie'yi ekleyecektir:
GET / HTTP/1.1
Accept: text/html, application/xhtml+xml, */*
Accept-Language: tr,en-US;q=0.7,en;q=0.3
Host: attacker.badsites.local
Pragma: no-cache
Cookie: PHPSESSID=1fr54qg3j9rf77toohcpcsk8h0
Durum 3: Cookie domain bilgisi, .badsites.local olarak edilmiştir:
HTTP/1.1 200 OK
Date: Sat, 27 Feb 2016 21:38:02 GMT
Server: Apache/2.4.7 (Ubuntu)
X-Powered-By: PHP/5.5.9-1ubuntu4.14
Set-Cookie: PHPSESSID=q3a20kfes2u6fgvgsrspv0rpf0; path=/; domain=.badsites.local
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
IE, Chrome ve Firefox, attacker.badsites.local 'e yapılan isteklere Cookie'yi ekleyecektir:
GET / HTTP/1.1
Accept: text/html, application/xhtml+xml, */*
Accept-Language: tr,en-US;q=0.7,en;q=0.3
Proxy-Connection: Keep-Alive
Host: attacker.badsites.local
Cookie: PHPSESSID=q3a20kfes2u6fgvgsrspv0rpf0
Görüldüğü üzere Cookie domain değeri dikkatle set edilmesi gerekli bir alan. Doğru değerlerin set edilmemesi uygulamamız açısından büyük güvenlik risklerine neden olabilir. Çözüm olarak www alt etki alanını domainlerinizde kullanmayı zorlayabilirsiniz. Bu durumda domain alanınızı set edin ya da etmeyin, yalnızca www.badsites.local adreslerine yapılan isteklere Cookie'ler eklenecektir.
Bu yazıda WWW subdomainini tartıştık. Yukarıdaki durumu yani birden fazla kullanıcıya ait siteleri host etmek zorunda kaldığınız durumları nasıl yönetebileceksiniz? İkinci bir çözüm olarak da, güvenlik açısından risk doğurabilecek siteleri, ana domaininiz altında host etmeyin. Bu yüzden Github gibi pek çok farklı kod host eden siteler bu işlemi github.com domaini altında değil de github.io altında host etmektedir.
Kaynaklar:
https://jacob.hoffman-andrews.com/README/why-you-need-a-www/
http://erik.io/blog/2014/03/04/definitive-guide-to-cookie-domains/