Yazılar

CORS Hatası Nedir ve Aslında Seni Kimden Korur? (Same-Origin Policy & Preflight OPTIONS)

Postman veya cURL ile sorunsuz çalışan API neden tarayıcıda kırmızı "Blocked by CORS policy" hatası verir? Same-Origin Policy, Preflight OPTIONS istekleri ve Access-Control-Max-Age optimizasyonu.

Furkan Özay30 Ekim 2026 · 3 dk okuma
czCZAY.DEV // EDITORIALTR
WEB GÜVENLIĞI

#Web Güvenliği · 3 DK OKUMA

FURKAN ÖZAYVOL. 2026 // #FB4E

Frontend geliştirirken tarayıcı konsolunda şu meşhur kırmızı hatayı görmemiş tek bir yazılımcı bile yoktur:

text
Access to fetch at 'https://api.ornek.com/v1/transfer' from origin 'http://localhost:3000' has been blocked by CORS policy

Çoğu geliştiricinin ilk refleksi sinirlenip backend koduna Access-Control-Allow-Origin: * eklemek ve sorunu "çözmek" olur. Ancak bunu yapmadan önce şu kritik soruyu sormak gerekir: Aynı API isteği Postman veya cURL üzerinden atıldığında hiçbir hata vermezken, neden sadece tarayıcıda engelleniyor?

Çünkü CORS (Cross-Origin Resource Sharing) bir sunucu güvenlik duvarı değildir; tarayıcıdaki kullanıcıyı koruyan bir güvenlik mekanizmasıdır.

1. Same-Origin Policy (Aynı Köken Politikası) Neden Var?

Tarayıcılar varsayılan olarak Same-Origin Policy (SOP) adı verilen katı bir güvenlik kuralıyla çalışır. İki adresin aynı kökene (origin) sahip olması için protokol (https), alan adı (czay.dev) ve port (443) bilgilerinin birebir aynı olması gerekir.

Eğer tarayıcılarda Same-Origin Policy olmasaydı ne olurdu?

  1. Bir sekmede bankanıza (https://banka.com) giriş yaptığınızı ve oturum çerezinizin (session cookie) tarayıcıda kayıtlı olduğunu düşünün.
  2. Yan sekmede masum görünen bir oyun veya haber sitesi (https://zararli-site.com) açtınız.
  3. Bu sitenin içindeki birkaç satırlık JavaScript kodu, arka planda sizin tarayıcınız üzerinden https://banka.com/api/bakiye adresine istek atıp hesap bakiyenizi, özel mesajlarınızı veya kişisel verilerinizi okuyabilirdi.

İşte Same-Origin Policy, zararli-site.com'un banka.com'dan dönen yanıtı okumasını kesin olarak yasaklar.

2. CORS Devreye Nasıl Girer?

Modern web mimarilerinde frontend (https://app.sirket.com) ile backend API (https://api.sirket.com) genellikle farklı alt alan adlarında barındırılır. Tarayıcının bu meşru çapraz köken (Cross-Origin) isteğine izin vermesi için sunucunun yanıt başlıklarında (Response Headers) tarayıcıya açıkça şunu söylemesi gerekir:

http
Access-Control-Allow-Origin: https://app.sirket.com
Access-Control-Allow-Credentials: true

Kritik Güvenlik Notu: Eğer kimlik doğrulama çerezleri veya Authorization başlığı (credentials: 'include') kullanıyorsanız, Access-Control-Allow-Origin: * (yıldız) kullanamazsınız ve asla gelen Origin başlığını doğrulamadan aynen geri yansıtmamalısınız (CORS Misconfiguration zafiyeti). Yalnızca güvendiğiniz domainlerden oluşan bir Whitelist (İzin Listesi) kullanmalısınız.

3. Gizli "OPTIONS" (Preflight / Ön Kontrol) İsteği ve Performans Tuzağı

Tarayıcıdan POST, PUT, DELETE veya Content-Type: application/json içeren bir istek attığınızda, Network sekmesinde asıl isteğinizden hemen önce OPTIONS metoduna sahip ekstra bir istek gittiğini görürsünüz. Buna Preflight (Ön Kontrol) İsteği denir.

Tarayıcı, sunucu üzerinde veri değiştirebilecek bu isteği göndermeden önce sunucuya sorar:

  • "Ben https://app.sirket.com kökeninden geliyorum, sana DELETE metoduyla ve Authorization başlığıyla istek atacağım. İznim var mı?"

Sunucu 204 No Content ve uygun Access-Control-Allow-Methods / Access-Control-Allow-Headers başlıklarıyla onay verirse tarayıcı asıl isteği gönderir.

Access-Control-Max-Age ile Gecikmeyi Sıfırlamak

Kullanıcının yaptığı her API çağrısında önce bir OPTIONS isteği gidip gelmesi (ekstra bir ağ turu / Round-Trip Time), uygulamanızın API yanıt süresini ikiye katlar!

Bunu önlemek için sunucunuzda Access-Control-Max-Age başlığını döndürebilirsiniz:

http
Access-Control-Max-Age: 86400

Bu başlık tarayıcıya "Aldığın bu CORS iznini 86.400 saniye (24 saat) boyunca önbelleğinde (Preflight Cache) tut; aynı endpoint için tekrar tekrar OPTIONS isteği atma!" der. Tek bir satırlık bu yapılandırma, hem sunucu yükünü hem de frontend API gecikmesini dramatik biçimde düşürür.

Bunu da oku