Application Security

CORS Yapılandırmasını Uzmanlaşmak: Güvenli Çapraz Köken İstekleri İçin Geliştirici Rehberi

Modern web uygulamaları giderek daha karmaşık hale geldikçe, çapraz köken istekleri yapma ihtiyacı temel bir gereklilik haline gelmiştir. Ancak bu istekler, güvenlik korumasını sağlarken işlevselliği etkinleştirmek için dikkatli bir şekilde yapılandırılmalıdır. Çapraz Köken Kaynak Paylaşımı (CORS), tarayıcıların çapraz köken istekleri nasıl işlediğini kontrol eden mekanizmadır ve web API'leriyle çalışan her geliştirici için doğru yapılandırmanın anlaşılması kritik öneme sahiptir.

CORS Temellerini Anlamak

CORS, sunucuların hangi kökenlerin kaynaklarına erişim izni aldığını belirtmesine izin veren HTTP başlık tabanlı bir mekanizmadır. Tarayıcı bir çapraz köken isteği yaptığında, önce asıl isteğin izin verilip verilmediğini kontrol etmek için OPTIONS yöntemiyle bir önceden ön isteği gönderir.

CORS ile ilgili ana başlıklar şunlardır:

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Max-Age: 86400

Temel CORS Yapılandırma Desenleri

Geliştirme ortamları için tüm kökenleri geçici olarak izin vermek isteyebilirsiniz:

// Node.js/Express örneği
app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
  res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
  next();
});

Bu yaklaşım, üretim ortamları için çok tehlikelidir. Daha güvenli bir yaklaşım, güvenilen kökenleri açıkça tanımlamaktır:

// Üretim güvenli CORS yapılandırması
const corsOptions = {
  origin: ['https://yourdomain.com', 'https://www.yourdomain.com'],
  methods: ['GET', 'POST', 'PUT', 'DELETE'],
  allowedHeaders: ['Content-Type', 'Authorization'],
  credentials: true
};

app.use(cors(corsOptions));

Krediler ve Preflight İsteklerini İşleme

Krediler (çerezler, yetkilendirme başlıkları) ile istekler gönderirken, credentials: true seçeneğini ayarlamanız ve Access-Control-Allow-Origin başlığını * yerine belirli bir kökene ayarlamanız gerekir:

// Kredi işleme örneği
app.use((req, res, next) => {
  const allowedOrigins = ['https://yourdomain.com'];
  const origin = req.headers.origin;
  
  if (allowedOrigins.includes(origin)) {
    res.header('Access-Control-Allow-Origin', origin);
    res.header('Access-Control-Allow-Credentials', 'true');
  }
  
  res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
  res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
  next();
});

Yaygın Güvenlik Yakalanmaları ve Çözümler

En tehlikeli hatalardan biri tüm kökenler için * kullanmaktır. Bu yaklaşım uygulamanızı güvenlik açıklarına açar:

// ❌ TEHLİKELİ - Üretimde asla yapmayın
res.header('Access-Control-Allow-Origin', '*');

Bir başka yaygın sorun, önceden ön istekleri düzgün şekilde işlememektir:

// ✅ Doğru önceden ön istek işleme
app.options('*', (req, res) => {
  res.header('Access-Control-Allow-Origin', 'https://yourdomain.com');
  res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
  res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
  res.sendStatus(200);
});

Karmaşık Senaryolar İçin Gelişmiş Yapılandırma

Birden fazla alt alan adı veya karmaşık yönlendirme içeren uygulamalar için dinamik köken kontrolü uygulamayı düşünün:

// Dinamik köken doğrulama
const validateOrigin = (origin) => {
  const allowedOrigins = [
    'https://yourdomain.com',
    'https://api.yourdomain.com',
    'https://admin.yourdomain.com'
  ];
  
  return allowedOrigins.includes(origin) || 
         origin.startsWith('https://staging.yourdomain.com');
};

app.use((req, res, next) => {
  const origin = req.headers.origin;
  
  if (origin && validateOrigin(origin)) {
    res.header('Access-Control-Allow-Origin', origin);
  }
  
  res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
  res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With');
  res.header('Access-Control-Allow-Credentials', 'true');
  res.header('Access-Control-Max-Age', '86400');
  
  if (req.method === 'OPTIONS') {
    res.sendStatus(200);
  } else {
    next();
  }
});

CORS Sorunlarını Ayıklama

Tarayıcı geliştirici araçları CORS sorunlarını ayıklamak için değerli araçlardır. CORS hatalarıyla karşılaştığınızda şunlara bakın:

  • Önceden ön istekler için tarayıcının Ağ sekmesi
  • Belirli CORS ihlallerini gösteren konsol hataları
  • CORS başlıklarının mevcut olduğundan emin olmak için sunucu yanıt başlıkları

CORS başlıklarını doğrudan test etmek için curl kullanın:

curl -H "Origin: https://yourdomain.com" \
     -H "Access-Control-Request-Method: POST" \
     -H "Access-Control-Request-Headers: Content-Type" \
     -X OPTIONS \
     -v https://api.yourdomain.com/endpoint

Sonuç

Doğru CORS yapılandırması, modern web uygulamalarında hem güvenlik hem işlevselliği korumak için gereklidir. Basit görünse de CORS işleme ile ilgili ince ayarlar, doğru uygulanmadıklarında ciddi güvenlik açıklarına yol açabilir. Her zaman kökenleri açıkça doğrulayın, üretimde joker kökenleri kullanmaktan kaçının ve hangi başlıkların ve yöntemlerin izin verileceğini dikkatli düşünün. İyi bir CORS yapılandırmasının sadece işlevselliği etkinleştirmek değil, aynı zamanda uygulamanızı yetkisiz çapraz köken erişimlerinden korumak için önemli olduğunu unutmayın. Bu kılavuzda açıklanan desenleri ve en iyi uygulamaları takip ederek CORS'u güvenli ve verimli bir şekilde yönetmek için iyi donatılmış olacaksınız.

Share: