رموز (CSRF (tokens

المصدر: https://portswigger.net/web-security/csrf/tokens

رموز CSRF

في هذا القسم ، سنشرح ماهية رموز (CSRF tokens)CSRF، وكيفية حمايتها من هجماتCSRF، و كيف ينبغي إنشاء رموز و التحقق منها.

ما هي رموز CSRF ؟

رمز CSRF هو قيمة فريدة سرية و لا يمكن التنبؤ بها يتم إنشاؤها بواسطة تطبيق على السيرفر و يتم إرسالها إلى العميل (client) بحيث يتم تضمينها في اي طلب HTTP request تالٍ مرسل من العميل (client). و لاحقاً عند إرسال الطلب request، يتحقق التطبيق على السيرفر (sever-side application) من أن الطلب يتضمن الرمز المميز (token) المتوقع و يرفض الطلب إذا كان الرمز المميز مفقوداً أو غير صالح.

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

كيف ينبغي إنشاء رموز CSRF ؟

  • يجب أن تشتمل رموز CSRF على عشوائية عالية و أن تكون غير قابلة للتنبؤ بشدة، و بنفس خصائص رموز الجلسة (session tokens) بشكل عام.

  • يجب أن تستخدم مولد أرقام عشوائية زائف (PRNG) [هو إجراء يقوم بتوليد أرقام عشوائية بناءً على توابع رياضية معينة و هو “زائف” لأن الأرقام الناتجة ليست عشوائية في الحقيقة و إنما قابلة للتنبؤ إذا عُرف التابع الرياضي المستخدَم] قوي التشفير، يتم إعطاؤه الطابع الزمني عندما يتم إنشاؤه بالإضافة إلى رقم سري ثابت.

  • إذا كنت بحاجة إلى مزيد من الموثوقية اللتي تتجاوز قوة الـPRNG ، فيمكنك إنشاء الرموز المميزة بشكل فردي من خلال ربط ناتجها مع بعض العشوائية الخاصة بالمستخدم وعمل hash (مزج - خلط) قوي للبنية بأكملها. يشكل ذلك عائقاً إضافياً للمهاجمين الذين يحاولون تحليل الرموز المميزة tokens بناءً على نموذج تم إصداره لهم.

كيف يجب إرسال رموز الـ CSRF ؟

يجب أن تعامل رموز الـ CSRF كأسرار و أن تعالج بطريقة آمنة طوال دورة حياتها. إحدى الطرق الفعالة عادة تتمثل في إرسال الرمز المميز token إلى الزبون client داخل حقل مخفي من نموذج HTML (HTML form) يتم إرساله باستخدام طريقةPOST. بعد ذلك، سيتم تضمين الرمز المميز كوسيط في الطلب request عند إرسال النموذج:

<input type="hidden" name="csrf-token" value="CIwNZNlR4XbisJF39I8yWnWX9wX4WFoz" />

لمزيد من الأمان، يجب وضع الحقل الذي يحتوي على رمز CSRF في أسرع وقت ضمن مستند HTML. نموذجياً، يتم وضعه قبل أية حقول إدخال (input fields) غير مخفية، وقبل أية مواقع تحتوي على بيانات يمكن التحكم فيها من المستخدم ضمنHTML . هذا يخفف من الأساليب المتنوعة التي يمكن أن يستخدم المهاجم فيها بيانات معدّة مسبقاً لمعالجة مستند HTML و أخذ أجزاءٍ من محتوياته.

الطريقة البديلة بوضع الرمز في سلسلة استعلام URL (URL query string) أقل أماناً إلى حد ما لأن سلسلة الاستعلام :

  • يتم تسجيلها في مواقع مختلفة عند الزبون و الخادم (السيرفر) ،

  • عرضة للإرسال إلى أطراف ثالثة من خلال ترويسة Referer (HTTP Referer header)

  • يمكن عرضها على الشاشة ضمن المتصفح الخاص بالمستخدم.

تقوم بعض التطبيقات بإرسال رموز CSRF ضمن ترويسة مخصصة في الطلب (custom request header). يقدم هذا دفاعاً إضافياً ضد المهاجم الذي يتمكن من التنبؤ بالرمز المميز لمستخدم آخر أو التقاطه، لأن المتصفحات لا تسمح عادةً بإرسال الترويسات المخصصة (custom headers) عبر النطاق (من نطاق إلى نطاق آخر خارجي). إلا أن هذه الطريقة تحد من إمكانية التطبيق على إنشاء طلبات محمية من الـ CSRF باستخدام الـ XHR (بخلاف نماذج HTML [HTML forms]) كما أنها قد تكون شديدة التعقيد في العديد من الحالات.

يجب ألا يتم إرسال رموز CSRF ضمن ملفات تعريف الارتباط (cookies) .

كيف يجب التحقق من صحة رموز الـ CSRF ؟

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