حماية الموارد من هجمات الويب باستخدام ميزة "جلب البيانات الوصفية"

منع تسرُّب المعلومات من مصادر متعددة (CSRF) وXSSI وXSSI

لماذا يجب الاهتمام بعزل موارد الويب؟

تكون العديد من تطبيقات الويب عُرضة للهجمات من مصادر متعددة، مثل تزوير الطلبات من مواقع إلكترونية متعددة (CSRF) أو تضمين النصوص البرمجية من عدة مواقع إلكترونية (XSSI) أو هجمات التوقيت أو تسرُّب المعلومات من مصادر متعددة أو هجمات القنوات الجانبية المفترَضة لتنفيذ الطلبات (Spectre).

تتيح لك عناوين طلبات جلب البيانات الوصفية تفعيل آلية قوية للدفاع عن الموقع، وهي سياسة عزل الموارد، لحماية تطبيقك من هذه الهجمات الشائعة المشتركة المصدر.

من الشائع أن يتم تحميل الموارد التي يعرضها تطبيق ويب معين فقط من خلال التطبيق نفسه، وليس من خلال مواقع إلكترونية أخرى. في مثل هذه الحالات، لا يستغرق نشر سياسة عزل الموارد استنادًا إلى عناوين طلبات استرجاع البيانات الوصفية سوى القليل من الجهد، وفي الوقت نفسه حماية التطبيق من الهجمات على مواقع متعددة.

توافُق المتصفح

تتوفّر عناوين طلبات "جلب البيانات الوصفية" في جميع المحركات الحديثة.

التوافق مع المتصفح

  • 76
  • 79
  • 90
  • 16.4

المصدر

الخلفية

يمكن حدوث العديد من الهجمات على مواقع متعددة نظرًا لأن الويب مفتوح تلقائيًا وأن خادم التطبيقات لا يمكنه حماية نفسه بسهولة من الاتصالات الناشئة من التطبيقات الخارجية. هجوم تزييف طلبات المواقع الإلكترونية المتعددة المصادر هو تزوير طلبات من مواقع إلكترونية متعددة (CSRF)، حيث يستدرج المهاجم المستخدم إلى موقع يتحكم فيه ثم يرسل نموذجًا إلى الخادم الذي يسجّل المستخدم الدخول إليه. بما أنّ الخادم لا يمكنه معرفة ما إذا كان الطلب قد صدر من نطاق آخر (مواقع إلكترونية متعددة) وكان المتصفّح يرفق ملفات تعريف الارتباط تلقائيًا إلى الطلبات على مواقع إلكترونية متعددة، سينفّذ الخادم الإجراء الذي يطلبه المهاجم نيابةً عن المستخدم.

تتشابه الهجمات الأخرى التي تتم على عدة مواقع إلكترونية، مثل تضمين النصوص البرمجية على المواقع الإلكترونية (XSSI) أو تسرُّب المعلومات من مصادر متعددة، في طبيعة الحال مع CSRF وتعتمد على تحميل الموارد من تطبيق الضحية في مستند يتحكّم فيه المهاجم وتسريب المعلومات حول تطبيقات الضحايا. ونظرًا لأن التطبيقات لا يمكنها التمييز بسهولة بين الطلبات الموثوق بها والطلبات غير الموثوق بها، لا يمكنها تجاهل الزيارات الضارة من خلال المواقع الإلكترونية.

لمحة حول ميزة "جلب البيانات الوصفية"

رؤوس طلبات "جلب البيانات الوصفية" هي ميزة أمان جديدة للنظام الأساسي للويب مصمَّمة لمساعدة الخوادم في حماية نفسها من الهجمات المتعدّدة المصادر. إنّ توفير معلومات عن سياق طلب HTTP في مجموعة من عناوين Sec-Fetch-* يسمح للخادم المستجيب بتطبيق سياسات الأمان قبل معالجة الطلب. بهذه الطريقة، يمكن للمطوّرين اختيار قبول الطلب أو رفضه استنادًا إلى طريقة تقديمه والسياق الذي سيتم استخدامه فيه، ما يتيح للمطوّرين الردّ على الطلبات المشروعة فقط التي يرسلها تطبيقاتهم.

من نفس المصدر
وسيستمر عمل الطلبات الناشئة من المواقع الإلكترونية التي يعرضها خادمك (المصدر نفسه). يؤدّي طلب الاسترجاع من https://site.example للمورد https://site.example/foo.json في JavaScript إلى إرسال المتصفّح لعنوان طلب HTTP "Sec Fetch-Site: same-origin".
عدّة مواقع إلكترونية
قد يرفض الخادم الطلبات الضارة من عدة مواقع إلكترونية، بسبب السياق الإضافي في طلب HTTP الذي توفّره العناوين Sec-Fetch-*. في حال ظهور صورة على https://evil.example تم ضبط سمة src لعنصر img على "https://site.example/foo.json"، يتم إرسال عنوان طلب HTTP إلى "Sec-Fetch-Site: Cross-site" في المتصفّح.

Sec-Fetch-Site

التوافق مع المتصفح

  • 76
  • 79
  • 90
  • 16.4

المصدر

يخبر Sec-Fetch-Site الخادم بالموقع الإلكتروني الذي أرسل الطلب. يضبط المتصفّح هذه القيمة على أيّ ممّا يلي:

  • same-origin، إذا تم تقديم الطلب من خلال تطبيقك الخاص (مثل site.example)
  • same-site، إذا تم تقديم الطلب من خلال نطاق فرعي لموقعك الإلكتروني (مثل bar.site.example)
  • none، إذا كان الطلب ناجمًا بشكل صريح عن تفاعل المستخدم مع وكيل المستخدم (مثلاً، النقر على إشارة مرجعية)
  • cross-site، إذا تم إرسال الطلب من موقع إلكتروني آخر (مثل evil.example)

Sec-Fetch-Mode

التوافق مع المتصفح

  • 76
  • 79
  • 90
  • 16.4

المصدر

تحدّد السمة Sec-Fetch-Mode وضع الطلب. ويتجاوب هذا تقريبًا مع نوع الطلب ويسمح لك بتمييز تحميلات الموارد عن طلبات التنقل. على سبيل المثال، تشير وجهة navigate إلى طلب التنقّل في المستوى الأعلى، بينما تشير الوجهة no-cors إلى طلبات الموارد مثل تحميل صورة.

Sec-Fetch-Dest

التوافق مع المتصفح

  • 80
  • 80
  • 90
  • 16.4

المصدر

تعرض Sec-Fetch-Dest وجهة الطلب (على سبيل المثال، إذا تسبّبت علامة script أو img في طلب المتصفّح مورد).

كيفية استخدام البيانات الوصفية لميزة الجلب للحماية من الهجمات المتعددة المصادر

وتكون المعلومات الإضافية التي تقدمها عناوين الطلبات هذه بسيطة للغاية، لكن السياق الإضافي يتيح لك إنشاء منطق أمان قوي من جانب الخادم، والتي يُشار إليها أيضًا باسم سياسة عزل الموارد، باستخدام بضعة أسطر من التعليمات البرمجية.

تنفيذ سياسة عزل الموارد

تمنع سياسة عزل الموارد طلب الموارد من قبل المواقع الإلكترونية الخارجية. يحد حظر هذه الزيارات من الثغرات الأمنية الشائعة على الويب على المواقع الإلكترونية، مثل CSRF وXSSI وتوقيت الهجمات وتسرُّب المعلومات من مصادر متعددة. يمكن تفعيل هذه السياسة لجميع نقاط النهاية في تطبيقك والسماح بجميع طلبات الموارد الواردة من تطبيقك بالإضافة إلى عمليات التنقّل المباشرة (من خلال طلب HTTP GET). يمكن إيقاف استخدام نقاط النهاية التي يُفترض أن يتم تحميلها في سياق مواقع إلكترونية متعددة (مثل نقاط النهاية التي يتم تحميلها باستخدام سياسة مشاركة الموارد المتعددة المصادر (CORS)) وفقًا لهذا المنطق.

الخطوة 1: السماح بالطلبات من المتصفحات التي لا ترسل البيانات الوصفية للجلب

نظرًا لعدم توافق بعض المتصفحات مع البيانات الوصفية لميزة "جلب البيانات"، عليك السماح بالطلبات التي لم يتم ضبط عناوين Sec-Fetch-* لها، وذلك من خلال التأكّد من توفُّر sec-fetch-site.

if not req['sec-fetch-site']:
  return True  # Allow this request

الخطوة 2: السماح بالطلبات التي يجريها المتصفح نفسه ومن الموقع الإلكتروني نفسه

وسيُسمح بأي طلبات لا تأتي من سياق من مصادر متعددة (مثل evil.example). وعلى وجه الخصوص، يتمثّل ذلك في الطلبات التي:

  • أن يكون صادرًا من تطبيقك الخاص (مثل طلب من المصدر نفسه حيث سيتم دائمًا السماح باستخدام السمة site.example لطلبات site.example/foo.json)
  • أن تنشأ من نطاقاتك الفرعية.
  • تحدث بشكل صريح بسبب تفاعل المستخدم مع وكيل المستخدم (على سبيل المثال، الانتقال المباشر أو النقر على إشارة مرجعية وغير ذلك).
if req['sec-fetch-site'] in ('same-origin', 'same-site', 'none'):
  return True  # Allow this request

الخطوة 3: السماح بالتنقل البسيط على المستوى الأعلى وإطارات iFrame

لضمان إمكانية استمرار إمكانية ربط موقعك الإلكتروني من المواقع الإلكترونية الأخرى، عليك السماح بالتنقل البسيط في المستوى الأعلى (HTTP GET).

