33 puan yazan GN⁺ 2025-03-04 | 1 yorum | WhatsApp'ta paylaş
  • Cross-Site Request konusu ele alındığında, neden hem CSRF korumasına hem de CORS'a ihtiyaç duyulduğunu ilk başta anlamak kolay değil. Ancak bunu açıklamak için epey kelime gerekiyor.

CSRF ve CORS

  • CSRF (Cross-Site Request Forgery)
    • Geçmişte yaygındı, ancak günümüzde çoğu web framework'ü varsayılan olarak koruma sağladığı için artık neredeyse sorun olmaktan çıktı
    • Saldırı yöntemi: Kullanıcının kötü amaçlı bir sitede belirli bir forma tıklaması sağlanarak cross-site bir isteğin gönderilmesi tetiklenir
    • Savunma yöntemi: İsteğin başka bir siteden gelip gelmediğini doğrulamak
  • CORS (Cross-Origin Resource Sharing)
    • HTTP spesifikasyonunun bir parçasıdır ve belirli cross-site isteklere nasıl izin verileceğini tanımlar
    • Preflight isteği ve yanıt başlıkları kullanılarak hangi origin'lerden istek gönderilebileceği belirtilir

O hâlde cross-site istekler varsayılan olarak izinli olduğu için mi CSRF koruması gerekir, yoksa varsayılan olarak engellendiği için mi CORS ile ayrıca izin vermek gerekir? Doğru cevap ikisi de.

Varsayılan çalışma şekli

  • Same-origin policy
    • Tarayıcı tarafından zorunlu kılınan bir güvenlik politikasıdır
    • Genel olarak cross-site write'a izin verir, read'i ise yasaklar
    • Örneğin tarayıcı, form üzerinden gönderilen POST isteğine izin verir ama yanıtın okunmasına izin vermez
  • SameSite çerez politikası
    • 2019'da çerezlerin varsayılan davranışı değişti
    • Eskiden cross-site isteklerde çerezler her zaman gönderiliyordu
    • Yeni SameSite özniteliği eklendi ve varsayılan değer Lax olarak değişti
    • 2025 itibarıyla tarayıcıların %96'sı SameSite özniteliğini destekliyor, %75'i yeni varsayılanı (Lax) destekliyor
    • Ancak Safari bunu varsayılan olarak uygulamadı ve UCBrowser hâlâ desteklemiyor
  • Site ile Origin arasındaki fark
    • Origin: protokol + host adı + port birleşimi
    • Site: protokol + üst düzey alan adı + 1 birleşimi (alt alan adları ve port yok sayılır)

CORS

  • CORS, same-origin policy'ye belirli origin'ler için istisna tanıma mekanizmasıdır
  • Tarayıcı, isteği göndermeden önce OPTIONS türünde bir preflight request gönderir
  • Sunucu, yanıt başlıklarıyla izin kurallarını tanımlar (Access-Control-* başlıkları kullanılır)
  • CORS'un uygulandığı istek türleri:
    • fetch ve XMLHttpRequest
    • web font'ları
    • WebGL texture'ları
    • canvas içinde drawImage ile çizilen görsel/video kareleri
    • CSS shape-outside özelliğinde kullanılan görseller
  • Ancak form gönderimleri istisna olarak CORS'a tabi değildir
    • HTML 4.0'daki <form> etiketi çok uzun zamandır cross-site isteklere izin veriyordu
    • Bu nedenle mevcut sunucuların zaten CSRF saldırılarına karşı savunmalı olacak şekilde tasarlanmış olması gerekiyordu
    • Sunucu, yanıtı paylaşmak istiyorsa Access-Control-Allow-Origin ayarlamalıdır; ancak isteğin kendisi preflight olmadan da kabul edilir

Soru: SameSite politikası ile bu yaklaşım tutarlılığı nasıl koruyor?

CSRF koruma yöntemleri

  • Cross-site write isteklerine izin verilir, ancak yanıt paylaşılmaz
    • Çoğu web sitesi aslında cross-site write'a izin vermek istemez
  • Standart CSRF savunma yöntemi
    • İsteğe kullanıcıya özgü bir CSRF token eklenir ve doğrulanır
    • Yöntem:
      • Form gönderimi: Token'ı gizli bir input alanı olarak eklemek
      • JS istekleri: Çerezde veya meta etiketinde saklayıp istek başlığına ya da parametreye eklemek
  • JS istekleri normalde cross-site olarak zaten varsayılan biçimde engellenir
    • Ancak same-site request'lere izin verilir
    • CSRF token kullanılırsa tüm istekler aynı yöntemle doğrulanabilir
  • Ek güvenlik avantajı
    • Tarayıcının varsayılan olarak yanıt okumasını engelleyeceği varsayımına dayanır
    • Origin başlığını kontrol etmekten daha güvenlidir

Soru: Bazı framework'ler neden CSRF token'ı periyodik olarak değiştiriyor?

Tarayıcının rolü

  • Web güvenliğinin özü, tarayıcıya güvenilip güvenilemeyeceğine bağlıdır
  • Tarayıcı şunları yapar:
    • same-origin policy'yi uygular
    • Yanıta izin verilmiyorsa okunmasını engeller
    • SameSite=Lax varsayılanını uygulayıp uygulamayacağına karar verir
    • CORS'u uygular ve güvenli preflight istekleri gönderir

