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

تعرَّف على سبب الحاجة إلى حظر الوصول من نطاقات أخرى لاستخدام ميزات فعّالة مثل SharedArrayBuffer وperformance.measureUserAgentSpecificMemory() والموقّت عالي الدقة بدقة أفضل.

مقدمة

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

الخلفية

تم إنشاء الويب استنادًا إلى سياسة المصدر نفسه، وهي ميزة أمان تقيّد طريقة تفاعل المستندات والنصوص البرمجية مع الموارد من مصدر آخر. يقيّد هذا المبدأ الطرق التي يمكن للمواقع الإلكترونية من خلالها الوصول إلى موارد من مصادر متعددة. على سبيل المثال، يتم منع مستند من https://a.example من الوصول إلى البيانات المستضافة في https://b.example.

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

  • تضمين إطارات iframe متعددة المصادر
  • تضمين موارد من مصادر متعددة، مثل الصور أو النصوص البرمجية
  • فتح نوافذ منبثقة من مصادر متعددة باستخدام مرجع DOM

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

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

تتّخذ جميع قرارات السياسة هذه ضمن مجموعة سياقات تصفّح.

مجموعة سياقات التصفّح

لفترة طويلة، كان الجمع بين CORS والموارد غير الشفافة كافيًا لجعل المتصفحات آمنة. في بعض الأحيان، تم اكتشاف حالات هامشية (مثل ثغرات JSON) وكان يجب إصلاحها، ولكن بشكل عام، كان مبدأ عدم السماح بالوصول المباشر للقراءة إلى وحدات البايت الأولية للموارد من مصادر متعددة ناجحًا.

تغيّر كل ذلك مع Spectre، التي تجعل أي بيانات يتم تحميلها إلى مجموعة سياق التصفّح نفسها التي يتضمّنها الرمز قابلة للقراءة. ومن خلال قياس الوقت الذي تستغرقه عمليات معيّنة، يمكن للمهاجمين تخمين محتويات ذاكرة التخزين المؤقت لوحدة المعالجة المركزية، وبالتالي محتويات ذاكرة العملية. يمكن تنفيذ هجمات التوقيت باستخدام مؤقتات منخفضة الدقة متوفّرة في النظام الأساسي، ولكن يمكن تسريعها باستخدام مؤقتات عالية الدقة، سواء كانت صريحة (مثل performance.now()) أو ضمنية (مثل SharedArrayBuffer ثانية). إذا كان evil.com يضمّن صورة من مصدر خارجي، يمكنه استخدام هجوم Spectre لقراءة بيانات البكسل الخاصة بها، ما يجعل وسائل الحماية التي تعتمد على "التعتيم" غير فعّالة.

Spectr

من المفترض أن يخضع كل طلب من مصادر متعددة لتدقيق صريح من الخادم الذي يملك المورد. إذا لم يوفّر الخادم الذي يملك المورد عملية التدقيق، لن تصل البيانات إلى مجموعة سياق التصفّح الخاصة بالجهات المسيئة، وبالتالي لن تكون عرضة لأي هجمات Spectre يمكن أن تنفّذها صفحة ويب. نسمّي ذلك حالة حظر الوصول من نطاقات أخرى. هذا هو بالضبط ما يهدف إليه COOP+COEP.

في حالة العزل بين المصادر، يُعدّ الموقع الإلكتروني الذي يطلب البيانات أقل خطورة، ما يتيح استخدام ميزات قوية مثل SharedArrayBuffer وperformance.measureUserAgentSpecificMemory() ومؤقتات عالية الدقة بدقة أفضل، والتي يمكن استخدامها بطريقة أخرى لتنفيذ هجمات شبيهة بهجمات Spectre. ويمنع أيضًا تعديل document.domain.

سياسة مُضمِّن عناوين URL التابعة للنطاق نفسه

تمنع سياسة Cross-Origin Embedder Policy (COEP) المستند من تحميل أي موارد من مصادر متعددة لا تمنح المستند الإذن صراحةً (باستخدام CORP أو CORS). باستخدام هذه الميزة، يمكنك الإشارة إلى أنّ المستند لا يمكنه تحميل هذه الموارد.

طريقة عمل COEP

لتفعيل هذه السياسة، أضِف عنوان HTTP التالي إلى المستند:

Cross-Origin-Embedder-Policy: require-corp

تتلقّى سياسة COEP قيمة واحدة من require-corp. يفرض ذلك السياسة التي تنص على أنّه لا يمكن للمستند تحميل الموارد إلا من المصدر نفسه، أو الموارد التي تم وضع علامة عليها بشكل صريح بأنّها قابلة للتحميل من مصدر آخر.

