در منظره مدرن توسعه وب، ارتباطات بین دامنهای نه تنها یک ویژگی، بلکه یک نیاز اساسی است. چه در حال ساخت یک برنامه تکصفحهای (SPA) میزبانی شده روی app.example.com باشید که از یک API روی api.example.com استفاده میکند، و چه در حال یکپارچهسازی میکروسرویسهای شخص ثالث، شما ناگزیر با پروتکل اشتراکگذاری منابع بین مبدأ (CORS) مواجه خواهید شد. اگرچه CORS برای محافظت از کاربران طراحی شده است، اما پیکربندی نادرست همچنان یکی از شایعترین منابع آسیبپذیریهای امنیتی و مشکلات توسعه است. این راهنما یک بررسی فنی جامع در مورد پیکربندی مؤثر، امن و کارآمد CORS ارائه میدهد.
درک سیاست همان مبدأ (Same-Origin Policy)
برای درک CORS، ابتدا باید «سیاست همان مبدأ» (SOP) مرورگر را بشناسید. SOP یک مکانیزم امنیتی حیاتی است که اسناد بالقوه مخرب را با محدود کردن نحوه تعامل یک سند یا اسکریپت بارگذاری شده از یک مبدأ با منبعی از یک مبدأ دیگر، از هم جدا میکند. «مبدأ» توسط طرح (scheme)، میزبان (host) و پورت (port) تعریف میشود (به عنوان مثال، https://example.com:443).
وقتی یک مرورگر درخواستی را به یک مبدأ متفاوت آغاز میکند، درخواست را به طور کامل مسدود نمیکند، بلکه پاسخ را مداخله میکند. اگر سرور به صراحت اجازه دسترسی را از طریق هدرهای HTTP خاص ندهد، مرورگر پاسخ را از خوانده شدن توسط اسکریپت سمت کلاینت مسدود میکند. این امر از دزدیده شدن دادههای حساس از دامنههای دیگر توسط مهاجمان از طریق اسکریپتهای مخرب در یک صفحه هک شده جلوگیری میکند.
هدرهای کلیدی CORS توضیح داده شده
CORS از طریق مجموعهای از هدرهای HTTP که بین کلاینت و سررور مبادله میشود، کار میکند. در اینجا مهمترین هدرهایی که باید بر آنها مسلط شوید آمده است:
- Access-Control-Allow-Origin (ACAO): مشخص میکند که کدام مبدأها مجاز هستند. میتواند یک مبدأ خاص (
https://frontend.com) یا یک wildcard (*) باشد. - Access-Control-Allow-Methods (ACAM): روشهای HTTP مجاز (GET, POST, PUT, DELETE و غیره) را فهرست میکند.
- Access-Control-Allow-Headers (ACAH): تعریف میکند که کدام هدرها میتوانند در طول درخواست اصلی استفاده شوند (به عنوان مثال،
Content-Type،Authorization). - Access-Control-Allow-Credentials (ACAC): یک مقدار بولی است که نشان میدهد آیا درخواست میتواند شامل اعتبارنامههای کاربر مانند کوکیها، هدرهای احراز هویت یا گواهیهای مشتری TLS باشد یا خیر.
بسیار مهم است که توجه داشته باشید وقتی Access-Control-Allow-Credentials روی true تنظیم شده است، نمیتوان از wildcard * برای Access-Control-Allow-Origin استفاده کرد. مرورگر پاسخ را در صورت دریافت یک ACAO همراه با اعتبارنامهها رد میکند. این یک دام رایج برای توسعهدهندگانی است که سعی در فعالسازی احراز هویت مبتنی بر جلسه دارند.
مثالهای پیکربندی عملی
بیایید نگاهی بیندازیم که چگونه میتوان CORS را در یک محیط معمول Node.js/Express پیکربندی کرد. این مثال یک پیکربندی امن را نشان میدهد که درخواستهای پیشسازماندهی (preflight) را به صورت پویا مدیریت کرده و مبدأها را با یک لیست سفید اعتبارسنجی میکند.
const express = require('express');
const app = express();
// تعریف مبدأهای مجاز برای مدیریت پویا
const allowedOrigins = ['https://frontend.example.com', 'https://admin.example.com'];
app.use((req, res, next) => {
const origin = req.headers.origin;
// بررسی کنید که آیا مبدأ درخواست در لیست مجاز است
if (allowedOrigins.includes(origin)) {
res.setHeader('Access-Control-Allow-Origin', origin);
}
// تعریف روشها و هدرهای مجاز
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
// اجازه استفاده از اعتبارنامهها
res.setHeader('Access-Control-Allow-Credentials', true);
// مدیریت درخواستهای پیشسازماندهی
if (req.method === 'OPTIONS') {
return res.sendStatus(204);
}
next();
});
در این قطعه کد، ما با اعتبارسنجی هدر Origin ورودی در برابر یک لیست سفید سختگیرانه، از خطر امنیتی استفاده از * اجتناب میکنیم. همچنین اطمینان حاصل میکنیم که کلاینت نمیتواند هدرهای دلخواه ارسال کند، با فهرست کردن صریح آنها در Allow-Headers. بررسی پیشسازماندهی (درخواست OPTIONS) به خوبی مدیریت میشود تا از پردازش غیرضروری برای درخواستهای داده اصلی جلوگیری شود.
بهترین شیوهها برای CORS امن
- هرگز از Wildcardها همراه با اعتبارنامهها استفاده نکنید: همانطور که ذکر شد،
Access-Control-Allow-Credentials: trueوAccess-Control-Allow-Origin: *در مرورگرهای مطابقتدار با هم ناسازگار هستند. - مبدأهای مجاز را به حداقل برسانید: همیشه از یک لیست سفید از دامنههای خاص استفاده کنید به جای باز کردن دسترسی به تمام دامنهها.
- روشها و هدرها را محدود کنید: تنها روشهای HTTP و هدرهایی که API شما واقعاً نیاز دارد را در دسترس قرار دهید. پیکربندیهای بیش از حد دستودلباز، سطح حمله را افزایش میدهند.
- درخواستهای پیشسازماندهی را به درستی مدیریت کنید: اطمینان حاصل کنید که سرور شما برای درخواستهای OPTIONS با
204 No Contentیا200 OKپاسخ میدهد بدون اینکه منطق کسبوکار شما اجرا شود. - از ذخیره دادههای حساس در APIهای عمومی خودداری کنید: CORS یک سیاست اعمال شده توسط مرورگر است. این امر درخواستهای HTTP مستقیم از سرورها یا ابزارهایی مانند cURL را جلوگیری نمیکند. بنابراین، هرگز به CORS برای محافظت از دادههای حساس سمت سرور تکیه نکنید؛ همیشه احراز هویت و مجوزدهی مناسب را پیادهسازی کنید.
نتیجهگیری
CORS یک ابزار قدرتمند است که تعاملپذیری مورد نیاز برنامههای وب مدرن را فراهم میکند، اما برای حفظ امنیت به پیکربندی دقیق نیاز دارد. با درک مکانیزمهای زیرین، استفاده از هدرهای خاص و پایبندی به اصل کمترین امتیاز، میتوانید برنامههای مستحکمی بسازید که هم کاربردی و هم امن باشند. به یاد داشته باشید که CORS تنها یک لایه از دفاع است؛ همیشه آن را با احراز هویت قوی، اعتبارسنجی ورودی و بررسیهای مجوزدهی سمت سرور تکمیل کنید.