- Konu sahibi
- #1
CORS, farklı origin’ler arasında tarayıcının bir yanıtı JavaScript koduna açıp açmayacağını belirleyen erişim mekanizmasıdır. CSRF ise kullanıcının oturum bilgileriyle, haberi veya onayı olmadan sunucuda işlem yaptırma saldırısıdır. Kısaca CORS bir tarayıcı erişim politikası, CSRF ise yetkisiz durum değiştirme saldırısı ve buna karşı alınan önlemler konusudur. Yalnızca CORS yanıt başlığı eklemek, genel bir CSRF korumasının yerine geçmez.
CORS genellikle farklı origin’deki bir arayüzün API’ye
Kimlik doğrulama çerezleri de gönderilecekse istemci tarafında kimlik bilgileriyle istek yapılmalı, sunucu da uygun şekilde
CSRF’de saldırganın amacı yanıtı okumak değil, kurbanın zaten giriş yaptığı uygulamaya istek göndertmektir. Örneğin kullanıcı
CORS ile CSRF’yi aynı sorun sanmamak için aşağıdaki ayrımı kullanın:
Önemli nokta şudur: CORS hatası görmek genellikle tarayıcının yanıtı JavaScript’e vermediği anlamına gelir. Bu, sunucunun isteği hiç almadığı anlamına gelmeyebilir. CSRF’de ise özellikle form gönderimleri gibi bazı cross-origin istekler, yanıt okunamasa bile sunucuya ulaşabilir. Bu nedenle yalnızca CORS yanıtının okunmasını engellemek, tek başına CSRF’yi çözmez. Örneğin saldırganın formu bir profil alanını değiştirebiliyorsa yanıtı görememesi gerçekleşmiş değişikliği geri almaz. Buna karşılık başka origin’den veri okuyacak meşru bir arayüzde CORS izni gerekebilir; bu iki testi farklı sonuçlarla değerlendirin.
Özel başlık zorunlu tutan API savunmalarında CORS preflight mekanizması korumanın bir parçası olabilir. Bunun için backend eksik özel başlığı reddetmeli ve CORS yalnız kesin olarak güvenilen origin’lere izin vermelidir. Bu tasarımı, herhangi bir CORS başlığı ekleyince bütün formların CSRF’ye kapandığı şeklinde yorumlamayın.
“CORS’u açarsam CSRF çözülür” düşüncesi yanlıştır. CORS, çoğunlukla yanıtın okunmasını sınırlar; saldırganın form veya benzeri yollarla istek göndermesini tek başına engellemez.
“Sadece POST kabul ediyorum, CSRF olmaz” yaklaşımı da yeterli değildir. Saldırgan başka bir sayfadaki otomatik HTML formuyla POST isteği oluşturabilir. Durum değiştiren POST istekleri de CSRF token’ı veya eşdeğer bir sunucu doğrulaması gerektirir.
“Origin başlığını gelen değerle aynen geri döndüreyim” uygulaması güvenli bir CORS politikası değildir. İzin verilen origin’leri sabit bir listeyle karşılaştırın; kimlik bilgili isteklerde wildcard ve gelişigüzel origin yansıtma kullanmayın.
Yetkili bir test hesabında, durum değiştiren uç noktanın geçersiz veya eksik CSRF doğrulamasını reddettiğini ayrıca sınayın. Başarılı bir CORS yanıtı bu kontrolün geçtiğini kanıtlamaz. CORS hatası görmek de güvenlik denetimlerinin tamamlandığını göstermez.
Hayır. Aynı şemayla açılan app.example.com ve api.example.com farklı origin’lerken same-site kapsamında olabilir. Bu nedenle SameSite çerezi, CORS origin izin listesinin eşdeğeri değildir. Alt alan adlarının güvenliğini ve hangi çerezlerin hangi isteğe eklendiğini ayrıca değerlendirin.
JWT’nin nerede tutulduğu ve isteğe nasıl eklendiği önemlidir. Token otomatik gönderilen bir çerezde tutuluyorsa CSRF riski devam edebilir; yalnızca JavaScript’in açıkça eklediği bir başlıkla gönderiliyorsa klasik çerez tabanlı CSRF senaryosu farklılaşır, fakat XSS gibi başka riskler ayrıca ele alınmalıdır.
Temel çalışma farkı
CORS genellikle farklı origin’deki bir arayüzün API’ye
fetch() veya XMLHttpRequest ile erişmesi gerektiğinde kullanılır. Origin; şema, alan adı ve portun birleşimidir. Örneğin https://app.example.com ile https://api.example.com farklı origin’lerdir. API, izin verilen arayüze şu tür bir yanıt başlığı göndererek yanıtın okunmasına izin verebilir:
Kod:
Access-Control-Allow-Origin: https://app.example.com
Kimlik doğrulama çerezleri de gönderilecekse istemci tarafında kimlik bilgileriyle istek yapılmalı, sunucu da uygun şekilde
Access-Control-Allow-Credentials: true döndürmelidir. Bu durumda Access-Control-Allow-Origin: * kullanılamaz; izin verilen origin açıkça belirtilmelidir.CSRF’de saldırganın amacı yanıtı okumak değil, kurbanın zaten giriş yaptığı uygulamaya istek göndertmektir. Örneğin kullanıcı
https://bank.example.com üzerinde oturum açmışken kötü amaçlı bir sayfa, para transferi veya e-posta değiştirme isteği oluşturmaya çalışabilir. Tarayıcı oturum çerezini isteğe eklerse sunucu, isteği kullanıcının kendisi göndermiş gibi değerlendirebilir.Karşılaştırma
CORS ile CSRF’yi aynı sorun sanmamak için aşağıdaki ayrımı kullanın:
| Konu | CORS | CSRF |
|---|---|---|
| Temel soru | Bu origin yanıtı JavaScript ile okuyabilir mi? | Bu istek gerçekten kullanıcının isteği mi? |
| Amaç | Farklı origin’lerden kontrollü yanıt erişimi | Saldırganın kullanıcı adına işlem yaptırması |
| İlgili mekanizma | HTTP yanıt başlıkları ve tarayıcı politikası | CSRF token’ı, SameSite çerezi ve istek doğrulaması |
| Sonuç | Yanıt okunamaz veya okunabilir | İşlem reddedilir veya saldırı gerçekleşir |
Özel başlık zorunlu tutan API savunmalarında CORS preflight mekanizması korumanın bir parçası olabilir. Bunun için backend eksik özel başlığı reddetmeli ve CORS yalnız kesin olarak güvenilen origin’lere izin vermelidir. Bu tasarımı, herhangi bir CORS başlığı ekleyince bütün formların CSRF’ye kapandığı şeklinde yorumlamayın.
Uygulamada hangi önlemi seçmelisiniz?
- Arayüzünüz başka bir origin’deki API yanıtını okuyacaksa API tarafında yalnızca gerekli origin’leri CORS ile izinli listeye alın. Özel API’lerde gelişigüzel
*kullanmayın. - Oturum çereziyle çalışan ve veri değiştiren her isteği CSRF açısından değerlendirin. Profil güncelleme, sipariş, ödeme veya parola değişikliği gibi işlemler
GETile yapılmamalıdır. - Önce framework’ün yerleşik CSRF korumasını kullanın. Form tabanlı token deseninde sunucunun ürettiği, tahmin edilemeyen CSRF token’ını formda ve sunucudaki doğrulamada kullanın. Token yoksa veya geçersizse isteği reddedin.
- JavaScript ile yapılan durum değiştiren isteklerde token’ı özel bir başlıkta veya uygun istek alanında gönderin; sunucu token’ı oturumla ilişkilendirerek kontrol etsin.
- Oturum çerezlerinde uygun
SameSitepolitikasını kullanın. Bu ek savunmadır; tek başına tüm CSRF senaryolarının yerine geçmez. - CORS preflight isteği kullanılıyorsa
OPTIONSyanıtında izin verilen yöntem ve başlıkları doğru tanımlayın. CORS ayarını düzeltmek, CSRF token doğrulamasını kaldırmayı gerektirmez.
Sık yapılan hatalar
“CORS’u açarsam CSRF çözülür” düşüncesi yanlıştır. CORS, çoğunlukla yanıtın okunmasını sınırlar; saldırganın form veya benzeri yollarla istek göndermesini tek başına engellemez.
“Sadece POST kabul ediyorum, CSRF olmaz” yaklaşımı da yeterli değildir. Saldırgan başka bir sayfadaki otomatik HTML formuyla POST isteği oluşturabilir. Durum değiştiren POST istekleri de CSRF token’ı veya eşdeğer bir sunucu doğrulaması gerektirir.
“Origin başlığını gelen değerle aynen geri döndüreyim” uygulaması güvenli bir CORS politikası değildir. İzin verilen origin’leri sabit bir listeyle karşılaştırın; kimlik bilgili isteklerde wildcard ve gelişigüzel origin yansıtma kullanmayın.
Yetkili bir test hesabında, durum değiştiren uç noktanın geçersiz veya eksik CSRF doğrulamasını reddettiğini ayrıca sınayın. Başarılı bir CORS yanıtı bu kontrolün geçtiğini kanıtlamaz. CORS hatası görmek de güvenlik denetimlerinin tamamlandığını göstermez.
Sık sorulan sorular
SameSite ile same-origin aynı sınır mı?
Hayır. Aynı şemayla açılan app.example.com ve api.example.com farklı origin’lerken same-site kapsamında olabilir. Bu nedenle SameSite çerezi, CORS origin izin listesinin eşdeğeri değildir. Alt alan adlarının güvenliğini ve hangi çerezlerin hangi isteğe eklendiğini ayrıca değerlendirin.
JWT kullanıyorsam CSRF tamamen ortadan kalkar mı?
JWT’nin nerede tutulduğu ve isteğe nasıl eklendiği önemlidir. Token otomatik gönderilen bir çerezde tutuluyorsa CSRF riski devam edebilir; yalnızca JavaScript’in açıkça eklediği bir başlıkla gönderiliyorsa klasik çerez tabanlı CSRF senaryosu farklılaşır, fakat XSS gibi başka riskler ayrıca ele alınmalıdır.