اختبار إدارة الجلسات

يتحقق اختبار إدارة الجلسات (Session Management Testing) من الطريقة التي ينشئ بها التطبيق الجلسات التي تُبقي المستخدمين مسجّلي الدخول، ويحميها ويجددها وينهيها. ويطرح خمسة أسئلة: هل يمكن توقّع المعرّفات؟ هل يمكن استخدام معرّف زُرع قبل تسجيل الدخول بعده، وهو تثبيت الجلسة (Session Fixation)؟ هل تُفرض مهلة الخمول (idle timeout) والمهلة المطلقة (absolute timeout)؟ هل يُنهي تسجيل الخروج الجلسة على الخادم؟ وهل يحمل كل ملف تعريف ارتباط للجلسة السمات (flags) الصحيحة؟

مثال: بوابة موارد بشرية تُبقي المعرّف نفسه من صفحة الدخول إلى لوحة التحكم. تسجيل الدخول يعمل، فتنجح كل الاختبارات الوظيفية، ومع ذلك فإن من وضع تلك القيمة في متصفح الموظف قبل دخوله يشاركه الآن جلسته. ولا يكشف ذلك إلا اختبار يعيد إرسال المعرّف القديم.

لماذا يهم

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

ولا تظهر هذه العيوب في الاختبار الوظيفي، لأن رحلة المستخدم نفسه تعمل. ولا تكشفها إلا اختبارات مصممة لها، وأغلبها رخيص: ملفّان شخصيان للمتصفح وأدوات المطوّر وحساب اختبار. ويخصص دليل OWASP لاختبار أمان الويب (WSTG) فئة كاملة لاختبارات إدارة الجلسات، وهذا الدرس يحوّل أهمها إلى شروط اختبار تنفّذها في كل إصدار.

دورة حياة الجلسة نموذجاً للحالات

في درس ملفات تعريف الارتباط والجلسات في HTTP تتبّعت جلسة واحدة يدوياً. أما خطة الاختبار الأمني فيجب أن تغطي كل طريقة تبدأ بها الجلسة وتتغير وتنتهي، ونموذج الحالات، كما في اختبار انتقالات الحالة، يجعل ذلك مرئياً: لا جلسة، ثم جلسة مجهولة الهوية (تنشئها تطبيقات كثيرة قبل تسجيل الدخول)، ثم مسجّل الدخول، ثم خامل، ثم منتهية. وكل انتقال شرط اختبار.

وقاعدة واحدة تغطي النموذج كله: عند تسجيل الدخول، وعند كل تغيير في الصلاحيات، وعند كل طريقة تنتهي بها الجلسة، يجب أن يتوقف المعرّف القديم عن العمل على الخادم؛ ولا يبقى المعرّف نفسه إلا في الانتقال بين «مسجّل الدخول» و«خامل». والفحص واحد دائماً: احتفظ بنسخة من المعرّف القديم، وأعد إرساله بعد الانتقال، وتوقّع صفحة الدخول أو 401، لا بيانات المستخدم أبداً. أما القيم المتوقعة، مثل المهلتين والأحداث التي تُنهي الجلسات الأخرى، فتأتي من سياسة الجلسات لدى الفريق.

جلسة تسجيل الدخول آلةَ حالات: يجب أن يُبطل تسجيل الدخول وكل تغيير في الصلاحيات وكل إنهاء للجلسة المعرّفَ القديم على الخادم، فكل انتقال مرقّم من هذه اختبارٌ يُفحص بإعادة إرسال المعرّف القديم. نموذج مفاهيمي
الانتقالات
#منإلىالحدث / ما يجب أن يفعله الخادم
1لا جلسةالبدايةجلسة مجهولة Aالزيارة الأولى / يصدر الخادم معرّف ما قبل الدخول A (إن كان التطبيق ينشئه)
2جلسة مجهولة Aمسجّل الدخول Bالحالة الحاليةنجاح تسجيل الدخول / معرّف جديد B، وإعادة إرسال A تنتهي الآن بصفحة الدخول
3مسجّل الدخول Bالحالة الحاليةمسجّل الدخول Bالحالة الحاليةتغيير الصلاحيات (إعادة المصادقة، تبديل الدور) / معرّف جديد، ويتوقف المعرّف السابق عن العمل
4مسجّل الدخول Bالحالة الحاليةمسجّل الدخول، خامللا طلبات من المستخدم
5مسجّل الدخول، خاملمسجّل الدخول Bالحالة الحاليةطلب من المستخدم قبل حد الخمول / يبدأ عدّاد الخمول من جديد
6مسجّل الدخول، خاملمنتهية على الخادمالنهايةبلوغ حد الخمول بساعة الخادممسار بديل
7مسجّل الدخول Bالحالة الحاليةمنتهية على الخادمالنهايةتسجيل الخروج / يحذف الخادم سجلّ الجلسة
8مسجّل الدخول Bالحالة الحاليةمنتهية على الخادمالنهايةبلوغ المهلة المطلقة أو تغيير كلمة المرور أو إبطال الجلسة من المسؤولمسار بديل

نموذج مبسّط: قد تضيف التطبيقات الحقيقية حالات مثل جهاز مُتذكَّر أو حساب مقفَل.

جرّبها: مولّد انتقالات الحالات

عشوائية المعرّف: ابحث عن البنية

تطلب ورقة OWASP المرجعية لإدارة الجلسات (Session Management Cheat Sheet) معرّفات يولّدها مولّد عشوائي آمن تشفيرياً بإنتروبيا لا تقل عن ⁦64⁩ بت، بينما يطلب الإصدار ⁦5.0⁩ من معيار OWASP للتحقق من أمان التطبيقات (ASVS) ⁦128⁩ بت على الأقل، فاعتمد الحد الأدنى الذي تتبنّاه سياسة فريقك. لا يمكنك إثبات العشوائية بالنظر، لكنك تستطيع أن تجد البنية التي تنفيها. سجّل الدخول نحو ⁦20⁩ مرة بحساب اختبار وبضع مرات بحساب آخر، ودوّن كل معرّف مع وقته، ثم رتّب المعرّفات بعضها تحت بعض.

  • الطول لا يعطي إلا حداً أعلى: ⁦32⁩ محرفاً ست عشرياً تحمل ⁦128⁩ بت على الأكثر. فإذا لم يتغير ⁦24⁩ منها أبداً، فالمحارف ⁦8⁩ الباقية تحمل ⁦32⁩ بت على الأكثر، أي أقل من الحد الأدنى.
  • البادئة التي تشترك فيها كل القيم، أو الجزء الذي يزيد بواحد عند كل تسجيل دخول، عدّاد وليس عشوائية.
  • فكّ ترميز القيمة كـBase64، وحوّل الأرقام الطويلة كطوابع زمنية Unix (عدد الثواني أو أجزاء الألف من الثانية منذ ⁦1⁩ يناير ⁦1970⁩ بالتوقيت العالمي UTC): فوجود رقم مستخدم أو بريد إلكتروني أو وقت الدخول داخلها يعني أن المعرّف مُركَّب لا عشوائي.
  • يجب أن يعطي تسجيل الدخول الثاني للمستخدم نفسه قيمة مختلفة تماماً، وألا يظهر المعرّف أبداً في العناوين (URL) أو مصدر الصفحة أو رسائل الخطأ.
  • هذه الفحوص تكشف البنية لكنها لا تثبت غيابها. فالتحليل الإحصائي لعيّنة كبيرة، بأداة مثل Sequencer في Burp Suite، عمل المتخصصين؛ وأقوى دليل أن مدير الجلسات المدمج في إطار العمل هو من يولّد المعرّف، وهو ما توصي به OWASP بدلاً من حلّ مصنوع داخلياً.

جرّبها: مفكّك ترميز Base64 جرّبها: محوّل الطوابع الزمنية

مثال تطبيقي: اختبار تثبيت الجلسة

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

الإعداد: بوابة موظفين https://hr.example في بيئة اختبار، وحساب اختبار واحد، وملفّان شخصيان للمتصفح (browser profiles): A للمهاجم وB للموظف. لا تختبر إلا أنظمة تملكها أو لديك إذن مكتوب باختبارها. يُظهر التتبّع زيارة A، ثم دخول B بعد ضبط ملف تعريف الارتباط يدوياً، ثم إعادة الإرسال من A.

  • في A افتح صفحة الدخول وانسخ قيمة sid السابقة للدخول. وفي B اضبط sid على تلك القيمة من لوحة التخزين في أدوات المطوّر، ثم سجّل الدخول.
  • المتوقع: تضبط استجابة الدخول قيمة sid جديدة، وإعادة تحميل /dashboard في A تنتهي بصفحة الدخول. فإن رأى A لوحة تحكم الموظف فالجلسة مثبَّتة: اقترح الخطورة حرج (Critical).
  • كرّر الاختبار بقيمة لم يصدرها الخادم قط، مثل sid=tester-made-0001. مدير الجلسات الصارم (strict) يتجاهلها ويصدر قيمته، أما الذي يقبلها فتسميه OWASP متساهلاً (permissive). أبلغ عن ذلك حتى لو ظل التجديد يحمي تسجيل الدخول.
  • كرّر الاختبار عند كل تغيير في الصلاحيات: إعادة المصادقة قبل إجراء حساس، وتبديل الدور أو المؤسسة، ودخول مستخدم آخر من المتصفح نفسه. وحين تنتقل الجلسة في ملف تعريف ارتباط، يجب تجاهل أي معرّف في العنوان، مثل ?sid= أو ;jsessionid=.
