TB
← Tüm yazılar

CORS doğru yapılandırma

Cross-Origin Resource Sharing mekanizmasinin doğru anlasilmasi, güvenli yapilandirmasi ve yaygın hatalarin onlenmesi icin üretim ortamina uygun teknik rehber.

Cross-Origin Resource Sharing (CORS), modern web uygulamalarinda tarayicinin Same-Origin Policy kisitini kontrollu bicimde gevseten bir güvenlik mekanizmasidir. Bir SPA (Single Page Application) farklı bir origin uzerinde barindirilan API ile konusmak istediginde, sunucunun hangi originlerden gelen isteklere izin verecegini açıkça bildirmesi gerekir. CORS yanlış anlasildiginda ya gereksiz yere tüm originlere acilir ya da geliştirme ortaminda çalışan entegrasyonlar uretimde sessizce kirilir. Güvenli CORS yapilandirmasi, hem saldırı yuzeyini daraltir hem de istemci-sunucu sozlesmesini netlestirir.

Same-Origin Policy temeli

Tarayici, güvenlik icin varsayilan olarak bir sayfanin baska origindeki kaynaklara erismesini kisitlar. Origin; protokol, host ve port birlesiminden olusur. https://app.example.com ile https://api.example.com farklı origin sayilir. fetch, XMLHttpRequest ve bazi font veya canvas islemleri bu kurala tabidir. CORS, sunucunun Access-Control-* basliklari ile belirli cross-origin isteklere izin vermesini sağlar; bu bir authentication mekanizmasi degildir, yalnizca tarayici tarafli erişim politikasidir.

Simple vs preflight istekler

Bazi istekler simple request olarak siniflandirilir ve on kontrol (preflight) gerektirmez: GET, HEAD, POST; güvenli header seti; Content-Type yalnizca application/x-www-form-urlencoded, multipart/form-data veya text/plain olabilir. Özel header (Authorization, X-Request-Id), application/json body veya PUT/PATCH/DELETE gibi yöntemler preflight OPTIONS istegi tetikler. Sunucu preflight yanitinda izin verilen yöntem, header ve origin bilgisini dondurmelidir.

OPTIONS /api/orders HTTP/1.1
Origin: https://app.example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: authorization, content-type

HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: authorization, content-type
Access-Control-Max-Age: 600

Access-Control basliklari

Temel basliklar ve anlamlari:

  • Access-Control-Allow-Origin: Izin verilen origin veya * (kimlik bilgili isteklerde kullanılamaz).
  • Access-Control-Allow-Credentials: true ise cookie ve Authorization header gonderilebilir.
  • Access-Control-Expose-Headers: Istemcinin okuyabilecegi özel yanıt headerlari.
  • Access-Control-Allow-Methods: Preflight sonrasi izinli HTTP yontemleri.
  • Access-Control-Allow-Headers: Istekte kullanilabilecek özel headerlar.
  • Vary: Origin: Cache'in origin bazli ayrilmasi icin önemli.

Access-Control-Allow-Origin: * ile Access-Control-Allow-Credentials: true birlikte kullanılamaz. Oturum cookie'si veya JWT bearer token gerektiren API'lerde origin whitelist zorunludur.

ASP.NET Core CORS yapilandirmasi

ASP.NET Core'da CORS middleware sırası kritiktir: UseRouting sonrasi, UseAuthentication ve UseAuthorization oncesi konumlandirilmalidir. Named policy tanimi okunabilirligi artirir:

builder.Services.AddCors(options =>
{
    options.AddPolicy("ProductionWeb", policy =>
    {
        policy.WithOrigins(
                "https://app.example.com",
                "https://staging.example.com")
            .WithMethods("GET", "POST", "PUT", "DELETE", "PATCH")
            .WithHeaders("Authorization", "Content-Type", "X-Correlation-Id")
            .AllowCredentials()
            .SetPreflightMaxAge(TimeSpan.FromMinutes(10));
    });
});

app.UseCors("ProductionWeb");

SetIsOriginAllowed ile dinamik origin kontrolu yapilabilir; ancak wildcard subdomain (*.example.com) regex ile acilirken dikkatli olunmali, sahte domain (evil-example.com) engellenmelidir.

Güvenlik anti-patternleri

Yaygın ve tehlikeli hatalar:

  1. AllowAnyOrigin + AllowCredentials: Framework engeller; buna benzer custom kod credential sizintisina yol acar.
  2. Origin yansitma (reflection): Gelen Origin header'i dogrulanmadan geri dondurmek saldirgan domainine izin verir.
  3. Null origin kabulu: Sandbox iframe veya data URL kaynakli istekler icin dikkatli değerlendirme gerekir.
  4. CORS'u authentication sanmak: Postman, curl ve sunucu-sunucu cagrilari CORS'a tabi degildir; API yetkilendirmesi ayri katmanda olmalidir.
  5. Internal API'de gereksiz CORS: Yalnizca backend-to-backend erisilen servislerde CORS acmak anlamsiz genisleme yaratir.

CSRF ile ilişki

CORS, cross-origin okuma yanitini kisitlar; ancak CSRF baska bir tehdittir. Cookie tabanli oturumda SameSite=Lax veya Strict kullanın; state-changing islemlerde anti-forgery token veya double-submit cookie degerlendirin. JWT bearer ile çalışan SPA'larda cookie CSRF riski düşük olsa da XSS ile token calinmasi ayri savunma gerektirir.

Reverse proxy ve CDN katmanı

