> ## Content Index
> Fetch the complete content index at: https://arabroot.io/llms.txt
> Use this file to discover other available public pages before exploring further.

# المصادقة Authentication والتفويض Authorization: ما الفرق؟
- URL: https://arabroot.io/articles/المصادقة-والتفويض-authentication-authorization-الفرق/
- Published: 2026-10-28T15:03:48.000Z
- Updated: 2026-10-28T16:04:30.000Z
- Description: من أنت؟ سؤال المصادقة. وماذا يحق لك؟ سؤال التفويض. والخلط بينهما هو أكثر ثغرات الويب شيوعاً، نراه ونصلحه بالتجربة.
- Author: فريق عرب رووت
- Tags: الأدلة التقنية, الأمن السيبراني, أساسيات

كل مرة تقرأ عن الهوية والوصول، تمر عليك كلمتان متشابهتان: المصادقة Authentication والتفويض Authorization، وكثيراً ما تختصران بالحرفين AuthN وAuthZ حتى يصعب التمييز بينهما، فهما يبدآن بالحروف نفسها وينتهيان بها، ويحدثان في اللحظة نفسها تقريباً. وقد تظن أنهما وجهان لشيء واحد: «تسجيل الدخول». لكنهما في الحقيقة سؤالان مختلفان تماماً، والخلط بينهما ليس خطأ لغوياً، بل سبب أكثر ثغرات الويب شيوعاً. فحين تتصدر «التحكم في الوصول المعطل Broken Access Control» قائمة OWASP لأخطر مخاطر تطبيقات الويب، فإن جذر المشكلة في معظم الحالات هو هذا الخلط بالذات: نظام يتحقق جيداً من هويتك، ثم ينسى أن يتحقق مما يحق لك.