GET /login HTTP/1.1
Host: hr.example

HTTP/1.1 200 OK
Set-Cookie: sid=Pq7Lm2Vx9Rt4Kw8N; Path=/; Secure; HttpOnly; SameSite=Lax

POST /login HTTP/1.1
Host: hr.example
Cookie: sid=Pq7Lm2Vx9Rt4Kw8N

HTTP/1.1 303 See Other
Location: /dashboard
Set-Cookie: sid=Zc4Hn8Tq1Wy6Bd3F; Path=/; Secure; HttpOnly; SameSite=Lax

GET /dashboard HTTP/1.1
Host: hr.example
Cookie: sid=Pq7Lm2Vx9Rt4Kw8N

HTTP/1.1 302 Found
Location: /login

جرّبها: مولّد أوامر cURL

المهلات وتسجيل الخروج: كل طريقة يجب أن تنتهي بها الجلسة

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

  • حركة الخلفية: اترك صفحة تستطلع الخادم دورياً (polling)، كعدّاد الإشعارات، خاملة إلى ما بعد الحد. فإن عُدّ الاستطلاع نشاطاً فلن تنتهي الجلسة بالخمول أبداً؛ اسأل هل هذا مقصود.
  • نوافذ التحذير: يجب أن يمدّد زر «البقاء مسجّلاً الدخول» الجلسة على الخادم، وأن يُنهيها تجاهل التحذير هناك، لا أن يخفي الصفحة فقط. ولا يمدّد أي نشاط المهلة المطلقة.
  • التبويبات والأجهزة: تسجيل الخروج في تبويب واحد يُنهي الجلسة في كل التبويبات، و«تسجيل الخروج من جميع الأجهزة» يُنهي الجلسة في ملف شخصي ثانٍ للمتصفح أيضاً.
  • تغيير كلمة المرور: يتوقع معيار ASVS خياراً لإنهاء كل الجلسات الأخرى بعد تغيير أي عامل مصادقة، مثل تغيير كلمة المرور، بما في ذلك التغيير عبر استعادة كلمة المرور، أو تحديث إعدادات المصادقة متعددة العوامل (MFA). ويتوقع أيضاً أن تنتهي كل جلسات الحساب المعطَّل أو المحذوف؛ واسأل ماذا تقول السياسة عن الأدوار المسحوبة.
  • كل بيانات الاعتماد: يجب أن يتوقف عن العمل عند تسجيل الخروج أيضاً ملف تعريف ارتباط «تذكّرني» (ملف دائم يعيد تسجيل دخول المستخدم دون كلمة المرور)، ورمز التحديث (refresh token)، وهو رمز طويل العمر يُستخدم للحصول على رموز وصول جديدة، ورمز الوصول (access token) في تطبيقات الصفحة الواحدة. أعد إرسال كل واحد منها.
  • بعد تسجيل الخروج قد يعرض زر «رجوع» صفحة من سجل المتصفح. هذه مسألة تخزين مؤقت؛ أعد التحميل أو انقر أي شيء، ويجب أن يجيب الخادم بصفحة الدخول.

أخطاء شائعة

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

من منظور ضمان الجودة

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

معظم هذا السلوك إعدادات في إطار العمل أو بوابة الواجهات البرمجية، لذا أعد تشغيل الاختبارات بعد الترقيات وتغييرات البنية التحتية. وفي تقرير الخطأ اذكر الانتقال، والمعرّفين قبله وبعده مُقنَّعين، والأوقات، وإجابة الخادم. واترك الاستغلال والتحليل الإحصائي لمتخصصي الأمان، واتفق معهم على النطاق قبل أي اختبار خارج بيئة الاختبار.