لكي يمكن تحميل الموارد من مصدر آخر، يجب أن تتيح إما مشاركة الموارد المشتركة المنشأ (CORS) أو سياسة تضمين الموارد من مصادر خارجية (CORP).

مشاركة الموارد المشتركة النطاق

إذا كان أحد الموارد المتعدّدة المصادر يتيح مشاركة الموارد المتعدّدة المصادر (CORS)، يمكنك استخدام السمة crossorigin لتحميله إلى صفحة الويب بدون أن يتم حظره بواسطة COEP.

<img src="https://third-party.example.com/image.jpg" crossorigin>

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

وبالمثل، يمكنك جلب بيانات من مصادر متعددة من خلال طريقة fetch() التي لا تتطلّب معالجة خاصة طالما أنّ الخادم يستجيب باستخدام عناوين HTTP الصحيحة.

سياسة مشاركة الموارد مع نطاقات خارجية

تم طرح سياسة مشاركة الموارد المشتركة المنشأ (CORP) في الأصل كخيار متاح لحماية مواردك من أن يتم تحميلها من خلال مصدر آخر. في سياق COEP، يمكن أن تحدّد CORP سياسة مالك المورد بشأن المستخدمين الذين يمكنهم تحميل مورد.

يتضمّن العنوان Cross-Origin-Resource-Policy ثلاث قيم محتملة:

Cross-Origin-Resource-Policy: same-site

لا يمكن تحميل الموارد التي تحمل العلامة same-site إلا من الموقع الإلكتروني نفسه.

Cross-Origin-Resource-Policy: same-origin

لا يمكن تحميل الموارد التي تم وضع علامة same-origin عليها إلا من المصدر نفسه.

Cross-Origin-Resource-Policy: cross-origin

يمكن لأي موقع إلكتروني تحميل الموارد التي تحمل العلامة cross-origin. (تمت إضافة هذه القيمة إلى مواصفات CORP مع COEP).

السياسة المحدّدة لفتح المستندات المشتركة المصدر

تتيح لك سياسة Cross-Origin-Opener-Policy (COOP) التأكّد من عزل النافذة ذات المستوى الأعلى عن المستندات الأخرى من خلال وضعها في مجموعة مختلفة من سياقات التصفّح، وبالتالي لا يمكنها التفاعل مباشرةً مع النافذة ذات المستوى الأعلى. على سبيل المثال، إذا فتح مستند يتضمّن COOP نافذة منبثقة، ستكون قيمة السمة window.opener هي null. بالإضافة إلى ذلك، ستعرض السمة .closed الخاصة بمرجع النافذة الأصلية القيمة true.

COOP

يتضمّن العنوان Cross-Origin-Opener-Policy ثلاث قيم محتملة:

Cross-Origin-Opener-Policy: same-origin

يمكن للمستندات التي تم وضع علامة same-origin عليها مشاركة مجموعة سياق التصفّح نفسها مع المستندات ذات المصدر نفسه التي تم وضع علامة same-origin عليها أيضًا بشكل صريح.

COOP

Cross-Origin-Opener-Policy: same-origin-allow-popups

يحتفظ المستند ذو المستوى الأعلى الذي يتضمّن same-origin-allow-popups بمراجع لأي من نوافذه المنبثقة التي لا تضبط سياسة COOP أو التي تختار إيقاف العزل من خلال ضبط سياسة COOP على unsafe-none.

COOP

Cross-Origin-Opener-Policy: unsafe-none

unsafe-none هو الإعداد التلقائي ويسمح بإضافة المستند إلى مجموعة سياق التصفّح الخاصة بنافذة الفتح، ما لم يكن لنافذة الفتح نفسها سياسة COOP بقيمة same-origin.

ملخّص

إذا كنت تريد ضمان الوصول إلى ميزات قوية مثل SharedArrayBuffer أو performance.measureUserAgentSpecificMemory() أو مؤقتات عالية الدقة بدقة أفضل، تذكَّر أنّ المستند يجب أن يستخدم كلاً من COEP بالقيمة require-corp وCOOP بالقيمة same-origin. وفي حال عدم توفّر أي منهما، لن يضمن المتصفّح توفير عزل كافٍ لتفعيل هذه الميزات القوية بأمان. يمكنك تحديد حالة صفحتك من خلال التحقّق مما إذا كان self.crossOriginIsolated يعرض القيمة true.

يمكنك التعرّف على خطوات تنفيذ ذلك في مقالة جعل موقعك الإلكتروني "معزولاً عن المصادر الخارجية" باستخدام COOP وCOEP.

الموارد