Kullandığımız tarayıcıya güvenmek zorundayız.

Sonuç

  • SameSite=Lax tüm tarayıcıların %100'ünde desteklenirse güvenlik daha da güçlenecek olsa da,
    şu anda hâlâ cross-site POST istekleri için istisnai bir izin durumu var
  • Bu nedenle geliştiricilerin CSRF korumasını sürekli dikkate alması gerekir

"İnternet giderek daha güvenli hâle geliyor, ama bunun karşılığında geçmişe dönük uyumluluk da giderek azalıyor."

Kaynaklar

  1. Same-origin policy
  2. caniuse SameSite cookie attribute
  3. OWASP CSRF cheatsheet
  4. CORS wiki with requirements
  5. CORS spec
  6. CORS on MDN
  7. Preflight request
  8. Origin request header
  9. Origin and Site

1 yorum

 
GN⁺ 2025-03-04
Hacker News görüşü
  • CORS, sunucunun tarayıcıya hangi cross-origin isteklerin yanıtı okuyabileceğini açıkça bildirmesini sağlayan bir mekanizmadır

    • Varsayılan olarak tarayıcı, cross-origin script'lerin yanıtı okumasını engeller
    • Açıkça izin verilmedikçe, isteği yapan alan adı yanıtı okuyamaz
    • Örneğin, evil.com üzerindeki bir script bank.com/transactions'a istek gönderip kurbanın işlem geçmişini okumaya çalışabilir
    • Tarayıcı isteğin bank.com'a ulaşmasına izin verir, ancak evil.com'un yanıtı okumasını engeller
  • CSRF koruması, kimliği doğrulanmış kullanıcı adına kötü amaçlı cross-origin isteklerin yetkisiz işlemler gerçekleştirmesini önler

    • Örneğin, evil.com üzerindeki bir script bank.com'da bir işlem yapılması için istek gönderebilir (ör. bank.com/transfer?from=victim&to=hacker ile para transferi)
    • bank.com'un sunucu tarafındaki CSRF koruması bunu reddeder (muhtemelen istekte gizli bir CSRF token'ı bulunmadığı için)
  • CSRF koruması yazma korumasıyla, CORS ise okuma korumasıyla ilgilidir

  • JS ile başlatılan isteklerde varsayılan olarak cross-site izin verilmez

    • fetch() kullanıp yalnızca izin verilen header'ları kullanırsanız cross-site istek başlatabilirsiniz
  • Bu konu hakkında daha iyi bir açıklama olduğunu düşünüyorum

    • İlgili blog bağlantısı paylaşılıyor
  • Blog yazısındaki soruya yanıt

    • HTML 4.0'ın <form> öğesi, herhangi bir origin'e basit istek gönderebilir
    • Bunun SameSite girişimiyle nasıl uyumlu olduğuna dair bir soru vardı
  • 2022'de MDN CORS makalesine, "basit istek" teriminin kaynağını netleştirmek için bir paragraf eklendi

    • Daha önce yalnızca bunun fetch spesifikasyonunda geçmediği yazıyordu
    • 2019'da tarayıcıların CSRF önleme özelliği olarak SameSite=Lax'ı desteklediğine veya varsayılan yaptığına dair bir ifade yoktu
  • SameSite'ın CORS preflight'tan bağımsız olarak eklenmiş olması kafa karıştırıcı

    • Tarayıcı üreticilerinin neden tüm cross-origin POST isteklerinde preflight zorunlu kılmadığını merak ediyorum
  • csrf kullanmadan da güvenli olduğunuzu düşünebilirsiniz, ancak bazı kütüphaneler (ör. django rest framework) content-type header'ı ayarlanmışsa HTML form'larını işleyebilir

    • Bu, birinin sitenize form göndererek kullanıcı adına istek yollayabilmesini mümkün kılar
  • CSRF token'larının neden döndürüldüğüne dair bir soru

    • OWASP bunun daha güvenli olduğunu söylüyor ama nedeninden emin değilim
  • Karmaşık bir konu için bir akış şeması talebi

    • Yeni bir uygulama platformu ve standartlar seti isteniyor
  • Bunlar kolay tanılama izlerini desteklemiyor

    • Doğru yapılandırılmamış meşru kullanım senaryolarında birçok kez opak hatalar yaşadım
  • CORS ortaya çıkmadan önce, sayfanın origin'i dışındaki rastgele endpoint'lere istek gönderilebildiği ama yanıtın görülemediği durumun nedenini anlamıyorum

    • Bunun spesifikasyona tesadüfen mi girdiğini, XSS öngörülerek bilinçli şekilde mi yapıldığını, yoksa öncü bir tarayıcının böyle davranıp diğerlerinin onu mu izlediğini merak ediyorum
  • CSRF koruması hakkındaki kafa karışıklığı

    • Saldırganın goodsite.com'dan bir CSRF token alıp bunu badsite.com'a koyarak Alice'i badsite.com üzerinden goodsite.com'a istek göndermeye kandırmasını neyin engellediğini merak ediyorum