اختبار التحكم في الوصول
اختبار التحكم في الوصول (Access Control Testing) يتحقق من أن قرار التفويض الذي تعرّفت إليه في درس المصادقة والتفويض مُطبَّق فعلاً في كل طلب: فالخادم يسمح بما تسمح به سياسة الوصول بالضبط، لكل دور وإجراء وسجل، ويرفض ما عداه. وهو اختبار سلبي بطبيعته: تطلب عمداً ما لا يحق للمستخدم الحالي الحصول عليه. ففي تطبيق فواتير، يعيد حساب «المشاهد» إرسال طلب «إرسال الفاتورة» الخاص بالمحاسب بعد نسخه من أدوات المطوّر، ويتوقع 403 مع بقاء الفاتورة دون تغيير.
يتعطّل التحكم في الوصول بثلاث طرق: رأسياً (Vertical) حين ينفّذ دور أدنى وظيفة دور أعلى؛ وأفقياً (Horizontal) حين يصل مستخدم إلى سجل مستخدم آخر في المستوى نفسه، ويُسمّى ذلك مرجعاً مباشراً غير آمن للكائن (IDOR) حين يُعنوَن السجل بمعرّف يستطيع المستدعي تغييره؛ وعلى مستوى الوظيفة (Function-level) حين لا تكون الوظيفة محمية أصلاً. ومصفوفة الأدوار × الإجراءات تحوّل السياسة إلى شروط اختبار تغطي الأنواع الثلاثة.
لماذا يهم
يضع OWASP Top 10:2025 «التحكم في الوصول المعطّل» (Broken Access Control) في المرتبة الأولى (A01)، ويبدأ OWASP API Security Top 10 (2023) بالتفويض المعطّل على مستوى الكائن (API1) ويدرج أيضاً التفويض المعطّل على مستوى الوظيفة (API5). فالمستخدمون الحقيقيون يتبعون الشاشات المصممة لدورهم، لذا لا يرسل الاختبار الذي يتبع تلك الشاشات أبداً الطلبات التي تكشف هذه العيوب، ومعرّف واحد مغيَّر قد يكشف بيانات كل الزبائن.
وبالنسبة إلى المختبِر، هذه الاختبارات زهيدة الكلفة وعالية القيمة: حسابا اختبار وأداة لإرسال الطلبات، ونتائج متوقعة تحددها السياسة فتسهل أتمتتها، ونتائج كثيراً ما تُصنَّف خطورتها حرجة (Critical) أو رئيسية (Major) لأنها تكشف بيانات أو إجراءات تعود لشخص آخر.
الإخفاقات الرأسية والأفقية وعلى مستوى الوظيفة
يجيب التفويض عن سؤال واحد في كل طلب: هل يحق لهذه الهوية تنفيذ هذا الإجراء على هذا المورد؟ وللفحص مستويان: فحص على مستوى الوظيفة يسأل هل يحق لهذا الدور استدعاء هذه الوظيفة أصلاً (دعوة مستخدم، تصدير كل الفواتير)، وفحص على مستوى الكائن يسأل هل يحق لهذا المستخدم التصرف في هذا السجل بعينه (الفاتورة 3107 لا 3108). ويُسمّى إخفاقان منها بحسب الاتجاه الذي يكسب فيه المستدعي الوصول، والثالث بحسب الفحص المفقود.
- تصعيد الامتيازات الرأسي: دور أدنى يستخدم وظيفة دور أعلى، مثلاً «مشاهد» يرسل طلب المالك
POST /api/users. الفحص مفقود أو يثق بالعميل، كدور يُنقل في كوكي أو في جسم الطلب. المتوقع:403ولا يحدث شيء. - تصعيد الامتيازات الأفقي: الدور نفسه وسجل شخص آخر. محاسب في الشركة A يغيّر رقماً واحداً ويطلب
GET /api/invoices/3108، وهي فاتورة للشركة B. تسمّي OWASP ذلك مرجعاً مباشراً غير آمن للكائن (IDOR)، ويسمّي OWASP API Security Top 10 العيب نفسه تفويضاً معطّلاً على مستوى الكائن (BOLA). المتوقع:403، أو404حين يخفي العقد سجلات الزبائن الآخرين. - غياب التحكم في الوصول على مستوى الوظيفة: وظيفة لا يحميها سوى الخفاء. الرابط غير معروض، أو نقطة النهاية غير موثّقة، أو
/api/v1/exportالقديم ما زال يجيب، أو الفحص يغطيGETدونDELETEعلى العنوان نفسه. المتوقع:401أو403كما تقول السياسة؛ وأي نجاح عيب. وغياب الفحص على مستوى الوظيفة هو أيضاً السبب المعتاد للتصعيد الرأسي، لكن الاسم المستقل يُبقي انتباهك على الوظائف التي لا تعرضها أي شاشة ولا تذكرها أي قائمة. - وهناك مستوى أدق: مستخدم يحق له تحديث سجل فيغيّر حقلاً ليس له، مثل
"role": "owner"في تحديث الملف الشخصي، وهو ما يسمّيه OWASP API Security Top 10 التفويض المعطّل على مستوى خصائص الكائن (API3:2023). أبقِه في قائمتك، ويتوسع فيه درس اختبار أمان الواجهات البرمجية.
من سياسة الوصول إلى مصفوفة الأدوار × الإجراءات
أساس الاختبار هو سياسة الوصول. وقليل من الفِرق تكتبها، فاجمعها من المتطلبات ووصف الأدوار وقوائم كل دور وعقد الواجهة البرمجية، ودع مالك المنتج يؤكدها: فكل خلية لا تستطيع ملأها سؤال. الصفوف هي الأدوار، ومعها «مجهول الهوية» ومستخدم بالدور نفسه في فريق أو شركة أخرى للحالة الأفقية. والأعمدة هي كل إجراء يقدّمه المنتج، مأخوذاً من كل مصدر لا من شاشات دور واحد: القوائم، وعقد الواجهة البرمجية، والتصدير، وصفحات الإدارة، والطلبات التي ترسلها جلسة الدور الأعلى.
املأ كل خلية بالنتيجة المتوقعة قبل أن ترسل أي شيء: رمز النجاح والأثر الظاهر للخلية المسموحة، والرمز و«لا أثر جانبي» للخلية المرفوضة. كل خلية شرط اختبار: فالخلية المرفوضة التي يعود إجراؤها لدور أعلى اختبار رأسي؛ والخلية المسموحة التي تسمّي سجلاً تُكرَّر بسجل مستخدم آخر بوصفها الاختبار الأفقي؛ وكل عمود يُطلب مباشرةً في كل صف بوصفه اختبار مستوى الوظيفة. وتطلب ورقة OWASP الإرشادية للتفويض (Authorization Cheat Sheet) من الفِرق كتابة اختبارات وحدة وتكامل لمنطق التفويض؛ والمصفوفة هي المصدر المشترك لتلك الاختبارات ولاختباراتك.
مثال تطبيقي: تطبيق فواتير بثلاثة أدوار
خدمة فواتير على https://invoices.test، في بيئة اختبار لديك إذن كتابي باختبارها، تخدم شركات كثيرة. السياسة: «ينتمي المستخدم إلى شركة واحدة ولا يرى إلا بياناتها؛ وأي طلب يخص فاتورة شركة أخرى يعيد 404. المشاهدون يقرؤون الفواتير. والمحاسبون ينشئون الفواتير ويرسلونها أيضاً. والمالكون يصدّرون كل الفواتير ويدعون المستخدمين أيضاً. وبلا جلسة صالحة تعيد الواجهة 401». حسابات الاختبار: مها (مشاهدة) ويوسف (محاسب) ورنا (مالكة) في الشركة A التي تملك الفاتورة 3107، وطارق (محاسب) في الشركة B.
سجّل الدخول بحساب رنا، ونفّذ كل إجراء من الإجراءات الخمسة مرة واحدة، وانسخ كل طلب يرسله الإجراء من لوحة الشبكة بصيغة cURL؛ ففتح الفاتورة 3107 مثلاً يحمّل أيضاً معاينتها بصيغة PDF من GET /api/invoices/3107/pdf. ثم أعد إرسال كل طلب في أداة طلبات بكوكي جلسة مها ثم يوسف ثم طارق على التوالي، ومرة أخيرة بلا كوكي، دون تغيير أي شيء آخر. وإن حمل الطلب أيضاً رمزاً مرتبطاً بجلسة رنا، كرمز مكافحة CSRF، فبدّله كذلك، وإلا فقد يأتي الرفض من فحص ذلك الرمز لا من التفويض. كشفت الجولة عيبين.
| المستدعي | A1 · عرض الفاتورة 3107GET /api/invoices/3107 | A2 · إنشاء فاتورةPOST /api/invoices | A3 · إرسال الفاتورة 3107POST /api/invoices/3107/send | A4 · تصدير كل الفواتيرGET /api/export/invoices.csv | A5 · دعوة مستخدمPOST /api/users |
|---|---|---|---|---|---|
| مجهول الهويةبلا جلسة | 401المصادقة | 401المصادقة | 401المصادقة | 401المصادقة | 401المصادقة |
| مها · مشاهدةالشركة A | 200مسموح | 403رأسي | 403رأسي | 403رأسي | 403رأسي |
| يوسف · محاسبالشركة A | 200مسموح | 201مسموح | 200مسموح | 403رأسي | 403رأسي |
| رنا · مالكةالشركة A | 200مسموح | 201مسموح | 200مسموح | 200مسموح | 201مسموح |
| طارق · محاسبالشركة B، على فاتورة الشركة A | 404أفقي (IDOR) | لا سجل للشركة A في هذا الإجراء | 404أفقي (IDOR) | 403رأسي | 403رأسي |
- مسموح وفق السياسة، مع رمز النجاح المتوقع
- اختبار رأسي:
403لوظيفة أعلى من دور المستدعي - اختبار أفقي (IDOR):
404لفاتورة شركة أخرى يخفيها العقد - المصادقة:
401بلا جلسة صالحة
نتائج متوقعة مكتوبة من السياسة قبل إرسال أي طلب: المشاهدون يقرؤون الفواتير؛ والمحاسبون ينشئونها ويرسلونها أيضاً؛ والمالكون يصدّرون كل الفواتير ويدعون المستخدمين أيضاً؛ وفاتورة شركة أخرى تعيد 404.
- إعادة مها إرسال
POST /api/invoices/3107/sendأعادت200ووصلت الفاتورة إلى الزبون: تصعيد رأسي؛ فالفحص كان موجوداً في القائمة فقط. الخطورة: حرج (Critical). - طلب طارق
GET /api/invoices/3107أعاد404كما يجب، لكن طلب المعاينةGET /api/invoices/3107/pdfأعاد ملف PDF: تصعيد أفقي عبر مسار ثانٍ إلى السجل نفسه. الخطورة: حرج. - طابقت كل الخلايا الأخرى المصفوفة. أكّد كل إصلاح بإعادة تشغيل العمود كاملاً، لا الخلية التي فشلت وحدها.
النسخة النصية
Expected result per cell, written from the policy before any request is sent
Caller A1 view 3107 A2 create A3 send 3107 A4 export A5 invite
Anonymous 401 401 401 401 401
Maha, viewer A 200 403 403 403 403
Yousef, accountant A 200 201 200 403 403
Rana, owner A 200 201 200 200 201
Tariq, accountant B 404 - 404 403 403
401 = authentication (no session) 403 = vertical: a function above the role
404 = horizontal: Company B's user on Company A's invoice (the contract hides it)جرّبها: محلّل أوامر cURL جرّبها: مختبِر مصادقة API جرّبها: مقارنة استجابات API
أخطاء شائعة
- اختبار كل دور عبر شاشاته فقط، وعدم إرسال الطلبات التي لا تقدّمها الشاشات.
- تنفيذ معظم الاختبارات بحساب مالك أو مسؤول ينجح في كل فحص فلا يختبر شيئاً.
- اختبار المسار الرئيسي للسجل وتجاوز مسارات PDF والتصدير والبحث والمشاركة.
- قبول أي رفض: إعادة توجيه إلى صفحة الدخول ما زال جسمها يحمل البيانات، أو
403حدث الإجراء بعده على أي حال. اقرأ الجسم وتحقق من البيانات بعده. - اعتبار الروابط المخفية أو أسماء الملفات العشوائية أو UUID تحكماً في الوصول.
- اختبار بيئة الإنتاج أو نظام لا تملك إذناً كتابياً باختباره، أو لصق الكوكيز والرموز الحية في تقارير الأخطاء بدل إخفائها.
من منظور ضمان الجودة
اطلب سياسة الوصول أثناء التنقيح (Refinement)، حين تكون للميزة أكثر من دور أو أكثر من مالك: أي الأدوار موجودة، ومن يملك كل نوع من السجلات، وما الذي يحق لكل دور، وأي رمز يعيده الرفض، بما في ذلك سجل شركة أخرى. اكتب المصفوفة بوصفها أساس الاختبار، ودع مالك المنتج يؤكد كل خلية، واطلب حسابات اختبار لكل دور ومستخدماً إضافياً بالدور نفسه في فريق أو شركة أخرى.
سجّل كل جولة بوصفها المصفوفة مع النتيجة المتوقعة والفعلية لكل خلية؛ وفي تقرير الخطأ اذكر الخلية والهويتين وبيانات الاعتماد المخفاة والطلب والاستجابة والأثر الجانبي. ولأن السياسة تحدد النتائج المتوقعة، حوّل المصفوفة إلى اختبارات واجهة برمجية تعمل في كل إصدار. ودع الاستغلال لمتخصصي الأمان، ولا تختبر شيئاً خارج بيئة الاختبار دون إذن كتابي يحدد النطاق.
تمرين عملي
ابنِ مصفوفة الوصول لمنصة دورات تعليمية
منصة دورات لها ثلاثة أدوار. المتعلمون لا يرون إلا تسليماتهم وشهاداتهم. والمدرّسون يرون قائمة متعلمي الدورات التي يدرّسونها، ويرون تسليماتها ويقيّمونها، ويرون شهاداتها. والمسؤولون يفعلون كل شيء وهم وحدهم من يُجري استرداد المدفوعات. تعيد الواجهة 401 بلا جلسة صالحة، و403 لوظيفة لا يحق للدور استخدامها، و404 لسجل يعود لمتعلم آخر أو دورة أخرى. ولديك إذن كتابي باختبار بيئة الاختبار.
ابنِ مصفوفة المستدعين مقابل الإجراءات الخمسة في المادة، وتوقّع رمز كل خلية، وصنّف كل خلية مرفوضة: مصادقة أو رأسي أو أفقي. ثم أضف ثلاثة اختبارات من قسم الوظائف المخفية.
Setup: submission 4410 = learner Lina, course QA-101 (instructor Hani)
certificate 7702 = learner Omar, course DB-201 (instructor Dana)
Lina and Omar are learners; Hani and Dana are instructors; Sami is an admin
# Action Request
A1 view submission 4410 GET /api/submissions/4410
A2 grade submission 4410 POST /api/submissions/4410/grade
A3 download certificate 7702 GET /api/certificates/7702
A4 list learners of QA-101 GET /api/courses/QA-101/learners
A5 refund a payment POST /api/payments/88/refund- اكتب المستدعين: مجهول الهوية، وكل دور، ومستخدماً ثانياً بالدور نفسه للحالة الأفقية.
- اكتب الإجراءات من كل مصدر، بما فيها ما لا يراه المتعلم أبداً.
- املأ كل خلية من السياسة قبل أن تنظر إلى النظام.
- صنّف كل خلية مرفوضة: مصادقة (
401) أو رأسي (403) أو أفقي (404). - أضف اختبارات للمسارات والطرق الأخرى والقيم التي يرسلها العميل.
إظهار الإجابة النموذجية
مجهول الهوية: 401 في كل عمود (مصادقة). سامي، المسؤول: مسموح في كل عمود، 200 للقراءات و200 أو 201 للتقييم والاسترداد كما يحدد العقد.
لينا، متعلمة وصاحبة التسليم 4410: A1 200؛ A2 403 (رأسي: المتعلمون لا يقيّمون أبداً)؛ A3 404 (أفقي: شهادة عمر)؛ A4 403 وA5 403 (رأسي).
عمر، متعلم: A1 404 (أفقي، خلية IDOR الكلاسيكية)؛ A2 403 (رأسي)؛ A3 200؛ A4 403 وA5 403 (رأسي).
هاني، مدرّس QA-101: A1 200؛ A2 مسموح (200 أو 201 كما يحدد العقد) ثم تأكد من تخزين التقييم؛ A3 404 (أفقي: شهادة من دورة دانا)؛ A4 200؛ A5 403 (رأسي: الاسترداد للمسؤولين فقط).
دانا، مدرّسة DB-201: A1 وA2 404 (أفقي: تسليم من دورة أخرى، مع بقاء التقييم دون تغيير)؛ A3 200؛ A4 404 (أفقي: دورة مدرّس آخر)؛ A5 403 (رأسي).
اختبارات الوظائف المخفية، مثلاً: لينا تطلب شهادة عمر بصيغة ملف GET /api/certificates/7702/pdf وتتوقع 404 ولا ملف؛ ولينا ترسل DELETE /api/submissions/4410 وتتوقع 403 أو 405 كما يحدد العقد ولا تغيير؛ ودانا تقيّم 4410 مع "courseId": "DB-201" في الجسم وتتوقع 404 مع بقاء التقييم دون تغيير.
أسئلة شائعة
هل IDOR هو نفسه تصعيد الامتيازات الأفقي؟
IDOR هو الصورة المعتادة للتصعيد الأفقي: سجل يُعنوَن بمعرّف يستطيع المستدعي تغييره، والخادم لا يفحص الملكية. ويحدث التصعيد الأفقي أيضاً عبر مرشّحات البحث والتصدير وروابط المشاركة التي تعيد سجلات مستخدمين آخرين دون تعديل أي معرّف. ويجمع OWASP API Security Top 10 هذه كلها تحت التفويض المعطّل على مستوى الكائن (BOLA).
كم حساب اختبار أحتاج؟
حساباً واحداً على الأقل لكل دور، ومستخدماً إضافياً بالدور نفسه في فريق أو شركة أخرى للصف الأفقي، وكلها في بيئة اختبار وليست حسابات مستخدمين حقيقيين أبداً. وفي المنتجات متعددة المستأجرين (Multi-tenant)، حيث يخدم نظام واحد شركات كثيرة، تحتاج إلى شركتين لكل منهما سجلاتها، كي يكون لكل إجراء مرتبط بسجل سجلٌ يعود لشخص آخر.
هل تجعل معرّفات UUID العشوائية اختبارات IDOR غير ضرورية؟
لا. يصعب تخمين UUID، لكن المعرّفات تتسرب عبر التصدير والبريد والسجلات وصفحات المستخدمين الآخرين، وعلى الخادم رفض الطلب أياً كان من يقدّمه. انسخ معرّفاً حقيقياً من حساب الاختبار الآخر وتوقّع الرفض نفسه الذي يناله معرّف تسلسلي.
المراجع
- OWASP Web Security Testing Guide (WSTG)المنهجية المرجعية لاختبار تطبيقات الويب وواجهات API بحثاً عن نقاط الضعف الأمنية، اختباراً تلو الآخر.
- OWASP Top 10:2025أخطر عشرة مخاطر أمنية لتطبيقات الويب، مع كيفية اختبار كل منها والوقاية منه.
- OWASP Cheat Sheet Series: Authorizationضبط الوصول بالشكل الصحيح: أقل الصلاحيات، والرفض افتراضياً، والتحقق من الصلاحيات في كل طلب، وتفضيل النماذج المبنية على السمات أو العلاقات، واختبار منطق التفويض.
- OWASP API Security Top 10 (2023)أكثر عشر نقاط ضعف شيوعاً في واجهات API: خلل التفويض على مستوى الكائن، وخلل التوثيق، والاستهلاك غير المقيد للموارد، وغيرها.
تدرّب بأدوات متقن
أنشئ طلبات HTTP وأرسلها (الطريقة وعنوان URL والترويسات والمصادقة والجسم) وافحص الاستجابة — بديل خفيف لـ Postman داخل متصفحك.
اختبر مصادقة Bearer وBasic ومفتاح API والترويسات المخصّصة على نقطة نهاية وقارن الاستجابات المصرّح بها بغير المصرّح بها.
اختبر نقاط نهاية REST بتحكم كامل في الطريقة والترويسات وجسم JSON، ثم أضف تأكيدات على الحالة والترويسات ومسارات JSON.
قارن استجابتي API (مثل بيئة التجريب مقابل الإنتاج) واحصل على قائمة بكل فرق بنيوي أو في القيم.
ولّد مصفوفة حالات اختبار منظّمة (إيجابية وسلبية ومصادقة وقيم حدّية) من مواصفة OpenAPI / Swagger.
تحليل أمر cURL إلى الطريقة وعنوان URL والترويسات والمتن، ثم تحويله إلى fetch أو axios أو Python أو طلب منظّم.
للتعمّق أكثر
تقدّمك في هذا الموضوع
سجّل الدخول لتتابع تقدّمك
علّم الموضوعات مكتملة، وتابع من حيث توقفت، وافتح امتحانات التخصص.