CORS Preflight Requests: Güvenli Cross-Origin İstekleri
Merhaba değerli okuyucular! Bugün, web güvenliğinin önemli bir parçası olan CORS (Cross-Origin Resource Sharing) ve özellikle de CORS preflight istekleri hakkında derinlemesine bir inceleme yapacağız. Bu konunun nasıl çalıştığını, neden önemli olduğunu ve nasıl doğru bir şekilde uygulanacağını ele alacağız. Hazırsanız, güvenli cross-origin iletişimin dünyasına dalalım!
CORS Nedir?
CORS, bir web sayfasının farklı bir domain'den (origin) kaynaklara erişmesine izin veren bir güvenlik mekanizmasıdır. Bu mekanizma, tarayıcılar tarafından uygulanır ve potansiyel olarak tehlikeli cross-origin isteklerini engeller.
CORS Preflight Nedir?
CORS preflight, bazı cross-origin isteklerinden önce tarayıcı tarafından otomatik olarak gönderilen bir OPTIONS isteğidir. Bu istek, asıl isteğin güvenli olup olmadığını kontrol eder.
Preflight İsteği Ne Zaman Gönderilir?
- İstek "basit" değilse (GET, HEAD veya POST dışında bir metot kullanılıyorsa)
- İstek özel başlıklar içeriyorsa
- Content-Type "application/x-www-form-urlencoded", "multipart/form-data" veya "text/plain" dışında bir değerse
CORS Preflight Nasıl Çalışır?
- Tarayıcı, OPTIONS metoduyla bir preflight isteği gönderir.
- Sunucu, uygun CORS başlıklarıyla yanıt verir.
- Tarayıcı, yanıtı değerlendirir ve güvenliyse asıl isteği gönderir.
Örnek Preflight İsteği:
OPTIONS /api/data HTTP/1.1 Origin: https://example.com Access-Control-Request-Method: POST Access-Control-Request-Headers: X-Custom-Header
Örnek Preflight Yanıtı:
HTTP/1.1 204 No Content Access-Control-Allow-Origin: https://example.com Access-Control-Allow-Methods: POST, GET, OPTIONS Access-Control-Allow-Headers: X-Custom-Header Access-Control-Max-Age: 86400
CORS Preflight'ı Nasıl Uygularız?
1. Sunucu Tarafı Konfigürasyonu (Node.js/Express Örneği):
const express = require('express'); const cors = require('cors'); const app = express(); // CORS middleware'ini yapılandırma const corsOptions = { origin: 'https://example.com', methods: ['POST', 'GET', 'OPTIONS'], allowedHeaders: ['Content-Type', 'X-Custom-Header'], maxAge: 86400 // Preflight sonuçlarını 24 saat önbelleğe al }; app.use(cors(corsOptions)); app.options('*', cors(corsOptions)); // Tüm rotalar için preflight yanıtlarını etkinleştir app.post('/api/data', (req, res) => { // API mantığı }); app.listen(3000, () => console.log('Server running on port 3000'));
2. İstemci Tarafı İstek (JavaScript Örneği):
fetch('https://api.example.com/data', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Custom-Header': 'SomeValue' }, body: JSON.stringify({ key: 'value' }) }) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error));
CORS Güvenlik Best Practices
1. Origin'leri Sıkı Bir Şekilde Kısıtlayın
Sadece güvendiğiniz domain'lere izin verin.
const allowedOrigins = ['https://example.com', 'https://sub.example.com']; app.use(cors({ origin: function (origin, callback) { if (!origin || allowedOrigins.indexOf(origin) !== -1) { callback(null, true); } else { callback(new Error('CORS policy violation')); } } }));
2. Gereksiz HTTP Metodlarına İzin Vermeyin
Sadece uygulamanızın ihtiyaç duyduğu HTTP metodlarına izin verin.
app.use(cors({ methods: ['GET', 'POST', 'PUT', 'DELETE'] }));
3. Hassas Bilgileri İçeren Başlıklara Dikkat Edin
Access-Control-Allow-Headers'da hassas bilgiler içeren başlıklara izin vermemeye dikkat edin.
4. Credentials'ı Dikkatli Kullanın
credentials: true kullanırken çok dikkatli olun ve sadece güvenilir kaynaklara izin verin.
app.use(cors({ origin: 'https://trusted-origin.com', credentials: true }));
5. Preflight Önbellek Süresini Optimize Edin
Access-Control-Max-Age başlığını kullanarak, gereksiz preflight isteklerini azaltın.
app.use(cors({ maxAge: 3600 // 1 saat }));
CORS Preflight Güvenlik Kontrol Listesi
CORS ve preflight isteklerinin güvenliğini sağlamak için bu kontrol listesini kullanabilirsiniz:
class CORSSecurityChecker { constructor() { this.checks = { originRestriction: false, methodRestriction: false, headerRestriction: false, credentialsHandling: false, preflightCaching: false }; } restrictOrigins(origins) { // Origin kısıtlama implementasyonu this.checks.originRestriction = true; } restrictMethods(methods) { // HTTP metot kısıtlama implementasyonu this.checks.methodRestriction = true; } restrictHeaders(headers) { // Header kısıtlama implementasyonu this.checks.headerRestriction = true; } handleCredentials(allowCredentials) { // Credentials yönetimi implementasyonu this.checks.credentialsHandling = true; } setPreflightCaching(maxAge) { // Preflight önbellek yönetimi implementasyonu this.checks.preflightCaching = true; } isSecure() { return Object.values(this.checks).every(check => check === true); } printSecurityStatus() { console.log("CORS Security Status:"); for (const [check, status] of Object.entries(this.checks)) { console.log(`${check}: ${status ? 'Implemented' : 'Not Implemented'}`); } console.log(`Overall Security: ${this.isSecure() ? 'Secure' : 'Not Secure'}`); } } // Kullanım örneği const corsChecker = new CORSSecurityChecker(); corsChecker.restrictOrigins(['https://example.com']); corsChecker.restrictMethods(['GET', 'POST']); corsChecker.restrictHeaders(['Content-Type', 'X-Custom-Header']); corsChecker.handleCredentials(true); corsChecker.setPreflightCaching(3600); corsChecker.printSecurityStatus();
CORS preflight istekleri, web uygulamalarının güvenliğini sağlamada kritik bir rol oynar. Doğru yapılandırıldığında, cross-origin isteklerini güvenli bir şekilde yönetmenize olanak tanır ve potansiyel güvenlik risklerini azaltır.
Ancak, CORS'un bir güvenlik özelliği olduğunu unutmayın; tek başına tüm güvenlik ihtiyaçlarınızı karşılamaz. CORS'u diğer güvenlik önlemleriyle (örneğin, güvenli kimlik doğrulama, yetkilendirme, input validasyonu) birlikte kullanmak önemlidir.
Siz CORS ve preflight isteklerini nasıl yönetiyorsunuz? Karşılaştığınız zorluklar veya paylaşmak istediğiniz ek öneriler var mı? Yorumlarınızı bekliyorum!
Güvenli kodlamalar ve sorunsuz cross-origin iletişimler dilerim!