كل المقالات

CORS: لماذا يحظر المتصفح طلبات "عادية" إلى نطاق آخر

ووردبريس، الذي يشغّل نسبة كبيرة من المواقع العربية، لا يفعّل ترويسات CORS على REST API الخاص به افتراضيًا. الحل الشائع الذي ينسخه كثير من المطورين من منتديات الدعم هو إضافة header('Access-Control-Allow-Origin: *') يدويًا داخل functions.php عبر خطاف rest_api_init — وهذا يعمل جيدًا لطلبات القراءة البسيطة، لكنه ينهار فور أن يحتاج الموقع لإرسال بيانات اعتماد (مثل كوكي جلسة المستخدم) مع الطلب.

سياسة المصدر الواحد

افتراضيًا، تطبّق المتصفحات سياسة Same-Origin: لا يمكن لكود JavaScript من صفحة مصدر واحد (نطاق + بروتوكول + منفذ) قراءة استجابات طلبات موجّهة إلى مصدر آخر. هذه آلية أمنية أساسية تمنع كودًا خبيثًا في موقع من سرقة بيانات من موقع آخر يكون المستخدم مسجّلًا فيه.

كيف يخفّف CORS هذه السياسة

CORS (Cross-Origin Resource Sharing) مجموعة من ترويسات HTTP يسمح بها خادم صراحةً لمصادر خارجية معيّنة (أو جميعها) بقراءة استجاباته. الترويسة الأساسية هي Access-Control-Allow-Origin، التي تحدّد النطاقات المسموح لها.

فخ المصدر العام (wildcard) مع بيانات الاعتماد

عند إرسال طلب بخاصية credentials: 'include' — الضرورية لإرسال كوكي الجلسة إلى واجهة API على نطاق فرعي مختلف — يرفض المتصفح تمامًا قبول Access-Control-Allow-Origin: * في الاستجابة. يمنع المعيار صراحةً الجمع بين مصدر عام وبيانات اعتماد؛ يجب على الخادم إعادة النطاق الفعلي الذي أرسل الطلب بدلًا من ذلك.

لماذا نحتاج هذا

  • تشخيص خطأ CORS ومعرفة الترويسات الناقصة تحديدًا على الخادم.
  • اكتشاف إعداد Access-Control-Allow-Origin: * المفرط في السماحية في REST API الخاص بووردبريس قبل أن يصبح مشكلة أمنية.
  • فهم الفرق بين الطلبات "البسيطة" وطلبات preflight (OPTIONS).

CORS لا يحمي الخادم من الهجمات

من الخطأ الشائع الاعتقاد بأن CORS إجراء أمني من جانب الخادم — في الواقع هو يقيّد فقط ما يمكن لـJavaScript في المتصفح قراءته. مهاجم يستخدم curl أو Postman أو سكربتًا خلفيًا مباشرةً يتجاوز CORS تمامًا، لأن هذه الأدوات لا تطبّق سياسة المصدر الواحد. لا يجب أبدًا اعتبار CORS بديلًا عن مصادقة وتفويض حقيقيَّين على الخادم.

جرّب الأداة