13 Mayıs 2016 Cuma

SameSite Cookie: CSRF'e Veda!


HTTP protokolünün stateless özelliğinden dolayı, bir içsel mekanizma olarak sunucular, ard arda gelen isteklerin hangi kullanıcıdan geldiğini ayırt edemezlerdi.

Ta ki 1994 yılında Cookie icad olunana kadar.  Cookie ile birlikte sunucular, istemci tarafında set ettikleri/saklanması talimatını verdikleri benzersiz bir değer ile, istekleri birbirinden ayırma yetisine kavuştular.

Bu kadarlık bir girizgahın Cookie'lerin işlevselliği için yeterli olacağını ümit ediyorum. Kısmetse yakında bu konuda çok daha uzun bir araştırma yazımız Netsparker Türkiye'nin hazırlık aşamasındaki blogunda yayınlanacak.  Bu yazı ile birlikte hem Cookie'yi enine boyuna tartışmış olacak;  hem de bir attack surface, saldırı sathı olarak Cookie özelliklerine değerlendireceğiz.

Browser, kendisinden X bir kaynağa istek yapıldığında, browserda tutulan Cookie listesinde, bu kaynakla eşleşen bir Cookie olup olmadığına bakar. Eğer eşleşen bir Cookie varsa (domain - path şayet set edildiyse secure ve protokol eşleştirmeleri) bu istekle birlikte, browserın tuttuğu Cookie, istekle birlikte gönderilir.

Bu işlem, üçüncü bir kaynaktan yüklediğiniz Javascript, CSS, embed edilmiş diğer içeriklerde de aynen tekrarlanır.

Burada güvenlik açısından kritik nokta şudur. Siz bir A sitesine girdiğinizde, A sitesi üzerinden B sitesine yapılan bir istekte de B sitesine ait Cookie isteğe eklenecektir. Dolayısı ile B sitesi üzerinde devam eden bir oturum, bu yolla kullanılabilecek, daha kötüsü istismar edilebilecektir.

Güvenlik terminolojisinde CSRF -Sea Surf  - Cross Site Scripting (CSRF- Sea Surf), olarak bilinen zafiyet -Türkçe karşılığı ile Siteler Arası İstek Sahteciliği- hali hazırda yetkili olan bir kullancı oturumunun üçüncü taraflar tarafından istismar edilmesi işlemidir.

Yine bu üçüncü taraf erişimler, reklam ve takip amaçlı da kullanılabilirler. Bunun altında yatan mekanizması ise kısaca şöyle. Siz bir siteye girdiğinizde (example.com), tarayıcınız bu siteye yerleştirilmiş  bir Facebook Like butonu, bir Google Analytics kodu sebebiyle bu kaynaklara istek yapar ve bu isteklerle birlikte browserda bu kaynaklar tarafından set edilmiş Cookie'ler  gönderilir. İstekle birlikte bu isteğin kaynaklandığı sitenin adı (example.com), Referer bilgisi olarak istekte yerini alır. Böylece bu üçüncü taraflar, Cookie ve Referer bilgisini birleştirerek, hangi kullanıcının hangi siteye eriştiğinin kayıtlarını tutabilirler.

Normalde bu tarz izlemelerinin önünü alabilmek için Firefox ve Chrome'da üçüncü taraflardan kaynaklanan isteklere Cookie eklenmesi özelliğini kapatabilmek mümkün, fakat bu, tüm siteleri ve tüm Cookie'leri engelleyeceği için HTTP navigasyonunu felce uğratabilecek bir özellik. Evet izlenmeyi ve CSRF 'i engelleyecek ama attığımız taş ürküttüğümüz kuşa değecek mi?

Chrome 51 ve Opera 39 browserlarına eklenen SameSite Cookie özelliği ile, site sahipleri, istemciye yolladıkları Cookie'leri SameSite parametresi ile kontrol edip, üçüncü taraflardan kaynaklanan isteklere eklenip eklenmeyeceği konusunda tarayıcılara talimat verebiliyorlar.

Oldukça kullanışlı olan bu özellik sayesinde, tüm Cookie'lerin gönderimini iptal etmek yerine, arzu ettiğiniz Cookie için SameSite özelliği set edebilirsiniz.

SameSite Cookie set edilmesi gayet basit. HTTP spesifikasyonunda yer alan Cookie talimatına ek olarak SameSite=Lax veya SameSite=Strict parametrelerini eklemeniz yeterli.

Set-Cookie: CookieName=CookieValue; SameSite=Lax;
Set-Cookie: CookieName=CookieValue; SameSite=Strict;

Strict ve Lax

Strict: Adından da anlaşılacağı üzere, SameSite kuralının en kati biçimde uygulandığı opsiyondur. SameSite parametresi Strict olarak set edildğinde üçüncü taraflardan kaynaklanan hiçbir isteğe SameSite olarak set edilen Cookie gönderilmeyecektir.

Lax: Strict olarak set ettiğimiz bir Cookie, HTTP navigasyonumuzu olumsuz yönde etkileyebilecektir. Örneğin bir sayfadan, bir Facebook profil sayfasına link verildiğinde bu linki tıklayarak navigasyona devam ettiğimizde, eğer Facebook.com oturum Cookie'lerini SameSite=Strict olarak set ettiyse, Facebook.com sayfası tekrar oturum açmamızı isteyecektir.
Çünkü üçüncü taraf bir siteden Facebook.com 'a yönelen bu isteğe Strict olarak işaretlenen Cookie eklenmeyecektir.

