Mikroservisler ve tek sayfa uygulamaları (SPA'lar) ekosisteminde, Kaynaklar Arası Kaynak Paylaşımı (CORS), en sık yanlış anlaşılan ancak web güvenliğinin kritik bileşenlerinden biri haline gelmiştir. Tarayıcı konsolunuzda "Access to fetch at... from origin... has been blocked by CORS policy" şeklinde şaşırtıcı bir hata mesajıyla karşılaştıysanız, yalnız değilsiniz. Bu rehber, CORS'u aydınlatmayı, altında yatan güvenlik mekanizmalarını açıklamayı ve geliştiriciler için sağlam yapılandırma stratejileri sunmayı amaçlamaktadır.
Aynı Kaynak Politikasını Anlamak
CORS'un neden var olduğunu anlamak için önce Aynı Kaynak Politikası'na (SOP) bakmalıyız. Tarayıcılar, potansiyel olarak zararlı belgeleri izole etmek için SOP'yi uygular. Protokol, ana bilgisayar (alan adı) ve bağlantı noktası aynı olduğunda iki kaynak aynı kabul edilir. SOP, https://app.example.com adresinden yüklenen bir betinin, açıkça izin verilmedikçe https://api.example.com adresinden veri okumasını engeller.
CORS kendi başına bir güvenlik özelliği değildir; SOP'yi gevşetmeye izin veren bir mekanizmadır. Sunuculara, belirli kaynaklar arası isteklere izin vererek yalnızca güvenilir istemcilerin hassas verilere erişmesini sağladığı kontrollü bir yol sunar.
Bir CORS İsteğinin Anatomisi
Bir tarayıcı kaynaklar arası bir istek yaptığında bir kapıcı gibi davranır. İsteğin izin verilip verilmeyeceğini belirlemek için sunucudan gelen yanıt başlıklarını denetler. İsteklerin iki türü vardır: basit ve ön uçlu (preflight).
Basit İstekler herhangi bir önceden iletişimi gerektirmez. Bunlar, standart içerik türlerine sahip GET veya POST istekleridir (örneğin application/x-www-form-urlencoded veya multipart/form-data). Tarayıcı, isteğin nereden geldiğini belirten bir Origin başlığıyla isteği gönderir.
Ön Uçlu İstekler, istek yöntemi DELETE, PUT veya PATCH ise veya özel başlıklar (örneğin X-Custom-Header) veya standart olmayan içerik türleri kullanılırsa gerçekleşir. Bu durumlarda, tarayıcı sunucuya "Bu asıl isteği göndermemde bir sakınca var mı?" diye sormak için önce bir OPTIONS isteği gönderir. Sunucu yalnızca belirli izin verilen başlıkları ve yöntemleri içeren bir yanıt verirse, tarayıcı asıl isteği devam ettirir.
Temel CORS Başlıkları Açıklaması
Yapılandırma, HTTP başlıklarının doğru şekilde ayarlanmasına dayanır. İşte en kritik olanlar:
Access-Control-Allow-Origin: İzin verilen kaynakları belirtir.*kullanmak tüm kaynaklara izin verir, ancak bu genellikle kimlik doğrulaması gerektiren API'ler için tavsiye edilmez.Access-Control-Allow-Methods: İzin verilen HTTP yöntemlerini listeler (örneğin, GET, POST, OPTIONS).Access-Control-Allow-Headers: Asıl istekte hangi başlıkların kullanılabileceğini belirtir.Access-Control-Allow-Credentials:trueolarak ayarlanırsa, istekle birlikte çerezlerin ve kimlik doğrulama bilgilerinin gönderilmesine izin verir.
Pratik Yapılandırma Örnekleri
Aşağıda, popüler backend çerçevelerinde CORS'un nasıl yapılandırılacağına dair örnekler bulunmaktadır. Unutmayın ki amaç, mümkün olduğunda kısıtlayıcı olmak ve yalnızca gerekli olanlara izin vermektir.
Express ile Node.js
cors ara yazılımını kullanmak standart yaklaşımdır. Üretim API'leri için, kimlik bilgilerini desteklemeniz gerekiyorsa * joker karakterlerini kullanmaktan kaçının.
const cors = require('cors');
const express = require('express');
const app = express();
// Yalnızca belirli kaynaklara izin ver
const corsOptions = {
origin: ['https://frontend.example.com', 'http://localhost:3000'],
optionsSuccessStatus: 200, // Bazı eski tarayıcılar 204'te takılıyor
credentials: true // Çerez göndermeye izin verir
};
app.use(cors(corsOptions));
Flask ile Python
flask-cors uzantısı bu süreci önemli ölçüde basitleştirir.
from flask import Flask
from flask_cors import CORS
app = Flask(__name__)
# Belirli bir alan adıyla kısıtla
CORS(app, origins=["https://frontend.example.com"])
@app.route('/data')
def get_data():
return {'message': 'Güvenli veri'}
Yaygın Tuzaklar ve En İyi Uygulamalar
En yaygın hatalardan biri, Access-Control-Allow-Credentials: true etkinleştirilirken aynı anda Access-Control-Allow-Origin: * ayarlamaktır. Bu kombinasyon, CORS belirtimine göre geçersizdir. Kimlik bilgileri söz konusu olduğunda, kesin kaynağı belirtmeniz gerekir.
Başka bir tuzak, ön uçlu isteklerin yanlış yönetilmesidir. Sunucunuzun OPTIONS istekleri için 204 No Content veya 200 OK durumunu döndürdüğünden emin olun. Ön uçlu istek başarısız olursa, asıl istek asla gönderilmez ve bu da kafa karıştırıcı hatalara yol açar.
Son olarak, güvenlik durumunuzu her zaman göz önünde bulundurun. CORS yapılandırmalarınızı düzenli olarak denetleyin. Kaynaklar arası erişime ihtiyaç duymayan bir hizmetiniz varsa, CORS'u tamamen devre dışı bırakın veya yalnızca localhost ile sınırlayın. İçerik Güvenliği Politikası (CSP) uygulamak, belirli saldırı türlerine karşı ek bir savunma katmanı da sağlayabilir.
Sonuç
CORS, ince ama web geliştirmenin temel bir yönüdür. Basit ve ön uçlu istekler arasındaki farkı anlayarak ve izin verilen kaynakları, yöntemleri ve başlıkları dikkatlice yapılandırarak geliştiriciler hem güvenli hem de erişilebilir API'ler oluşturabilir. Üretim ortamında geniş joker karakter yapılandırmaları kullanma cazibesine karşı koyun. Bunun yerine, hizmetlerinize kimin konuşabileceğini tam olarak belirten bir beyaz liste yaklaşımı benimseyin. Doğru yapılandırma ile, uygulamanız yetkisiz kaynaklar arası erişime karşı sağlam kalırken, meşru kullanıcılar için sorunsuz işlevselliği koruyabilirsiniz.