CSRF koruması ve CORS neden birlikte kullanılıyor?
(smagin.fyi)- 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ğerLaxolarak 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ı + portbirleşimi - Site:
protokol + üst düzey alan adı + 1birleşimi (alt alan adları ve port yok sayılır)
- Origin:
CORS
- CORS, same-origin policy'ye belirli origin'ler için istisna tanıma mekanizmasıdır
- Tarayıcı, isteği göndermeden önce
OPTIONStü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:
fetchveXMLHttpRequest- web font'ları
- WebGL texture'ları
canvasiçindedrawImageile ç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-Originayarlamalıdır; ancak isteğin kendisi preflight olmadan da kabul edilir
- HTML 4.0'daki
Soru:
SameSitepolitikası 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
metaetiketinde 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
Originbaş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=Laxvarsayı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=Laxtü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."
1 yorum
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
CSRF koruması, kimliği doğrulanmış kullanıcı adına kötü amaçlı cross-origin isteklerin yetkisiz işlemler gerçekleştirmesini önler
CSRF koruması yazma korumasıyla, CORS ise okuma korumasıyla ilgilidir
JS ile başlatılan isteklerde varsayılan olarak cross-site izin verilmez
Bu konu hakkında daha iyi bir açıklama olduğunu düşünüyorum
Blog yazısındaki soruya yanıt
2022'de MDN CORS makalesine, "basit istek" teriminin kaynağını netleştirmek için bir paragraf eklendi
SameSite'ın CORS preflight'tan bağımsız olarak eklenmiş olması kafa karıştırıcı
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
CSRF token'larının neden döndürüldüğüne dair bir soru
Karmaşık bir konu için bir akış şeması talebi
Bunlar kolay tanılama izlerini desteklemiyor
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
CSRF koruması hakkındaki kafa karışıklığı