CSRF (Cross-Site Request Forgery) Nedir?
CSRF, bir saldırganın kullanıcının tarayıcısını kullanarak, onun haberi olmadan ve istemeden bir işlem yaptırmasıdır. Kullanıcı farkında olmadan kendi hesabıyla bir işlem yapmış olur. Yani CSRF, kullanıcı oturumu açıkken saldırganın hazırladığı bir link veya sayfa aracılığıyla, kullanıcının adına işlem yaptırmasıdır.
CSRF saldırısında saldırgan, kullanıcının verilerini (şifresini, kredi kartı numarasını) göremez. Sadece kullanıcının sahip olduğu yetkiyi kullanarak işlem yaptırır.
Örneğin:
- Kullanıcının e-posta adresini değiştirmek
- Şifresini değiştirmek
- Para transferi yapmak
Eğer kullanıcı admin yetkilerine sahipse, saldırgan tüm sistemi ele geçirebilir
CSRF’nin çalışması için gereken 3 şart:
- İlgili bir işlem olmalı: Saldırganın yapmak isteyeceği bir işlem olmalı: e-posta değişikliği, para transferi gibi.
- Oturum sadece cookie ile tutulmalı: Site, kullanıcının kimliğini doğrulamak için sadece session cookie kullanıyorsa (ekstra güvenlik yoksa: CSRF token, captcha vb.) saldırıya açıktır.
- Tahmin edilemez parametre olmamalı: İstek için gerekli veriler tahmin edilebilir olmalı. Örneğin şifre değiştirmek için “eski şifre”yi bilmek gerekiyorsa saldırı yapılamaz.
CSRF Örnek Senaryo
- Hedef Site: example.com
- Saldırgan Site: halilibrahim.net
- Kurban giriş yapar:
- Kullanıcı example.com sitesine giriş yapar.
- Site, tarayıcıya oturum açıldığını gösteren bir cookie bırakır.
- Saldırgan tuzak kodu hazırlar
- Saldırgan, kendi sitesine (halilibrahimkaya.net) zararlı bir form veya script ekler. Örnek:
<form action=”https://example.com/email/degistir” method=”POST” id=”csrf-form” style=”display:none;”>
<input type=”hidden” name=”email” value=”saldirgan@mail.com”>
</form><h3>Hediye Kazandınız! Sayfa yükleniyor…</h3><script>
// Sayfa yüklendiği an formu kurbana fark ettirmeden gönderir
document.getElementById(‘csrf-form’).submit();
</script>- Bu kod, example.com üzerinde işlem yapacak şekilde hazırlanmıştır (örneğin e-posta değiştirme, parola değiştirme).
- Saldırgan, kendi sitesine (halilibrahimkaya.net) zararlı bir form veya script ekler. Örnek:
- Kurban saldırganın sitesine gider
- Saldırgan, kurbanı kendi sitesine çekmek için phishing, sahte link veya sosyal mühendislik yöntemlerini kullanır.
-
- Kurban, arka planda yapılacak işlemlerden habersiz halilibrahimkaya.net adresine gider.
- İstek otomatik gönderilir
- Kurban halilibrahimkaya.net adresine geldiğinde; tarayıcı, saldırganın hazırladığı formu otomatik çalıştırır.
- Bu işlem yapılırken tarayıcı, example.com’a ait cookie değerini de otomatik olarak isteğe ekler.
- Sonuç
- example.com sunucusu isteği, kurban göndermiş gibi algılar.
- Kurbanın hesabındaki bilgiler (e-posta, parola, vb.) saldırganın istediği şekilde değiştirilir.
CSRF Token
CSRF Token, sunucu tarafından üretilen ve sayfanın HTML kaynak koduna yerleştirilen benzersiz bir anahtardır. Tarayıcılar, bir siteye istek gönderirken oturum çerezlerini (cookie) otomatik olarak eklese de, HTML kaynağında bulunan bu token değerini otomatik olarak isteğe dahil edemez. Bir işlemin sunucu tarafından onaylanması için bu token’ın istekle birlikte gönderilmesi zorunludur.
Eğer CSRF Token koruması olmasaydı, saldırganın hazırladığı form arka planda başarıyla çalışır ve kullanıcı sadece “Hediye Kazandınız” yazısını görürken işlemi tamamlanmış olurdu. Ancak sunucu, gelen istekte geçerli bir token bulamadığı için bu işlemi reddeder.
Saldırgan, geçerli bir istek oluşturabilmek için kullanıcının tarayıcısındaki token değerini ele geçirmeye çalışabilir. Örneğin, gizli bir pencerede hedef siteyi açıp JavaScript ile bu sayfanın içeriğine erişmek isteyebilir:
-
- Saldırgan, token çalmak veya veri okumak için zararlı bir script hazırlar. Örnek:
// Hedef siteyi gizli bir pencerede açar
var hedefPencere = window.open(“https://example.com/email/degistir”, “gizliCerceve”);
// Sayfa yüklendiğinde içeriğe erişmeye çalışır
hedefPencere.onload = function() {
// Sayfa kaynağındaki CSRF token’ı okuma girişimi
var calinanToken = hedefPencere.document.getElementsByName(“csrf_token”)[0].value;
};
- Saldırgan, token çalmak veya veri okumak için zararlı bir script hazırlar. Örnek:
Same-Origin Policy (SOP) dediğimiz kavram bu noktada devreye girer. SOP, bir siteden gelen scriptin, başka bir siteye ait olan sayfa içeriğini okumasını engeller. Tarayıcı bu erişimi kısıtladığı için saldırgan, başka bir sekmede veya pencerede açık olan hedef sitenin içindeki token değerini kopyalayamaz. Token kopyalanamadığı için de saldırganın hazırladığı sahte istekte geçerli bir anahtar bulunmaz ve sunucu bu “tokensiz” isteği reddeder.
Site ve Origin Kavramları
Web güvenliği bağlamında “site” ve “origin” kavramları birbirine benzer görünse de aslında farklı kapsamları ifade eder. Site kavramı daha geniş bir tanımı kapsar ve bir URL’nin şeması (http veya https) ile birlikte TLD+1 (örneğin example.com) kısmına bakılarak belirlenir. Bu nedenle https://app.example.com ve https://shop.example.com adresleri aynı siteye aittir; çünkü her ikisi de aynı protokolü (https) kullanır ve aynı ana domaine (example.com) bağlıdır. Alt alan adlarının (subdomain) farklı olması site tanımını değiştirmez. Aynı şekilde port numarası da site kavramında dikkate alınmaz.
Origin ise daha dar ve güvenlik açısından daha kritik bir kavramdır. Origin belirlenirken URL’nin şeması (http/https), tam alan adı (örneğin app.example.com) ve port numarası birlikte değerlendirilir. Bu üç bileşenden herhangi biri farklıysa origin de farklı kabul edilir. Örneğin https://app.example.com:443 ile https://app.example.com:8443 farklı origin’dir çünkü port numaraları farklıdır. Benzer şekilde https://app.example.com ile https://shop.example.com da farklı origin sayılır, çünkü alt alan adları farklıdır.
SOP (Same-Origin Policy)
Tarayıcıların en temel güvenlik kalkanı olan Same-Origin Policy (SOP), bir internet sitesinden gelen scriptlerin başka bir sitenin verilerine erişip erişemeyeceğine karar verirken Origin (Köken) kontrolü yapar. Bir kaynağın “aynı origin”den sayılabilmesi için şu üç unsurun birebir aynı olması şarttır yani:
- Protokol (http veya https)
- Alan Adı (example.com)
- Port (80, 443 vb.)
Eğer bu bileşenlerden biri bile farklıysa, tarayıcı bu işlemi “Cross-Origin” (Farklı Köken) olarak işaretler ve katı kısıtlamalar uygular.
İnternetin işleyişi gereği tarayıcılar, siteler arası “yazma” (istek gönderme) işlemlerine (örneğin bir formun POST edilmesi) varsayılan olarak izin verir. CSRF saldırılarının temel çıkış noktası da budur; saldırgan kurbanın tarayıcısına banka adresine bir istek attırabilir.
Ancak SOP, farklı kökenler arasında “okuma” (veri çekme) işlemine kesin bir duvar örer. Saldırganın sitesinde çalışan bir JavaScript kodu, kurbanın tarayıcısında banka sayfasını açtırabilir ama o sayfanın HTML kaynak koduna erişip içindeki gizli verileri kendi tarafına kopyalayamaz.
SameSite
SameSite, tarayıcının bir web isteğine oturum çerezlerini (cookie) ekleyip eklemeyeceğine karar veren bir güvenlik talimatıdır. Temel amacı, çerezlerin sadece “aynı site” içerisindeki işlemlerde paketlenmesini sağlayarak, dış sitelerden (cross-site) gelen sahte isteklerin kurbanın kimliğiyle yürütülmesini engellemektir. Böylece tarayıcı, saldırganın sitesinden başlatılan bir isteği fark eder ve oturum çerezlerini o isteğe dahil etmeyerek CSRF saldırısını daha kapıdan dönerken etkisiz hale getirir. 3 tane metodu vardır:
1. SameSite=Strict
Strict ayarı, çerezin sadece kendi sitesinde gönderilmesini sağlar. Yani tarayıcı, başka bir siteden gelen isteklerde çerezi hiç göndermez. Bu, kullanıcı verilerini korumak açısından en güvenli seçenektir ve özellikle oturum açma veya veri değiştirme gibi hassas işlemler için önerilir. Ancak bazı durumlarda, kullanıcı başka bir siteden yönlendirilirse çerez gönderilmediği için bazı işlevler çalışmayabilir.
2. SameSite=Lax (varsayılan çoğu tarayıcıda)
Lax ayarında, çerez sınırlı şekilde başka sitelere gönderilir. Yalnızca kullanıcı tarafından tıklanan linkler gibi üst düzey (top-level) gezintiler ve GET istekleri için geçerlidir. POST istekleri veya arka planda çalışan scriptler, iframe’ler ve resim gibi kaynak isteklerinde çerez gönderilmez. Bu sayede CSRF saldırıları büyük ölçüde engellenirken, temel site geçişleri hâlâ çalışır.
3. SameSite=None; Secure
None ayarı ise SameSite kısıtlamasını tamamen kaldırır ve çerezin her istekte, başka sitelerden gelen isteklerde dahi gönderilmesini sağlar. Bu ayar genellikle üçüncü taraf çerezleri veya takip çerezleri için kullanılır. Ancak güvenlik açısından, bu çerezlerin yalnızca HTTPS üzerinden gönderilmesini sağlamak için Secure özelliği ile birlikte kullanılması gerekir.
CSRF Token doğrulamasındaki yaygın kusurlar
İstek metodunu Değiştirmek:
Bazı uygulamalarda, CSRF token’ı yalnızca POST isteklerinde doğru şekilde kontrol edilirken, GET isteklerinde bu doğrulama göz ardı edilebilir. Bu durumda saldırgan, token doğrulamasını atlatmak ve CSRF saldırısı gerçekleştirmek için isteği GET yöntemiyle gönderir. Eğer saldırgan GET ile gönderilecek isteklerde token kontrolü yoksa, o zaman token değerini bilmeye gerek kalmaz.
CSRF Token’in Kullanıcı Oturumuna Bağlı Olmaması:
Bazı uygulamalarda CSRF token’ları kullanıcının oturumuyla ilişkilendirilmez; sunucu tüm token’ları bir havuzda tutar ve bu havuzdaki herhangi bir geçerli token’ı kabul eder. Bu durumda saldırgan, kendi hesabıyla giriş yaparak elde ettiği token’ı kurbanın isteğine ekleyebilir ve böylece CSRF saldırısını gerçekleştirebilir.
CSRF SameSite cookie
CSRF saldırılarını engellemek için SameSite cookie özelliği getirildi. Bu özellik, tarayıcıya “bu çerez sadece hangi durumlarda gönderilsin” bilgisini söyler.
CSRF saldırıları, kullanıcının haberi olmadan onun hesabı üzerinden işlem yapılmasına yol açtığı için oldukça tehlikelidir. Bu yüzden korunmak için tek bir yönteme güvenmek yerine, birden fazla önlemi birlikte kullanmak gerekir. Örneğin hassas işlemler mutlaka CSRF token ile korunmalı, bu işlemler için sadece POST kullanılmalı ve cookie’ler de SameSite, Secure gibi bayraklarla güvence altına alınmalıdır.
Kısacası, CSRF’ye karşı sağlam bir koruma sağlamak için hem uygulama tarafında hem de tarayıcı tarafında doğru ayarların yapılması, güvenliğin katmanlı şekilde düşünülmesi gerekir.