نادي الناديفرع شيراتون
الإصدار الأول | 24 أكتوبر 2026

تقرير فني | الأمان والجاهزية للتشغيل

أمان المنظومة وقدرتها على التحمّلما قِسناه فعلًا، بالأرقام، وكيف تُحمى بيانات الأعضاء

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

من 5 إلى 50 مستخدمًا متزامنًا: صفر أخطاء.نتيجة اختبار الضغط

الخلاصة

النتيجة قبل التفاصيل

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

50مستخدمًا متزامنًا

صفر أخطاء حتى آخر مرحلة

كل مستخدم بحسابه وجلسته، على شاشات عمل حقيقية.

0بيانات بطاقات

لا تُخزَّن إطلاقًا

لا رقم بطاقة ولا CVV ولا تاريخ انتهاء — ولا بوابة دفع.

108فحصًا آليًا

كلها تمر

أمان الواجهة، وجلسة مسجَّلة، ووحدات، وتوجيه، ونسخ احتياطي حقيقي.

1864مسارًا محميًا

لكل مسار صلاحيته

لا يوجد باب خلفي: الصلاحية تُفحص في الوسيط قبل الكود.

التحمّل: رفعنا الضغط تدريجيًا من 5 إلى 50 موظفًا متزامنًا، كلٌّ بحسابه وجلسته المستقلة، على شاشات ثقيلة فعلًا (67–76 كيلوبايت لكل صفحة: قوائم الأعضاء، ولوحة المؤشرات، والبحث، والاشتراكات). المنظومة أنهت 6,598 طلبًا بصفر أخطاء، وبلغت ذروة 106.6 طلبًا في الثانية. وتحت الإشباع لم تنكسر: طالت مدة الانتظار وحدها ثم عادت.

الأمان: اجتازت المنظومة فحصًا خارجيًا (33 فحصًا) وفحصًا داخليًا بجلسة موظف مسجَّل (6 فحوص) بنتيجة كاملة وصفر ملاحظات عالية الخطورة، إضافة إلى 68 اختبار وحدة تغطي الترميز والتوجيه والتشفير.

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

لا نكتب في التقرير ما لم نجعله صحيحًا أولًا.قاعدة العمل في هذا التقرير

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

التحمّل

ماذا يحدث حين يضغط الجميع معًا

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

موظف متزامنطلباتطلب/ثانيةأخطاءوسيط (مللي)p95 (مللي)p99 (مللي)
576450.50.0%89.5149.1185.8
101,39792.50.0%92.5181.1237.1
201,620106.60.0%156.1271.2355.7
301,41491.90.0%247.3467.6583.4
501,40391.00.0%419.6760.91026.4

اقرأ العمود الرابع أولًا: صفر أخطاء في كل مرحلة، حتى 50 مستخدمًا متزامنًا. المنظومة لم تُسقط طلبًا واحدًا ولم تُرجع خطأ خادم واحدًا طوال الاختبار.

عند 20 موظفًا متزامنًا — وهو أعلى من الذروة الواقعية لمكتب النادي — تأتي الصفحة الكاملة في أقل من ثلث ثانية لـ95٪ من الطلبات. وعند مضاعفة ذلك إلى 50، لم تظهر أخطاء: طال الانتظار إلى أقل من ثانية، ثم عادت المنظومة لوضعها فور انتهاء الضغط. هذا هو السلوك المطلوب تحت الضغط: طابور منظَّم، لا انهيار.

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

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

والنمو بعد ذلك: المنظومة تُشغَّل كحاويات خلف موزِّع أحمال، فالتوسّع يكون بإضافة نسخ متوازية لا بتغيير الكود. دليل التشغيل يشرح الخطوة ومتطلبها (تخزين الجلسات المشترك) بالتفصيل.

بيانات الدفع

أقوى حماية لبيانات البطاقات: ألّا توجد

أكثر سؤال يُطرح على أي منظومة تتعامل مع مال: أين تُحفظ أرقام البطاقات، وكيف تُحمى؟ إجابتنا هنا مختلفة — لا تُحفظ.

بحثنا في بنية قاعدة البيانات كلها (595 ملف ترحيل) عن أي عمود يحمل رقم بطاقة أو رمز تحقق أو تاريخ انتهاء، وفي الكود كله عن أي تكامل مع بوابة دفع. لا يوجد ولا واحد.

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