تمرين عملي

احكم على أول اختبارات الجلسة لبوابة صيدلية

المطلوب

بوابة صيدلية في بيئة الاختبار لديك إذن مكتوب باختبارها، وسياسة جلساتها: مهلة خمول ⁦15⁩ دقيقة ومهلة مطلقة ⁦8⁩ ساعات، كلتاهما على الخادم؛ ومعرّف جديد عند الدخول وعند كل تغيير في الصلاحيات؛ وتسجيل الخروج يُنهي الجلسة؛ وتغيير كلمة المرور يُنهي كل الجلسات الأخرى.

أنتجت اختباراتك الأولى المادة أدناه وثلاث ملاحظات: قيمة sid السابقة للدخول تفتح لوحة التحكم عند إعادة إرسالها بعد الدخول؛ وتبويب يستطلع /api/notifications كل ⁦60⁩ ثانية ما زال مسجّل الدخول بعد ⁦40⁩ دقيقة من الخمول؛ وبعد تغيير كلمة المرور في الملف الشخصي ⁦1⁩ ما زال الملف الشخصي ⁦2⁩ يحمّل سجل الطلبات. لكل نتيجة اذكر المجال، والقاعدة التي تخالفها، والخطورة المقترحة، واختبار تأكيد للإصلاح.

المادة
المعرّفات بعد خمس عمليات دخول لمستخدم الاختبار 2041
sid=s-2041-8f3a01
sid=s-2041-8f3a02
sid=s-2041-8f3a03
sid=s-2041-8f3a04
sid=s-2041-8f3a05

استجابة الدخول دون «تذكّرني»
Set-Cookie: sid=s-2041-8f3a05; Path=/; Secure; HttpOnly; SameSite=Lax

استجابة الدخول مع «تذكّرني»
Set-Cookie: sid=s-2041-8f3a06; Path=/; Max-Age=2592000
الخطوات
  1. رتّب المعرّفات بعضها تحت بعض، وحدّد الأجزاء التي لا تتغير والأجزاء التي تعدّ.
  2. قارن سطري Set-Cookie سمةً سمة.
  3. ضع كل ملاحظة على انتقال من نموذج حالات الجلسة.
إظهار الإجابة النموذجية
الإجابة النموذجية

العشوائية: 2041 رقم المستخدم، و8f3a0 لا يتغير أبداً، والرقم الأخير يعدّ تصاعدياً ويستمر إلى 06 في الدخول التالي. فمن يرى معرّفاً واحداً يستطيع تخمين البقية. القاعدة: معرّف عشوائي بإنتروبيا لا تقل عن ⁦64⁩ بت وبلا معنى، كما توصي OWASP؛ وهنا لا يتغير إلا محرف ست عشري واحد، أي ⁦4⁩ بت على الأكثر. الخطورة: حرج (Critical). اختبار التأكيد: عيّنة جديدة لا تُظهر أجزاء مشتركة أو متزايدة أو مقروءة، ويؤكد الفريق أن المولّد الآمن في إطار العمل هو من ينشئ المعرّف.

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

المهلة: يعيد الاستطلاع ضبط عدّاد الخمول، فلا تنطبق قاعدة الدقائق الـ⁦15⁩ ما دام التبويب مفتوحاً. الخطورة: رئيسي (Major)، ما لم تنص السياسة على أن الاستطلاع نشاط. اختبار التأكيد: مع فتح تبويب الاستطلاع ودون أي إجراء من المستخدم، ينتهي أول إجراء بعد ⁦16⁩ دقيقة بصفحة الدخول، ويعمل الإجراء بعد ⁦14⁩ دقيقة.

الإبطال: لم يُنهِ تغيير كلمة المرور الجلسة الأخرى، فمن سرق جلسة يحتفظ بها بعد أن يغيّر المستخدم كلمة مروره. الخطورة: حرج. اختبار التأكيد: بعد التغيير في الملف الشخصي ⁦1⁩، ينتهي الطلب التالي في الملف الشخصي ⁦2⁩ بصفحة الدخول؛ وكرّر مع تغيير عبر استعادة كلمة المرور.