وهذا المقال يفصل بين المفهومين فصلاً واضحاً: المصادقة تجيب «من أنت؟»، والتفويض يجيب «ماذا يحق لك؟»، وبينهما فرق يبنى عليه كل نظام هوية. ونبني في المختبر خدمة صغيرة نرى فيها كيف يفصل الكود بين السؤالين، ثم نرى أشهر ثغرة تنشأ من دمجهما، ونصلحها بسطر واحد. وهذا المقال أول مقال في [مرحلة الهوية والدخول الموحد](https://arabroot.io/start/#stage-identity)، وهو الأساس الذي تبنى عليه بقية المرحلة. وسوف نناقش ما يلي:

- الفرق الجوهري: بابان متتابعان لا باب واحد، بتعريفات NIST الرسمية.
- كيف تعمل المصادقة: من كلمة المرور إلى الرموز الموقعة، ولماذا تثبت الهوية مرة وتحمل إثباتها بعدها.
- كيف يعمل التفويض: نماذج التحكم في الوصول DAC وMAC وRBAC وABAC، ومبدأ أقل صلاحية.
- تجربة عملية: خدمة تفصل المصادقة عن التفويض، ونرى ثغرة BOLA/IDOR ونصلحها.
- تجربة ثانية: تصعيد الصلاحيات حين يثق الخادم ببيانات يرسلها العميل عن نفسه.
- أخطاء شائعة، والجانب السعودي، وإلى أين بعد هذا المقال.

## الفرق الجوهري: بابان لا باب واحد

تخيل مبنى شركة فيه بابان متتابعان. الأول عند المدخل يتحقق من بطاقتك: هل أنت موظف فعلاً؟ والثاني عند غرفة الخزنة يتحقق من صلاحيتك: موظف نعم، لكن هل يحق لك أنت دخول الخزنة؟ فمن اجتاز الباب الأول (أثبت أنه موظف) لا يعني أنه يجتاز الثاني (يحق له كل شيء). والصورة التالية تبين هذا التتابع:

![مستخدم يصل فيمر بباب أول هو المصادقة Authentication بقفل أزرق يسأل من أنت، ثم باب ثان هو التفويض Authorization بدرع أخضر يسأل ماذا يحق لك، ثم يصل إلى المورد، مع تنبيه أن الخطأ الأشهر فحص الباب الأول ونسيان الثاني](https://arabroot.io/content/images/2026/10/authn-vs-authz-01-two-doors.webp)

بابان متتابعان: المصادقة تثبت الهوية، والتفويض يقرر الصلاحية

والتعريفان الرسميان يوضحان الفرق بدقة. فالمصادقة في [معجم NIST](https://csrc.nist.gov/glossary/term/authentication?ref=arabroot.io) هي التحقق من هوية مستخدم أو عملية أو جهاز، غالباً كشرط مسبق للسماح بالوصول إلى موارد النظام. والتفويض في [معجم NIST](https://csrc.nist.gov/glossary/term/authorization?ref=arabroot.io) هو صلاحيات الوصول الممنوحة لمستخدم أو برنامج أو عملية، أو فعل منح تلك الصلاحيات. ولاحظ الفرق: المصادقة تتحقق من الهوية، والتفويض يقرر الصلاحية، وبينهما شيء ثالث يجمعهما هو التحكم في الوصول Access Control، وهو في [معجم NIST](https://csrc.nist.gov/glossary/term/access%5Fcontrol?ref=arabroot.io) عملية منح أو رفض طلبات محددة للوصول إلى المعلومات والخدمات.

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

ولماذا يخلط الناس بينهما رغم وضوح الفرق؟ لأن تجربة المستخدم تدمجهما في لحظة واحدة: تكتب كلمة المرور فتدخل، فتظن أن «الدخول» شيء واحد. لكن ما حدث شيئان: النظام تحقق من هويتك (مصادقة)، ثم عرض لك ما يحق لك فقط (تفويض). والدمج في الواجهة يخفي أنهما طبقتان في الكود، والمبرمج الذي يرى الدخول شيئاً واحداً قد يكتب كوداً يتحقق من الهوية وينسى الصلاحية، فينشأ الخطأ من الخلط ذاته. ولهذا فإن تفكيك اللحظة الواحدة إلى بابين هو أول خطوة لكتابة نظام آمن.

ولتثبت الفرق في ذهنك، تذكر هذه المقابلات: المصادقة عن الهوية، والتفويض عن الصلاحية. المصادقة تحدث مرة عند الدخول، والتفويض يحدث عند كل طلب. المصادقة تجيب بنعم أو لا (أنت أو لست)، والتفويض يجيب بما يحق وما لا يحق لكل مورد. ومن فهم هذا التتابع فهم لماذا لا يكفي «تسجيل الدخول» وحده، ولماذا يجب أن يسأل النظام عند كل فعل: هل يحق لصاحب هذا الطلب أن يفعله؟

وكم هي شائعة هذه المشكلة؟ في [قائمة OWASP لأخطر عشر مخاطر لتطبيقات الويب لعام 2021](https://top10.owasp.org/A01%5F2021-Broken%5FAccess%5FControl?ref=arabroot.io)، تصدرت فئة «التحكم في الوصول المعطل Broken Access Control» القائمة في المرتبة الأولى A01، صاعدة من المرتبة الخامسة في النسخة السابقة. وذكرت المنظمة أن شكلاً من أشكال هذا الخلل ظهر في 94% من التطبيقات التي اختبرت. وهذا الرقم يقول شيئاً مهماً: المشكلة ليست استثناء نادراً، بل القاعدة الغالبة، وسببها في معظم الحالات ليس جهلاً بالتشفير أو نقصاً في أدوات، وإنما هذا الخلط البسيط بين «من أنت؟» و«ماذا يحق لك؟». ولذلك فإتقان الفرق بينهما ليس ترفاً نظرياً، بل أهم ما يحمي تطبيقك من أكثر الثغرات انتشاراً.

## كيف تعمل المصادقة؟

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

الإجابة أن الموقع يعطيك بعد المصادقة الناجحة إثباتاً تحمله معك في كل طلب لاحق: رمزاً Token أو معرف جلسة Session ID. وهذا الإثبات موقع من الخادم بحيث لا تستطيع تزويره: لو حاولت تغيير اسمك فيه، يكتشف الخادم أن التوقيع لم يعد صحيحاً فيرفضه. وبهذا تثبت هويتك مرة، ثم تحمل إثباتها في كل طلب، والخادم يتحقق من الإثبات لا من كلمة المرور في كل مرة. وتفاصيل هذا الإثبات (الجلسات وملفات تعريف الارتباط وJWT) موضوع مقال مستقل في هذه المرحلة، لكن ما يعنينا أن المصادقة تنتهي بإثبات محمول، والتفويض يبدأ من هذا الإثبات: من أنت؟ يجيب الإثبات، ثم ماذا يحق لك؟ يقرره التفويض. وسوف نبني هذا الإثبات الموقع بأنفسنا في المختبر لنرى كيف يفصل بين السؤالين.

ونقطة مهمة في محتوى الإثبات: ماذا يجب أن يحمل؟ الجواب هو الهوية فقط (من أنت)، لا الصلاحيات (ماذا يحق لك). فبعض المطورين يضعون دور المستخدم أو صلاحياته داخل الرمز نفسه، وهذا خطر، لأن الصلاحيات قد تتغير (يرقى الموظف أو تسحب صلاحيته)، والرمز القديم يبقى يحمل الصلاحية القديمة حتى ينتهي. والأخطر أن وضع الصلاحية في الرمز يغري بالوثوق بها دون مراجعة، بينما الصحيح أن يحمل الرمز الهوية، ويرجع الخادم إلى سجله الحي ليعرف صلاحيات هذه الهوية الآن. فالرمز يقول «أنا أمل»، والخادم يقرر ما يحق لأمل اللحظة، لا ما كان يحق لها حين أصدر الرمز. وهذا يربطنا بالتجربة الثانية في المختبر: لا تثق بما يحمله الرمز أو يرسله العميل عن الصلاحيات.

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

والفرق الزمني بين المصادقة والتفويض يوضح كل شيء: المصادقة حدث يقع مرة عند الدخول، والتفويض فحص يتكرر عند كل طلب، كما تبين الصورة التالية:

![في الأعلى المصادقة مرة واحدة: تكتب كلمة المرور فتحصل على إثبات موقع، وفي الأسفل التفويض في كل طلب: اقرأ وثيقة may_read، عدل may_write، احذف is_admin، صدر may_export، كل فعل يسأل عن صلاحيته](https://arabroot.io/content/images/2026/10/authn-vs-authz-04-lifecycle.webp)

المصادقة حدث واحد عند الدخول، والتفويض فحص متكرر عند كل طلب لكل كائن

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

## كيف يعمل التفويض؟

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

![أربع بطاقات لنماذج التحكم في الوصول: DAC تحكم تقديري المالك يقرر، وMAC تحكم إلزامي النظام يفرض، وRBAC بالأدوار حسب دور المستخدم، وABAC بالخصائص قواعد على سمات متعددة](https://arabroot.io/content/images/2026/10/authn-vs-authz-03-models.webp)

نماذج التحكم في الوصول: من الأبسط DAC إلى الأدق ABAC، وأكثرها شيوعاً RBAC

- **التحكم التقديري DAC (Discretionary Access Control):** مالك المورد يقرر من يصل إليه. وأشهر مثال صلاحيات ملفات Linux: مالك الملف يحدد من يقرأ ويكتب. وهو مرن لكنه يعتمد على قرار كل مالك، فيصعب ضبطه مركزياً.
- **التحكم الإلزامي MAC (Mandatory Access Control):** النظام يفرض القواعد، لا المالك. وأشهر مثال التصنيفات العسكرية (سري، سري للغاية): لا يستطيع صاحب وثيقة سرية أن يشاركها مع من لا يحمل التصنيف المناسب، مهما أراد. وهو صارم، يستخدم حيث الحساسية عالية.
- **التحكم بالأدوار RBAC (Role-Based Access Control):** تمنح الصلاحيات للأدوار لا للأفراد، ثم تسند لكل مستخدم دوراً. فبدل أن تعطي كل موظف صلاحياته فرداً، تقول: دور «المحرر» يستطيع التعديل، ودور «المراجع» يستطيع الموافقة، ثم تجعل أمل محررة. وهو في [معجم NIST](https://csrc.nist.gov/glossary/term/role%5Fbased%5Faccess%5Fcontrol?ref=arabroot.io) التحكم المبني على أدوار المستخدمين، وأكثر النماذج شيوعاً في التطبيقات اليوم لأنه يبسط الإدارة: تغير صلاحيات الدور مرة فتنطبق على كل من يحمله.
- **التحكم بالخصائص ABAC (Attribute-Based Access Control):** تبني القواعد على سمات متعددة: من المستخدم (قسمه)، ومن المورد (تصنيفه)، ومن السياق (الوقت، المكان). مثل: «يسمح لموظفي المالية بالوصول خلال ساعات الدوام من داخل الشبكة». وهو الأدق والأكثر مرونة، وتشرحه [وثيقة NIST SP 800-162](https://csrc.nist.gov/pubs/sp/800/162/final?ref=arabroot.io)، لكنه أعقد في التصميم والصيانة.

وهناك نموذج خامس يكثر في الخدمات الحديثة اسمه التحكم بالعلاقات ReBAC (Relationship-Based Access Control): تمنح الصلاحية بناء على علاقة بين المستخدم والمورد، مثل «أنت تملك هذا الملف»، أو «أنت عضو في هذا الفريق الذي يملك المجلد»، أو «شارك معك صاحب الوثيقة». وهو ما طبقناه ضمنياً في المختبر حين قلنا «المالك يقرأ وثيقته»: فهذه علاقة ملكية بين أمل والوثيقة. وأي نموذج تختار؟ للمؤسسات والتطبيقات المعتادة، RBAC هو الخيار العملي: واضح، سهل الإدارة، ويكفي أغلب الحالات. وتضيف ABAC أو ReBAC حين تحتاج قواعد دقيقة تعتمد على السياق أو العلاقات. ومهما اخترت، يحكمه مبدأ واحد فوق الجميع: أقل صلاحية Least Privilege، أي أن يحصل كل مستخدم (ودور) على ما يحتاجه لعمله فقط، لا أكثر. فالموظف الذي يحتاج القراءة لا يعطى الكتابة، والدور الذي يحتاج وحدة واحدة لا يعطى صلاحية على كل شيء. وهذا المبدأ يقلل الضرر إذا سرق حساب أو أخطأ مستخدم، لأن ما يملكه الحساب محدود أصلاً.

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

ويرتبط بأقل صلاحية مبدآن آخران تقابلهما كثيراً: الحاجة إلى المعرفة Need-to-Know، أي ألا يطلع أحد على معلومة لا يحتاجها لعمله مهما كانت رتبته؛ وفصل المهام Segregation of Duties، أي ألا يجمع شخص واحد صلاحيات متعارضة، فمن يطلب الصرف لا ينبغي أن يكون هو من يوافق عليه، لئلا يحتال وحده. وهذه المبادئ كلها تطبيقات للتفويض الدقيق: ليس كل من دخل يرى كل شيء، بل كل حسب حاجته ودوره، مع حواجز تمنع تجميع ما لا ينبغي جمعه.

## تجربة عملية: افصل المصادقة عن التفويض

الكلام عن الفصل بين المصادقة والتفويض يبقى مجرداً حتى تراه في الكود، وتراه يفشل حين يدمج. ولنرى الفرق في الكود لا في الكلام، سوف نبني خدمة صغيرة جداً تفصل بوضوح بين السؤالين: دالة تجيب «من أنت؟» (المصادقة)، ودالة تجيب «هل يحق لك؟» (التفويض). ثم نكتب نقطتي وصول Endpoints: واحدة معطوبة تفحص الهوية فقط، وأخرى سليمة تفحص الاثنين، ونرى الفرق بأعيننا. كل شيء في مختبرنا على كود نكتبه نحن، لا على أي نظام حقيقي.

### الكود

احفظ الملف التالي باسم `access.py`:

```python
import hmac, hashlib, json, base64, time
SERVER_KEY = b"lab-signing-key"   # سر الخادم لتوقيع الرموز، لا يشارك

# البيانات: مستخدمون بأدوارهم، ووثائق يملكها كل منهم
USERS = {"amal": {"role": "user"}, "basim": {"role": "user"}, "root": {"role": "admin"}}
DOCS = {
    1: {"owner": "amal",  "title": "amal salary letter"},
    2: {"owner": "basim", "title": "basim contract"},
    3: {"owner": "root",  "title": "company policy"},
}

# --- المصادقة: إصدار رمز موقع يثبت مَن أنت، والتحقق منه ---
def issue_token(username):
    body = base64.urlsafe_b64encode(json.dumps({"sub": username, "iat": int(time.time())}).encode()).decode()
    sig = hmac.new(SERVER_KEY, body.encode(), hashlib.sha256).hexdigest()[:16]
    return f"{body}.{sig}"

def authenticate(token):
    try:
        body, sig = token.split(".")
        good = hmac.new(SERVER_KEY, body.encode(), hashlib.sha256).hexdigest()[:16]
        if not hmac.compare_digest(sig, good):
            return None                      # توقيع خاطئ: غير موثق
        return json.loads(base64.urlsafe_b64decode(body))["sub"]
    except Exception:
        return None

# --- التفويض: يقرر ماذا يحق للمستخدم الموثق ---
def may_read(user, doc_id):
    doc = DOCS.get(doc_id)
    if not doc: return False
    if USERS[user]["role"] == "admin": return True   # المدير يقرأ الكل
    return doc["owner"] == user                        # المالك يقرأ وثيقته

# --- نقطتا وصول: معطوبة (هوية فقط) وسليمة (هوية + صلاحية) ---
def get_doc_BROKEN(token, doc_id):
    user = authenticate(token)
    if not user: return (401, "not authenticated")
    return (200, DOCS[doc_id]["title"])                # الخطأ: لا يفحص الملكية (BOLA/IDOR)

def get_doc_CORRECT(token, doc_id):
    user = authenticate(token)
    if not user: return (401, "not authenticated")      # المصادقة
    if not may_read(user, doc_id): return (403, "forbidden")  # التفويض
    return (200, DOCS[doc_id]["title"])
```

في الكود أعلاه لاحظ الفصل الواضح: الدالة `authenticate` تجيب «من أنت؟» فقط (تتحقق من التوقيع وتعيد اسم المستخدم)، والدالة `may_read` تجيب «هل يحق لك؟» فقط (تقرر حسب الملكية والدور). والنقطة المعطوبة `get_doc_BROKEN` تستدعي الأولى وتنسى الثانية، والسليمة `get_doc_CORRECT` تستدعي الاثنتين بالترتيب. الفرق بينهما سطر واحد، وهو الفرق بين نظام آمن ونظام يسرب. نضيف إلى الملف اختبارات ونشغله:

```python
amal_tok = issue_token("amal")
print("tampered token authenticates?:", authenticate(amal_tok[:-1] + "0"))
print("amal -> her own doc #1 : BROKEN", get_doc_BROKEN(amal_tok, 1), "CORRECT", get_doc_CORRECT(amal_tok, 1))
print("amal -> basim's doc #2 : BROKEN", get_doc_BROKEN(amal_tok, 2), "CORRECT", get_doc_CORRECT(amal_tok, 2))
print("admin -> any doc #2    : CORRECT", get_doc_CORRECT(issue_token("root"), 2))
print("forged token          : CORRECT", get_doc_CORRECT("forged.token", 1))
```

نشغله في حاوية (وفي Git Bash على Windows أضف `MSYS_NO_PATHCONV=1` واستخدم `"$(pwd -W)"`):

```bash
docker run --rm -v "$PWD":/w python:3.13.17-slim python3 /w/access.py
```

```text
tampered token authenticates?: None
amal -> her own doc #1 : BROKEN (200, 'amal salary letter') CORRECT (200, 'amal salary letter')
amal -> basim's doc #2 : BROKEN (200, 'basim contract') CORRECT (403, 'forbidden')
admin -> any doc #2    : CORRECT (200, 'basim contract')
forged token          : CORRECT (401, 'not authenticated')
```

والصورة التالية تبين المقارنة الحاسمة في السطر الثالث:

![مسار معطوب في الأعلى: أمل الموثقة تطلب وثيقة باسم رقم 2 فيعيدها الخادم 200 OK مسرّباً وثيقة غيرها، ومسار سليم في الأسفل: الطلب نفسه يرفض 403 Forbidden لأن أمل لا تملك الوثيقة 2](https://arabroot.io/content/images/2026/10/authn-vs-authz-02-bola.webp)

ثغرة BOLA: مصادقة سليمة لكن بلا تفويض، فتسرب وثيقة مستخدم آخر

في المخرج والصورة أعلاه لاحظ التالي:

- الرمز المعبوث (غيرنا آخر حرف فيه) رفض في المصادقة وأعاد `None`، لأن توقيعه لم يعد صحيحاً. فالمصادقة صارمة: لا هوية دون توقيع سليم.
- حين طلبت أمل وثيقتها هي (رقم 1)، نجحت النقطتان، لأنها تملكها. فالتفويض لا يمنع الحق، وإنما يمنع تجاوزه.
- حين طلبت أمل وثيقة باسم (رقم 2، ليست لها): النقطة المعطوبة أعادتها لها (`200`) فسربت وثيقة مستخدم آخر، والسليمة رفضت (`403`). وهذا بالضبط هو الفرق بين وجود التفويض وغيابه: أمل موثقة في الحالتين، لكن المعطوبة لم تسأل «هل تملك هذه الوثيقة؟».
- هذه الثغرة لها اسم: الوصول المعطوب على مستوى الكائن BOLA (Broken Object Level Authorization)، وتسمى أيضاً IDOR (مرجع كائن مباشر غير آمن Insecure Direct Object Reference). وهي من أكثر ثغرات الويب شيوعاً، وسببها دائماً هذا: الاعتماد على رقم في الطلب دون التحقق أن صاحب الطلب يملك الكائن الذي يشير إليه الرقم.
- المدير حصل على وثيقة باسم (`200`) في النقطة السليمة، لأن دوره `admin` يسمح بذلك. فالتفويض ليس منعاً دائماً، وإنما قرار حسب القاعدة: المالك أو المدير نعم، وغيرهما لا. وهذا يجمع في دالة `may_read` نموذجين معاً: التحكم بالأدوار RBAC (المدير يرى الكل) والتحكم بالملكية (المالك يرى وثيقته)، وهو مزيج شائع جداً في التطبيقات الحقيقية.

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

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

ولاحظ لماذا تنشأ ثغرة BOLA بالذات من الدمج بين السؤالين. فالمبرمج الذي يرى الدخول شيئاً واحداً يفكر هكذا: «تحققت أن أمل مسجلة الدخول، فأعطيها ما تطلب». لكن ما تطلبه أمل يحدده رقم في الطلب (`/docs/2`)، وهذا الرقم يختاره صاحب الطلب، فتستطيع أمل أن تغيره إلى أي رقم. فالمصادقة أثبتت أنها أمل، لكنها لم تقل شيئاً عن أي وثيقة يحق لأمل أن تراها. والفحص الناقص هو هذا بالذات: التحقق من الهوية (أمل) دون التحقق من العلاقة بين الهوية والكائن (هل تملك أمل الوثيقة 2؟). ولهذا السبب تظهر BOLA كثيراً في الواجهات البرمجية API: لأنها تتعامل مع كائنات مرقمة مباشرة، فيسهل أن ينسى المبرمج ربط كل كائن بمالكه.

### تجربة ثانية: تصعيد الصلاحيات

هناك خطأ تفويض آخر خطير: أن يثق الخادم ببيانات يرسلها العميل عن نفسه. فإذا سأل الخادم العميل «ما دورك؟» وصدق جوابه، أرسل المهاجم `admin` وصار مديراً. ولنرى ذلك، احفظ `privesc.py` (نموذج مبسط على نفس فكرة الرموز السابقة):

```python
def delete_all_users_BROKEN(tok, claimed_role):
    user = who(tok)
    if claimed_role == "admin":            # الخطأ: يثق بدور يرسله العميل، لا بسجل الخادم
        return "DELETED ALL USERS (!!)"
    return "forbidden"

def delete_all_users_CORRECT(tok):
    user = who(tok)
    if user and USERS[user]["role"] == "admin":   # يثق بسجل الخادم عن هذا المستخدم فقط
        return "DELETED ALL USERS (authorized admin)"
    return "forbidden"
```

وعند تشغيله، يرسل المستخدم العادي أمل الحقل `claimed_role="admin"`:

```text
== النقطة المعطوبة تثق بحقل الدور الذي يرسله العميل ==
  amal sends claimed_role='admin': DELETED ALL USERS (!!)  <- تصعيد صلاحيات
== النقطة السليمة تتجاهل ادعاء العميل، وتفحص سجل الخادم ==
  amal (real role=user) tries    : forbidden
  root (real role=admin) tries    : DELETED ALL USERS (authorized admin)
```

والصورة التالية تبين الفكرة:

![مسار معطوب: أمل دورها user ترسل طلباً فيه حقل role=admin فينفذ الخادم الحذف فيحدث تصعيد صلاحيات، ومسار سليم: الخادم يتجاهل الدور المدعى ويرجع إلى سجله فيرى أمل=user فيمنع](https://arabroot.io/content/images/2026/10/authn-vs-authz-05-trust.webp)

مصدر قرار التفويض: سجل الخادم لا ما يدعيه العميل عن نفسه

في المخرج والصورة أعلاه لاحظ التالي:

- النقطة المعطوبة سمحت لأمل (مستخدمة عادية) بحذف كل المستخدمين، لأنها صدقت الدور الذي أرسلته أمل عن نفسها. وهذا تصعيد صلاحيات Privilege Escalation: مستخدم يرفع صلاحيته إلى ما لا يحق له.
- النقطة السليمة تجاهلت ما ادعته أمل، ورجعت إلى سجل الخادم عن أمل (دورها الحقيقي `user`)، فرفضت. والمدير الحقيقي وحده نجح.
- القاعدة: لا تثق أبداً ببيانات يرسلها العميل عن صلاحياته أو هويته. فالعميل يخبرك من يدعي أنه (ويثبته الرمز الموقع)، لكن ماذا يحق له يقرره الخادم من سجلاته هو، لا من كلام العميل. وكل حقل يرسله العميل (رقم مورد، دور، معرف مستخدم) هو مدخل غير موثوق حتى يتحقق منه الخادم.

وبعد التجربتين لا يبقى شيء يحتاج تنظيفاً، فكل شيء جرى داخل حاوية مؤقتة بالخيار `--rm`، ولم نمس أي نظام خارجها.

## أين يجب أن يعيش التفويض؟

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

وهذه الفكرة هي نفسها مبدأ المراقب المرجعي Reference Monitor الذي ذكرناه في مقال تاريخ الأمن: نقطة فحص واحدة لا يمكن تجاوزها، تستدعى في كل وصول، صغيرة بما يكفي لمراجعتها. فمن بنى تفويضه على هذا المبدأ ضمن أن النسيان في مكان لا يفتح ثغرة، لأن لا طريق إلى المورد يتجاوز نقطة الفحص. ومن وزع فحص التفويض في مئة مكان ترك لنفسه مئة فرصة للنسيان، وتكفي واحدة.

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

ونقطة تصميم أخرى: افصل قرار التفويض عن منطق العمل. أي أن تكون قواعد «من يحق له ماذا» في مكان واضح يمكن مراجعته وتدقيقه، لا مبعثرة داخل كود كل ميزة. فهذا يسهل المراجعة (يستطيع مدقق أن يقرأ القواعد في مكان واحد)، والتغيير (تعدل القاعدة مرة)، والاختبار (تختبر القرار معزولاً). وهذا بالضبط ما فعلناه في المختبر حين وضعنا `may_read` دالة مستقلة: فصلنا قرار الصلاحية عن جلب الوثيقة، فصار القرار واضحاً قابلاً للفحص.

## أخطاء شائعة Common Mistakes

- **الاكتفاء بالمصادقة:** «المستخدم سجل دخوله، إذاً يحق له» خطأ، فالدخول يثبت الهوية لا الصلاحية. افحص التفويض عند كل طلب.
- **الوثوق بمعرف الكائن في الطلب:** قبول رقم الوثيقة أو المستخدم دون التحقق أن صاحب الطلب يملكه، وهو ثغرة BOLA/IDOR.
- **الوثوق ببيانات العميل عن نفسه:** تصديق دور أو صلاحية يرسلها العميل، وهو تصعيد صلاحيات. القرار من سجل الخادم لا من كلام العميل.
- **إخفاء الزر بدل منع الفعل:** إخفاء زر «حذف» من الواجهة لا يحمي، فالمهاجم يرسل الطلب مباشرة. المنع يكون في الخادم عند تنفيذ الفعل، لا في الواجهة.
- **التحقق في مكان واحد ونسيان غيره:** فحص التفويض في بعض النقاط ونسيانه في أخرى (واجهة برمجية قديمة، تصدير بيانات). يجب أن يكون الفحص مركزياً يمر به كل طلب.
- **إعطاء صلاحيات زائدة «احتياطاً»:** منح دور أوسع مما يحتاج العمل يخالف مبدأ أقل صلاحية، ويكبر الضرر عند أي اختراق.
- **الخلط في الأدوار مع الوقت:** تراكم الصلاحيات حين ينتقل الموظف بين الأدوار دون إزالة القديمة (زحف الصلاحيات)، فيجمع صلاحيات لا يحتاجها. راجع الأدوار دورياً.

## الجانب السعودي

الضوابط الأساسية للأمن السيبراني ECC تعالج هذا في إدارة الهوية والوصول (المكون 2-2)، وتجمع المصادقة والتفويض معاً: فهي تطلب المصادقة متعددة العوامل للدخول عن بعد وللحسابات المميزة (وهذا جانب المصادقة)، وتطلب منح الصلاحيات بناء على مبادئ الحاجة إلى المعرفة Need-to-Know والحاجة إلى الاستخدام Need-to-Use والحد الأدنى من الصلاحيات وفصل المهام Segregation of Duties (وهذا جانب التفويض)، وتطلب المراجعة الدورية للهويات والصلاحيات. ولاحظ أن الضوابط لا تفصل بين المفهومين في مكونات منفصلة، لأنهما في العمل يعملان معاً: تثبت الهوية ثم تمنح الصلاحية المناسبة لها فقط. وشرح قراءة الضوابط في [مقال الضوابط الأساسية NCA ECC](https://arabroot.io/articles/%D8%A7%D9%84%D8%B6%D9%88%D8%A7%D8%A8%D8%B7-%D8%A7%D9%84%D8%A7%D8%B3%D8%A7%D8%B3%D9%8A%D8%A9-%D9%84%D9%84%D8%A7%D9%85%D9%86-%D8%A7%D9%84%D8%B3%D9%8A%D8%A8%D8%B1%D8%A7%D9%86%D9%8A-nca-ecc-%D8%A8%D9%84%D8%BA%D8%A9-%D8%A8%D8%B3%D9%8A%D8%B7%D8%A9/).

## إلى أين بعد هذا المقال؟

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

وهذا المقال هو الأساس الذي تبنى عليه بقية مرحلة الهوية. فبعد أن فهمت الفرق بين «من أنت؟» و«ماذا يحق لك؟»، تأتي المقالات التي تعمق كل جانب: كيف يتذكرك الموقع بعد الدخول (الجلسات وJWT)، وكيف تسمح لتطبيق بالوصول نيابة عنك دون أن تعطيه كلمة مرورك (OAuth وOpenID Connect)، وكيف تدار الهوية والوصول في المؤسسة (IAM وPAM):

[![](https://arabroot.io/content/images/2026/10/sessions-cookies-jwt-cover-cover.webp)دليلكيف يتذكرك الموقع بعد تسجيل الدخول؟ الجلسات وJWTبروتوكول HTTP لا يتذكر أحداً، فكيف يبقى المستخدم مسجلاً بين الصفحات، ومتى تختار الجلسة على السيرفر ومتى تختار JWT.](https://arabroot.io/articles/%D8%A7%D9%84%D8%AC%D9%84%D8%B3%D8%A7%D8%AA-%D9%88%D9%85%D9%84%D9%81%D8%A7%D8%AA-%D8%AA%D8%B9%D8%B1%D9%8A%D9%81-%D8%A7%D9%84%D8%A7%D8%B1%D8%AA%D8%A8%D8%A7%D8%B7-%D9%88-jwt-%D9%84%D9%84%D9%85%D8%A8%D8%AA%D8%AF%D8%A6%D9%8A%D9%86/)[![](https://arabroot.io/content/images/2026/10/oauth-oidc-cover-cover.webp)دليلشرح OAuth وOpenID Connect للمبتدئينلماذا لا يجب أن يعرف أي تطبيق كلمة مرورك، وكيف يحل OAuth ذلك بتوكنات محدودة، وكيف يضيف OpenID Connect الدخول الموحد.](https://arabroot.io/articles/%D8%B4%D8%B1%D8%AD-oauth-%D9%88-openid-connect-%D9%84%D9%84%D9%85%D8%A8%D8%AA%D8%AF%D8%A6%D9%8A%D9%86/)[![](https://arabroot.io/content/images/2026/10/iam-pam-cover-cover.webp)دليلإدارة الهوية والوصول IAM والوصول المميز PAMمن يملك صلاحية root على سيرفراتك ومنذ متى، وكيف تضبط حسابات المديرين بصلاحيات مؤقتة وجلسات مسجلة.](https://arabroot.io/articles/%D8%A7%D8%AF%D8%A7%D8%B1%D8%A9-%D8%A7%D9%84%D9%87%D9%88%D9%8A%D8%A9-%D9%88%D8%A7%D9%84%D9%88%D8%B5%D9%88%D9%84-iam-%D9%88%D8%A7%D9%84%D9%88%D8%B5%D9%88%D9%84-%D8%A7%D9%84%D9%85%D9%85%D9%8A%D8%B2-pam/)

## الخلاصة

وصلنا لنهاية الموضوع، وقد رأينا أن المصادقة والتفويض سؤالان لا سؤال واحد، وأن الخلط بينهما ليس مسألة لغوية، بل جذر أكثر ثغرات الويب شيوعاً. وأهم ما يجب أن تتذكره:

- المصادقة تجيب «من أنت؟»، والتفويض يجيب «ماذا يحق لك؟»، وهما بابان متتابعان لا باب واحد.
- المصادقة تحدث مرة عند الدخول وتنتهي بإثبات محمول موقع، والتفويض يتكرر عند كل طلب لكل كائن.
- أكثر النماذج شيوعاً للتفويض هو RBAC بالأدوار، ويحكمها جميعاً مبدأ أقل صلاحية.
- رأينا بالتجربة ثغرة BOLA/IDOR: مصادقة سليمة بلا تفويض تسرب وثيقة مستخدم آخر، وإصلاحها سطر واحد.
- لا تثق ببيانات العميل عن صلاحياته: من أنت يثبته الرمز، وماذا يحق لك يقرره الخادم من سجلاته.
- اجعل التفويض مركزياً لا يمكن تجاوزه، وافصل قراره عن منطق العمل ليسهل مراجعته وتغييره.
- التحكم في الوصول المعطل أكثر ثغرات الويب شيوعاً (A01 في OWASP، في 94% من التطبيقات)، وجذره دائماً الخلط بين السؤالين.

## تدريب عملي Practice

- أضف إلى خدمة المختبر نقطة «تعديل وثيقة» `update_doc`، وتأكد أنها تفحص التفويض (هل يملك المستخدم الوثيقة؟) قبل التعديل، لا بعده.
- أضف دوراً ثالثاً «مراجع» يستطيع القراءة فقط لا الكتابة، وطبق RBAC في دالة `may_read` ودالة جديدة `may_write`، واختبرهما.
- افتح أي تطبيق تستخدمه، وراقب الروابط التي تحمل رقماً (مثل `?id=42`): فكر، دون أن تجرب على نظام لا تملكه، في السؤال الذي يجب أن يسأله الخادم عن ذلك الرقم قبل أن يعيد البيانات.
- ارسم على ورقة نظاماً تعرفه (متجر، نظام موارد بشرية)، وحدد لكل دور فيه ما يحق له وما لا يحق، ثم اسأل: أين قد ينسى المبرمج فحص التفويض؟ فهذا تمرين تفكير المدافع.

## سجل التحديثات

- أكتوبر 2026: كتابة المقال، وبناء خدمة تفصل المصادقة عن التفويض على python:3.13.17-slim، وتجربة ثغرتي BOLA/IDOR وتصعيد الصلاحيات وإصلاحهما.