if req['sec-fetch-mode'] == 'navigate' and req.method == 'GET'
  # <object> and <embed> send navigation requests, which we disallow.
  and req['sec-fetch-dest'] not in ('object', 'embed'):
    return True  # Allow this request

الخطوة 4: إيقاف نقاط النهاية التي يُقصد منها عرض الزيارات على المواقع الإلكترونية المختلفة (اختياري)

في بعض الحالات، قد يوفر تطبيقك موارد تهدف إلى تحميلها من مواقع إلكترونية مختلفة. يجب استثناء هذه الموارد على أساس كل مسار أو لكل نقطة نهاية. في ما يلي أمثلة على نقاط النهاية هذه:

  • نقاط النهاية التي يمكن الوصول إليها من مصادر متعددة: إذا كان تطبيقك يعرض نقاط نهاية تم تفعيل "CORS" لها، عليك إيقاف عزل الموارد بوضوح لضمان استمرار إمكانية إرسال طلبات من مواقع إلكترونية متعددة إلى نقاط النهاية هذه.
  • الموارد العامة (مثل الصور والأنماط وغيرها): ويمكن أيضًا استثناء أي موارد عامة وغير مصادق عليها يجب أن تكون قابلة للتحميل من مصادر متعددة من مواقع إلكترونية أخرى.
if req.path in ('/my_CORS_endpoint', '/favicon.png'):
  return True

الخطوة 5: رفض جميع الطلبات الأخرى التي تكون من مواقع إلكترونية مختلفة وليست مخصّصة للتنقّل

سيتم رفض أي طلب آخر في عدة مواقع إلكترونية بموجب "سياسة عزل الموارد"، وبالتالي حماية تطبيقك من الهجمات الشائعة على المواقع الإلكترونية.

مثال: يوضِّح الرمز البرمجي التالي عملية تنفيذ كاملة لسياسة عزل الموارد الفعّالة على الخادم أو كبرامج وسيطة لرفض طلبات الموارد التي قد تكون ضارة من مواقع إلكترونية متعددة، مع السماح في الوقت نفسه بطلبات التنقّل البسيطة:

# Reject cross-origin requests to protect from CSRF, XSSI, and other bugs
def allow_request(req):
  # Allow requests from browsers which don't send Fetch Metadata
  if not req['sec-fetch-site']:
    return True

  # Allow same-site and browser-initiated requests
  if req['sec-fetch-site'] in ('same-origin', 'same-site', 'none'):
    return True

  # Allow simple top-level navigations except <object> and <embed>
  if req['sec-fetch-mode'] == 'navigate' and req.method == 'GET'
    and req['sec-fetch-dest'] not in ('object', 'embed'):
      return True

  # [OPTIONAL] Exempt paths/endpoints meant to be served cross-origin.
  if req.path in ('/my_CORS_endpoint', '/favicon.png'):
    return True

  # Reject all other requests that are cross-site and not navigational
  return False

نشر سياسة عزل الموارد

  1. ثبِّت وحدة مثل مقتطف الرمز المذكور أعلاه لتسجيل سلوك موقعك الإلكتروني وتتبُّعه والتأكّد من عدم تأثير القيود على أي زيارات شرعية.
  2. يجب معالجة الانتهاكات المحتمَلة من خلال استثناء نقاط النهاية المشروعة من مصادر متعددة.
  3. فرض السياسة من خلال تجاهل الطلبات غير المتوافقة مع السياسة

تحديد انتهاكات السياسة وإصلاحها

ننصحك باختبار سياستك بدون أي تأثيرات جانبية من خلال تفعيلها أولاً في وضع إعداد التقارير عن الرمز من جهة الخادم. وبدلاً من ذلك، يمكنك تنفيذ هذا المنطق في البرمجيات الوسيطة أو تنفيذ هذا المنطق في البرمجيات الوسيطة أو عبر خادم وكيل عكسي يسجّل أيّ انتهاكات قد تنتج عن سياستك عند تطبيقها على زيارات الإنتاج.

من خلال تجربتنا في طرح سياسة عزل موارد البيانات الوصفية في Google، تكون معظم التطبيقات متوافقة بشكل تلقائي مع هذه السياسة ونادرًا ما تتطلب نقاط نهاية للإعفاء للسماح بالزيارات إلى المواقع الإلكترونية.

فرض سياسة عزل الموارد

بعد التأكّد من أنّ سياستك لا تؤثر في عدد زيارات الإنتاج المشروعة، ستكون مستعدًا لفرض قيود على موقعك الإلكتروني، وضمان عدم تمكُّن المواقع الإلكترونية الأخرى من طلب مواردك وحماية المستخدمين من الهجمات على مواقع إلكترونية متعددة.

محتوى إضافي للقراءة