Nginx, Cloudflare veya API Gateway uzerinde CORS bazen iki kez uygulanir. Cakisan basliklar tarayiciyi karistirir. Tek bir katmanda (tercihen API uygulamasi veya gateway) merkezi yönetim tercih edilir. Cloudflare Transform Rules ile origin bazli whitelist otomatiklestirilebilir; ancak preflight OPTIONS yanitinin 204/200 dondugunden emin olun.

location /api/ {
    if ($request_method = OPTIONS) {
        add_header Access-Control-Allow-Origin $http_origin always;
        add_header Access-Control-Allow-Credentials true always;
        add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
        add_header Access-Control-Allow-Headers "Authorization, Content-Type" always;
        return 204;
    }
    proxy_pass http://backend;
}

Nginx if blogu dikkatli kullanılmalı; alternatif olarak dedicated OPTIONS location tanimlanabilir.

Test ve dogrulama

CORS testi yalnizca tarayicida anlamli sonuç verir. Playwright veya Cypress ile farklı origin'den istek senaryolari otomatiklestirilebilir. Unit testlerde DefaultHttpContext uzerinde CORS middleware calistirilarak preflight yaniti assert edilir. Güvenlik taramalarinda Access-Control-Allow-Origin: * ve credential kombinasyonu kontrol edilir.

  • Whitelist disi origin 403 veya CORS hatasi vermeli.
  • Preflight cache suresi (Max-Age) gereksiz uzun tutulmamali.
  • Production ve staging origin listeleri ayri policy'de tutulmali.
  • Vary: Origin CDN cache tutarliligini sağlar.

Mikro servis ve BFF mimarisi

Frontend dogrudan on servise erisiyorsa her servisin CORS ayari senkron tutulmalidir. Backend for Frontend (BFF) katmanı ile tarayici tek origin uzerinden konusur; CORS karmasikligi azalir. BFF yine de dis istemcilere aciksa kendi CORS politikasina ihtiyaç duyar. GraphQL endpoint'leri de ayni kurallara tabidir; POST tabanli sorgular preflight tetikleyebilir.

WebSocket ve CORS

WebSocket handshake baslangicta HTTP upgrade istegidir; Origin header kontrol edilmelidir. ASP.NET Core SignalR'da AddCors policy'si hub baglantilarina da uygulanir. Izinsiz origin'den gelen WebSocket baglantisi reddedilmelidir; aksi halde cross-site WebSocket hijacking riski dogar.

Özet kontrol listesi

  1. Origin whitelist açık ve minimum kapsamda mi?
  2. Credentials kullaniliyorsa wildcard origin yok mu?
  3. CORS authentication yerine gecmiyor mu?
  4. Middleware sırası doğru mu?
  5. Preflight OPTIONS hızlı ve cache'lenebilir mi?
  6. CDN/proxy katmaninda baslik cakismasi yok mu?
  7. CSRF ve XSS ile birlikte dusunuldu mu?

CORS, web güvenliğinin tek basina çözümü degildir; doğru yapilandirildiginda tarayici tabanli veri sizintisi ve yetkisiz cross-origin okuma riskini önemli olcude azaltir. Whitelist disiplini, credential kurallari ve katmanli güvenlik yaklasimi ile birlikte uygulandiginda üretim API'leri hem geliştirici dostu hem de saldirgana karşı daha direncli hale gelir.

Gerçek dünya saldırı senaryolari

Finans sektorunde bir fintech uygulamasinda geliştirici, hızlı prototipleme icin AllowAnyOrigin() kullanmis ve uretime tasinmis bir yapılandırma birakmistir. Saldirgan, kullanıcıyı zararli bir siteye yonlendirerek oturum acikken API'ye cross-origin istek gondermis; cookie tabanli oturumda credential izni açık oldugundan hassas hesap bilgileri okunmustur. Çözüm: origin whitelist, kisa oturum suresi, SameSite cookie ve hassas endpoint'lerde ek MFA.

Baska bir senaryoda, public API'de Access-Control-Allow-Origin degeri istemci gonderdigi origin'e echo ediliyordu. Saldirgan kendi domainini Origin olarak gonderip JSON yanitini okuyabiliyordu. Static whitelist ve origin string eslestirmesi (tam esitlik) bu acigi kapatir.

Performans ve operasyon

Preflight istekleri ek round-trip maliyeti getirir. API tasarımında simple request kosullarina uygun endpoint'ler dusunulebilir; ancak güvenlik ve JSON kullanımı genelde preflight'i kabul edilebilir kilar. Access-Control-Max-Age degeri 600-86400 saniye arasi tipiktir. Cok uzun cache, origin listesi degistiginde istemcilerin gec guncellenmesine neden olabilir.

Regulasyon ve denetim

PCI DSS ve SOC2 denetimlerinde cross-origin erişim politikalari sorulur. CORS yapilandirmasinin kod olarak versiyonlanmasi, değişiklik gecmisinin izlenebilir olmasi ve periyodik güvenlik taramasi ile dogrulanmasi beklenir. Penetrasyon testi bulgularinda açık CORS sik karsilasilir; remediation olarak whitelist ve credential review uygulanir.

Dokumantasyon ve ekip egitimi

Frontend ve backend ekipleri CORS hatalarini authentication sanarak saatler harcayabilir. Izin verilen origin listesi, preflight davranisi ve credential kurallari API dokumantasyonunda açıkça yazilmalidir. Yeni ortam acildiginda CORS policy guncellemesi deployment checklist maddesi olmalidir. Bu disiplin, üretim aciklarini ve geliştirme surtunmesini birlikte azaltir.