النتيجة العملية: تسريب قاعدة البيانات — في أسوأ احتمال — لا يُخرج رقم بطاقة واحدًا، ببساطة لأنه غير مخزَّن. وهذا يضع المنظومة خارج نطاق متطلبات PCI-DSS الخاصة بتخزين بيانات البطاقات عمليًا.

البيانالحالةلماذا
رقم البطاقة (PAN)لا يُخزَّنلا يمر بالمنظومة أصلًا
رمز التحقق (CVV)لا يُخزَّنلا حقل له في أي شاشة
تاريخ الانتهاءلا يُخزَّنلا عمود له في القاعدة
بوابة دفع إلكترونيةغير مربوطةالدفع على جهاز البنك
رقم العملية المرجعييُخزَّنلمطابقة التحصيل مع كشف البنك — لا يفتح بطاقة

الحقول الوحيدة التي تحمل كلمة «بطاقة» في المنظومة هي رقم كارنيه العضوية، ورقم البطاقة الضريبية للموظف — وكلاهما ليس وسيلة دفع.

الصلاحيات

كل موظف يرى ما يخص عمله، لا أكثر

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

  1. الصلاحية ملتصقة بالمسار نفسهكل مسار من 1864 مسارًا يحمل اسم الصلاحية المطلوبة في تعريفه، ويُفحص في الوسيط قبل أن يصل الطلب إلى الكود. لا يمكن لشاشة أن «تنسى» الفحص.
  2. الرقم القومي مقنَّع افتراضيًاكان يظهر كاملًا لكل من يفتح صفحة العضو. الآن يظهر بآخر ثلاثة أرقام فقط، ولا يُكشف كاملًا إلا لمن يملك صلاحية «عرض الرقم القومي كاملًا» — وهي ممنوحة لمن يعمل على الهوية فعلًا: مكتب العضوية والموارد البشرية.
  3. الملفات الحسّاسة لا تُفتح برابطمستندات الموارد البشرية والتقارير الطبية وعقود النشاط وصور إثبات المخالفات كلها خارج المجلد العام للموقع، وتُقدَّم عبر شاشة تفحص الصلاحية أولًا.
  4. الجلسة تُلغى من الخادمإنهاء جلسة موظف من شاشة الإدارة يُخرج جهازه فورًا، لأن كل طلب يتحقق من أن الجلسة ما زالت مفتوحة — ولا يكتفي بالكوكي.

اختبار حيّ أثناء إعداد هذا التقرير: سجّلنا الدخول بحساب موظف عضويات وفتحنا شاشة الإيصالات، فردّت المنظومة 403 — غير مصرَّح. وهذا ما نعنيه: المنع سلوك فعلي، لا بند في سياسة.

التشفير

كلمات المرور، والمفاتيح، والنسخ الاحتياطي

ما الذي يحدث فعليًا لكلمة مرور الموظف، ولتوكن التطبيق، وللنسخة الاحتياطية؟ هذه إجابات محددة، لا عناوين عامة.

ماذاكيفماذا يعني عمليًا
كلمات مرور الموظفين والأعضاءbcrypt (كلفة 12)لا تُخزَّن ولا تُشفَّر — تُحوَّل لبصمة لا رجعة فيها. حتى نحن لا نستطيع قراءتها.
توكنات التطبيقات والـAPISHA-256يُخزَّن أثر التوكن فقط. تسريب الجدول لا يعطي توكنًا صالحًا.
سرّ التحقق بخطوتينAES-256-GCMمشفَّر بمفتاح ساكن خارج قاعدة البيانات في ملف بصلاحية 600.
النسخ الاحتياطيAES-256-GCM + ضغطيومي. نسخة مسروقة بلا المفتاح لا تُقرأ، وأي بايت يتغيّر فيها يُرفض عند الاستعادة.
الاتصال بالمتصفحTLS + HSTS سنة كاملةمع سياسة محتوى صارمة ومنع التأطير وكوكي الجلسة مقفول عن الجافاسكربت.
قاعدة البياناتغير منشورة على الإنترنتلا تملك منفذًا عامًا — تُرى من داخل الشبكة الداخلية فقط.

