شرح CORS: إعداد آمن للمصادر عبر الأصول للمواقع الحديثة
يُساء فهم CORS بقدر ما يُساء إعداده. إليك ما تفعله هذه الترويسات فعلاً، وفخّ «الحرف البدل مع بيانات الاعتماد»، وكيف تُحكِم إغلاق واجهة API بشكل صحيح.
مشاركة المصادر عبر الأصول (CORS) هي غالباً أول لقاء لكثير من الفرق بأمان المتصفح — عادةً لأن شيئاً تعطّل وقالت أسرع نتيجة بحث «اسمح لكل الأصول ببساطة». يعمل هذا الحل وينقلب بصمت إلى ثغرة. إليك ما يفعله CORS حقاً، وكيف تُعِدّه دون أن تفتح واجهتك لكل موقع على الإنترنت.
ما الذي يتحكم به CORS فعلاً
CORS ليس ضابط وصول من جهة الخادم. إنه آلية في المتصفح تقرّر ما إذا كان يُسمح لـ JavaScript العامل على الأصل A بأن *يقرأ* استجابة من الأصل B. وهو لا يوقف بتاتاً طلباً مباشراً من curl أو خادم أو سكربت يتجاهل المتصفح. تعامل معه كحاجز وقائي لعملاء المتصفح، وأبقِ التفويض الحقيقي على الخادم على أي حال.
فخّ «الحرف البدل مع بيانات الاعتماد»
أخطر إعداد منفرد لـ CORS هو عكس أصل الطلب مع السماح ببيانات الاعتماد في الوقت نفسه:
Access-Control-Allow-Origin: https://evil.example
Access-Control-Allow-Credentials: trueإذا كان خادمك يعيد أي Origin يتلقاه كما هو ويضبط Allow-Credentials: true، فبإمكان أي موقع إرسال طلبات موثّقة بصفتك المستخدم المسجَّل وقراءة الاستجابة. لهذا يمنع المتصفح الحرف * الصريح مع بيانات الاعتماد — لكن عكس الأصل يتجاوز هذه الحماية ويعيد فتح الثغرة.
إعداد صحيح ومقيّد
طابِق الأصل الوارد مع قائمة سماح صريحة، وعندها فقط أعِده:
const allowed = new Set([
'https://app.example.com',
'https://admin.example.com',
]);
const origin = req.headers.get('origin');
if (origin && allowed.has(origin)) {
res.setHeader('Access-Control-Allow-Origin', origin);
res.setHeader('Vary', 'Origin');
res.setHeader('Access-Control-Allow-Credentials', 'true');
}ترويسة Vary: Origin سهلة النسيان ومهمة: بدونها قد تقدّم ذاكرة التخزين المؤقت ترويسة سماح أصلٍ ما إلى أصل مختلف.
قيّد الطرائق والترويسات أيضاً
Access-Control-Allow-Origin نصف السياسة فقط. أبقِ البقية ضيّقة:
- اسمح فقط بالطرائق التي تستخدمها نقطة النهاية، مثل
Access-Control-Allow-Methods: GET, POST. - اسمح فقط بترويسات الطلب المتوقَّعة، لا بقائمة شاملة.
- اضبط
Access-Control-Max-Ageمعقولاً كي تُخزَّن طلبات ما قبل التحقق مؤقتاً. - لا تجمع أبداً بين
Allow-Origin: *وAllow-Credentials: true.
متى يكون الحرف البدل مقبولاً فعلاً
واجهة API عامة حقاً وغير موثّقة وللقراءة فقط — تغذية أسعار صرف، أو نقطة حالة عامة — يمكنها استخدام Access-Control-Allow-Origin: * بأمان، تحديداً لعدم وجود بيانات اعتماد ولا شيء خاص يتسرّب. الخطر دائماً هو الانفتاح من نوع * مقترناً بالتوثيق فقط.
اختبره من سياق عبر-أصول حقيقي
يتصرّف CORS بشكل مختلف مع الطلبات البسيطة وتلك ذات ما قبل التحقق، فاختبر الاثنين من متصفح على أصل مختلف، لا بـ curl وحده (الذي يتجاهل CORS تماماً). يفحص الماسح ترويسات استجابة CORS تلقائياً مع بقية فحوص الأمان؛ ولمعرفة كيف تندرج نتائج CORS ضمن قائمة إصلاحات مرتبة حسب الأولوية، اقرأ كيف تقرأ تقرير فحص أمان الموقع.
حوّل هذه الفحوص إلى تقرير فحص لموقعك أنت.
شغّل فحصاً مجانياً واحصل على نتائج مرتبة حسب الأولوية وقابلة للتنفيذ في نحو 30 ثانية.
افحص موقعيتابع القراءة
كيف تقرأ تقرير فحص أمان الموقع
يعيد الفحص عشرات النتائج ودرجة إجمالية. إليك كيف تحوّل هذا الناتج إلى قائمة إصلاحات قصيرة ومرتبة حسب الأولوية دون أن تغرق في الضجيج.
أكثر 10 أخطاء شيوعاً في ترويسات الأمان (وكيفية إصلاحها)
ترويسات الأمان أرخص تحصين يمكنك نشره، وأسهله خطأً في التفاصيل. إليك أكثر عشرة أخطاء يشير إليها الفاحصون، مع الإصلاح الدقيق لكل منها.