Selam TurkTeam, BlueTornado yazıyor.
CSRF (Cross-Site Request Forgery), kimliği doğrulanmış bir kullanıcının tarayıcısını kandırarak, kullanıcının haberi olmadan siteye istek attırmaktır. XSS "saldırganın script'ini kurbanın tarayıcısında çalıştırır"; CSRF ise kurbanın mevcut oturumunu kullanarak istenmeyen bir eylemi tetikler. Bu rehberde teori, lab gözlemi, token/SameSite korunmaları ve modern API'lerdeki durumu inceliyoruz.
Konuda Anlatılacaklar
- CSRF nedir, hangi koşullarda çalışır?
- XSS ile farkı
- Lab: DVWA CSRF sayfası
- Klasik PoC formu ve cookie davranışı
- Korunma: Anti-CSRF token, SameSite, pratikler
- İleri seviye: JSON API, SameSite=None, login CSRF
- Kaynakça ve yasal uyarı
1) CSRF Nedir?
Tarayıcılar, bir siteye istek atarken o siteye ait çerezleri (oturum çerezi dahil) varsayılan kurallara göre ekler. Saldırgan, kötü amaçlı bir sayfada şu tür bir istek tetiklerse:
<!-- Kavramsal kötü sayfa (lab dışında kullanmayın) -->
<form action="https://bank.example/transfer" method="POST">
<input type="hidden" name="to" value="attacker">
<input type="hidden" name="amount" value="1000">
</form>
<script>document.forms[0].submit()</script>Kurban o anda bank.example oturumu açıksa, tarayıcı çerezi ekleyebilir ve transfer isteği "kurbandan gelmiş" gibi görünür. Sunucu, isteğin kullanıcının isteyerek mi yoksa başka siteden mi geldiğini ayırt edemiyorsa CSRF oluşur.
Gerekli koşullar (özet):
- İlgili sitede geçerli oturum (çerez tabanlı)
- Tarayıcının çerezi o isteğe eklemesi
- Sunucuda istek sahteciliğini engelleyen ek doğrulama olmaması
- Değiştirici (state-changing) bir eylem (POST ile para transferi, e-posta değiştirme vb.)
Alıntı:CSRF, "çerezi çalmak" zorunda değildir. Çerez tarayıcıda kalır; saldırgan sadece isteği tetikler.
2) XSS ile Fark
- XSS: Güvenilmeyen verinin sayfada script olarak çalışması
- CSRF: Güvenilen sitenin state-changing endpoint'ine çapraz siteden istek
- XSS varsa çoğu CSRF koruması da aşılabilir (token okunur); ikisi ayrı ayrı kapatılmalıdır
3) Lab: DVWA CSRF
git clone https://github.com/digininja/DVWA.git
cd DVWA
docker compose up -dDVWA menüsünden CSRF sayfasına gidin. Low seviyede parola değiştirme formu genelde anti-CSRF tokensızdır.
[center][/center]
Adım 1: Normal şekilde parolayı değiştirip isteği DevTools/Burp ile inceleyin.
POST /vulnerabilities/csrf/
password_new=...&password_conf=...&Change=Change
Cookie: PHPSESSID=...; security=lowAdım 2: Aynı parametrelerle, labınızda yerel bir HTML dosyasından formu işaret ederek davranışı gözlemleyin (yalnızca 127.0.0.1 DVWA). Impossible seviyede token eklenmiş olduğunu göreceksiniz.
<!-- Yerel lab HTML iskeleti -->
<form method="POST" action="http://127.0.0.1/vulnerabilities/csrf/">
<input type="hidden" name="password_new" value="hacked">
<input type="hidden" name="password_conf" value="hacked">
<input type="hidden" name="Change" value="Change">
</form>Çıktı yorumu: Low'da oturum açıkken bu sayfa yüklendiğinde parola değişiyorsa CSRF vardır. Impossible'da token eksik/yanlışsa işlem reddedilir.
[center][/center]
4) Kavram Referansı
Anti-CSRF synchronizer token: Sunucu, forma rastgele token koyar; POST'ta token oturumdaki ile eşleşmelidir. Saldırganın sitesi bu token'ı okuyamaz (same-origin policy), XSS yoksa.
<!-- Kavramsal -->
<input type="hidden" name="csrf_token" value="a3f9..."># Sunucu tarafı (kavramsal)
if not hmac.compare_digest(session["csrf"], request.form["csrf_token"]):
abort(403)SameSite çerez özelliği:
Set-Cookie: session=...; Secure; HttpOnly; SameSite=Lax- : Çapraz site isteklerinde çerez gönderilmez (en sıkı; bazı akışları bozabilir)Kod:
Strict - : Top-level GET navigasyonunda gönderilir; çoğu CSRF POST senaryosunu keserKod:
Lax - : Secure zorunlu; çapraz site çerez (dikkatli kullanın)Kod:
None
Origin / Referer kontrolü: Ek katman; Referer eksik olabilir, Origin daha güvenilirdir ama her istemci/senaryoda yetmeyebilir. Token ile birlikte düşünün.
# Örnek kontrol (kavramsal)
origin = request.headers.get("Origin")
if origin and origin not in ALLOWED_ORIGINS:
abort(403)5) Korunma Kontrol Listesi
- State-changing işlemleri POST/PUT/DELETE ile yapın; önemli işleri GET'e bağlamayın
- Anti-CSRF token (framework'ün built-in'i: Django, Rails, ASP.NET, Spring)
- SameSite=Lax veya Strict + Secure + HttpOnly
- Mümkünse oturumu çerez dışında authorization header (Bearer) ile taşıyan SPA'larda CSRF yüzeyi küçülür; XSS'e dikkat
- Kritik işlemlerde re-auth (şifre yeniden sor)
- CORS'u sıkı tutun; credentials ile * kullanmayın
# Django'da middleware varsayılan olarak CSRF korur
# Şablon:
{% csrf_token %}# Flask-WTF örneği
form = FlaskForm() # csrf_token alanı otomatik[center][/center]
6) İleri Seviye
Login CSRF: Kurbanı saldırganın hesabına zorla giriş yaptırma; sonra kurban o oturuma veri kaydeder. Login formuna da token koyun.
JSON API + simple request:
Content-Type: application/jsonSameSite=None gereken üçüncü parti gömülü senaryolarda CSRF riski geri gelir; ek token zorunlu düşünün.
Double-submit cookie: Token'ı hem çerezde hem formda göndermek. Basit ama subdomain XSS/cookie injection varsa zayıflayabilir; synchronizer pattern genelde tercih edilir.
# Rapor dili
Bulgu: CSRF (CWE-352)
Endpoint: POST /vulnerabilities/csrf/
Kanıt: Labda tokensız POST ile parola değişimi
Öneri: synchronizer token + SameSite=Lax7) Sonuç
CSRF, tarayıcının çerez ekleme davranışından beslenir. Token + SameSite + güvenli metod kullanımı temel üçlüdür. DVWA Low/Impossible karşılaştırması korumayı somut gösterir.
Ek: Framework Notları ve Test Kontrol Listesi
Modern çerçeveler CSRF için hazır çözüm sunar; asıl risk "korumayı kapatmak"tır.
# Django: CSRF_TRUSTED_ORIGINS doğru ayarlanmalı (HTTPS arkasında)
# @csrf_exempt yalnızca çok bilinçli istisnalarda; API için token veya auth tasarımını gözden geçirin# ASP.NET Core: Antiforgery middleware
# ValidateAntiForgeryToken attribute# SPA + cookie oturumu:
# 1) Frontend, login yanıtından veya cookie-olmayan bir endpoint'ten CSRF token alsın
# 2) Her state-changing istekte header olarak göndersin (ör. X-CSRF-Token)
# 3) SameSite=Lax + SecureManuel test listesi (izinli lab):
- Oturum açıkken çapraz origin HTML formu ile POST deneyin
- Token'ı silerek/değiştirerek 403 bekleyin
- Content-Type ve metod kombinasyonlarını not edin
- Logout sonrası token'ın geçersiz olduğunu doğrulayın
[center][/center]
Unutmayın: CSRF koruması XSS varken zayıflar çünkü script token'ı okuyabilir. İkisini birlikte ele alın.
Kaynakça
Yasal Uyarı
CSRF testleri yalnızca kendi labınızda veya yazılı yetkili pentest kapsamında yapılmalıdır. Başkalarının oturumunu kötüye kullanmak TCK 243-245 ve ilgili maddeler kapsamında suç olabilir. Eğitim amaçlıdır.
Yasal uyarı: Bu içerik eğitim amaçlıdır. Yalnızca kendi sistemlerinizde veya yazılı izin aldığınız hedeflerde uygulayın (TCK 243-245).