النسخ الاحتياطي كان الفجوة الأخطر. حين راجعنا المنظومة لم يكن فيها أي آلية نسخ احتياطي: لا مهمة مجدولة ولا سكربت ولا أمر — رغم وجود صلاحية باسم «النسخ الاحتياطي» بلا تنفيذ وراءها. بنينا النظام كاملًا قبل كتابة هذا السطر: نسخة يومية تُؤخذ بمعاملة واحدة متسقة، تُضغط، ثم تُشفَّر بمفتاح مشتق من مفتاح التطبيق المحفوظ خارج القاعدة. واختبرناه في الاتجاهين: النسخة تُستعاد مطابقة للأصل بالبايت، وقلب بِت واحد فيها يجعل الاستعادة ترفضها بدلًا من أن تُخرج بيانات تالفة بصمت.

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

لماذا موقع المفتاح مهم: المفتاح لا يُحفظ في قاعدة البيانات ولا داخل النسخة الاحتياطية. من يحصل على نسخة من البيانات وحدها لا يحصل على ما يفكّها.

سجل المراجعة

كل تعديل مسجَّل، وموقَّع، ويُكشف العبث به

السجل الذي يمكن تعديله لا قيمة له. سجل المنظومة مربوط بسلسلة توقيع، فأي حذف أو تبديل يظهر فورًا عند التحقق.

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

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

التحقق متاح كأمر يُشغَّل في أي وقت: php cli.php audit:verify — يطبع عدد السطور الموقَّعة، ويؤكد سلامة السلسلة أو يحدد أول موضع عبث.

الذكاء الاصطناعي

مساعد ذكي على بيانات حسّاسة — تحت حراسة

في المنظومة مساعد ذكي يجيب المديرين عن أسئلة بالعربية. وهذا بالضبط النوع الذي يجب أن يُسأل عنه بصرامة: ماذا يرى، وماذا يخرج منه؟

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

أضفنا في هذه المراجعة منع دوال معلومات الخادم (نسخة قاعدة البيانات، اسم المستخدم، مسار الملفات) حتى لا تتسرب تفاصيل البنية التحتية في إجابة.

الاختبارات

الأرقام، ومن أين جاءت

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

الاختبارالحجمالنتيجةماذا يغطي
فحص أمني خارجي (بدون تسجيل دخول)33 فحصًا33 / 33الترويسات، والتشفير، ومنع الوصول للملفات، وتسريب الأخطاء، ومحاولات حقن.
فحص أمني بجلسة موظف مسجَّل6 فحوص6 / 6سلامة الجلسة، وحقن SQL، وXSS منعكس، وفرض رمز الحماية، وتسريب المعلومات.
اختبارات وحدة أمنية47 اختبارًا47 / 47ترميز المخرجات، ومنع التحويل الخارجي، وتقنيع الرقم القومي، واقتباس المعرّفات.
اختبارات التوجيه13 حالة13 / 13تتأكد أن تسريع المطابقة لم يغيّر أي قاعدة توجيه.
اختبارات تشفير النسخ الاحتياطي8 اختبارات8 / 8الاسترجاع المطابق، ورفض الملف المعدَّل، ورفض المفتاح المختلف.
نسخة احتياطية حقيقية من البداية للنهاية442 جدولًااستُعيدت كاملة — والعبث رُفضأخذ نسخة من القاعدة الفعلية، وتشفيرها، واستعادتها، ورفض ملف معدَّل ببايت واحد.
اختبار الضغط5 مراحل6,598 طلبًا — صفر أخطاءبمستخدمين مسجَّلي الدخول، كلٌّ بحسابه، على شاشات عمل حقيقية.

إعادة التشغيل: سكربتات الاختبار محفوظة في مجلد tests/ داخل المنظومة، والنتائج الخام بصيغة JSON محفوظة في docs/security-report/evidence/. اختبار الضغط يتوقف تلقائيًا إذا ارتفعت الأخطاء، حتى لا يؤذي خادمًا مشتركًا.

الصراحة

ما لم نكتفِ به بعد

تقرير أمني بلا قائمة كهذه تقرير ناقص. هذه هي الخطوات التالية التي نوصي بها، ولا يمنع أيٌّ منها التشغيل اليوم.

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

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