السمات: استجابة «تذكّرني» تُسقط Secure وHttpOnly وSameSite، وتُبقي ملف تعريف ارتباط الجلسة ⁦30⁩ يوماً. القاعدة: الحد الأدنى لسمات ملف الجلسة في كل استجابة تضبطه. الخطورة: رئيسي؛ واسأل أيضاً هل يجب أن تستخدم «تذكّرني» ملفاً منفصلاً قابلاً للإبطال. اختبار التأكيد: تُظهر أداة Cookie Analyzer السمات نفسها في الاستجابتين.

ما زال للاختبار: المهلة المطلقة البالغة ⁦8⁩ ساعات مع نشاط مستمر، وإعادة إرسال sid وملف «تذكّرني» بعد تسجيل الخروج، والتجديد عند تغيير الصلاحيات.

أسئلة شائعة

هل أستطيع اختبار إدارة الجلسات دون أدوات أمنية؟

في معظمه نعم. فملفّان شخصيان للمتصفح وأدوات المطوّر وحساب اختبار وعميل سطر أوامر مثل curl تكفي لاختبار التجديد والتثبيت والمهلات وتسجيل الخروج وسمات ملفات تعريف الارتباط. أما التحليل الإحصائي للعشوائية والماسحات الآلية فعمل المتخصصين؛ أشرك فريق الأمان حين تستدعي المخاطر ذلك.

ما الذي يتغير حين يستخدم التطبيق JWT بدلاً من معرّف جلسة؟

تبقى الأسئلة وتتغير الفحوص. فحمولة JWT الموقَّع مرمَّزة فقط لا مشفّرة، ففكّ ترميزها وتحقق من خلوّها من البيانات الحساسة ومن قِصر exp. ولا يحتفظ الخادم عادةً بسجل لـJWT، فيحتاج تسجيل الخروج وتغيير كلمة المرور إلى تصميم إضافي، مثل رموز وصول قصيرة العمر مع رموز تحديث قابلة للإبطال: أعد إرسال الاثنين بعد تسجيل الخروج لترى ما يفعله التطبيق فعلاً.

كم معرّفاً أحتاج للحكم على العشوائية؟

للفحوص البصرية في هذا الدرس تكفي بضع عشرات لإظهار العدّادات والطوابع الزمنية والأجزاء الثابتة. ولا تثبت أي عيّنة تقرؤها بعينك أن القيم عشوائية بما يكفي؛ فذلك يحتاج إلى تحليل إحصائي أو دليل على مولّد مُجرَّب. أبلغ عما لاحظته، لا أن المعرّف آمن.

هل غياب التجديد عيب إذا لم يكن أحد قادراً على زرع معرّف؟

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

المراجع

  • OWASP Web Security Testing Guide (WSTG)OWASP Foundationالمنهجية المرجعية لاختبار تطبيقات الويب وواجهات API بحثاً عن نقاط الضعف الأمنية، اختباراً تلو الآخر.
  • OWASP Cheat Sheet Series: Session ManagementOWASP Foundationإنتروبيا معرّف الجلسة وسمات ملف تعريف الارتباط والانتهاء والتجديد بعد تسجيل الدخول ومعالجة تسجيل الخروج.
  • OWASP Application Security Verification Standard (ASVS)OWASP Foundationقائمة تحقق بمتطلبات أمنية قابلة للتحقق لتطبيقات الويب، مصنّفة في ثلاثة مستويات ضمان.
  • Using HTTP cookies — MDNMDN Web Docs (Mozilla)عمر ملف تعريف الارتباط ونطاقه وسمات Secure/HttpOnly/SameSite وآثارها الأمنية.

تدرّب بأدوات متقن

عرّف الحالات والأحداث، ثم ولّد جدول الانتقالات واختبارات الانتقالات الصالحة/غير الصالحة وتغطية 0-switch/1-switch.

تصميم الاختبارات

فكّ ترميز سلاسل Base64 أو Base64url إلى نص، مع إصلاح الحشو تلقائياً.

الترميز

حوّل الطوابع الزمنية (ثوانٍ، ميلي ثانية، ميكرو ثانية) إلى تواريخ مقروءة وبالعكس، بأي منطقة زمنية.

أدوات مساعدة

إنشاء أوامر cURL من الطريقة وعنوان URL والترويسات والمتن وخيارات المصادقة.

الويب

فكّ ترميز ترويسة JWT وحمولته، وفحص المطالبات (claims) والتحقق من انتهاء الصلاحية — بالكامل داخل متصفحك.

الأمان

للتعمّق أكثر

تقدّمك في هذا الموضوع

جزء من مسار تعلم ضمان الجودة