İşte navigasyonumuzu etkileyen bu  gibi engellerin önünü alabilmek için Lax parametresi kullanılabilir. SameSite=Lax parametresi ile üçüncü taraf bir siteden kaynaklanan GET isteklerine Lax olarak set edilmiş Cookie eklenecektir.

Buradaki kıstas şudur, GET navigasyonu ile yani HTTP protokolündeki manası ile bir kaynak erişimi için kullanılan GET parametresinin TOP LEVEL bir navigasyona neden olması gereklidir, ancak bu koşulda Lax olarak işaretlenmiş bir Cookie, üçüncü taraf bir siteden kaynaklanan isteğe eklenecektir.

Biraz daha açalım:

Bildiğiniz üzere bir kaynağı iframe ile, img tagları ile de yükleyebilirsiniz, script tagları ile de. Bu istekler browser tarafından GET fiili ile işlenecektir ama TOP LEVEL bir navigasyona, yani basit anlamıyla browser adres çubuğundaki adres alanında bir değişikliğe neden olmadıkları için bu isteklerle beraber Lax olarak set edilmiş Cookie'ler gönderilmeyecektir.

Özetleyecek olursak:


CSRF'e Veda mı gerçekten?

Evet öyle gözüküyor, çünkü üçüncü taraf sitelerden, izleme ya da saldırı amacıyla sitenize yönelmiş isteklerde önem arz eden Cookie'lerin, örneğin oturum Cookie'lerinin, kullanılmasını engelleyerek saldırıların önünü alabilirsiniz.

Bir örnek ile açıklayalım:

www.badbank.com 'a giriş yaptınız. O sırada da binbir türlü hile ile www.attacker.com 'a girmeniz sağlandı. www.attacker.com'daki bir kod www.badbank.com 'a bir FORM post ederek, havale yapmaya çalışıyor. Browser'ınızın işleyeceği bu istekte, www.badbank.com 'daki oturumunuza ait Cookie kullanılacak ve hal-i hazırda bir Anti-CSRF token yoksa, bu istek ile www.badbank.com 'da açık olan oturumunuz istismar edilecektir.

SameSite=Lax olarak set edilse idi, bu form post işlemi ile birlikte, oturuma ait Cookie gönderilmeyecek dolayısı ile atağın kendisinin başarılı olması için bir oturuma gereği olduğundan başarısız olacaktır.

Dikkatli Olmalısınız!

2010 yılında yayınlanan OWASP Top 10 zafiyet listesinde 5. sırada iken, 2013 yılındaki Top 10 listesinde 8. sıraya gerileyen CSRF zafiyeti için, raporu hazırlayanlar  bu zafiyet konusundaki farkındalığın arttığından ve pek çok framework'a Anti-CSRF tokenlarının eklendiğinden bahsediyorlar.

what_changed_from_2010_to_2013.png
Resim: https://www.owasp.org/index.php/Top_10_2013-Release_Notes

SameSite özelliği ile birlikte, gevşememeli ve tedbiri elden bırakmamalıyız.

Sistem tarafında durum değiştirilen tüm işlemleri GET dışında, örneğin POST gibi bir method ile yapmalıyız.

Bunun için hali hazırda birkaç sebebimiz zaten vardı:

1) GET, daha çok güvenli addedilen, navigasyon işlemleri için tasarlanmıştı.
2) GET ile parametre taşındığında, bu hem browser geçmişinde, hem de server loglarında, üçüncü taraf sitelere gönderilen Referer'larda yer alacaktı.

Ve buna 3. bir maddeyi bugün ekleyebiliriz. Hala GET güvensiz çünkü Lax olarak set edilen SameSite Cookie'ler, GET ile birlikte gönderilmeye devam edilecek.

Netsparker tarafında durumlar nasıl?



Netsparker tarafında gelişmelere çok çabuk adapte olup, hemen engine skalamıza ekliyoruz. SameSite Cookie ile ilgili Information düzeyinde bilgilendirme yapıyor ve SameSite Cookie özelliğinin Cookie tanımlarına eklenmesini tavsiye ediyoruz. Ayrıntılı bilgi için https://www.netsparker.com/blog/releases/june-2016-netsparker-desktop-update/


Yazı yine epey sürmüş..
Umarım derdimizi anlatabilmişizdir.

Kaynaklar
https://tools.ietf.org/html/draft-west-first-party-cookies-07
http://www.sjoerdlangkemper.nl/2016/04/14/preventing-csrf-with-samesite-cookie-attribute/
https://support.mozilla.org/en-US/kb/disable-third-party-cookies
https://support.google.com/chrome/answer/95647?hl=en
https://www.owasp.org/index.php/Top_10_2013-Release_Notes

2 yorum:

Erhan Atalar dedi ki...

Merhaba Ziyahan kardeşim,

Harika ve dolu dolu bir yazı olmuş. Tşekkürler..

zyhn dedi ki...

Erhan Ağabey selamlar;
Alakanız için çok teşekkür ederim.