Çapraz Kaynak Paylaşımı (CORS) ve ön kontrol isteklerinin derinlemesine incelenmesi. CORS sorunlarını nasıl ele alacağınızı ve web uygulamalarınızı küresel bir kitle için nasıl güvenli hale getireceğinizi öğrenin.
CORS'u Basitleştirmek: JavaScript Ön Kontrol İsteği İşlemeye Derinlemesine Bir Bakış
Web geliştirmenin sürekli genişleyen dünyasında güvenlik her şeyden önemlidir. Çapraz Kaynak Paylaşımı (CORS), web tarayıcıları tarafından, web sayfalarının, web sayfasının sunulduğu alan adından farklı bir alan adına istek göndermesini kısıtlamak için uygulanan önemli bir güvenlik mekanizmasıdır. Bu, kötü amaçlı web sitelerinin hassas verilere erişmesini önlemek için tasarlanmış temel bir güvenlik özelliğidir. Bu kapsamlı kılavuz, özellikle ön kontrol isteği işlemeye odaklanarak CORS'un inceliklerini derinlemesine inceleyecektir. Geliştiriciler tarafından dünya çapında karşılaşılan yaygın sorunlara pratik örnekler ve çözümler sunarak CORS'un 'neden', 'ne' ve 'nasıl' sorularını keşfedeceğiz.
Aynı Kaynak İlkesini Anlamak
CORS'un kalbinde Aynı Kaynak İlkesi (SOP) yatar. Bu ilke, bir kaynakta çalışan komut dosyalarının farklı bir kaynaktan kaynaklara erişmesini kısıtlayan tarayıcı düzeyinde bir güvenlik mekanizmasıdır. Bir kaynak, protokol (örneğin, HTTP veya HTTPS), alan adı (örneğin, example.com) ve bağlantı noktası (örneğin, 80 veya 443) ile tanımlanır. Bu üç bileşen tam olarak eşleşirse, iki URL aynı kaynağa sahiptir.
Örneğin:
https://www.example.com/app1/index.htmlvehttps://www.example.com/app2/index.htmlaynı kaynağa sahiptir (aynı protokol, alan adı ve bağlantı noktası).https://www.example.com/index.htmlvehttp://www.example.com/index.htmlfarklı kaynaklara sahiptir (farklı protokoller).https://www.example.com/index.htmlvehttps://api.example.com/index.htmlfarklı kaynaklara sahiptir (farklı alt alan adları farklı alan adları olarak kabul edilir).https://www.example.com:8080/index.htmlvehttps://www.example.com/index.htmlfarklı kaynaklara sahiptir (farklı bağlantı noktaları).
SOP, bir web sitesindeki kötü amaçlı komut dosyalarının başka bir web sitesindeki çerezler veya kullanıcı kimlik doğrulama bilgileri gibi hassas verilere erişmesini önlemek için tasarlanmıştır. Güvenlik için gerekli olmakla birlikte, SOP özellikle meşru çapraz kaynak istekleri gerektiğinde kısıtlayıcı olabilir.
Çapraz Kaynak Paylaşımı (CORS) Nedir?
CORS, sunucuların kaynaklarına hangi kaynakların (alan adları, şemalar veya bağlantı noktaları) erişmesine izin verildiğini belirtmelerine olanak tanıyan bir mekanizmadır. Esasen SOP'yi gevşetir ve kontrollü çapraz kaynak erişimine izin verir. CORS, istemci (genellikle bir web tarayıcısı) ve sunucu arasında değiş tokuş edilen HTTP başlıkları kullanılarak uygulanır.
Bir tarayıcı çapraz kaynak isteği yaptığında (yani, mevcut sayfadan farklı bir kaynağa istek), önce sunucunun isteğe izin verip vermediğini kontrol eder. Bu, sunucunun yanıtındaki Access-Control-Allow-Origin başlığı incelenerek yapılır. İsteğin kaynağı bu başlıkta listeleniyorsa (veya başlık tüm kaynaklara izin veren * olarak ayarlanmışsa), tarayıcı isteğin devam etmesine izin verir. Aksi takdirde, tarayıcı isteği engeller ve JavaScript kodunun yanıt verilerine erişmesini önler.
Ön Kontrol İsteklerinin Rolü
Belirli türdeki çapraz kaynak istekleri için tarayıcı bir ön kontrol isteği başlatır. Bu, gerçek istekten önce sunucuya gönderilen bir OPTIONS isteğidir. Ön kontrol isteğinin amacı, sunucunun gerçek isteği kabul etmeye istekli olup olmadığını belirlemektir. Sunucu, ön kontrol isteğine izin verilen yöntemler, başlıklar ve diğer kısıtlamalar hakkında bilgi ile yanıt verir.
Ön kontrol istekleri, çapraz kaynak isteği aşağıdaki koşullardan herhangi birini karşıladığında tetiklenir:
- İstek yöntemi
GET,HEADveyaPOSTdeğil. - İstek özel başlıklar içeriyor (yani, tarayıcı tarafından otomatik olarak eklenenler dışındaki başlıklar).
Content-Typebaşlığıapplication/x-www-form-urlencoded,multipart/form-dataveyatext/plaindışında herhangi bir değere ayarlanmış.- İstek gövdesinde
ReadableStreamnesneleri kullanıyor.
Örneğin, Content-Type'ı application/json olan bir PUT isteği, izin verilenlerden farklı bir yöntem ve potansiyel olarak izin verilmeyen bir içerik türü kullandığı için bir ön kontrol isteğini tetikleyecektir.
Neden Ön Kontrol İstekleri?
Ön kontrol istekleri, sunucuya potansiyel olarak zararlı çapraz kaynak isteklerini yürütülmeden önce reddetme fırsatı verdikleri için güvenlik açısından önemlidir. Ön kontrol istekleri olmadan, kötü amaçlı bir web sitesi, sunucunun açık izni olmadan sunucuya rastgele istekler gönderebilir. Bir ön kontrol isteği, sunucunun isteğin kabul edilebilir olduğunu doğrulamasını sağlar ve potansiyel olarak zararlı işlemleri önler.
Sunucu Tarafında Ön Kontrol İsteklerini İşleme
Web uygulamanızın doğru ve güvenli bir şekilde çalışmasını sağlamak için ön kontrol isteklerini doğru şekilde işlemek çok önemlidir. Sunucu, gerçek isteğe izin verilip verilmediğini belirtmek için OPTIONS isteğine uygun CORS başlıklarıyla yanıt vermelidir.
İşte ön kontrol yanıtlarında kullanılan temel CORS başlıklarının bir dökümü:
Access-Control-Allow-Origin: Bu başlık, kaynağa erişmesine izin verilen kaynakları belirtir. Belirli bir kaynağa (örneğin,https://www.example.com) veya tüm kaynaklara izin vermek için*olarak ayarlanabilir. Ancak, özellikle sunucu hassas verileri işliyorsa,*kullanılması genellikle güvenlik nedeniyle önerilmez.Access-Control-Allow-Methods: Bu başlık, çapraz kaynak isteği için izin verilen HTTP yöntemlerini belirtir (örneğin,GET,POST,PUT,DELETE).Access-Control-Allow-Headers: Bu başlık, gerçek istekte izin verilen standart olmayan HTTP başlıklarının listesini belirtir. İstemciX-Custom-HeaderveyaAuthorizationgibi özel başlıklar gönderiyorsa bu gereklidir.Access-Control-Allow-Credentials: Bu başlık, gerçek isteğin çerezler veya yetkilendirme başlıkları gibi kimlik bilgilerini içerip içeremeyeceğini gösterir. İstemci tarafı kodu kimlik bilgileri gönderiyorsa ve sunucu bunları kabul etmesi gerekiyorsa,trueolarak ayarlanmalıdır. Not: Bu başlık `true` olarak ayarlandığında, `Access-Control-Allow-Origin` `*` olarak ayarlanamaz. Kaynağı belirtmelisiniz.Access-Control-Max-Age: Bu başlık, tarayıcının ön kontrol yanıtını önbelleğe alabileceği maksimum süreyi (saniye cinsinden) belirtir. Bu, gönderilen ön kontrol isteklerinin sayısını azaltarak performansı artırmaya yardımcı olabilir.
Örnek: Express ile Node.js'de Ön Kontrol İsteklerini İşleme
İşte Express çerçevesini kullanarak bir Node.js uygulamasında ön kontrol isteklerinin nasıl işleneceğine dair bir örnek:
const express = require('express');
const cors = require('cors');
const app = express();
// Tüm kaynaklar için CORS'u etkinleştir (yalnızca geliştirme amaçları için!)
// Üretimde, daha iyi güvenlik için izin verilen kaynakları belirtin.
app.use(cors()); // veya app.use(cors({origin: 'https://www.example.com'}));
// OPTIONS isteklerini (ön kontrol) işleme rotası
app.options('/data', cors()); // Tek bir rota için CORS'u etkinleştir. Veya kaynağı belirtin: cors({origin: 'https://www.example.com'})
// GET isteklerini işleme rotası
app.get('/data', (req, res) => {
res.json({ message: 'Bu çapraz kaynak verisidir!' });
});
// Bir ön kontrolü ve bir post isteğini işleme rotası
app.options('/resource', cors()); // DELETE isteği için ön kontrol isteğini etkinleştir
app.delete('/resource', cors(), (req, res, next) => {
res.send('kaynağı sil')
})
const port = 3000;
app.listen(port, () => {
console.log(`Sunucu ${port} bağlantı noktasında dinleniyor`);
});
Bu örnekte, CORS isteklerini işlemek için cors ara yazılımını kullanıyoruz. Daha ayrıntılı kontrol için CORS, rota başına etkinleştirilebilir. Not: üretimde, tüm kaynaklara izin vermek yerine origin seçeneğini kullanarak izin verilen kaynakları belirtmeniz şiddetle tavsiye edilir. * kullanarak tüm kaynaklara izin vermek, uygulamanızı güvenlik açıklarına maruz bırakabilir.
Örnek: Flask ile Python'da Ön Kontrol İsteklerini İşleme
İşte Flask çerçevesini ve flask_cors uzantısını kullanarak bir Python uygulamasında ön kontrol isteklerinin nasıl işleneceğine dair bir örnek:
from flask import Flask, jsonify
from flask_cors import CORS, cross_origin
app = Flask(__name__)
CORS(app) # Tüm rotalar için CORS'u etkinleştir
@app.route('/data')
@cross_origin()
def get_data():
data = {"message": "Bu çapraz kaynak verisidir!"}
return jsonify(data)
if __name__ == '__main__':
app.run(debug=True)
Bu en basit kullanımdır. Daha önce olduğu gibi, kaynaklar kısıtlanabilir. Ayrıntılar için flask-cors belgelerine bakın.
Örnek: Spring Boot ile Java'da Ön Kontrol İsteklerini İşleme
İşte Spring Boot kullanarak bir Java uygulamasında ön kontrol isteklerinin nasıl işleneceğine dair bir örnek:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@SpringBootApplication
public class CorsApplication {
public static void main(String[] args) {
SpringApplication.run(CorsApplication.class, args);
}
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/data").allowedOrigins("http://localhost:8080");
}
};
}
}
Ve ilgili denetleyici:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DataController {
@GetMapping("/data")
public String getData() {
return "Bu çapraz kaynak verisidir!";
}
}
Yaygın CORS Sorunları ve Çözümleri
Önemi ne olursa olsun, CORS genellikle geliştiriciler için bir hayal kırıklığı kaynağı olabilir. İşte bazı yaygın CORS sorunları ve çözümleri:
-
Hata: "İstenen kaynakta 'Access-Control-Allow-Origin' başlığı bulunmuyor."
Bu hata, sunucunun yanıtında
Access-Control-Allow-Originbaşlığını döndürmediğini gösterir. Bunu düzeltmek için, sunucunun başlığı içerecek şekilde yapılandırıldığından ve doğru kaynağa veya (uygunsa)*değerine ayarlandığından emin olun.Çözüm: Sunucuyu, yanıtında `Access-Control-Allow-Origin` başlığını içerecek ve bunu istekte bulunan web sitesinin kaynağına veya tüm kaynaklara izin vermek için `*` olarak ayarlayacak şekilde yapılandırın (dikkatli kullanın).
-
Hata: "Ön kontrol isteğine yanıt erişim kontrolü kontrolünü geçemedi: İstek başlığı alanı X-Custom-Header, ön kontrol yanıtında Access-Control-Allow-Headers tarafından izin verilmiyor."
Bu hata, sunucunun çapraz kaynak isteğinde özel başlığa (bu örnekte
X-Custom-Header) izin vermediğini gösterir. Bunu düzeltmek için, sunucunun ön kontrol yanıtındakiAccess-Control-Allow-Headersbaşlığında başlığı içerdiğinden emin olun.Çözüm: Sunucunun ön kontrol yanıtındaki `Access-Control-Allow-Headers` başlığına özel başlığı (örneğin, `X-Custom-Header`) ekleyin.
-
Hata: "Kimlik bilgileri bayrağı 'true', ancak 'Access-Control-Allow-Origin' başlığı '*'."
Access-Control-Allow-Credentialsbaşlığıtrueolarak ayarlandığında,Access-Control-Allow-Originbaşlığı*değil, belirli bir kaynağa ayarlanmalıdır. Bunun nedeni, tüm kaynaklardan gelen kimlik bilgilerine izin vermenin bir güvenlik riski oluşturmasıdır.Çözüm: Kimlik bilgilerini kullanırken, `Access-Control-Allow-Origin` öğesini `*` yerine belirli bir kaynağa ayarlayın.
-
Ön kontrol isteği gönderilmiyor.
Javascript kodunuzun `credentials: 'include'` özelliğini içerdiğinden emin olun. Ayrıca sunucunuzun `Access-Control-Allow-Credentials: true` öğesine izin verdiğini de kontrol edin.
-
Sunucu ve istemci arasında çakışan yapılandırmalar.
İstemci tarafı ayarlarının yanı sıra sunucu tarafı CORS yapılandırmanızı da dikkatlice kontrol edin. Uyuşmazlıklar (örneğin, sunucunun yalnızca GET isteklerine izin vermesi ancak istemcinin POST göndermesi) CORS hatalarına neden olur.
CORS ve Güvenlik En İyi Uygulamaları
CORS, kontrollü çapraz kaynak erişimine izin verirken, güvenlik açıklarını önlemek için güvenlik en iyi uygulamalarını izlemek önemlidir:
- Üretimde
Access-Control-Allow-Originbaşlığında*kullanmaktan kaçının. Bu, tüm kaynakların kaynaklarınıza erişmesine izin verir ve bu da bir güvenlik riski olabilir. Bunun yerine, izin verilen tam kaynakları belirtin. - İzin verilecek yöntemleri ve başlıkları dikkatlice değerlendirin. Yalnızca uygulamanızın doğru şekilde çalışması için kesinlikle gerekli olan yöntemlere ve başlıklara izin verin.
- Uygun kimlik doğrulama ve yetkilendirme mekanizmaları uygulayın. CORS, kimlik doğrulama ve yetkilendirmenin yerine geçmez. API'nizin uygun güvenlik önlemleriyle korunduğundan emin olun.
- Tüm kullanıcı girişlerini doğrulayın ve temizleyin. Bu, siteler arası komut dosyası çalıştırma (XSS) saldırılarını ve diğer güvenlik açıklarını önlemeye yardımcı olur.
- Sunucu tarafı CORS yapılandırmanızı güncel tutun. Uygulamanızın güvenlik gereksinimleriyle uyumlu olduğundan emin olmak için CORS yapılandırmanızı düzenli olarak gözden geçirin ve güncelleyin.
Farklı Geliştirme Ortamlarında CORS
CORS sorunları, çeşitli geliştirme ortamlarında ve teknolojilerinde farklı şekilde ortaya çıkabilir. İşte birkaç yaygın senaryoda CORS'a nasıl yaklaşılacağına dair bir bakış:
Yerel Geliştirme Ortamları
Yerel geliştirme sırasında CORS sorunları özellikle can sıkıcı olabilir. Tarayıcılar genellikle yerel geliştirme sunucunuzdan (örneğin, localhost:3000) uzak bir API'ye gelen istekleri engeller. Çeşitli teknikler bu acıyı hafifletebilir:
- Tarayıcı Uzantıları: "CORS'a İzin Ver: Access-Control-Allow-Origin" gibi uzantılar, test amacıyla CORS kısıtlamalarını geçici olarak devre dışı bırakabilir. Ancak, bunları üretimde *asla* kullanmayın.
- Proxy Sunucuları: İstekleri yerel geliştirme sunucunuzdan uzak API'ye ileten bir proxy sunucusu yapılandırın. Bu, istekleri tarayıcının bakış açısından etkili bir şekilde "aynı kaynak" yapar.
http-proxy-middleware(Node.js için) gibi araçlar bu konuda yardımcı olur. - Sunucu CORS'unu Yapılandırın: Geliştirme sırasında bile, API sunucunuzu yerel geliştirme kaynağınızdan (örneğin,
http://localhost:3000) gelen isteklere açıkça izin verecek şekilde yapılandırmak en iyi uygulamadır. Bu, gerçek dünya CORS yapılandırmasını simüle eder ve sorunları erken yakalamanıza yardımcı olur.
Sunucusuz Ortamlar (örneğin, AWS Lambda, Google Cloud Functions)
Sunucusuz işlevler genellikle dikkatli CORS yapılandırması gerektirir. Birçok sunucusuz platform, yerleşik CORS desteği sağlar, ancak bunu doğru şekilde yapılandırmak çok önemlidir:
- Platforma Özgü Ayarlar: Platformun yerleşik CORS yapılandırma seçeneklerini kullanın. Örneğin AWS Lambda, API Gateway ayarlarında izin verilen kaynakları, yöntemleri ve başlıkları doğrudan belirtmenize olanak tanır.
- Ara Yazılım/Kitaplıklar: Daha fazla esneklik için, sunucusuz işlev kodunuz içinde CORS'u işlemek üzere ara yazılım veya kitaplıklar kullanabilirsiniz. Bu, geleneksel sunucu ortamlarında kullanılan yaklaşımlara benzer (örneğin, Node.js Lambda işlevlerinde `cors` paketini kullanmak).
- `OPTIONS` Yöntemini Göz Önünde Bulundurun: Sunucusuz işlevinizin
OPTIONSisteklerini doğru şekilde işlediğinden emin olun. Bu genellikle, uygun CORS başlıklarını döndüren ayrı bir rota oluşturmayı içerir.
Mobil Uygulama Geliştirme (örneğin, React Native, Flutter)
Yerel mobil uygulamalar (Android, iOS) için CORS, web tarayıcıları ile aynı şekilde aynı kaynak ilkesini zorlamadıkları için doğrudan bir endişe kaynağı değildir. Bununla birlikte, mobil uygulamanız web içeriğini görüntülemek için bir web görünümü kullanıyorsa veya JavaScript'ten yararlanan React Native veya Flutter gibi çerçeveler kullanıyorsanız, CORS hala alakalı olabilir:
- Web Görünümleri: Mobil uygulamanız web içeriğini görüntülemek için bir web görünümü kullanıyorsa, web tarayıcısındakiyle aynı CORS kuralları geçerlidir. Sunucunuzu, web içeriğinin kaynağından gelen isteklere izin verecek şekilde yapılandırın.
- React Native/Flutter: Bu çerçeveler, API istekleri yapmak için JavaScript kullanır. Yerel ortam CORS'u doğrudan zorlamasa da, temel HTTP istemcileri (örneğin,
fetch) bazı durumlarda hala CORS benzeri davranışlar sergileyebilir. - Yerel HTTP İstemcileri: Doğrudan yerel koddan API istekleri yaparken (örneğin, Android'de OkHttp veya iOS'te URLSession kullanırken), CORS genellikle bir faktör değildir. Ancak, uygun kimlik doğrulama ve yetkilendirme gibi güvenlik en iyi uygulamalarını yine de dikkate almanız gerekir.
CORS Yapılandırması için Küresel Hususlar
Küresel olarak erişilebilir bir uygulama için CORS'u yapılandırırken, aşağıdakiler gibi faktörleri dikkate almak çok önemlidir:
- Veri Egemenliği: Bazı bölgelerdeki düzenlemeler, verilerin bölge içinde bulunmasını zorunlu kılar. Sınır ötesi kaynaklara erişirken CORS dahil olabilir ve potansiyel olarak veri yerleşimi yasalarına aykırı olabilir.
- Bölgesel Güvenlik Politikaları: Farklı ülkeler, CORS'un nasıl uygulanması ve güvence altına alınması gerektiğini etkileyen farklı siber güvenlik düzenlemelerine ve yönergelerine sahip olabilir.
- İçerik Dağıtım Ağları (CDN'ler): CDN'nizin gerekli CORS başlıklarını geçirecek şekilde doğru şekilde yapılandırıldığından emin olun. Yanlış yapılandırılmış CDN'ler, CORS başlıklarını kaldırabilir ve beklenmedik hatalara yol açabilir.
- Yük Dengeleyiciler ve Proxy'ler: Altyapınızdaki yük dengeleyicilerin veya ters proxy'lerin ön kontrol isteklerini doğru şekilde işlediğini ve CORS başlıklarını geçirdiğini doğrulayın.
- Çok Dilli Destek: CORS'un uygulamanızın uluslararasılaştırma (i18n) ve yerelleştirme (l10n) stratejileriyle nasıl etkileşime girdiğini göz önünde bulundurun. CORS ilkelerinin uygulamanızın farklı dil sürümlerinde tutarlı olduğundan emin olun.
CORS'u Test Etme ve Hata Ayıklama
CORS'u etkili bir şekilde test etmek ve hatalarını ayıklamak hayati önem taşır. İşte bazı teknikler:
- Tarayıcı Geliştirici Araçları: Tarayıcının geliştirici konsolu ilk durağınızdır. "Ağ" sekmesi, ön kontrol isteklerini ve yanıtları gösterecek ve CORS başlıklarının mevcut olup olmadığını ve doğru şekilde yapılandırılıp yapılandırılmadığını ortaya çıkaracaktır.
- `curl` Komut Satırı Aracı: Ön kontrol isteklerini manuel olarak göndermek ve sunucunun yanıt başlıklarını incelemek için `curl -v -X OPTIONS
` kullanın. - Çevrimiçi CORS Denetleyicileri: CORS yapılandırmanızı doğrulamanıza yardımcı olabilecek çok sayıda çevrimiçi araç vardır. Sadece "CORS denetleyicisi" araması yapın.
- Birim ve Entegrasyon Testleri: CORS yapılandırmanızın beklendiği gibi çalıştığını doğrulamak için otomatik testler yazın. Bu testler, hem başarılı çapraz kaynak isteklerini hem de CORS'un erişimi engellemesi gereken senaryoları kapsamalıdır.
- Günlüğe Kayıt ve İzleme: Ön kontrol istekleri ve engellenen istekler gibi CORS ile ilgili olayları izlemek için günlüğe kaydı uygulayın. Şüpheli etkinlik veya yapılandırma hataları için günlüklerinizi izleyin.
Sonuç
Çapraz Kaynak Paylaşımı (CORS), web kaynaklarına kontrollü çapraz kaynak erişimini sağlayan hayati bir güvenlik mekanizmasıdır. Özellikle ön kontrol istekleri olmak üzere CORS'un nasıl çalıştığını anlamak, güvenli ve güvenilir web uygulamaları oluşturmak için çok önemlidir. Bu kılavuzda özetlenen en iyi uygulamaları izleyerek, CORS sorunlarını etkili bir şekilde ele alabilir ve uygulamanızı potansiyel güvenlik açıklarından koruyabilirsiniz. Her zaman güvenliğe öncelik vermeyi ve CORS yapılandırmanızın etkilerini dikkatlice değerlendirmeyi unutmayın.
Web geliştirme geliştikçe, CORS web güvenliğinin kritik bir yönü olmaya devam edecektir. Güvenli ve küresel olarak erişilebilir web uygulamaları oluşturmak için en son CORS en iyi uygulamaları ve teknikleri hakkında bilgi sahibi olmak çok önemlidir.