توضّح هذه الصفحة بعض أفضل الممارسات لضبط سياسة المُحيل واستخدام المُحيل في الطلبات الواردة.
ملخّص
- يؤدي تسرُّب المعلومات غير المتوقّع متعدّد المصادر إلى الإضرار بخصوصية مستخدمي الويب. ويمكن أن تساعد سياسة المُحيل الوقائية في ذلك.
- ننصحك بضبط سياسة المُحيل على
strict-origin-when-cross-origin. ويحافظ على معظم فائدة المُحيل، مع تقليل مخاطر تسرُّب البيانات متعدّدة المصادر. - لا تستخدِم المُحيلين للحماية من هجمات تزوير الطلبات عبر المواقع (CSRF). استخدِم رموز CSRF المميّزة بدلاً من ذلك، واستخدِم عناوين أخرى كطبقة أمان إضافية.
مقدّمة حول Referer وReferrer-Policy
يمكن أن تتضمّن طلبات HTTP عنوان Referer اختياريًا، يشير إلى المصدر أو عنوان URL لصفحة الويب التي تم إرسال الطلب منها. يحدّد العنوان Referrer-Policy البيانات التي يتم توفيرها في العنوان Referer.
في المثال التالي، يتضمّن العنوان Referer عنوان URL الكامل للصفحة على site-one التي تم إرسال الطلب منها.
قد يظهر العنوان Referer في أنواع مختلفة من الطلبات:
- طلبات التنقّل، عندما ينقر المستخدم على رابط
- طلبات الموارد الفرعية، عندما يطلب المتصفّح الصور وإطارات iframe والنصوص البرمجية والموارد الأخرى التي تحتاجها الصفحة
بالنسبة إلى عمليات التنقّل وإطارات iframe، يمكنك أيضًا الوصول إلى هذه البيانات باستخدام JavaScript من خلال
document.referrer.
يمكنك معرفة الكثير من قيم Referer. على سبيل المثال، قد تستخدمها خدمة إحصاءات لتحديد أنّ% 50 من زوّار site-two.example أتوا من social-network.example. ولكن عندما يتم إرسال عنوان URL الكامل، بما في ذلك المسار وسلسلة طلب البحث، في Referer عبر المصادر، يمكن أن يعرّض ذلك خصوصية المستخدم للخطر ويؤدي إلى مخاطر أمنية:
تحتوي عناوين URL من 1 إلى 5 على معلومات خاصة، وأحيانًا معلومات حساسة أو تكشف الهوية. ويمكن أن يؤدي تسريب هذه البيانات بدون إشعار المستخدمين عبر المصادر إلى اختراق خصوصية مستخدمي الويب.
عنوان URL رقم 6 هو عنوان URL للإمكانات. إذا تلقّى أي شخص آخر غير المستخدم المقصود هذا الرمز، يمكن لجهة مسيئة التحكّم في حساب هذا المستخدم.
لحصر بيانات المُحيل المتاحة للطلبات الواردة من موقعك الإلكتروني، يمكنك ضبط سياسة المُحيل.
ما هي السياسات المتاحة وما هي أوجه الاختلاف بينها؟
يمكنك اختيار واحدة من ثماني سياسات. استنادًا إلى السياسة، يمكن أن تكون البيانات
المتاحة من عنوان Referer (وdocument.referrer) كما يلي:
- ما مِن بيانات (لا يتوفّر عنوان
Referer) - المصدر فقط
- عنوان URL الكامل: المصدر والمسار وسلسلة طلب البحث
تم تصميم بعض السياسات لتعمل بشكل مختلف حسب السياق: طلب من المصدر نفسه أو طلب متعدّد المصادر، وما إذا كانت وجهة الطلب آمنة مثل المصدر أو كليهما. ويُعدّ ذلك مفيدًا للحدّ من كمية المعلومات التي تتم مشاركتها بين المصادر أو مع مصادر أقل أمانًا، مع الحفاظ على ثراء المُحيل داخل موقعك الإلكتروني.
يوضّح الجدول التالي كيف تفرض سياسات المُحيل قيودًا على بيانات عناوين URL المتاحة من عنوان Referer وdocument.referrer:
| نطاق السياسة | اسم السياسة | Referer: No data | المُحيل: المصدر فقط | المُحيل: عنوان URL الكامل |
|---|---|---|---|---|
| لا يأخذ في الاعتبار سياق الطلب | no-referrer |
check | ||
origin |
check | |||
unsafe-url |
check | |||
| التركيز على الأمان | strict-origin |
طلب من HTTPS إلى HTTP | الطلب من HTTPS إلى HTTPS أو من HTTP إلى HTTP |
|
no-referrer-when-downgrade |
طلب من HTTPS إلى HTTP | الطلب من HTTPS إلى HTTPS أو من HTTP إلى HTTP |
||
| التركيز على الخصوصية | origin-when-cross-origin |
طلب متعدّد المصادر | طلب من المصدر نفسه | |
same-origin |
طلب متعدّد المصادر | طلب من المصدر نفسه | ||
| التركيز على الخصوصية والأمان | strict-origin-when-cross-origin |
طلب من HTTPS إلى HTTP | طلب متعدّد المصادر من HTTPS إلى HTTPS أو من HTTP إلى HTTP |
طلب من المصدر نفسه |
توفّر شبكة مطوّري برامج Mozilla (MDN) قائمة كاملة بالسياسات وأمثلة على السلوك.
في ما يلي بعض النقاط التي يجب الانتباه إليها عند ضبط سياسة المُحيل:
- جميع السياسات التي تأخذ المخطط (HTTPS مقابل HTTP) في الاعتبار
(
strict-originوno-referrer-when-downgradeوstrict-origin-when-cross-origin) تتعامل مع الطلبات من مصدر HTTP إلى مصدر HTTP آخر بالطريقة نفسها التي تتعامل بها مع الطلبات من مصدر HTTPS إلى مصدر HTTPS آخر، على الرغم من أنّ HTTP أقل أمانًا. والسبب في ذلك هو أنّ هذه السياسات تركّز على ما إذا كان هناك تخفيض في مستوى الأمان، أي ما إذا كان الطلب يمكن أن يكشف عن بيانات من مصدر مشفّر إلى مصدر غير مشفّر، كما هو الحال في طلبات HTTPS → HTTP. يكون طلب HTTP → HTTP غير مشفّر بالكامل، لذلك لا يتم الرجوع إلى إصدار أقدم. - إذا كان الطلب من المصدر نفسه، يعني ذلك أنّ المخطط (HTTPS أو HTTP) هو نفسه، وبالتالي لا يتم خفض مستوى الأمان.
سياسات المُحيل التلقائية في المتصفّحات
اعتبارًا من أكتوبر 2021
في حال عدم ضبط سياسة المُحيل، يستخدم المتصفّح سياسته التلقائية.
| المتصفح | Referrer-Policy التلقائي / السلوك |
|---|---|
| Chrome |
القيمة التلقائية هي strict-origin-when-cross-origin.
|
| Firefox |
القيمة التلقائية هي strict-origin-when-cross-origin.اعتبارًا من الإصدار 93، بالنسبة إلى مستخدمي ميزة "الحماية من التتبّع" الصارمة و"التصفّح بخصوصية تامة"، يتم تجاهل سياسات المُحيل الأقل تقييدًا no-referrer-when-downgrade وorigin-when-cross-origin وunsafe-url للطلبات من مواقع إلكترونية مختلفة، ما يعني أنّه يتم دائمًا اقتطاع المُحيل للطلبات من مواقع إلكترونية مختلفة، بغض النظر عن سياسة الموقع الإلكتروني.
|
| Edge |
القيمة التلقائية هي strict-origin-when-cross-origin.
|
| Safari |
الإعداد التلقائي مشابه لـ strict-origin-when-cross-origin،
مع بعض الاختلافات المحدّدة. لمعرفة التفاصيل، يُرجى الاطّلاع على مقالة
منع تتبُّع ميزة "منع التتبُّع".
|
أفضل الممارسات لإعداد سياسة المُحيل
هناك طرق مختلفة لضبط سياسات المُحيل لموقعك الإلكتروني:
يمكنك ضبط سياسات مختلفة لصفحات أو طلبات أو عناصر مختلفة.
يكون كلّ من عنوان HTTP وعنصر البيانات الوصفية على مستوى الصفحة. ترتيب الأولوية لتحديد السياسة السارية على عنصر هو كالتالي:
- سياسة على مستوى العنصر
- السياسة على مستوى الصفحة
- المظهر التلقائي للمتصفّح
مثال:
index.html:
<meta name="referrer" content="strict-origin-when-cross-origin" />
<img src="..." referrerpolicy="no-referrer-when-downgrade" />
يتم طلب الصورة باستخدام سياسة no-referrer-when-downgrade، وتتبع جميع طلبات الموارد الفرعية الأخرى من هذه الصفحة سياسة strict-origin-when-cross-origin.
كيف يمكن الاطّلاع على سياسة المُحيل؟
securityheaders.com هو موقع إلكتروني مفيد لتحديد السياسة التي يستخدمها موقع إلكتروني أو صفحة معيّنة.
يمكنك أيضًا استخدام أدوات المطوّرين في Chrome أو Edge أو Firefox للاطّلاع على سياسة المُحيل المستخدَمة لطلب معيّن. في وقت كتابة هذه المقالة، لا يعرض Safari
رأس Referrer-Policy، ولكنه يعرض Referer الذي تم
إرساله.
ما هي السياسة التي يجب ضبطها لموقعك الإلكتروني؟
ننصح بشدة بضبط سياسة تعزيز الخصوصية بشكل صريح، مثل
strict-origin-when-cross-origin (أو سياسة أكثر صرامة).
لماذا "صراحةً"؟
إذا لم تضبط سياسة المُحيل، سيتم استخدام السياسة التلقائية للمتصفّح، وفي الواقع، غالبًا ما تلتزم المواقع الإلكترونية بالإعدادات التلقائية للمتصفّح. لكن هذا ليس مثاليًا، لأن:
- تختلف السياسات التلقائية باختلاف المتصفّحات، لذا إذا كنت تعتمد على الإعدادات التلقائية للمتصفّح، لن يعمل موقعك الإلكتروني على النحو المتوقّع في جميع المتصفّحات.
- تعتمد المتصفّحات إعدادات تلقائية أكثر صرامة، مثل
strict-origin-when-cross-originوآليات مثل اقتطاع المُحيل للطلبات المتعدّدة المصادر. إنّ الموافقة صراحةً على سياسة تعزيز الخصوصية قبل تغيير الإعدادات التلقائية للمتصفّح تمنحك إمكانية التحكّم وتساعدك في إجراء الاختبارات على النحو الذي تراه مناسبًا.
لماذا strict-origin-when-cross-origin (أو أكثر صرامة)؟
أنت بحاجة إلى سياسة آمنة ومفيدة وتعزّز الخصوصية. يعتمد معنى "مفيد" على ما تريده من المُحيل:
- آمن: إذا كان موقعك الإلكتروني يستخدم بروتوكول HTTPS (وإذا لم يكن كذلك، اجعل ذلك
أولوية)، لن ترغب في تسرُّب عناوين URL الخاصة بموقعك الإلكتروني في
طلبات HTTP غير الآمنة. وبما أنّ أي مستخدم على الشبكة يمكنه الاطّلاع على هذه البيانات، فإنّ عمليات التسريب ستعرّض المستخدمين لهجمات الوسيط. وتحلّ السياسات
no-referrer-when-downgradeوstrict-origin-when-cross-originوno-referrerوstrict-originهذه المشكلة. - تعزيز الخصوصية: في طلبات البيانات المتعدّدة المصادر، يشارك
no-referrer-when-downgradeعنوان URL الكامل، ما قد يؤدي إلى مشاكل في الخصوصية. يشاركstrict-origin-when-cross-originوstrict-originالمصدر فقط، ولا يشاركno-referrerأي شيء على الإطلاق. يترك لك هذا الخياراتstrict-origin-when-cross-originوstrict-originوno-referrerكخيارات لتعزيز الخصوصية. - مفيد: لا يشارك
no-referrerوstrict-originعنوان URL الكامل أبدًا، حتى بالنسبة إلى الطلبات من المصدر نفسه. إذا كنت بحاجة إلى عنوان URL الكامل،strict-origin-when-cross-originهو خيار أفضل.
كل هذا يعني أنّ strict-origin-when-cross-origin هو بشكل عام خيار معقول.
مثال: ضبط سياسة strict-origin-when-cross-origin
index.html:
<meta name="referrer" content="strict-origin-when-cross-origin" />
أو من جهة الخادم، على سبيل المثال في Express:
const helmet = require('helmet');
app.use(helmet.referrerPolicy({policy: 'strict-origin-when-cross-origin'}));
ماذا لو لم يكن الإصدار strict-origin-when-cross-origin (أو إصدار أحدث) مناسبًا لجميع حالات الاستخدام؟
في هذه الحالة، اتّبِع نهجًا تدريجيًا: اضبط سياسة وقائية مثل strict-origin-when-cross-origin لموقعك الإلكتروني، وإذا لزم الأمر، اضبط سياسة أكثر تساهلاً لطلبات معيّنة أو عناصر HTML.
مثال: سياسة على مستوى العنصر
index.html:
<head>
<!-- document-level policy: strict-origin-when-cross-origin -->
<meta name="referrer" content="strict-origin-when-cross-origin" />
<head>
<body>
<!-- policy on this <a> element: no-referrer-when-downgrade -->
<a src="…" href="…" referrerpolicy="no-referrer-when-downgrade"></a>
<body></body>
</body>
</head>
</head>
قد يضع Safari/WebKit حدًا أقصى لـ document.referrer أو عنوان Referer
للطلبات من موقع إلكتروني مختلف.
مزيد من التفاصيل
مثال: سياسة على مستوى الطلب
script.js:
fetch(url, {referrerPolicy: 'no-referrer-when-downgrade'});
ما الذي يجب مراعاته أيضًا؟
يجب أن تعتمد سياستك على موقعك الإلكتروني وحالات الاستخدام، على النحو الذي تحدّده أنت وفريقك وشركتك. إذا كانت بعض عناوين URL تحتوي على بيانات حسّاسة أو تكشف الهوية، يجب ضبط سياسة وقائية.
أفضل الممارسات المتعلقة بالطلبات الواردة
في ما يلي بعض الإرشادات حول ما يجب فعله إذا كان موقعك الإلكتروني يستخدم عنوان URL الخاص بالمُحيل للطلبات الواردة.
حماية بيانات المستخدمين
يمكن أن يحتوي Referer على بيانات خاصة أو شخصية أو تعريفية، لذا تأكد من
التعامل معها على هذا النحو.
يمكن للمُحيلين الواردين تغيير {referer-can-change}
هناك بعض القيود على استخدام المُحيل من الطلبات الواردة المتعدّدة المصادر:
- إذا لم يكن لديك إمكانية التحكّم في تنفيذ مُرسِل الطلب، لا يمكنك
وضع افتراضات حول عنوان
Referer(وdocument.referrer) الذي تتلقّاه. قد يقرّر مُرسِل الطلب التبديل إلى سياسةno-referrerفي أي وقت، أو بشكل عام إلى سياسة أكثر صرامة من تلك التي استخدمها من قبل. يعني ذلك أنّك تتلقّى بيانات أقل من "Referer" مقارنةً بالسابق. - تستخدم المتصفّحات بشكل متزايد سياسة المُحيل
strict-origin-when-cross-originبشكل تلقائي. يعني ذلك أنّه قد يصلك الآن المصدر فقط، بدلاً من عنوان URL الكامل للمُحيل، في الطلبات الواردة من مصادر متعددة، إذا لم يكن الموقع الإلكتروني للمُرسِل يتضمّن سياسة محدّدة. - قد تغيّر المتصفّحات طريقة إدارة
Referer. على سبيل المثال، قد يقرّر بعض مطوّري المتصفّحات اقتطاع المُحيلين دائمًا إلى المصادر في طلبات الموارد الفرعية المتعدّدة المصادر، وذلك لحماية خصوصية المستخدمين. - قد يحتوي العنوان
Referer(وdocument.referrer) على بيانات أكثر مما تحتاج إليه. على سبيل المثال، قد يحتوي على عنوان URL كامل عندما تريد فقط معرفة ما إذا كان الطلب متعدّد المصادر.
بدائل "Referer"
قد تحتاج إلى التفكير في بدائل إذا:
- تستخدم ميزة أساسية في موقعك الإلكتروني عنوان URL المُحيل للطلبات الواردة المتعدّدة المصادر.
- لم يعُد موقعك الإلكتروني يتلقّى الجزء الذي يحتاجه من عنوان URL للمُحيل في طلب متعدّد المصادر. يحدث ذلك عندما يغيّر مُرسِل الطلب سياسته أو عندما لا يكون لديه سياسة محدّدة ويتم تغيير سياسة المتصفّح التلقائية (كما هو الحال في الإصدار 85 من Chrome).
لتحديد البدائل، عليك أولاً تحليل الجزء الذي تستخدمه من المُحيل.
إذا كنت بحاجة إلى المصدر فقط
- إذا كنت تستخدم المُحيل في نص برمجي لديه إذن وصول إلى الصفحة على المستوى الأعلى،
يمكنك استخدام
window.location.originكبديل. - إذا كانت الرؤوس مثل
OriginوSec-Fetch-Siteمتاحة، ستمنحكOriginأو توضّح ما إذا كان الطلب متعدّد المصادر، وهو ما قد يكون بالضبط ما تحتاجه.
إذا كنت بحاجة إلى عناصر أخرى من عنوان URL (المسار، معلمات طلب البحث، وما إلى ذلك)
- قد تعالج مَعلمات الطلب حالة الاستخدام، ما يوفّر عليك عناء تحليل المُحيل.
- إذا كنت تستخدم المُحيل في نص برمجي لديه إذن وصول إلى الصفحة على المستوى الأعلى،
قد يكون
window.location.pathnameبديلاً مناسبًا. استخرِج فقط قسم المسار من عنوان URL ومرِّره كوسيطة، وبذلك لا يتم تمرير أي معلومات يُحتمل أن تكون حساسة في مَعلمات عنوان URL.
إذا لم تتمكّن من استخدام هذه البدائل:
- يُرجى التحقّق مما إذا كان بإمكانك تغيير أنظمتك لتتوقّع من مُرسِل الطلب
(مثلاً،
site-one.example) ضبط المعلومات التي تحتاج إليها بشكل صريح في نوع معيّن من الإعدادات.- المزايا: أكثر وضوحًا، وأكثر حفاظًا على خصوصية مستخدمي
site-one.example، وأكثر توافقًا مع الاحتياجات المستقبلية. - السلبيات: قد يتطلّب ذلك المزيد من العمل من جانبك أو من جانب مستخدمي نظامك.
- المزايا: أكثر وضوحًا، وأكثر حفاظًا على خصوصية مستخدمي
- يُرجى التحقّق مما إذا كان الموقع الإلكتروني الذي يُصدر الطلبات يوافق على ضبط
سياسة المُحيل لكل عنصر أو لكل طلب على
no-referrer-when-downgrade.- السلبيات: قد تكون أقل حفاظًا على الخصوصية لمستخدمي
site-one.example، وقد لا تكون متاحة في بعض المتصفّحات.
- السلبيات: قد تكون أقل حفاظًا على الخصوصية لمستخدمي
الحماية من تزوير الطلبات من مواقع إلكترونية مختلفة (CSRF)
يمكن لمرسل الطلب دائمًا اختيار عدم إرسال المُحيل من خلال ضبط سياسة no-referrer، ويمكن لجهة مسيئة حتى انتحال هوية المُحيل.
استخدِم رموز CSRF المميّزة
كوسيلة الحماية الأساسية. للحصول على حماية إضافية، استخدِم
SameSite،
وبدلاً من Referer، استخدِم عناوين مثل
Origin
(متوفّرة في طلبات POST وCORS) و
Sec-Fetch-Site
إذا كانت متوفّرة.
التسجيل وتصحيح الأخطاء
احرص على حماية بيانات المستخدمين الشخصية أو الحساسة التي قد تكون في
Referer.
إذا كنت تستخدم المصدر فقط، تحقَّق مما إذا كان بإمكانك استخدام العنوان Origin كبديل. قد يوفّر لك ذلك المعلومات التي تحتاجها لأغراض تصحيح الأخطاء بطريقة أبسط وبدون الحاجة إلى تحليل المُحيل.
الدفعات
قد يعتمد مقدّمو خدمات الدفع على عنوان Referer للطلبات الواردة لإجراء
فحوصات الأمان.
على سبيل المثال:
- ينقر المستخدم على زر شراء في
online-shop.example/cart/checkout. - يُعيد
online-shop.exampleالتوجيه إلىpayment-provider.exampleلإدارة المعاملة. - يتحقّق
payment-provider.exampleمنRefererلهذا الطلب من خلال مقارنته بقائمة قيمRefererالمسموح بها التي أعدّها التجّار. وإذا لم يتطابق مع أي إدخال في القائمة، يرفضpayment-provider.exampleالطلب. إذا تطابق، يمكن للمستخدم المتابعة إلى المعاملة.
أفضل الممارسات المتعلّقة بعمليات التحقّق من أمان مسار الدفع
بصفتك مقدّم خدمات دفع، يمكنك استخدام Referer كإجراء أساسي للتحقّق من بعض الهجمات. ومع ذلك، لا يُعدّ عنوان Referer وحده أساسًا موثوقًا لإجراء عملية التحقّق. يمكن للموقع الإلكتروني الذي يطلب المعلومات، سواء كان تاجرًا شرعيًا أم لا، ضبط سياسة no-referrer تجعل معلومات Referer غير متاحة لمقدّم خدمات الدفع.
قد يساعد الاطّلاع على Referer مقدّمي خدمات الدفع في رصد المهاجمين المبتدئين الذين لم يضبطوا سياسة no-referrer. إذا كنت تستخدم Referer كأول عملية تحقّق:
- لا تتوقّع أن يكون
Refererمتاحًا دائمًا. وإذا كان موجودًا، تحقَّق منه مقابل الحد الأدنى من البيانات التي يمكن أن يتضمّنها، وهو المصدر.- عند ضبط قائمة قيم
Refererالمسموح بها، تأكَّد من تضمين المصدر فقط بدون أي مسار. - على سبيل المثال، يجب أن تكون قيم
Refererالمسموح بها لـonline-shop.exampleهيonline-shop.example، وليسonline-shop.example/cart/checkout. من خلال توقُّع عدم توفُّرRefererعلى الإطلاق أو توقُّع قيمةRefererتمثّل مصدر الموقع الإلكتروني الذي يرسل الطلب فقط، يمكنك تجنُّب الأخطاء التي قد تنتج عن وضع افتراضات حولReferrer-Policyالتاجر.
- عند ضبط قائمة قيم
- إذا لم يكن
Refererمتوفّرًا، أو إذا كان متوفّرًا ونجح التحقّق الأساسي من مصدرReferer، يمكنك الانتقال إلى طريقة أخرى أكثر موثوقية للتحقّق.
للتحقّق من الدفعات بشكل أكثر موثوقية، يمكنك السماح لمقدّم الطلب بتجزئة مَعلمات الطلب مع مفتاح فريد. ويمكن لمقدّمي خدمات الدفع بعد ذلك احتساب التجزئة نفسها من جانبك وقبول الطلب فقط إذا كان يتطابق مع عملية الاحتساب.
ماذا يحدث لـ Referer عندما يعيد موقع تاجر يستخدم HTTP ولا يتضمّن سياسة المُحيل التوجيه إلى مقدم خدمات دفع يستخدم HTTPS؟
لا يظهر Referer في الطلب المرسَل إلى مقدّم خدمات الدفع عبر HTTPS، لأنّ معظم المتصفّحات تستخدم strict-origin-when-cross-origin أو no-referrer-when-downgrade تلقائيًا عندما لا تكون هناك سياسة محدّدة للموقع الإلكتروني.
لن يؤدي تغيير Chrome إلى سياسة تلقائية جديدة إلى تغيير هذا السلوك.
الخاتمة
تُعدّ سياسة المُحيل الوقائية طريقة رائعة لمنح المستخدمين المزيد من الخصوصية.
لمزيد من المعلومات حول الأساليب المختلفة لحماية المستخدمين، يمكنك الاطّلاع على مجموعة الأمان والسلامة.
الموارد
- فهم مفهومَي "الموقع الإلكتروني نفسه" و "المصدر نفسه"
- عنوان أمان جديد: سياسة المُحيل (2017)
- Referrer-Policy على MDN
- Referer header: privacy and security concerns on MDN
- تغيير في Chrome: نية Blink في التنفيذ
- تغيير في Chrome: نية Blink في الشحن
- تغيير في Chrome: إدخال الحالة
- تغيير في Chrome: منشور المدوّنة حول الإصدار التجريبي 85
- سلسلة محادثات GitHub حول اقتطاع المُحيل: ما تفعله المتصفّحات المختلفة
- مواصفات Referrer-Policy
مع خالص الشكر على المساهمات والملاحظات لجميع المراجعين، خاصةً "كوستوبها غوفيند" و"ديفيد فان كليف" و"مايك ويست" و"سام داتون" و"روان ميريوود" و"جيك" و"كايس باسك".